@google/gemini-cli 0.18.0-nightly.20251118.7cc5234b9 → 0.18.0-preview.0

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 (240) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +1 -0
  3. package/dist/package.json +4 -4
  4. package/dist/src/commands/extensions/disable.test.js +19 -13
  5. package/dist/src/commands/extensions/disable.test.js.map +1 -1
  6. package/dist/src/commands/extensions/enable.test.js +16 -9
  7. package/dist/src/commands/extensions/enable.test.js.map +1 -1
  8. package/dist/src/commands/extensions/link.test.js +18 -11
  9. package/dist/src/commands/extensions/link.test.js.map +1 -1
  10. package/dist/src/commands/extensions/list.test.js +20 -13
  11. package/dist/src/commands/extensions/list.test.js.map +1 -1
  12. package/dist/src/commands/extensions/uninstall.test.js +26 -18
  13. package/dist/src/commands/extensions/uninstall.test.js.map +1 -1
  14. package/dist/src/commands/extensions/update.test.js +20 -13
  15. package/dist/src/commands/extensions/update.test.js.map +1 -1
  16. package/dist/src/commands/mcp/add.test.js +8 -3
  17. package/dist/src/commands/mcp/add.test.js.map +1 -1
  18. package/dist/src/commands/mcp/list.test.js +1 -6
  19. package/dist/src/commands/mcp/list.test.js.map +1 -1
  20. package/dist/src/commands/mcp/remove.test.js +23 -12
  21. package/dist/src/commands/mcp/remove.test.js.map +1 -1
  22. package/dist/src/config/config.d.ts +2 -1
  23. package/dist/src/config/config.js +38 -14
  24. package/dist/src/config/config.js.map +1 -1
  25. package/dist/src/config/config.test.js +64 -10
  26. package/dist/src/config/config.test.js.map +1 -1
  27. package/dist/src/config/extension.test.js +131 -125
  28. package/dist/src/config/extension.test.js.map +1 -1
  29. package/dist/src/config/settingsSchema.d.ts +2 -2
  30. package/dist/src/config/settingsSchema.js +3 -3
  31. package/dist/src/config/settingsSchema.js.map +1 -1
  32. package/dist/src/config/settingsSchema.test.js +1 -1
  33. package/dist/src/config/settingsSchema.test.js.map +1 -1
  34. package/dist/src/gemini.js +65 -7
  35. package/dist/src/gemini.js.map +1 -1
  36. package/dist/src/gemini.test.js +55 -15
  37. package/dist/src/gemini.test.js.map +1 -1
  38. package/dist/src/generated/git-commit.d.ts +2 -2
  39. package/dist/src/generated/git-commit.js +2 -2
  40. package/dist/src/generated/git-commit.js.map +1 -1
  41. package/dist/src/nonInteractiveCli.js +4 -1
  42. package/dist/src/nonInteractiveCli.js.map +1 -1
  43. package/dist/src/nonInteractiveCli.test.js +2 -2
  44. package/dist/src/nonInteractiveCli.test.js.map +1 -1
  45. package/dist/src/services/CommandService.test.js +3 -2
  46. package/dist/src/services/CommandService.test.js.map +1 -1
  47. package/dist/src/services/McpPromptLoader.js +5 -3
  48. package/dist/src/services/McpPromptLoader.js.map +1 -1
  49. package/dist/src/services/McpPromptLoader.test.js +29 -1
  50. package/dist/src/services/McpPromptLoader.test.js.map +1 -1
  51. package/dist/src/test-utils/render.d.ts +26 -2
  52. package/dist/src/test-utils/render.js +76 -3
  53. package/dist/src/test-utils/render.js.map +1 -1
  54. package/dist/src/ui/AppContainer.js +57 -32
  55. package/dist/src/ui/AppContainer.js.map +1 -1
  56. package/dist/src/ui/AppContainer.test.js +169 -102
  57. package/dist/src/ui/AppContainer.test.js.map +1 -1
  58. package/dist/src/ui/auth/AuthDialog.test.js +2 -2
  59. package/dist/src/ui/auth/AuthDialog.test.js.map +1 -1
  60. package/dist/src/ui/commands/aboutCommand.js +8 -1
  61. package/dist/src/ui/commands/aboutCommand.js.map +1 -1
  62. package/dist/src/ui/commands/aboutCommand.test.js +4 -0
  63. package/dist/src/ui/commands/aboutCommand.test.js.map +1 -1
  64. package/dist/src/ui/commands/clearCommand.js +12 -0
  65. package/dist/src/ui/commands/clearCommand.js.map +1 -1
  66. package/dist/src/ui/commands/clearCommand.test.js +5 -0
  67. package/dist/src/ui/commands/clearCommand.test.js.map +1 -1
  68. package/dist/src/ui/commands/memoryCommand.js +1 -0
  69. package/dist/src/ui/commands/memoryCommand.js.map +1 -1
  70. package/dist/src/ui/commands/memoryCommand.test.js +3 -0
  71. package/dist/src/ui/commands/memoryCommand.test.js.map +1 -1
  72. package/dist/src/ui/commands/setupGithubCommand.d.ts +1 -0
  73. package/dist/src/ui/commands/setupGithubCommand.js +82 -45
  74. package/dist/src/ui/commands/setupGithubCommand.js.map +1 -1
  75. package/dist/src/ui/commands/setupGithubCommand.test.js +35 -5
  76. package/dist/src/ui/commands/setupGithubCommand.test.js.map +1 -1
  77. package/dist/src/ui/components/AboutBox.d.ts +1 -0
  78. package/dist/src/ui/components/AboutBox.js +1 -1
  79. package/dist/src/ui/components/AboutBox.js.map +1 -1
  80. package/dist/src/ui/components/AppHeader.js +3 -8
  81. package/dist/src/ui/components/AppHeader.js.map +1 -1
  82. package/dist/src/ui/components/Banner.d.ts +4 -2
  83. package/dist/src/ui/components/Banner.js +18 -4
  84. package/dist/src/ui/components/Banner.js.map +1 -1
  85. package/dist/src/ui/components/DebugProfiler.d.ts +1 -0
  86. package/dist/src/ui/components/DebugProfiler.js +23 -34
  87. package/dist/src/ui/components/DebugProfiler.js.map +1 -1
  88. package/dist/src/ui/components/DebugProfiler.test.js +1 -0
  89. package/dist/src/ui/components/DebugProfiler.test.js.map +1 -1
  90. package/dist/src/ui/components/DialogManager.js +1 -1
  91. package/dist/src/ui/components/DialogManager.js.map +1 -1
  92. package/dist/src/ui/components/GradientRegression.test.js +22 -1
  93. package/dist/src/ui/components/GradientRegression.test.js.map +1 -1
  94. package/dist/src/ui/components/Header.test.js +27 -2
  95. package/dist/src/ui/components/Header.test.js.map +1 -1
  96. package/dist/src/ui/components/HistoryItemDisplay.js +1 -1
  97. package/dist/src/ui/components/HistoryItemDisplay.js.map +1 -1
  98. package/dist/src/ui/components/InputPrompt.js +16 -24
  99. package/dist/src/ui/components/InputPrompt.js.map +1 -1
  100. package/dist/src/ui/components/InputPrompt.test.js +84 -24
  101. package/dist/src/ui/components/InputPrompt.test.js.map +1 -1
  102. package/dist/src/ui/components/ModelDialog.js +2 -2
  103. package/dist/src/ui/components/ModelDialog.js.map +1 -1
  104. package/dist/src/ui/components/SettingsDialog.d.ts +3 -1
  105. package/dist/src/ui/components/SettingsDialog.js +4 -1
  106. package/dist/src/ui/components/SettingsDialog.js.map +1 -1
  107. package/dist/src/ui/components/ThemedGradient.js +2 -1
  108. package/dist/src/ui/components/ThemedGradient.js.map +1 -1
  109. package/dist/src/ui/components/messages/ShellToolMessage.d.ts +14 -0
  110. package/dist/src/ui/components/messages/ShellToolMessage.js +76 -0
  111. package/dist/src/ui/components/messages/ShellToolMessage.js.map +1 -0
  112. package/dist/src/ui/components/messages/ShellToolMessage.test.d.ts +6 -0
  113. package/dist/src/ui/components/messages/ShellToolMessage.test.js +123 -0
  114. package/dist/src/ui/components/messages/ShellToolMessage.test.js.map +1 -0
  115. package/dist/src/ui/components/messages/ToolGroupMessage.js +19 -1
  116. package/dist/src/ui/components/messages/ToolGroupMessage.js.map +1 -1
  117. package/dist/src/ui/components/messages/ToolMessage.d.ts +3 -6
  118. package/dist/src/ui/components/messages/ToolMessage.js +5 -121
  119. package/dist/src/ui/components/messages/ToolMessage.js.map +1 -1
  120. package/dist/src/ui/components/messages/ToolMessage.test.js +13 -5
  121. package/dist/src/ui/components/messages/ToolMessage.test.js.map +1 -1
  122. package/dist/src/ui/components/messages/ToolResultDisplay.d.ts +13 -0
  123. package/dist/src/ui/components/messages/ToolResultDisplay.js +54 -0
  124. package/dist/src/ui/components/messages/ToolResultDisplay.js.map +1 -0
  125. package/dist/src/ui/components/messages/ToolShared.d.ts +23 -0
  126. package/dist/src/ui/components/messages/ToolShared.js +40 -0
  127. package/dist/src/ui/components/messages/ToolShared.js.map +1 -0
  128. package/dist/src/ui/components/shared/text-buffer.js +4 -1
  129. package/dist/src/ui/components/shared/text-buffer.js.map +1 -1
  130. package/dist/src/ui/contexts/KeypressContext.js +21 -11
  131. package/dist/src/ui/contexts/KeypressContext.js.map +1 -1
  132. package/dist/src/ui/contexts/KeypressContext.test.js +29 -10
  133. package/dist/src/ui/contexts/KeypressContext.test.js.map +1 -1
  134. package/dist/src/ui/contexts/UIActionsContext.d.ts +1 -0
  135. package/dist/src/ui/contexts/UIActionsContext.js.map +1 -1
  136. package/dist/src/ui/hooks/shellCommandProcessor.js +8 -4
  137. package/dist/src/ui/hooks/shellCommandProcessor.js.map +1 -1
  138. package/dist/src/ui/hooks/shellCommandProcessor.test.js +4 -3
  139. package/dist/src/ui/hooks/shellCommandProcessor.test.js.map +1 -1
  140. package/dist/src/ui/hooks/slashCommandProcessor.d.ts +1 -1
  141. package/dist/src/ui/hooks/slashCommandProcessor.js +5 -3
  142. package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
  143. package/dist/src/ui/hooks/useBracketedPaste.js +3 -2
  144. package/dist/src/ui/hooks/useBracketedPaste.js.map +1 -1
  145. package/dist/src/ui/hooks/useCommandCompletion.test.js +5 -5
  146. package/dist/src/ui/hooks/useCommandCompletion.test.js.map +1 -1
  147. package/dist/src/ui/hooks/useConsoleMessages.d.ts +0 -1
  148. package/dist/src/ui/hooks/useConsoleMessages.js +26 -1
  149. package/dist/src/ui/hooks/useConsoleMessages.js.map +1 -1
  150. package/dist/src/ui/hooks/useConsoleMessages.test.js +37 -5
  151. package/dist/src/ui/hooks/useConsoleMessages.test.js.map +1 -1
  152. package/dist/src/ui/hooks/useEditorSettings.d.ts +2 -2
  153. package/dist/src/ui/hooks/useEditorSettings.js.map +1 -1
  154. package/dist/src/ui/hooks/useEditorSettings.test.js.map +1 -1
  155. package/dist/src/ui/hooks/useGeminiStream.d.ts +1 -1
  156. package/dist/src/ui/hooks/useGeminiStream.js +48 -10
  157. package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
  158. package/dist/src/ui/hooks/useGeminiStream.test.js +20 -21
  159. package/dist/src/ui/hooks/useGeminiStream.test.js.map +1 -1
  160. package/dist/src/ui/hooks/useHistoryManager.d.ts +5 -2
  161. package/dist/src/ui/hooks/useHistoryManager.js +39 -3
  162. package/dist/src/ui/hooks/useHistoryManager.js.map +1 -1
  163. package/dist/src/ui/hooks/useIncludeDirsTrust.js +0 -1
  164. package/dist/src/ui/hooks/useIncludeDirsTrust.js.map +1 -1
  165. package/dist/src/ui/hooks/useInputHistoryStore.test.js +4 -1
  166. package/dist/src/ui/hooks/useInputHistoryStore.test.js.map +1 -1
  167. package/dist/src/ui/hooks/useKittyKeyboardProtocol.d.ts +0 -1
  168. package/dist/src/ui/hooks/useKittyKeyboardProtocol.js +1 -2
  169. package/dist/src/ui/hooks/useKittyKeyboardProtocol.js.map +1 -1
  170. package/dist/src/ui/hooks/useMouseClick.d.ts +12 -0
  171. package/dist/src/ui/hooks/useMouseClick.js +28 -0
  172. package/dist/src/ui/hooks/useMouseClick.js.map +1 -0
  173. package/dist/src/ui/hooks/useMouseClick.test.d.ts +6 -0
  174. package/dist/src/ui/hooks/useMouseClick.test.js +59 -0
  175. package/dist/src/ui/hooks/useMouseClick.test.js.map +1 -0
  176. package/dist/src/ui/hooks/useReactToolScheduler.d.ts +1 -1
  177. package/dist/src/ui/hooks/useReactToolScheduler.js +1 -8
  178. package/dist/src/ui/hooks/useReactToolScheduler.js.map +1 -1
  179. package/dist/src/ui/hooks/useReactToolScheduler.test.js +1 -8
  180. package/dist/src/ui/hooks/useReactToolScheduler.test.js.map +1 -1
  181. package/dist/src/ui/hooks/useReverseSearchCompletion.test.js +18 -12
  182. package/dist/src/ui/hooks/useReverseSearchCompletion.test.js.map +1 -1
  183. package/dist/src/ui/hooks/useSessionBrowser.js +13 -4
  184. package/dist/src/ui/hooks/useSessionBrowser.js.map +1 -1
  185. package/dist/src/ui/hooks/useSessionBrowser.test.js +37 -0
  186. package/dist/src/ui/hooks/useSessionBrowser.test.js.map +1 -1
  187. package/dist/src/ui/hooks/useSessionResume.js +1 -1
  188. package/dist/src/ui/hooks/useSessionResume.js.map +1 -1
  189. package/dist/src/ui/hooks/useSessionResume.test.js +4 -4
  190. package/dist/src/ui/hooks/useSessionResume.test.js.map +1 -1
  191. package/dist/src/ui/hooks/useThemeCommand.d.ts +2 -2
  192. package/dist/src/ui/hooks/useThemeCommand.js.map +1 -1
  193. package/dist/src/ui/hooks/useToolScheduler.test.js +2 -2
  194. package/dist/src/ui/hooks/useToolScheduler.test.js.map +1 -1
  195. package/dist/src/ui/themes/theme-manager.test.js +2 -1
  196. package/dist/src/ui/themes/theme-manager.test.js.map +1 -1
  197. package/dist/src/ui/types.d.ts +2 -0
  198. package/dist/src/ui/types.js.map +1 -1
  199. package/dist/src/ui/utils/ConsolePatcher.js +6 -9
  200. package/dist/src/ui/utils/ConsolePatcher.js.map +1 -1
  201. package/dist/src/ui/utils/kittyProtocolDetector.d.ts +6 -2
  202. package/dist/src/ui/utils/kittyProtocolDetector.js +48 -43
  203. package/dist/src/ui/utils/kittyProtocolDetector.js.map +1 -1
  204. package/dist/src/ui/utils/mouse.js +3 -3
  205. package/dist/src/ui/utils/mouse.js.map +1 -1
  206. package/dist/src/utils/cleanup.d.ts +2 -0
  207. package/dist/src/utils/cleanup.js +16 -0
  208. package/dist/src/utils/cleanup.js.map +1 -1
  209. package/dist/src/utils/errors.js +10 -0
  210. package/dist/src/utils/errors.js.map +1 -1
  211. package/dist/src/utils/events.d.ts +0 -2
  212. package/dist/src/utils/events.js +0 -1
  213. package/dist/src/utils/events.js.map +1 -1
  214. package/dist/src/utils/installationInfo.test.js +8 -9
  215. package/dist/src/utils/installationInfo.test.js.map +1 -1
  216. package/dist/src/utils/sessionCleanup.test.js +4 -2
  217. package/dist/src/utils/sessionCleanup.test.js.map +1 -1
  218. package/dist/src/utils/sessionUtils.d.ts +5 -0
  219. package/dist/src/utils/sessionUtils.js +6 -1
  220. package/dist/src/utils/sessionUtils.js.map +1 -1
  221. package/dist/src/utils/sessions.test.d.ts +6 -0
  222. package/dist/src/utils/sessions.test.js +516 -0
  223. package/dist/src/utils/sessions.test.js.map +1 -0
  224. package/dist/src/utils/stdio.d.ts +32 -0
  225. package/dist/src/utils/stdio.js +85 -0
  226. package/dist/src/utils/stdio.js.map +1 -0
  227. package/dist/src/utils/stdio.test.d.ts +6 -0
  228. package/dist/src/utils/stdio.test.js +47 -0
  229. package/dist/src/utils/stdio.test.js.map +1 -0
  230. package/dist/src/validateNonInterActiveAuth.js +2 -0
  231. package/dist/src/validateNonInterActiveAuth.js.map +1 -1
  232. package/dist/src/validateNonInterActiveAuth.test.js +10 -6
  233. package/dist/src/validateNonInterActiveAuth.test.js.map +1 -1
  234. package/dist/src/zed-integration/schema.d.ts +30 -30
  235. package/dist/src/zed-integration/zedIntegration.d.ts +0 -7
  236. package/dist/src/zed-integration/zedIntegration.js +9 -21
  237. package/dist/src/zed-integration/zedIntegration.js.map +1 -1
  238. package/dist/tsconfig.tsbuildinfo +1 -1
  239. package/package.json +5 -5
  240. package/dist/google-gemini-cli-0.18.0-nightly.20251118.86828bb56.tgz +0 -0
