fix: pass startup warnings to app as prop (#342)
This commit is contained in:
parent
d3303fd3a0
commit
7116ab9c29
|
@ -16,6 +16,7 @@ import { dirname } from 'node:path';
|
||||||
import { sandbox_command, start_sandbox } from './utils/sandbox.js';
|
import { sandbox_command, start_sandbox } from './utils/sandbox.js';
|
||||||
import { loadSettings } from './config/settings.js';
|
import { loadSettings } from './config/settings.js';
|
||||||
import { themeManager } from './ui/themes/theme-manager.js';
|
import { themeManager } from './ui/themes/theme-manager.js';
|
||||||
|
import { getStartupWarnings } from './utils/startupWarnings.js';
|
||||||
|
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
const __dirname = dirname(__filename);
|
const __dirname = dirname(__filename);
|
||||||
|
@ -41,6 +42,7 @@ async function main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
let input = config.getQuestion();
|
let input = config.getQuestion();
|
||||||
|
const startupWarnings = await getStartupWarnings();
|
||||||
|
|
||||||
// Render UI, passing necessary config values. Check that there is no command line question.
|
// Render UI, passing necessary config values. Check that there is no command line question.
|
||||||
if (process.stdin.isTTY && input?.length === 0) {
|
if (process.stdin.isTTY && input?.length === 0) {
|
||||||
|
@ -53,6 +55,7 @@ async function main() {
|
||||||
config,
|
config,
|
||||||
settings,
|
settings,
|
||||||
cliVersion,
|
cliVersion,
|
||||||
|
startupWarnings,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -16,7 +16,6 @@ import { LoadingIndicator } from './components/LoadingIndicator.js';
|
||||||
import { EditorState, InputPrompt } from './components/InputPrompt.js';
|
import { EditorState, InputPrompt } from './components/InputPrompt.js';
|
||||||
import { Footer } from './components/Footer.js';
|
import { Footer } from './components/Footer.js';
|
||||||
import { ThemeDialog } from './components/ThemeDialog.js';
|
import { ThemeDialog } from './components/ThemeDialog.js';
|
||||||
import { useStartupWarnings } from './hooks/useAppEffects.js';
|
|
||||||
import { shortenPath, type Config } from '@gemini-code/server';
|
import { shortenPath, type Config } from '@gemini-code/server';
|
||||||
import { Colors } from './colors.js';
|
import { Colors } from './colors.js';
|
||||||
import { Help } from './components/Help.js';
|
import { Help } from './components/Help.js';
|
||||||
|
@ -33,16 +32,21 @@ interface AppProps {
|
||||||
config: Config;
|
config: Config;
|
||||||
settings: LoadedSettings;
|
settings: LoadedSettings;
|
||||||
cliVersion: string;
|
cliVersion: string;
|
||||||
|
startupWarnings?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const App = ({ config, settings, cliVersion }: AppProps) => {
|
export const App = ({
|
||||||
|
config,
|
||||||
|
settings,
|
||||||
|
cliVersion,
|
||||||
|
startupWarnings = [],
|
||||||
|
}: AppProps) => {
|
||||||
const { history, addItem, clearItems } = useHistory();
|
const { history, addItem, clearItems } = useHistory();
|
||||||
const [staticKey, setStaticKey] = useState(0);
|
const [staticKey, setStaticKey] = useState(0);
|
||||||
const refreshStatic = useCallback(() => {
|
const refreshStatic = useCallback(() => {
|
||||||
setStaticKey((prev) => prev + 1);
|
setStaticKey((prev) => prev + 1);
|
||||||
}, [setStaticKey]);
|
}, [setStaticKey]);
|
||||||
|
|
||||||
const [startupWarnings, setStartupWarnings] = useState<string[]>([]);
|
|
||||||
const [debugMessage, setDebugMessage] = useState<string>('');
|
const [debugMessage, setDebugMessage] = useState<string>('');
|
||||||
const [showHelp, setShowHelp] = useState<boolean>(false);
|
const [showHelp, setShowHelp] = useState<boolean>(false);
|
||||||
const [themeError, setThemeError] = useState<string | null>(null);
|
const [themeError, setThemeError] = useState<string | null>(null);
|
||||||
|
@ -74,8 +78,6 @@ export const App = ({ config, settings, cliVersion }: AppProps) => {
|
||||||
const { elapsedTime, currentLoadingPhrase } =
|
const { elapsedTime, currentLoadingPhrase } =
|
||||||
useLoadingIndicator(streamingState);
|
useLoadingIndicator(streamingState);
|
||||||
|
|
||||||
useStartupWarnings(setStartupWarnings);
|
|
||||||
|
|
||||||
const handleFinalSubmit = useCallback(
|
const handleFinalSubmit = useCallback(
|
||||||
(submittedValue: string) => {
|
(submittedValue: string) => {
|
||||||
const trimmedValue = submittedValue.trim();
|
const trimmedValue = submittedValue.trim();
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright 2025 Google LLC
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { useEffect } from 'react';
|
|
||||||
import fs from 'fs';
|
|
||||||
import path from 'path';
|
|
||||||
import os from 'os';
|
|
||||||
import { getErrorMessage } from '@gemini-code/server';
|
|
||||||
|
|
||||||
const warningsFilePath = path.join(os.tmpdir(), 'gemini-code-cli-warnings.txt');
|
|
||||||
|
|
||||||
// Effect to handle startup warnings
|
|
||||||
export function useStartupWarnings(
|
|
||||||
setStartupWarnings: React.Dispatch<React.SetStateAction<string[]>>,
|
|
||||||
) {
|
|
||||||
useEffect(() => {
|
|
||||||
try {
|
|
||||||
if (fs.existsSync(warningsFilePath)) {
|
|
||||||
const warningsContent = fs.readFileSync(warningsFilePath, 'utf-8');
|
|
||||||
setStartupWarnings(
|
|
||||||
warningsContent.split('\n').filter((line) => line.trim() !== ''),
|
|
||||||
);
|
|
||||||
try {
|
|
||||||
fs.unlinkSync(warningsFilePath);
|
|
||||||
} catch {
|
|
||||||
setStartupWarnings((prev) => [
|
|
||||||
...prev,
|
|
||||||
`Warning: Could not delete temporary warnings file.`,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (err: unknown) {
|
|
||||||
setStartupWarnings((prev) => [
|
|
||||||
...prev,
|
|
||||||
`Error checking/reading warnings file: ${getErrorMessage(err)}`,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}, [setStartupWarnings]); // Include setStartupWarnings in dependency array
|
|
||||||
}
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright 2025 Google LLC
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import fs from 'fs/promises';
|
||||||
|
import os from 'os';
|
||||||
|
import { join as pathJoin } from 'node:path';
|
||||||
|
import { getErrorMessage } from '@gemini-code/server';
|
||||||
|
|
||||||
|
const warningsFilePath = pathJoin(os.tmpdir(), 'gemini-code-cli-warnings.txt');
|
||||||
|
|
||||||
|
export async function getStartupWarnings(): Promise<string[]> {
|
||||||
|
try {
|
||||||
|
await fs.access(warningsFilePath); // Check if file exists
|
||||||
|
const warningsContent = await fs.readFile(warningsFilePath, 'utf-8');
|
||||||
|
const warnings = warningsContent
|
||||||
|
.split('\n')
|
||||||
|
.filter((line) => line.trim() !== '');
|
||||||
|
try {
|
||||||
|
await fs.unlink(warningsFilePath);
|
||||||
|
} catch {
|
||||||
|
warnings.push('Warning: Could not delete temporary warnings file.');
|
||||||
|
}
|
||||||
|
return warnings;
|
||||||
|
} catch (err: unknown) {
|
||||||
|
// If fs.access throws, it means the file doesn't exist or is not accessible.
|
||||||
|
// This is not an error in the context of fetching warnings, so return empty.
|
||||||
|
// Only return an error message if it's not a "file not found" type error.
|
||||||
|
// However, the original logic returned an error message for any fs.existsSync failure.
|
||||||
|
// To maintain closer parity while making it async, we'll check the error code.
|
||||||
|
// ENOENT is "Error NO ENTry" (file not found).
|
||||||
|
if (err instanceof Error && 'code' in err && err.code === 'ENOENT') {
|
||||||
|
return []; // File not found, no warnings to return.
|
||||||
|
}
|
||||||
|
// For other errors (permissions, etc.), return the error message.
|
||||||
|
return [`Error checking/reading warnings file: ${getErrorMessage(err)}`];
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue