From d4ae1ede395f1ace413fca29359784e95b07716e Mon Sep 17 00:00:00 2001 From: Brandon Keiji Date: Tue, 27 May 2025 21:40:46 +0000 Subject: refactor: use React strict mode (#569) --- packages/cli/src/gemini.ts | 136 ------------------------------------------- packages/cli/src/gemini.tsx | 138 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+), 136 deletions(-) delete mode 100644 packages/cli/src/gemini.ts create mode 100644 packages/cli/src/gemini.tsx diff --git a/packages/cli/src/gemini.ts b/packages/cli/src/gemini.ts deleted file mode 100644 index 2adf4c7d..00000000 --- a/packages/cli/src/gemini.ts +++ /dev/null @@ -1,136 +0,0 @@ -/** - * @license - * Copyright 2025 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -import React from 'react'; -import { render } from 'ink'; -import { App } from './ui/App.js'; -import { loadCliConfig } from './config/config.js'; -import { readStdin } from './utils/readStdin.js'; -import { GeminiClient } from '@gemini-code/server'; -import { readPackageUp } from 'read-package-up'; -import { fileURLToPath } from 'node:url'; -import { dirname } from 'node:path'; -import { sandbox_command, start_sandbox } from './utils/sandbox.js'; -import { loadSettings } from './config/settings.js'; -import { themeManager } from './ui/themes/theme-manager.js'; -import { getStartupWarnings } from './utils/startupWarnings.js'; - -const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); - -async function main() { - const settings = loadSettings(process.cwd()); - const config = await loadCliConfig(settings.merged); - - // warn about deprecated environment variables - if (process.env.GEMINI_CODE_MODEL) { - console.warn('GEMINI_CODE_MODEL is deprecated. Use GEMINI_MODEL instead.'); - process.env.GEMINI_MODEL = process.env.GEMINI_CODE_MODEL; - } - if (process.env.GEMINI_CODE_SANDBOX) { - console.warn( - 'GEMINI_CODE_SANDBOX is deprecated. Use GEMINI_SANDBOX instead.', - ); - process.env.GEMINI_SANDBOX = process.env.GEMINI_CODE_SANDBOX; - } - if (process.env.GEMINI_CODE_SANDBOX_IMAGE) { - console.warn( - 'GEMINI_CODE_SANDBOX_IMAGE is deprecated. Use GEMINI_SANDBOX_IMAGE_NAME instead.', - ); - process.env.GEMINI_SANDBOX_IMAGE = process.env.GEMINI_CODE_SANDBOX_IMAGE; - } - - if (settings.merged.theme) { - if (!themeManager.setActiveTheme(settings.merged.theme)) { - // If the theme is not found during initial load, log a warning and continue. - // The useThemeCommand hook in App.tsx will handle opening the dialog. - console.warn(`Warning: Theme "${settings.merged.theme}" not found.`); - } - } - - // hop into sandbox if we are outside and sandboxing is enabled - if (!process.env.SANDBOX) { - const sandbox = sandbox_command(config.getSandbox()); - if (sandbox) { - await start_sandbox(sandbox); - process.exit(0); - } - } - - let input = config.getQuestion(); - const startupWarnings = await getStartupWarnings(); - - // Render UI, passing necessary config values. Check that there is no command line question. - if (process.stdin.isTTY && input?.length === 0) { - const readUpResult = await readPackageUp({ cwd: __dirname }); - const cliVersion = - process.env.CLI_VERSION || readUpResult?.packageJson.version || 'unknown'; - - render( - React.createElement(App, { - config, - settings, - cliVersion, - startupWarnings, - }), - ); - return; - } - // If not a TTY, read from stdin - // This is for cases where the user pipes input directly into the command - if (!process.stdin.isTTY) { - input += await readStdin(); - } - if (!input) { - console.error('No input provided via stdin.'); - process.exit(1); - } - - // If not a TTY and we have initial input, process it directly - const geminiClient = new GeminiClient(config); - const chat = await geminiClient.startChat(); - try { - for await (const event of geminiClient.sendMessageStream(chat, [ - { text: input }, - ])) { - if (event.type === 'content') { - process.stdout.write(event.value); - } - // We might need to handle other event types later, but for now, just content. - } - process.stdout.write('\n'); // Add a newline at the end - process.exit(0); - } catch (error) { - console.error('Error processing piped input:', error); - process.exit(1); - } -} - -// --- Global Unhandled Rejection Handler --- -process.on('unhandledRejection', (reason, _promise) => { - // Log other unexpected unhandled rejections as critical errors - console.error('========================================='); - console.error('CRITICAL: Unhandled Promise Rejection!'); - console.error('========================================='); - console.error('Reason:', reason); - console.error('Stack trace may follow:'); - if (!(reason instanceof Error)) { - console.error(reason); - } - // Exit for genuinely unhandled errors - process.exit(1); -}); - -// --- Global Entry Point --- -main().catch((error) => { - console.error('An unexpected critical error occurred:'); - if (error instanceof Error) { - console.error(error.message); - } else { - console.error(String(error)); - } - process.exit(1); -}); diff --git a/packages/cli/src/gemini.tsx b/packages/cli/src/gemini.tsx new file mode 100644 index 00000000..11875593 --- /dev/null +++ b/packages/cli/src/gemini.tsx @@ -0,0 +1,138 @@ +/** + * @license + * Copyright 2025 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from 'react'; +import { render } from 'ink'; +import { App } from './ui/App.js'; +import { loadCliConfig } from './config/config.js'; +import { readStdin } from './utils/readStdin.js'; +import { GeminiClient } from '@gemini-code/server'; +import { readPackageUp } from 'read-package-up'; +import { fileURLToPath } from 'node:url'; +import { dirname } from 'node:path'; +import { sandbox_command, start_sandbox } from './utils/sandbox.js'; +import { loadSettings } from './config/settings.js'; +import { themeManager } from './ui/themes/theme-manager.js'; +import { getStartupWarnings } from './utils/startupWarnings.js'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +async function main() { + const settings = loadSettings(process.cwd()); + const config = await loadCliConfig(settings.merged); + + // warn about deprecated environment variables + if (process.env.GEMINI_CODE_MODEL) { + console.warn('GEMINI_CODE_MODEL is deprecated. Use GEMINI_MODEL instead.'); + process.env.GEMINI_MODEL = process.env.GEMINI_CODE_MODEL; + } + if (process.env.GEMINI_CODE_SANDBOX) { + console.warn( + 'GEMINI_CODE_SANDBOX is deprecated. Use GEMINI_SANDBOX instead.', + ); + process.env.GEMINI_SANDBOX = process.env.GEMINI_CODE_SANDBOX; + } + if (process.env.GEMINI_CODE_SANDBOX_IMAGE) { + console.warn( + 'GEMINI_CODE_SANDBOX_IMAGE is deprecated. Use GEMINI_SANDBOX_IMAGE_NAME instead.', + ); + process.env.GEMINI_SANDBOX_IMAGE = process.env.GEMINI_CODE_SANDBOX_IMAGE; + } + + if (settings.merged.theme) { + if (!themeManager.setActiveTheme(settings.merged.theme)) { + // If the theme is not found during initial load, log a warning and continue. + // The useThemeCommand hook in App.tsx will handle opening the dialog. + console.warn(`Warning: Theme "${settings.merged.theme}" not found.`); + } + } + + // hop into sandbox if we are outside and sandboxing is enabled + if (!process.env.SANDBOX) { + const sandbox = sandbox_command(config.getSandbox()); + if (sandbox) { + await start_sandbox(sandbox); + process.exit(0); + } + } + + let input = config.getQuestion(); + const startupWarnings = await getStartupWarnings(); + + // Render UI, passing necessary config values. Check that there is no command line question. + if (process.stdin.isTTY && input?.length === 0) { + const readUpResult = await readPackageUp({ cwd: __dirname }); + const cliVersion = + process.env.CLI_VERSION || readUpResult?.packageJson.version || 'unknown'; + + render( + + + , + ); + return; + } + // If not a TTY, read from stdin + // This is for cases where the user pipes input directly into the command + if (!process.stdin.isTTY) { + input += await readStdin(); + } + if (!input) { + console.error('No input provided via stdin.'); + process.exit(1); + } + + // If not a TTY and we have initial input, process it directly + const geminiClient = new GeminiClient(config); + const chat = await geminiClient.startChat(); + try { + for await (const event of geminiClient.sendMessageStream(chat, [ + { text: input }, + ])) { + if (event.type === 'content') { + process.stdout.write(event.value); + } + // We might need to handle other event types later, but for now, just content. + } + process.stdout.write('\n'); // Add a newline at the end + process.exit(0); + } catch (error) { + console.error('Error processing piped input:', error); + process.exit(1); + } +} + +// --- Global Unhandled Rejection Handler --- +process.on('unhandledRejection', (reason, _promise) => { + // Log other unexpected unhandled rejections as critical errors + console.error('========================================='); + console.error('CRITICAL: Unhandled Promise Rejection!'); + console.error('========================================='); + console.error('Reason:', reason); + console.error('Stack trace may follow:'); + if (!(reason instanceof Error)) { + console.error(reason); + } + // Exit for genuinely unhandled errors + process.exit(1); +}); + +// --- Global Entry Point --- +main().catch((error) => { + console.error('An unexpected critical error occurred:'); + if (error instanceof Error) { + console.error(error.message); + } else { + console.error(String(error)); + } + process.exit(1); +}); -- cgit v1.2.3