@machina.ai/cell-cli 1.19.4-rc3 → 1.20.2-rc1
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 +3 -3
- package/dist/src/commands/extensions/link.d.ts +1 -0
- package/dist/src/commands/extensions/link.js +15 -2
- package/dist/src/commands/extensions/link.js.map +1 -1
- package/dist/src/commands/extensions/link.test.js +6 -0
- package/dist/src/commands/extensions/link.test.js.map +1 -1
- package/dist/src/commands/mcp/list.js +1 -1
- package/dist/src/commands/mcp/list.js.map +1 -1
- package/dist/src/config/config.js +4 -1
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/config.test.js +23 -1
- package/dist/src/config/config.test.js.map +1 -1
- package/dist/src/config/extension.test.js +1 -1
- package/dist/src/config/extension.test.js.map +1 -1
- package/dist/src/config/extensions/consent.js +2 -2
- package/dist/src/config/extensions/consent.js.map +1 -1
- package/dist/src/config/extensions/github.js +1 -1
- package/dist/src/config/extensions/github.js.map +1 -1
- package/dist/src/config/extensions/storage.js +1 -1
- package/dist/src/config/extensions/storage.js.map +1 -1
- package/dist/src/config/settings.js +11 -0
- package/dist/src/config/settings.js.map +1 -1
- package/dist/src/config/settingsSchema.d.ts +18 -0
- package/dist/src/config/settingsSchema.js +18 -0
- package/dist/src/config/settingsSchema.js.map +1 -1
- package/dist/src/core/initializer.js +3 -1
- package/dist/src/core/initializer.js.map +1 -1
- package/dist/src/gemini.js +24 -11
- package/dist/src/gemini.js.map +1 -1
- package/dist/src/gemini.test.js +190 -125
- package/dist/src/gemini.test.js.map +1 -1
- package/dist/src/gemini_cleanup.test.js +1 -1
- package/dist/src/gemini_cleanup.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/nonInteractiveCli.js +3 -2
- package/dist/src/nonInteractiveCli.js.map +1 -1
- package/dist/src/nonInteractiveCli.test.js +4 -0
- package/dist/src/nonInteractiveCli.test.js.map +1 -1
- package/dist/src/services/BuiltinCommandLoader.js +3 -0
- package/dist/src/services/BuiltinCommandLoader.js.map +1 -1
- package/dist/src/ui/AppContainer.js +18 -36
- package/dist/src/ui/AppContainer.js.map +1 -1
- package/dist/src/ui/AppContainer.test.js +34 -51
- package/dist/src/ui/AppContainer.test.js.map +1 -1
- package/dist/src/ui/auth/AuthDialog.js +11 -4
- package/dist/src/ui/auth/AuthDialog.js.map +1 -1
- package/dist/src/ui/auth/AuthDialog.test.js +15 -4
- package/dist/src/ui/auth/AuthDialog.test.js.map +1 -1
- package/dist/src/ui/auth/useAuth.js +6 -1
- package/dist/src/ui/auth/useAuth.js.map +1 -1
- package/dist/src/ui/auth/useAuth.test.js +11 -0
- package/dist/src/ui/auth/useAuth.test.js.map +1 -1
- package/dist/src/ui/commands/aboutCommand.js +1 -0
- package/dist/src/ui/commands/aboutCommand.js.map +1 -1
- package/dist/src/ui/commands/authCommand.js +1 -0
- package/dist/src/ui/commands/authCommand.js.map +1 -1
- package/dist/src/ui/commands/bugCommand.js +1 -0
- package/dist/src/ui/commands/bugCommand.js.map +1 -1
- package/dist/src/ui/commands/chatCommand.js +6 -0
- package/dist/src/ui/commands/chatCommand.js.map +1 -1
- package/dist/src/ui/commands/clearCommand.js +1 -0
- package/dist/src/ui/commands/clearCommand.js.map +1 -1
- package/dist/src/ui/commands/compressCommand.js +1 -0
- package/dist/src/ui/commands/compressCommand.js.map +1 -1
- package/dist/src/ui/commands/copyCommand.js +1 -0
- package/dist/src/ui/commands/copyCommand.js.map +1 -1
- package/dist/src/ui/commands/corgiCommand.js +1 -0
- package/dist/src/ui/commands/corgiCommand.js.map +1 -1
- package/dist/src/ui/commands/directoryCommand.js +1 -0
- package/dist/src/ui/commands/directoryCommand.js.map +1 -1
- package/dist/src/ui/commands/docsCommand.js +1 -0
- package/dist/src/ui/commands/docsCommand.js.map +1 -1
- package/dist/src/ui/commands/editorCommand.js +1 -0
- package/dist/src/ui/commands/editorCommand.js.map +1 -1
- package/dist/src/ui/commands/extensionsCommand.js +7 -0
- package/dist/src/ui/commands/extensionsCommand.js.map +1 -1
- package/dist/src/ui/commands/helpCommand.js +1 -0
- package/dist/src/ui/commands/helpCommand.js.map +1 -1
- package/dist/src/ui/commands/ideCommand.js +6 -0
- package/dist/src/ui/commands/ideCommand.js.map +1 -1
- package/dist/src/ui/commands/initCommand.js +1 -0
- package/dist/src/ui/commands/initCommand.js.map +1 -1
- package/dist/src/ui/commands/mcpCommand.js +6 -0
- package/dist/src/ui/commands/mcpCommand.js.map +1 -1
- package/dist/src/ui/commands/memoryCommand.js +5 -0
- package/dist/src/ui/commands/memoryCommand.js.map +1 -1
- package/dist/src/ui/commands/modelCommand.js +1 -0
- package/dist/src/ui/commands/modelCommand.js.map +1 -1
- package/dist/src/ui/commands/permissionsCommand.js +2 -0
- package/dist/src/ui/commands/permissionsCommand.js.map +1 -1
- package/dist/src/ui/commands/policiesCommand.js +2 -0
- package/dist/src/ui/commands/policiesCommand.js.map +1 -1
- package/dist/src/ui/commands/privacyCommand.js +1 -0
- package/dist/src/ui/commands/privacyCommand.js.map +1 -1
- package/dist/src/ui/commands/profileCommand.js +1 -0
- package/dist/src/ui/commands/profileCommand.js.map +1 -1
- package/dist/src/ui/commands/quitCommand.js +1 -0
- package/dist/src/ui/commands/quitCommand.js.map +1 -1
- package/dist/src/ui/commands/restoreCommand.js +1 -0
- package/dist/src/ui/commands/restoreCommand.js.map +1 -1
- package/dist/src/ui/commands/resumeCommand.js +1 -0
- package/dist/src/ui/commands/resumeCommand.js.map +1 -1
- package/dist/src/ui/commands/settingsCommand.js +1 -0
- package/dist/src/ui/commands/settingsCommand.js.map +1 -1
- package/dist/src/ui/commands/setupGithubCommand.js +4 -1
- package/dist/src/ui/commands/setupGithubCommand.js.map +1 -1
- package/dist/src/ui/commands/setupGithubCommand.test.js +55 -14
- package/dist/src/ui/commands/setupGithubCommand.test.js.map +1 -1
- package/dist/src/ui/commands/statsCommand.js +19 -5
- package/dist/src/ui/commands/statsCommand.js.map +1 -1
- package/dist/src/ui/commands/terminalSetupCommand.js +1 -0
- package/dist/src/ui/commands/terminalSetupCommand.js.map +1 -1
- package/dist/src/ui/commands/themeCommand.js +1 -0
- package/dist/src/ui/commands/themeCommand.js.map +1 -1
- package/dist/src/ui/commands/toolsCommand.js +1 -0
- package/dist/src/ui/commands/toolsCommand.js.map +1 -1
- package/dist/src/ui/commands/types.d.ts +7 -0
- package/dist/src/ui/commands/vimCommand.js +1 -0
- package/dist/src/ui/commands/vimCommand.js.map +1 -1
- package/dist/src/ui/components/AsciiArt.d.ts +6 -6
- package/dist/src/ui/components/AsciiArt.js +6 -6
- package/dist/src/ui/components/ConfigInitDisplay.js +15 -2
- package/dist/src/ui/components/ConfigInitDisplay.js.map +1 -1
- package/dist/src/ui/components/ConfigInitDisplay.test.js +34 -4
- package/dist/src/ui/components/ConfigInitDisplay.test.js.map +1 -1
- package/dist/src/ui/components/FolderTrustDialog.js +5 -2
- package/dist/src/ui/components/FolderTrustDialog.js.map +1 -1
- package/dist/src/ui/components/FolderTrustDialog.test.js +2 -1
- package/dist/src/ui/components/FolderTrustDialog.test.js.map +1 -1
- package/dist/src/ui/components/HistoryItemDisplay.js +1 -1
- package/dist/src/ui/components/HistoryItemDisplay.js.map +1 -1
- package/dist/src/ui/components/InputPrompt.d.ts +1 -1
- package/dist/src/ui/components/InputPrompt.js +24 -18
- package/dist/src/ui/components/InputPrompt.js.map +1 -1
- package/dist/src/ui/components/InputPrompt.test.js +151 -17
- package/dist/src/ui/components/InputPrompt.test.js.map +1 -1
- package/dist/src/ui/components/StatsDisplay.d.ts +2 -0
- package/dist/src/ui/components/StatsDisplay.js +36 -5
- package/dist/src/ui/components/StatsDisplay.js.map +1 -1
- package/dist/src/ui/components/StatsDisplay.test.js +51 -1
- package/dist/src/ui/components/StatsDisplay.test.js.map +1 -1
- package/dist/src/ui/contexts/UIActionsContext.d.ts +1 -1
- package/dist/src/ui/hooks/useCommandCompletion.d.ts +8 -1
- package/dist/src/ui/hooks/useCommandCompletion.js +50 -6
- package/dist/src/ui/hooks/useCommandCompletion.js.map +1 -1
- package/dist/src/ui/hooks/useCommandCompletion.test.js +4 -5
- package/dist/src/ui/hooks/useCommandCompletion.test.js.map +1 -1
- package/dist/src/ui/hooks/useFolderTrust.js +5 -3
- package/dist/src/ui/hooks/useFolderTrust.js.map +1 -1
- package/dist/src/ui/hooks/useFolderTrust.test.js +4 -4
- package/dist/src/ui/hooks/useFolderTrust.test.js.map +1 -1
- package/dist/src/ui/hooks/useMessageQueue.d.ts +1 -1
- package/dist/src/ui/hooks/useMessageQueue.js +8 -12
- package/dist/src/ui/hooks/useMessageQueue.js.map +1 -1
- package/dist/src/ui/hooks/useMessageQueue.test.js +7 -19
- package/dist/src/ui/hooks/useMessageQueue.test.js.map +1 -1
- package/dist/src/ui/hooks/useSlashCompletion.d.ts +1 -0
- package/dist/src/ui/hooks/useSlashCompletion.js +18 -0
- package/dist/src/ui/hooks/useSlashCompletion.js.map +1 -1
- package/dist/src/ui/types.d.ts +2 -1
- package/dist/src/ui/types.js.map +1 -1
- package/dist/src/ui/utils/InlineMarkdownRenderer.js +1 -1
- package/dist/src/ui/utils/InlineMarkdownRenderer.test.d.ts +6 -0
- package/dist/src/ui/utils/InlineMarkdownRenderer.test.js +21 -0
- package/dist/src/ui/utils/InlineMarkdownRenderer.test.js.map +1 -0
- package/dist/src/ui/utils/commandUtils.d.ts +12 -0
- package/dist/src/ui/utils/commandUtils.js +17 -0
- package/dist/src/ui/utils/commandUtils.js.map +1 -1
- package/dist/src/ui/utils/textOutput.d.ts +2 -0
- package/dist/src/ui/utils/textOutput.js +5 -1
- package/dist/src/ui/utils/textOutput.js.map +1 -1
- package/dist/src/utils/handleAutoUpdate.test.js +1 -1
- package/dist/src/utils/handleAutoUpdate.test.js.map +1 -1
- package/dist/src/utils/sandbox.js +2 -2
- package/dist/src/utils/sandbox.js.map +1 -1
- package/dist/src/utils/sessionCleanup.integration.test.js +3 -3
- package/dist/src/utils/sessionCleanup.integration.test.js.map +1 -1
- package/dist/src/utils/sessionUtils.d.ts +7 -0
- package/dist/src/utils/sessionUtils.js +11 -0
- package/dist/src/utils/sessionUtils.js.map +1 -1
- package/dist/src/utils/sessionUtils.test.js +201 -1
- package/dist/src/utils/sessionUtils.test.js.map +1 -1
- package/dist/src/validateNonInterActiveAuth.js +3 -3
- package/dist/src/validateNonInterActiveAuth.js.map +1 -1
- package/dist/src/zed-integration/acp.js +4 -4
- package/dist/src/zed-integration/acp.js.map +1 -1
- package/dist/src/zed-integration/acp.test.js +0 -5
- package/dist/src/zed-integration/acp.test.js.map +1 -1
- package/dist/src/zed-integration/schema.d.ts +0 -46
- package/dist/src/zed-integration/schema.js +0 -1
- package/dist/src/zed-integration/schema.js.map +1 -1
- package/dist/src/zed-integration/zedIntegration.js +4 -7
- package/dist/src/zed-integration/zedIntegration.js.map +1 -1
- package/dist/src/zed-integration/zedIntegration.test.js +0 -5
- package/dist/src/zed-integration/zedIntegration.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
package/dist/src/gemini.test.js
CHANGED
|
@@ -7,6 +7,7 @@ import { describe, it, expect, vi, beforeEach, afterEach, } from 'vitest';
|
|
|
7
7
|
import { main, setupUnhandledRejectionHandler, validateDnsResolutionOrder, startInteractiveUI, getNodeMemoryArgs, } from './gemini.js';
|
|
8
8
|
import os from 'node:os';
|
|
9
9
|
import v8 from 'node:v8';
|
|
10
|
+
import {} from './config/config.js';
|
|
10
11
|
import {} from './config/settings.js';
|
|
11
12
|
import { appEvents, AppEvent } from './utils/events.js';
|
|
12
13
|
import { debugLogger, } from '@google/gemini-cli-core';
|
|
@@ -32,7 +33,7 @@ vi.mock('@google/gemini-cli-core', async (importOriginal) => {
|
|
|
32
33
|
recordSlowRender: vi.fn(),
|
|
33
34
|
writeToStdout: vi.fn((...args) => process.stdout.write(...args)),
|
|
34
35
|
patchStdio: vi.fn(() => () => { }),
|
|
35
|
-
|
|
36
|
+
createWorkingStdio: vi.fn(() => ({
|
|
36
37
|
stdout: {
|
|
37
38
|
write: vi.fn((...args) => process.stdout.write(...args)),
|
|
38
39
|
columns: 80,
|
|
@@ -176,10 +177,11 @@ describe('gemini.tsx main function', () => {
|
|
|
176
177
|
delete process.env['SANDBOX'];
|
|
177
178
|
}
|
|
178
179
|
const currentListeners = process.listeners('unhandledRejection');
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
180
|
+
currentListeners.forEach((listener) => {
|
|
181
|
+
if (!initialUnhandledRejectionListeners.includes(listener)) {
|
|
182
|
+
process.removeListener('unhandledRejection', listener);
|
|
183
|
+
}
|
|
184
|
+
});
|
|
183
185
|
vi.restoreAllMocks();
|
|
184
186
|
});
|
|
185
187
|
it('verifies that we dont load the config before relaunchAppInChildProcess', async () => {
|
|
@@ -612,53 +614,6 @@ describe('gemini.tsx main function kitty protocol', () => {
|
|
|
612
614
|
expect(processExitSpy).toHaveBeenCalledWith(0);
|
|
613
615
|
processExitSpy.mockRestore();
|
|
614
616
|
});
|
|
615
|
-
it('should exit with error when --prompt-interactive is used with piped input', async () => {
|
|
616
|
-
const { loadCliConfig, parseArguments } = await import('./config/config.js');
|
|
617
|
-
const { loadSettings } = await import('./config/settings.js');
|
|
618
|
-
const core = await import('@google/gemini-cli-core');
|
|
619
|
-
const processExitSpy = vi
|
|
620
|
-
.spyOn(process, 'exit')
|
|
621
|
-
.mockImplementation((code) => {
|
|
622
|
-
throw new MockProcessExitError(code);
|
|
623
|
-
});
|
|
624
|
-
const writeToStderrSpy = vi
|
|
625
|
-
.spyOn(core, 'writeToStderr')
|
|
626
|
-
.mockImplementation(() => true);
|
|
627
|
-
vi.mocked(loadSettings).mockReturnValue({
|
|
628
|
-
merged: { advanced: {}, security: { auth: {} }, ui: {} },
|
|
629
|
-
setValue: vi.fn(),
|
|
630
|
-
forScope: () => ({ settings: {}, originalSettings: {}, path: '' }),
|
|
631
|
-
errors: [],
|
|
632
|
-
}); // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
633
|
-
vi.mocked(parseArguments).mockResolvedValue({
|
|
634
|
-
promptInteractive: true,
|
|
635
|
-
}); // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
636
|
-
vi.mocked(loadCliConfig).mockResolvedValue({
|
|
637
|
-
isInteractive: () => false,
|
|
638
|
-
getQuestion: () => '',
|
|
639
|
-
getSandbox: () => false,
|
|
640
|
-
}); // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
641
|
-
// Mock stdin to be non-TTY
|
|
642
|
-
Object.defineProperty(process.stdin, 'isTTY', {
|
|
643
|
-
value: false,
|
|
644
|
-
configurable: true,
|
|
645
|
-
});
|
|
646
|
-
try {
|
|
647
|
-
await main();
|
|
648
|
-
}
|
|
649
|
-
catch (e) {
|
|
650
|
-
if (!(e instanceof MockProcessExitError))
|
|
651
|
-
throw e;
|
|
652
|
-
}
|
|
653
|
-
expect(writeToStderrSpy).toHaveBeenCalledWith(expect.stringContaining('Error: The --prompt-interactive flag cannot be used'));
|
|
654
|
-
expect(processExitSpy).toHaveBeenCalledWith(1);
|
|
655
|
-
processExitSpy.mockRestore();
|
|
656
|
-
writeToStderrSpy.mockRestore();
|
|
657
|
-
Object.defineProperty(process.stdin, 'isTTY', {
|
|
658
|
-
value: true,
|
|
659
|
-
configurable: true,
|
|
660
|
-
}); // Restore TTY
|
|
661
|
-
});
|
|
662
617
|
it('should log warning when theme is not found', async () => {
|
|
663
618
|
const { loadCliConfig, parseArguments } = await import('./config/config.js');
|
|
664
619
|
const { loadSettings } = await import('./config/settings.js');
|
|
@@ -729,12 +684,11 @@ describe('gemini.tsx main function kitty protocol', () => {
|
|
|
729
684
|
it('should handle session selector error', async () => {
|
|
730
685
|
const { loadCliConfig, parseArguments } = await import('./config/config.js');
|
|
731
686
|
const { loadSettings } = await import('./config/settings.js');
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
},
|
|
687
|
+
const { SessionSelector } = await import('./utils/sessionUtils.js');
|
|
688
|
+
vi.mocked(SessionSelector).mockImplementation(() => ({
|
|
689
|
+
resolveSession: vi
|
|
690
|
+
.fn()
|
|
691
|
+
.mockRejectedValue(new Error('Session not found')),
|
|
738
692
|
}));
|
|
739
693
|
const processExitSpy = vi
|
|
740
694
|
.spyOn(process, 'exit')
|
|
@@ -793,7 +747,7 @@ describe('gemini.tsx main function kitty protocol', () => {
|
|
|
793
747
|
throw e;
|
|
794
748
|
}
|
|
795
749
|
expect(consoleErrorSpy).toHaveBeenCalledWith(expect.stringContaining('Error resuming session: Session not found'));
|
|
796
|
-
expect(processExitSpy).toHaveBeenCalledWith(
|
|
750
|
+
expect(processExitSpy).toHaveBeenCalledWith(42);
|
|
797
751
|
processExitSpy.mockRestore();
|
|
798
752
|
consoleErrorSpy.mockRestore();
|
|
799
753
|
});
|
|
@@ -862,35 +816,27 @@ describe('gemini.tsx main function kitty protocol', () => {
|
|
|
862
816
|
expect(processExitSpy).toHaveBeenCalledWith(0); // Should not exit on cleanup failure
|
|
863
817
|
processExitSpy.mockRestore();
|
|
864
818
|
});
|
|
865
|
-
it('should
|
|
819
|
+
it('should read from stdin in non-interactive mode', async () => {
|
|
866
820
|
const { loadCliConfig, parseArguments } = await import('./config/config.js');
|
|
867
821
|
const { loadSettings } = await import('./config/settings.js');
|
|
868
|
-
const {
|
|
822
|
+
const { readStdin } = await import('./utils/readStdin.js');
|
|
869
823
|
const processExitSpy = vi
|
|
870
824
|
.spyOn(process, 'exit')
|
|
871
825
|
.mockImplementation((code) => {
|
|
872
826
|
throw new MockProcessExitError(code);
|
|
873
827
|
});
|
|
874
|
-
const debugLoggerErrorSpy = vi
|
|
875
|
-
.spyOn(debugLogger, 'error')
|
|
876
|
-
.mockImplementation(() => { });
|
|
877
828
|
vi.mocked(loadSettings).mockReturnValue({
|
|
878
|
-
merged: {
|
|
879
|
-
advanced: {},
|
|
880
|
-
security: { auth: { selectedType: 'google' } },
|
|
881
|
-
ui: {},
|
|
882
|
-
},
|
|
829
|
+
merged: { advanced: {}, security: { auth: {} }, ui: {} },
|
|
883
830
|
setValue: vi.fn(),
|
|
884
831
|
forScope: () => ({ settings: {}, originalSettings: {}, path: '' }),
|
|
885
832
|
errors: [],
|
|
886
833
|
}); // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
887
|
-
vi.mocked(loadSandboxConfig).mockResolvedValue({}); // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
888
834
|
vi.mocked(parseArguments).mockResolvedValue({
|
|
889
835
|
promptInteractive: false,
|
|
890
836
|
}); // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
891
837
|
vi.mocked(loadCliConfig).mockResolvedValue({
|
|
892
|
-
isInteractive: () =>
|
|
893
|
-
getQuestion: () => '',
|
|
838
|
+
isInteractive: () => false,
|
|
839
|
+
getQuestion: () => 'test-question',
|
|
894
840
|
getSandbox: () => false,
|
|
895
841
|
getDebugMode: () => false,
|
|
896
842
|
getPolicyEngine: vi.fn(),
|
|
@@ -918,8 +864,23 @@ describe('gemini.tsx main function kitty protocol', () => {
|
|
|
918
864
|
getFileFilteringRespectGitIgnore: () => true,
|
|
919
865
|
getOutputFormat: () => 'text',
|
|
920
866
|
getUsageStatisticsEnabled: () => false,
|
|
921
|
-
refreshAuth: vi.fn().mockRejectedValue(new Error('Auth refresh failed')),
|
|
922
867
|
}); // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
868
|
+
vi.mock('./utils/readStdin.js', () => ({
|
|
869
|
+
readStdin: vi.fn().mockResolvedValue('stdin-data'),
|
|
870
|
+
}));
|
|
871
|
+
const runNonInteractiveSpy = vi.hoisted(() => vi.fn());
|
|
872
|
+
vi.mock('./nonInteractiveCli.js', () => ({
|
|
873
|
+
runNonInteractive: runNonInteractiveSpy,
|
|
874
|
+
}));
|
|
875
|
+
runNonInteractiveSpy.mockClear();
|
|
876
|
+
vi.mock('./validateNonInterActiveAuth.js', () => ({
|
|
877
|
+
validateNonInteractiveAuth: vi.fn().mockResolvedValue({}),
|
|
878
|
+
}));
|
|
879
|
+
// Mock stdin to be non-TTY
|
|
880
|
+
Object.defineProperty(process.stdin, 'isTTY', {
|
|
881
|
+
value: false,
|
|
882
|
+
configurable: true,
|
|
883
|
+
});
|
|
923
884
|
try {
|
|
924
885
|
await main();
|
|
925
886
|
}
|
|
@@ -927,49 +888,172 @@ describe('gemini.tsx main function kitty protocol', () => {
|
|
|
927
888
|
if (!(e instanceof MockProcessExitError))
|
|
928
889
|
throw e;
|
|
929
890
|
}
|
|
930
|
-
expect(
|
|
931
|
-
|
|
891
|
+
expect(readStdin).toHaveBeenCalled();
|
|
892
|
+
// In this test setup, runNonInteractive might be called on the mocked module,
|
|
893
|
+
// but we need to ensure we are checking the correct spy instance.
|
|
894
|
+
// Since vi.mock is hoisted, runNonInteractiveSpy is defined early.
|
|
895
|
+
expect(runNonInteractiveSpy).toHaveBeenCalled();
|
|
896
|
+
const callArgs = runNonInteractiveSpy.mock.calls[0][0];
|
|
897
|
+
expect(callArgs.input).toBe('test-question');
|
|
898
|
+
expect(processExitSpy).toHaveBeenCalledWith(0);
|
|
932
899
|
processExitSpy.mockRestore();
|
|
900
|
+
Object.defineProperty(process.stdin, 'isTTY', {
|
|
901
|
+
value: true,
|
|
902
|
+
configurable: true,
|
|
903
|
+
});
|
|
933
904
|
});
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
905
|
+
});
|
|
906
|
+
describe('gemini.tsx main function exit codes', () => {
|
|
907
|
+
let originalEnvNoRelaunch;
|
|
908
|
+
beforeEach(() => {
|
|
909
|
+
originalEnvNoRelaunch = process.env['CELL_CLI_NO_RELAUNCH'];
|
|
910
|
+
process.env['CELL_CLI_NO_RELAUNCH'] = 'true';
|
|
911
|
+
vi.spyOn(process, 'exit').mockImplementation((code) => {
|
|
941
912
|
throw new MockProcessExitError(code);
|
|
942
913
|
});
|
|
914
|
+
// Mock stderr to avoid cluttering output
|
|
915
|
+
vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
|
|
916
|
+
});
|
|
917
|
+
afterEach(() => {
|
|
918
|
+
if (originalEnvNoRelaunch !== undefined) {
|
|
919
|
+
process.env['CELL_CLI_NO_RELAUNCH'] = originalEnvNoRelaunch;
|
|
920
|
+
}
|
|
921
|
+
else {
|
|
922
|
+
delete process.env['CELL_CLI_NO_RELAUNCH'];
|
|
923
|
+
}
|
|
924
|
+
vi.restoreAllMocks();
|
|
925
|
+
});
|
|
926
|
+
it('should exit with 42 for invalid input combination (prompt-interactive with non-TTY)', async () => {
|
|
927
|
+
const { loadCliConfig, parseArguments } = await import('./config/config.js');
|
|
928
|
+
const { loadSettings } = await import('./config/settings.js');
|
|
929
|
+
vi.mocked(loadCliConfig).mockResolvedValue({});
|
|
943
930
|
vi.mocked(loadSettings).mockReturnValue({
|
|
944
|
-
merged: {
|
|
945
|
-
setValue: vi.fn(),
|
|
946
|
-
forScope: () => ({ settings: {}, originalSettings: {}, path: '' }),
|
|
931
|
+
merged: { security: { auth: {} }, ui: {} },
|
|
947
932
|
errors: [],
|
|
948
|
-
});
|
|
933
|
+
});
|
|
949
934
|
vi.mocked(parseArguments).mockResolvedValue({
|
|
950
|
-
promptInteractive:
|
|
951
|
-
});
|
|
935
|
+
promptInteractive: true,
|
|
936
|
+
});
|
|
937
|
+
Object.defineProperty(process.stdin, 'isTTY', {
|
|
938
|
+
value: false,
|
|
939
|
+
configurable: true,
|
|
940
|
+
});
|
|
941
|
+
try {
|
|
942
|
+
await main();
|
|
943
|
+
expect.fail('Should have thrown MockProcessExitError');
|
|
944
|
+
}
|
|
945
|
+
catch (e) {
|
|
946
|
+
expect(e).toBeInstanceOf(MockProcessExitError);
|
|
947
|
+
expect(e.code).toBe(42);
|
|
948
|
+
}
|
|
949
|
+
});
|
|
950
|
+
it('should exit with 41 for auth failure during sandbox setup', async () => {
|
|
951
|
+
const { loadCliConfig, parseArguments } = await import('./config/config.js');
|
|
952
|
+
const { loadSettings } = await import('./config/settings.js');
|
|
953
|
+
const { loadSandboxConfig } = await import('./config/sandboxConfig.js');
|
|
954
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
955
|
+
vi.mocked(loadSandboxConfig).mockResolvedValue({});
|
|
956
|
+
vi.mocked(loadCliConfig).mockResolvedValue({
|
|
957
|
+
refreshAuth: vi.fn().mockRejectedValue(new Error('Auth failed')),
|
|
958
|
+
});
|
|
959
|
+
vi.mocked(loadSettings).mockReturnValue({
|
|
960
|
+
merged: {
|
|
961
|
+
security: { auth: { selectedType: 'google', useExternal: false } },
|
|
962
|
+
ui: {},
|
|
963
|
+
},
|
|
964
|
+
errors: [],
|
|
965
|
+
});
|
|
966
|
+
vi.mocked(parseArguments).mockResolvedValue({});
|
|
967
|
+
vi.mock('./config/auth.js', () => ({
|
|
968
|
+
validateAuthMethod: vi.fn().mockReturnValue(null),
|
|
969
|
+
}));
|
|
970
|
+
try {
|
|
971
|
+
await main();
|
|
972
|
+
expect.fail('Should have thrown MockProcessExitError');
|
|
973
|
+
}
|
|
974
|
+
catch (e) {
|
|
975
|
+
expect(e).toBeInstanceOf(MockProcessExitError);
|
|
976
|
+
expect(e.code).toBe(41);
|
|
977
|
+
}
|
|
978
|
+
});
|
|
979
|
+
it('should exit with 42 for session resume failure', async () => {
|
|
980
|
+
const { loadCliConfig, parseArguments } = await import('./config/config.js');
|
|
981
|
+
const { loadSettings } = await import('./config/settings.js');
|
|
952
982
|
vi.mocked(loadCliConfig).mockResolvedValue({
|
|
953
983
|
isInteractive: () => false,
|
|
954
|
-
getQuestion: () => 'test
|
|
984
|
+
getQuestion: () => 'test',
|
|
955
985
|
getSandbox: () => false,
|
|
956
986
|
getDebugMode: () => false,
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
getContentGeneratorConfig: vi.fn(),
|
|
987
|
+
getListExtensions: () => false,
|
|
988
|
+
getListSessions: () => false,
|
|
989
|
+
getDeleteSession: () => undefined,
|
|
961
990
|
getMcpServers: () => ({}),
|
|
962
991
|
getMcpClientManager: vi.fn(),
|
|
992
|
+
initialize: vi.fn(),
|
|
963
993
|
getIdeMode: () => false,
|
|
964
994
|
getExperimentalZedIntegration: () => false,
|
|
965
995
|
getScreenReader: () => false,
|
|
966
996
|
getGeminiMdFileCount: () => 0,
|
|
967
|
-
|
|
997
|
+
getPolicyEngine: vi.fn(),
|
|
998
|
+
getMessageBus: () => ({ subscribe: vi.fn() }),
|
|
999
|
+
getToolRegistry: vi.fn(),
|
|
1000
|
+
getContentGeneratorConfig: vi.fn(),
|
|
1001
|
+
getModel: () => 'gemini-pro',
|
|
1002
|
+
getEmbeddingModel: () => 'embedding-001',
|
|
1003
|
+
getApprovalMode: () => 'default',
|
|
1004
|
+
getCoreTools: () => [],
|
|
1005
|
+
getTelemetryEnabled: () => false,
|
|
1006
|
+
getTelemetryLogPromptsEnabled: () => false,
|
|
1007
|
+
getFileFilteringRespectGitIgnore: () => true,
|
|
1008
|
+
getOutputFormat: () => 'text',
|
|
1009
|
+
getExtensions: () => [],
|
|
1010
|
+
getUsageStatisticsEnabled: () => false,
|
|
1011
|
+
});
|
|
1012
|
+
vi.mocked(loadSettings).mockReturnValue({
|
|
1013
|
+
merged: { security: { auth: {} }, ui: {} },
|
|
1014
|
+
errors: [],
|
|
1015
|
+
});
|
|
1016
|
+
vi.mocked(parseArguments).mockResolvedValue({
|
|
1017
|
+
resume: 'invalid-session',
|
|
1018
|
+
});
|
|
1019
|
+
vi.mock('./utils/sessionUtils.js', () => ({
|
|
1020
|
+
SessionSelector: vi.fn().mockImplementation(() => ({
|
|
1021
|
+
resolveSession: vi
|
|
1022
|
+
.fn()
|
|
1023
|
+
.mockRejectedValue(new Error('Session not found')),
|
|
1024
|
+
})),
|
|
1025
|
+
}));
|
|
1026
|
+
try {
|
|
1027
|
+
await main();
|
|
1028
|
+
expect.fail('Should have thrown MockProcessExitError');
|
|
1029
|
+
}
|
|
1030
|
+
catch (e) {
|
|
1031
|
+
expect(e).toBeInstanceOf(MockProcessExitError);
|
|
1032
|
+
expect(e.code).toBe(42);
|
|
1033
|
+
}
|
|
1034
|
+
});
|
|
1035
|
+
it('should exit with 42 for no input provided', async () => {
|
|
1036
|
+
const { loadCliConfig, parseArguments } = await import('./config/config.js');
|
|
1037
|
+
const { loadSettings } = await import('./config/settings.js');
|
|
1038
|
+
vi.mocked(loadCliConfig).mockResolvedValue({
|
|
1039
|
+
isInteractive: () => false,
|
|
1040
|
+
getQuestion: () => '',
|
|
1041
|
+
getSandbox: () => false,
|
|
1042
|
+
getDebugMode: () => false,
|
|
968
1043
|
getListExtensions: () => false,
|
|
969
1044
|
getListSessions: () => false,
|
|
970
1045
|
getDeleteSession: () => undefined,
|
|
1046
|
+
getMcpServers: () => ({}),
|
|
1047
|
+
getMcpClientManager: vi.fn(),
|
|
1048
|
+
initialize: vi.fn(),
|
|
1049
|
+
getIdeMode: () => false,
|
|
1050
|
+
getExperimentalZedIntegration: () => false,
|
|
1051
|
+
getScreenReader: () => false,
|
|
1052
|
+
getGeminiMdFileCount: () => 0,
|
|
1053
|
+
getPolicyEngine: vi.fn(),
|
|
1054
|
+
getMessageBus: () => ({ subscribe: vi.fn() }),
|
|
971
1055
|
getToolRegistry: vi.fn(),
|
|
972
|
-
|
|
1056
|
+
getContentGeneratorConfig: vi.fn(),
|
|
973
1057
|
getModel: () => 'gemini-pro',
|
|
974
1058
|
getEmbeddingModel: () => 'embedding-001',
|
|
975
1059
|
getApprovalMode: () => 'default',
|
|
@@ -978,44 +1062,26 @@ describe('gemini.tsx main function kitty protocol', () => {
|
|
|
978
1062
|
getTelemetryLogPromptsEnabled: () => false,
|
|
979
1063
|
getFileFilteringRespectGitIgnore: () => true,
|
|
980
1064
|
getOutputFormat: () => 'text',
|
|
1065
|
+
getExtensions: () => [],
|
|
981
1066
|
getUsageStatisticsEnabled: () => false,
|
|
982
|
-
});
|
|
983
|
-
vi.
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
vi.
|
|
988
|
-
runNonInteractive: runNonInteractiveSpy,
|
|
989
|
-
}));
|
|
990
|
-
runNonInteractiveSpy.mockClear();
|
|
991
|
-
vi.mock('./validateNonInterActiveAuth.js', () => ({
|
|
992
|
-
validateNonInteractiveAuth: vi.fn().mockResolvedValue({}),
|
|
993
|
-
}));
|
|
994
|
-
// Mock stdin to be non-TTY
|
|
1067
|
+
});
|
|
1068
|
+
vi.mocked(loadSettings).mockReturnValue({
|
|
1069
|
+
merged: { security: { auth: {} }, ui: {} },
|
|
1070
|
+
errors: [],
|
|
1071
|
+
});
|
|
1072
|
+
vi.mocked(parseArguments).mockResolvedValue({});
|
|
995
1073
|
Object.defineProperty(process.stdin, 'isTTY', {
|
|
996
|
-
value:
|
|
1074
|
+
value: true, // Simulate TTY so it doesn't try to read stdin
|
|
997
1075
|
configurable: true,
|
|
998
1076
|
});
|
|
999
1077
|
try {
|
|
1000
1078
|
await main();
|
|
1079
|
+
expect.fail('Should have thrown MockProcessExitError');
|
|
1001
1080
|
}
|
|
1002
1081
|
catch (e) {
|
|
1003
|
-
|
|
1004
|
-
|
|
1082
|
+
expect(e).toBeInstanceOf(MockProcessExitError);
|
|
1083
|
+
expect(e.code).toBe(42);
|
|
1005
1084
|
}
|
|
1006
|
-
expect(readStdin).toHaveBeenCalled();
|
|
1007
|
-
// In this test setup, runNonInteractive might be called on the mocked module,
|
|
1008
|
-
// but we need to ensure we are checking the correct spy instance.
|
|
1009
|
-
// Since vi.mock is hoisted, runNonInteractiveSpy is defined early.
|
|
1010
|
-
expect(runNonInteractiveSpy).toHaveBeenCalled();
|
|
1011
|
-
const callArgs = runNonInteractiveSpy.mock.calls[0][0];
|
|
1012
|
-
expect(callArgs.input).toBe('test-question');
|
|
1013
|
-
expect(processExitSpy).toHaveBeenCalledWith(0);
|
|
1014
|
-
processExitSpy.mockRestore();
|
|
1015
|
-
Object.defineProperty(process.stdin, 'isTTY', {
|
|
1016
|
-
value: true,
|
|
1017
|
-
configurable: true,
|
|
1018
|
-
});
|
|
1019
1085
|
});
|
|
1020
1086
|
});
|
|
1021
1087
|
describe('validateDnsResolutionOrder', () => {
|
|
@@ -1098,7 +1164,6 @@ describe('startInteractiveUI', () => {
|
|
|
1098
1164
|
const renderSpy = vi.mocked(render);
|
|
1099
1165
|
await startTestInteractiveUI(mockConfig, mockSettings, mockStartupWarnings, mockWorkspaceRoot, undefined, mockInitializationResult);
|
|
1100
1166
|
// Verify render was called with correct options
|
|
1101
|
-
expect(renderSpy).toHaveBeenCalledTimes(1);
|
|
1102
1167
|
const [reactElement, options] = renderSpy.mock.calls[0];
|
|
1103
1168
|
// Verify render options
|
|
1104
1169
|
expect(options).toEqual(expect.objectContaining({
|