@@ -0,0 +1,516 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
7
+ import { ChatRecordingService } from '@google/gemini-cli-core';
8
+ import { listSessions, deleteSession } from './sessions.js';
9
+ import { SessionSelector } from './sessionUtils.js';
10
+ // Mock the SessionSelector and ChatRecordingService
11
+ vi.mock('./sessionUtils.js', () => ({
12
+ SessionSelector: vi.fn(),
13
+ formatRelativeTime: vi.fn(() => 'some time ago'),
14
+ }));
15
+ vi.mock('@google/gemini-cli-core', async () => {
16
+ const actual = await vi.importActual('@google/gemini-cli-core');
17
+ return {
18
+ ...actual,
19
+ ChatRecordingService: vi.fn(),
20
+ };
21
+ });
22
+ describe('listSessions', () => {
23
+ let mockConfig;
24
+ let mockListSessions;
25
+ let consoleLogSpy;
26
+ beforeEach(() => {
27
+ // Create mock config
28
+ mockConfig = {
29
+ storage: {
30
+ getProjectTempDir: vi.fn().mockReturnValue('/tmp/test-project'),
31
+ },
32
+ getSessionId: vi.fn().mockReturnValue('current-session-id'),
33
+ };
34
+ // Create mock listSessions method
35
+ mockListSessions = vi.fn();
36
+ // Mock SessionSelector constructor to return object with listSessions method
37
+ vi.mocked(SessionSelector).mockImplementation(() => ({
38
+ listSessions: mockListSessions,
39
+ }));
40
+ // Spy on console.log
41
+ consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
42
+ });
43
+ afterEach(() => {
44
+ vi.clearAllMocks();
45
+ consoleLogSpy.mockRestore();
46
+ });
47
+ it('should display message when no previous sessions were found', async () => {
48
+ // Arrange: Return empty array from listSessions
49
+ mockListSessions.mockResolvedValue([]);
50
+ // Act
51
+ await listSessions(mockConfig);
52
+ // Assert
53
+ expect(mockListSessions).toHaveBeenCalledOnce();
54
+ expect(consoleLogSpy).toHaveBeenCalledWith('No previous sessions found for this project.');
55
+ });
56
+ it('should list sessions when sessions are found', async () => {
57
+ // Arrange: Create test sessions
58
+ const now = new Date('2025-01-20T12:00:00.000Z');
59
+ const oneHourAgo = new Date(now.getTime() - 60 * 60 * 1000);
60
+ const twoDaysAgo = new Date(now.getTime() - 2 * 24 * 60 * 60 * 1000);
61
+ const mockSessions = [
62
+ {
63
+ id: 'session-1',
64
+ file: 'session-2025-01-18T12-00-00-session-1',
65
+ fileName: 'session-2025-01-18T12-00-00-session-1.json',
66
+ startTime: twoDaysAgo.toISOString(),
67
+ lastUpdated: twoDaysAgo.toISOString(),
68
+ firstUserMessage: 'First user message',
69
+ isCurrentSession: false,
70
+ index: 1,
71
+ },
72
+ {
73
+ id: 'session-2',
74
+ file: 'session-2025-01-20T11-00-00-session-2',
75
+ fileName: 'session-2025-01-20T11-00-00-session-2.json',
76
+ startTime: oneHourAgo.toISOString(),
77
+ lastUpdated: oneHourAgo.toISOString(),
78
+ firstUserMessage: 'Second user message',
79
+ isCurrentSession: false,
80
+ index: 2,
81
+ },
82
+ {
83
+ id: 'current-session-id',
84
+ file: 'session-2025-01-20T12-00-00-current-s',
85
+ fileName: 'session-2025-01-20T12-00-00-current-s.json',
86
+ startTime: now.toISOString(),
87
+ lastUpdated: now.toISOString(),
88
+ firstUserMessage: 'Current session',
89
+ isCurrentSession: true,
90
+ index: 3,
91
+ },
92
+ ];
93
+ mockListSessions.mockResolvedValue(mockSessions);
94
+ // Act
95
+ await listSessions(mockConfig);
96
+ // Assert
97
+ expect(mockListSessions).toHaveBeenCalledOnce();
98
+ // Check that the header was displayed
99
+ expect(consoleLogSpy).toHaveBeenCalledWith('\nAvailable sessions for this project (3):\n');
100
+ // Check that each session was logged
101
+ expect(consoleLogSpy).toHaveBeenCalledWith(expect.stringContaining('1. First user message'));
102
+ expect(consoleLogSpy).toHaveBeenCalledWith(expect.stringContaining('[session-1]'));
103
+ expect(consoleLogSpy).toHaveBeenCalledWith(expect.stringContaining('2. Second user message'));
104
+ expect(consoleLogSpy).toHaveBeenCalledWith(expect.stringContaining('[session-2]'));
105
+ expect(consoleLogSpy).toHaveBeenCalledWith(expect.stringContaining('3. Current session'));
106
+ expect(consoleLogSpy).toHaveBeenCalledWith(expect.stringContaining(', current)'));
107
+ expect(consoleLogSpy).toHaveBeenCalledWith(expect.stringContaining('[current-session-id]'));
108
+ });
109
+ it('should sort sessions by start time (oldest first)', async () => {
110
+ // Arrange: Create sessions in non-chronological order
111
+ const session1Time = new Date('2025-01-18T12:00:00.000Z');
112
+ const session2Time = new Date('2025-01-19T12:00:00.000Z');
113
+ const session3Time = new Date('2025-01-20T12:00:00.000Z');
114
+ const mockSessions = [
115
+ {
116
+ id: 'session-2',
117
+ file: 'session-2',
118
+ fileName: 'session-2.json',
119
+ startTime: session2Time.toISOString(), // Middle
120
+ lastUpdated: session2Time.toISOString(),
121
+ firstUserMessage: 'Middle session',
122
+ isCurrentSession: false,
123
+ index: 2,
124
+ },
125
+ {
126
+ id: 'session-1',
127
+ file: 'session-1',
128
+ fileName: 'session-1.json',
129
+ startTime: session1Time.toISOString(), // Oldest
130
+ lastUpdated: session1Time.toISOString(),
131
+ firstUserMessage: 'Oldest session',
132
+ isCurrentSession: false,
133
+ index: 1,
134
+ },
135
+ {
136
+ id: 'session-3',
137
+ file: 'session-3',
138
+ fileName: 'session-3.json',
139
+ startTime: session3Time.toISOString(), // Newest
140
+ lastUpdated: session3Time.toISOString(),
141
+ firstUserMessage: 'Newest session',
142
+ isCurrentSession: false,
143
+ index: 3,
144
+ },
145
+ ];
146
+ mockListSessions.mockResolvedValue(mockSessions);
147
+ // Act
148
+ await listSessions(mockConfig);
149
+ // Assert
150
+ // Get all the session log calls (skip the header)
151
+ const sessionCalls = consoleLogSpy.mock.calls.filter((call) => typeof call[0] === 'string' &&
152
+ call[0].includes('[session-') &&
153
+ !call[0].includes('Available sessions'));
154
+ // Verify they are sorted by start time (oldest first)
155
+ expect(sessionCalls[0][0]).toContain('1. Oldest session');
156
+ expect(sessionCalls[1][0]).toContain('2. Middle session');
157
+ expect(sessionCalls[2][0]).toContain('3. Newest session');
158
+ });
159
+ it('should format session output with relative time and session ID', async () => {
160
+ // Arrange
161
+ const now = new Date('2025-01-20T12:00:00.000Z');
162
+ const mockSessions = [
163
+ {
164
+ id: 'abc123def456',
165
+ file: 'session-file',
166
+ fileName: 'session-file.json',
167
+ startTime: now.toISOString(),
168
+ lastUpdated: now.toISOString(),
169
+ firstUserMessage: 'Test message',
170
+ isCurrentSession: false,
171
+ index: 1,
172
+ },
173
+ ];
174
+ mockListSessions.mockResolvedValue(mockSessions);
175
+ // Act
176
+ await listSessions(mockConfig);
177
+ // Assert
178
+ expect(consoleLogSpy).toHaveBeenCalledWith(expect.stringContaining('1. Test message'));
179
+ expect(consoleLogSpy).toHaveBeenCalledWith(expect.stringContaining('some time ago'));
180
+ expect(consoleLogSpy).toHaveBeenCalledWith(expect.stringContaining('[abc123def456]'));
181
+ });
182
+ it('should handle single session', async () => {
183
+ // Arrange
184
+ const now = new Date('2025-01-20T12:00:00.000Z');
185
+ const mockSessions = [
186
+ {
187
+ id: 'single-session',
188
+ file: 'session-file',
189
+ fileName: 'session-file.json',
190
+ startTime: now.toISOString(),
191
+ lastUpdated: now.toISOString(),
192
+ firstUserMessage: 'Only session',
193
+ isCurrentSession: true,
194
+ index: 1,
195
+ },
196
+ ];
197
+ mockListSessions.mockResolvedValue(mockSessions);
198
+ // Act
199
+ await listSessions(mockConfig);
200
+ // Assert
201
+ expect(consoleLogSpy).toHaveBeenCalledWith('\nAvailable sessions for this project (1):\n');
202
+ expect(consoleLogSpy).toHaveBeenCalledWith(expect.stringContaining('1. Only session'));
203
+ expect(consoleLogSpy).toHaveBeenCalledWith(expect.stringContaining(', current)'));
204
+ });
205
+ });
206
+ describe('deleteSession', () => {
207
+ let mockConfig;
208
+ let mockListSessions;
209
+ let mockDeleteSession;
210
+ let consoleLogSpy;
211
+ let consoleErrorSpy;
212
+ beforeEach(() => {
213
+ // Create mock config
214
+ mockConfig = {
215
+ storage: {
216
+ getProjectTempDir: vi.fn().mockReturnValue('/tmp/test-project'),
217
+ },
218
+ getSessionId: vi.fn().mockReturnValue('current-session-id'),
219
+ };
220
+ // Create mock methods
221
+ mockListSessions = vi.fn();
222
+ mockDeleteSession = vi.fn();
223
+ // Mock SessionSelector constructor
224
+ vi.mocked(SessionSelector).mockImplementation(() => ({
225
+ listSessions: mockListSessions,
226
+ }));
227
+ // Mock ChatRecordingService
228
+ vi.mocked(ChatRecordingService).mockImplementation(() => ({
229
+ deleteSession: mockDeleteSession,
230
+ }));
231
+ // Spy on console methods
232
+ consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
233
+ consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => { });
234
+ });
235
+ afterEach(() => {
236
+ vi.clearAllMocks();
237
+ consoleLogSpy.mockRestore();
238
+ consoleErrorSpy.mockRestore();
239
+ });
240
+ it('should display error when no sessions are found', async () => {
241
+ // Arrange
242
+ mockListSessions.mockResolvedValue([]);
243
+ // Act
244
+ await deleteSession(mockConfig, '1');
245
+ // Assert
246
+ expect(mockListSessions).toHaveBeenCalledOnce();
247
+ expect(consoleErrorSpy).toHaveBeenCalledWith('No sessions found for this project.');
248
+ expect(mockDeleteSession).not.toHaveBeenCalled();
249
+ });
250
+ it('should delete session by UUID', async () => {
251
+ // Arrange
252
+ const now = new Date('2025-01-20T12:00:00.000Z');
253
+ const mockSessions = [
254
+ {
255
+ id: 'session-uuid-123',
256
+ file: 'session-file-123',
257
+ fileName: 'session-file-123.json',
258
+ startTime: now.toISOString(),
259
+ lastUpdated: now.toISOString(),
260
+ firstUserMessage: 'Test session',
261
+ isCurrentSession: false,
262
+ index: 1,
263
+ },
264
+ ];
265
+ mockListSessions.mockResolvedValue(mockSessions);
266
+ mockDeleteSession.mockImplementation(() => { });
267
+ // Act
268
+ await deleteSession(mockConfig, 'session-uuid-123');
269
+ // Assert
270
+ expect(mockListSessions).toHaveBeenCalledOnce();
271
+ expect(mockDeleteSession).toHaveBeenCalledWith('session-file-123');
272
+ expect(consoleLogSpy).toHaveBeenCalledWith('Deleted session 1: Test session (some time ago)');
273
+ expect(consoleErrorSpy).not.toHaveBeenCalled();
274
+ });
275
+ it('should delete session by index', async () => {
276
+ // Arrange
277
+ const now = new Date('2025-01-20T12:00:00.000Z');
278
+ const oneHourAgo = new Date(now.getTime() - 60 * 60 * 1000);
279
+ const mockSessions = [
280
+ {
281
+ id: 'session-1',
282
+ file: 'session-file-1',
283
+ fileName: 'session-file-1.json',
284
+ startTime: oneHourAgo.toISOString(),
285
+ lastUpdated: oneHourAgo.toISOString(),
286
+ firstUserMessage: 'First session',
287
+ isCurrentSession: false,
288
+ index: 1,
289
+ },
290
+ {
291
+ id: 'session-2',
292
+ file: 'session-file-2',
293
+ fileName: 'session-file-2.json',
294
+ startTime: now.toISOString(),
295
+ lastUpdated: now.toISOString(),
296
+ firstUserMessage: 'Second session',
297
+ isCurrentSession: false,
298
+ index: 2,
299
+ },
300
+ ];
301
+ mockListSessions.mockResolvedValue(mockSessions);
302
+ mockDeleteSession.mockImplementation(() => { });
303
+ // Act
304
+ await deleteSession(mockConfig, '2');
305
+ // Assert
306
+ expect(mockListSessions).toHaveBeenCalledOnce();
307
+ expect(mockDeleteSession).toHaveBeenCalledWith('session-file-2');
308
+ expect(consoleLogSpy).toHaveBeenCalledWith('Deleted session 2: Second session (some time ago)');
309
+ });
310
+ it('should display error for invalid session identifier (non-numeric)', async () => {
311
+ // Arrange
312
+ const now = new Date('2025-01-20T12:00:00.000Z');
313
+ const mockSessions = [
314
+ {
315
+ id: 'session-1',
316
+ file: 'session-file-1',
317
+ fileName: 'session-file-1.json',
318
+ startTime: now.toISOString(),
319
+ lastUpdated: now.toISOString(),
320
+ firstUserMessage: 'Test session',
321
+ isCurrentSession: false,
322
+ index: 1,
323
+ },
324
+ ];
325
+ mockListSessions.mockResolvedValue(mockSessions);
326
+ // Act
327
+ await deleteSession(mockConfig, 'invalid-id');
328
+ // Assert
329
+ expect(consoleErrorSpy).toHaveBeenCalledWith('Invalid session identifier "invalid-id". Use --list-sessions to see available sessions.');
330
+ expect(mockDeleteSession).not.toHaveBeenCalled();
331
+ });
332
+ it('should display error for invalid session identifier (out of range)', async () => {
333
+ // Arrange
334
+ const now = new Date('2025-01-20T12:00:00.000Z');
335
+ const mockSessions = [
336
+ {
337
+ id: 'session-1',
338
+ file: 'session-file-1',
339
+ fileName: 'session-file-1.json',
340
+ startTime: now.toISOString(),
341
+ lastUpdated: now.toISOString(),
342
+ firstUserMessage: 'Test session',
343
+ isCurrentSession: false,
344
+ index: 1,
345
+ },
346
+ ];
347
+ mockListSessions.mockResolvedValue(mockSessions);
348
+ // Act
349
+ await deleteSession(mockConfig, '999');
350
+ // Assert
351
+ expect(consoleErrorSpy).toHaveBeenCalledWith('Invalid session identifier "999". Use --list-sessions to see available sessions.');
352
+ expect(mockDeleteSession).not.toHaveBeenCalled();
353
+ });
354
+ it('should display error for invalid session identifier (zero)', async () => {
355
+ // Arrange
356
+ const now = new Date('2025-01-20T12:00:00.000Z');
357
+ const mockSessions = [
358
+ {
359
+ id: 'session-1',
360
+ file: 'session-file-1',
361
+ fileName: 'session-file-1.json',
362
+ startTime: now.toISOString(),
363
+ lastUpdated: now.toISOString(),
364
+ firstUserMessage: 'Test session',
365
+ isCurrentSession: false,
366
+ index: 1,
367
+ },
368
+ ];
369
+ mockListSessions.mockResolvedValue(mockSessions);
370
+ // Act
371
+ await deleteSession(mockConfig, '0');
372
+ // Assert
373
+ expect(consoleErrorSpy).toHaveBeenCalledWith('Invalid session identifier "0". Use --list-sessions to see available sessions.');
374
+ expect(mockDeleteSession).not.toHaveBeenCalled();
375
+ });
376
+ it('should prevent deletion of current session', async () => {
377
+ // Arrange
378
+ const now = new Date('2025-01-20T12:00:00.000Z');
379
+ const mockSessions = [
380
+ {
381
+ id: 'current-session-id',
382
+ file: 'current-session-file',
383
+ fileName: 'current-session-file.json',
384
+ startTime: now.toISOString(),
385
+ lastUpdated: now.toISOString(),
386
+ firstUserMessage: 'Current session',
387
+ isCurrentSession: true,
388
+ index: 1,
389
+ },
390
+ ];
391
+ mockListSessions.mockResolvedValue(mockSessions);
392
+ // Act - try to delete by index
393
+ await deleteSession(mockConfig, '1');
394
+ // Assert
395
+ expect(consoleErrorSpy).toHaveBeenCalledWith('Cannot delete the current active session.');
396
+ expect(mockDeleteSession).not.toHaveBeenCalled();
397
+ });
398
+ it('should prevent deletion of current session by UUID', async () => {
399
+ // Arrange
400
+ const now = new Date('2025-01-20T12:00:00.000Z');
401
+ const mockSessions = [
402
+ {
403
+ id: 'current-session-id',
404
+ file: 'current-session-file',
405
+ fileName: 'current-session-file.json',
406
+ startTime: now.toISOString(),
407
+ lastUpdated: now.toISOString(),
408
+ firstUserMessage: 'Current session',
409
+ isCurrentSession: true,
410
+ index: 1,
411
+ },
412
+ ];
413
+ mockListSessions.mockResolvedValue(mockSessions);
414
+ // Act - try to delete by UUID
415
+ await deleteSession(mockConfig, 'current-session-id');
416
+ // Assert
417
+ expect(consoleErrorSpy).toHaveBeenCalledWith('Cannot delete the current active session.');
418
+ expect(mockDeleteSession).not.toHaveBeenCalled();
419
+ });
420
+ it('should handle deletion errors gracefully', async () => {
421
+ // Arrange
422
+ const now = new Date('2025-01-20T12:00:00.000Z');
423
+ const mockSessions = [
424
+ {
425
+ id: 'session-1',
426
+ file: 'session-file-1',
427
+ fileName: 'session-file-1.json',
428
+ startTime: now.toISOString(),
429
+ lastUpdated: now.toISOString(),
430
+ firstUserMessage: 'Test session',
431
+ isCurrentSession: false,
432
+ index: 1,
433
+ },
434
+ ];
435
+ mockListSessions.mockResolvedValue(mockSessions);
436
+ mockDeleteSession.mockImplementation(() => {
437
+ throw new Error('File deletion failed');
438
+ });
439
+ // Act
440
+ await deleteSession(mockConfig, '1');
441
+ // Assert
442
+ expect(mockDeleteSession).toHaveBeenCalledWith('session-file-1');
443
+ expect(consoleErrorSpy).toHaveBeenCalledWith('Failed to delete session: File deletion failed');
444
+ });
445
+ it('should handle non-Error deletion failures', async () => {
446
+ // Arrange
447
+ const now = new Date('2025-01-20T12:00:00.000Z');
448
+ const mockSessions = [
449
+ {
450
+ id: 'session-1',
451
+ file: 'session-file-1',
452
+ fileName: 'session-file-1.json',
453
+ startTime: now.toISOString(),
454
+ lastUpdated: now.toISOString(),
455
+ firstUserMessage: 'Test session',
456
+ isCurrentSession: false,
457
+ index: 1,
458
+ },
459
+ ];
460
+ mockListSessions.mockResolvedValue(mockSessions);
461
+ mockDeleteSession.mockImplementation(() => {
462
+ // eslint-disable-next-line no-restricted-syntax
463
+ throw 'Unknown error type';
464
+ });
465
+ // Act
466
+ await deleteSession(mockConfig, '1');
467
+ // Assert
468
+ expect(consoleErrorSpy).toHaveBeenCalledWith('Failed to delete session: Unknown error');
469
+ });
470
+ it('should sort sessions before finding by index', async () => {
471
+ // Arrange: Create sessions in non-chronological order
472
+ const session1Time = new Date('2025-01-18T12:00:00.000Z');
473
+ const session2Time = new Date('2025-01-19T12:00:00.000Z');
474
+ const session3Time = new Date('2025-01-20T12:00:00.000Z');
475
+ const mockSessions = [
476
+ {
477
+ id: 'session-3',
478
+ file: 'session-file-3',
479
+ fileName: 'session-file-3.json',
480
+ startTime: session3Time.toISOString(), // Newest
481
+ lastUpdated: session3Time.toISOString(),
482
+ firstUserMessage: 'Newest session',
483
+ isCurrentSession: false,
484
+ index: 3,
485
+ },
486
+ {
487
+ id: 'session-1',
488
+ file: 'session-file-1',
489
+ fileName: 'session-file-1.json',
490
+ startTime: session1Time.toISOString(), // Oldest
491
+ lastUpdated: session1Time.toISOString(),
492
+ firstUserMessage: 'Oldest session',
493
+ isCurrentSession: false,
494
+ index: 1,
495
+ },
496
+ {
497
+ id: 'session-2',
498
+ file: 'session-file-2',
499
+ fileName: 'session-file-2.json',
500
+ startTime: session2Time.toISOString(), // Middle
501
+ lastUpdated: session2Time.toISOString(),
502
+ firstUserMessage: 'Middle session',
503
+ isCurrentSession: false,
504
+ index: 2,
505
+ },
506
+ ];
507
+ mockListSessions.mockResolvedValue(mockSessions);
508
+ mockDeleteSession.mockImplementation(() => { });
509
+ // Act - delete index 1 (should be oldest session after sorting)
510
+ await deleteSession(mockConfig, '1');
511
+ // Assert
512
+ expect(mockDeleteSession).toHaveBeenCalledWith('session-file-1');
513
+ expect(consoleLogSpy).toHaveBeenCalledWith(expect.stringContaining('Oldest session'));
514
+ });
515
+ });
516
+ //# sourceMappingURL=sessions.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessions.test.js","sourceRoot":"","sources":["../../../src/utils/sessions.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ /**
7
+ * Writes to the real stdout, bypassing any monkey patching on process.stdout.write.
8
+ */
9
+ export declare function writeToStdout(...args: Parameters<typeof process.stdout.write>): boolean;
10
+ /**
11
+ * Writes to the real stderr, bypassing any monkey patching on process.stderr.write.
12
+ */
13
+ export declare function writeToStderr(...args: Parameters<typeof process.stderr.write>): boolean;
14
+ /**
15
+ * Monkey patches process.stdout.write and process.stderr.write to redirect output to the provided logger.
16
+ * This prevents stray output from libraries (or the app itself) from corrupting the UI.
17
+ * Returns a cleanup function that restores the original write methods.
18
+ */
19
+ export declare function patchStdio(): () => void;
20
+ /**
21
+ * Creates proxies for process.stdout and process.stderr that use the real write methods
22
+ * (writeToStdout and writeToStderr) bypassing any monkey patching.
23
+ * This is used by Ink to render to the real output.
24
+ */
25
+ export declare function createInkStdio(): {
26
+ stdout: NodeJS.WriteStream & {
27
+ fd: 1;
28
+ };
29
+ stderr: NodeJS.WriteStream & {
30
+ fd: 2;
31
+ };
32
+ };
@@ -0,0 +1,85 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { coreEvents } from '@google/gemini-cli-core';
7
+ // Capture the original stdout and stderr write methods before any monkey patching occurs.
8
+ const originalStdoutWrite = process.stdout.write.bind(process.stdout);
9
+ const originalStderrWrite = process.stderr.write.bind(process.stderr);
10
+ /**
11
+ * Writes to the real stdout, bypassing any monkey patching on process.stdout.write.
12
+ */
13
+ export function writeToStdout(...args) {
14
+ return originalStdoutWrite(...args);
15
+ }
16
+ /**
17
+ * Writes to the real stderr, bypassing any monkey patching on process.stderr.write.
18
+ */
19
+ export function writeToStderr(...args) {
20
+ return originalStderrWrite(...args);
21
+ }
22
+ /**
23
+ * Monkey patches process.stdout.write and process.stderr.write to redirect output to the provided logger.
24
+ * This prevents stray output from libraries (or the app itself) from corrupting the UI.
25
+ * Returns a cleanup function that restores the original write methods.
26
+ */
27
+ export function patchStdio() {
28
+ const previousStdoutWrite = process.stdout.write;
29
+ const previousStderrWrite = process.stderr.write;
30
+ process.stdout.write = (chunk, encodingOrCb, cb) => {
31
+ const encoding = typeof encodingOrCb === 'string' ? encodingOrCb : undefined;
32
+ coreEvents.emitOutput(false, chunk, encoding);
33
+ const callback = typeof encodingOrCb === 'function' ? encodingOrCb : cb;
34
+ if (callback) {
35
+ callback();
36
+ }
37
+ return true;
38
+ };
39
+ process.stderr.write = (chunk, encodingOrCb, cb) => {
40
+ const encoding = typeof encodingOrCb === 'string' ? encodingOrCb : undefined;
41
+ coreEvents.emitOutput(true, chunk, encoding);
42
+ const callback = typeof encodingOrCb === 'function' ? encodingOrCb : cb;
43
+ if (callback) {
44
+ callback();
45
+ }
46
+ return true;
47
+ };
48
+ return () => {
49
+ process.stdout.write = previousStdoutWrite;
50
+ process.stderr.write = previousStderrWrite;
51
+ };
52
+ }
53
+ /**
54
+ * Creates proxies for process.stdout and process.stderr that use the real write methods
55
+ * (writeToStdout and writeToStderr) bypassing any monkey patching.
56
+ * This is used by Ink to render to the real output.
57
+ */
58
+ export function createInkStdio() {
59
+ const inkStdout = new Proxy(process.stdout, {
60
+ get(target, prop, receiver) {
61
+ if (prop === 'write') {
62
+ return writeToStdout;
63
+ }
64
+ const value = Reflect.get(target, prop, receiver);
65
+ if (typeof value === 'function') {
66
+ return value.bind(target);
67
+ }
68
+ return value;
69
+ },
70
+ });
71
+ const inkStderr = new Proxy(process.stderr, {
72
+ get(target, prop, receiver) {
73
+ if (prop === 'write') {
74
+ return writeToStderr;
75
+ }
76
+ const value = Reflect.get(target, prop, receiver);
77
+ if (typeof value === 'function') {
78
+ return value.bind(target);
79
+ }
80
+ return value;
81
+ },
82
+ });
83
+ return { stdout: inkStdout, stderr: inkStderr };
84
+ }
85
+ //# sourceMappingURL=stdio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdio.js","sourceRoot":"","sources":["../../../src/utils/stdio.ts"],"names":[],"mappings":"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"}