mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-19 09:33:53 +00:00
Merge tag 'v0.1.15' into feature/yiheng/sync-gemini-cli-0.1.15
This commit is contained in:
@@ -17,7 +17,6 @@ import { start_sandbox } from './utils/sandbox.js';
|
||||
import {
|
||||
LoadedSettings,
|
||||
loadSettings,
|
||||
USER_SETTINGS_PATH,
|
||||
SettingScope,
|
||||
} from './config/settings.js';
|
||||
import { themeManager } from './ui/themes/theme-manager.js';
|
||||
@@ -40,6 +39,8 @@ import {
|
||||
} from '@qwen-code/qwen-code-core';
|
||||
import { validateAuthMethod } from './config/auth.js';
|
||||
import { setMaxSizedBoxDebugging } from './ui/components/shared/MaxSizedBox.js';
|
||||
import { validateNonInteractiveAuth } from './validateNonInterActiveAuth.js';
|
||||
import { appEvents, AppEvent } from './utils/events.js';
|
||||
|
||||
function getNodeMemoryArgs(config: Config): string[] {
|
||||
const totalMemoryMB = os.totalmem() / (1024 * 1024);
|
||||
@@ -84,8 +85,32 @@ async function relaunchWithAdditionalArgs(additionalArgs: string[]) {
|
||||
await new Promise((resolve) => child.on('close', resolve));
|
||||
process.exit(0);
|
||||
}
|
||||
import { runAcpPeer } from './acp/acpPeer.js';
|
||||
|
||||
export function setupUnhandledRejectionHandler() {
|
||||
let unhandledRejectionOccurred = false;
|
||||
process.on('unhandledRejection', (reason, _promise) => {
|
||||
const errorMessage = `=========================================
|
||||
This is an unexpected error. Please file a bug report using the /bug tool.
|
||||
CRITICAL: Unhandled Promise Rejection!
|
||||
=========================================
|
||||
Reason: ${reason}${
|
||||
reason instanceof Error && reason.stack
|
||||
? `
|
||||
Stack trace:
|
||||
${reason.stack}`
|
||||
: ''
|
||||
}`;
|
||||
appEvents.emit(AppEvent.LogError, errorMessage);
|
||||
if (!unhandledRejectionOccurred) {
|
||||
unhandledRejectionOccurred = true;
|
||||
appEvents.emit(AppEvent.OpenDebugConsole);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export async function main() {
|
||||
setupUnhandledRejectionHandler();
|
||||
const workspaceRoot = process.cwd();
|
||||
const settings = loadSettings(workspaceRoot);
|
||||
|
||||
@@ -141,6 +166,9 @@ export async function main() {
|
||||
|
||||
await config.initialize();
|
||||
|
||||
// Load custom themes from settings
|
||||
themeManager.loadCustomThemes(settings.merged.customThemes);
|
||||
|
||||
if (settings.merged.theme) {
|
||||
if (!themeManager.setActiveTheme(settings.merged.theme)) {
|
||||
// If the theme is not found during initial load, log a warning and continue.
|
||||
@@ -183,12 +211,16 @@ export async function main() {
|
||||
|
||||
if (
|
||||
settings.merged.selectedAuthType === AuthType.LOGIN_WITH_GOOGLE &&
|
||||
config.getNoBrowser()
|
||||
config.isBrowserLaunchSuppressed()
|
||||
) {
|
||||
// Do oauth before app renders to make copying the link possible.
|
||||
await getOauthClient(settings.merged.selectedAuthType, config);
|
||||
}
|
||||
|
||||
if (config.getExperimentalAcp()) {
|
||||
return runAcpPeer(config, settings);
|
||||
}
|
||||
|
||||
let input = config.getQuestion();
|
||||
const startupWarnings = [
|
||||
...(await getStartupWarnings()),
|
||||
@@ -264,21 +296,6 @@ function setWindowTitle(title: string, settings: LoadedSettings) {
|
||||
}
|
||||
}
|
||||
|
||||
// --- 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);
|
||||
});
|
||||
|
||||
async function loadNonInteractiveConfig(
|
||||
config: Config,
|
||||
extensions: Extension[],
|
||||
@@ -312,51 +329,8 @@ async function loadNonInteractiveConfig(
|
||||
await finalConfig.initialize();
|
||||
}
|
||||
|
||||
return await validateNonInterActiveAuth(
|
||||
return await validateNonInteractiveAuth(
|
||||
settings.merged.selectedAuthType,
|
||||
finalConfig,
|
||||
);
|
||||
}
|
||||
|
||||
async function validateNonInterActiveAuth(
|
||||
selectedAuthType: AuthType | undefined,
|
||||
nonInteractiveConfig: Config,
|
||||
) {
|
||||
// making a special case for the cli. many headless environments might not have a settings.json set
|
||||
// so if GEMINI_API_KEY or OPENAI_API_KEY is set, we'll use that. However since the oauth things are interactive anyway, we'll
|
||||
// still expect that exists
|
||||
if (
|
||||
!selectedAuthType &&
|
||||
!process.env.GEMINI_API_KEY &&
|
||||
!process.env.OPENAI_API_KEY
|
||||
) {
|
||||
console.error(
|
||||
`Please set an Auth method in your ${USER_SETTINGS_PATH} OR specify GEMINI_API_KEY or OPENAI_API_KEY env variable before running`,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Determine auth type based on available environment variables
|
||||
if (!selectedAuthType) {
|
||||
if (process.env.OPENAI_API_KEY) {
|
||||
selectedAuthType = AuthType.USE_OPENAI;
|
||||
} else if (process.env.GEMINI_API_KEY) {
|
||||
selectedAuthType = AuthType.USE_GEMINI;
|
||||
}
|
||||
}
|
||||
|
||||
// This should never happen due to the check above, but TypeScript needs assurance
|
||||
if (!selectedAuthType) {
|
||||
console.error('No valid authentication method found');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const err = validateAuthMethod(selectedAuthType);
|
||||
if (err != null) {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
await nonInteractiveConfig.refreshAuth(selectedAuthType);
|
||||
return nonInteractiveConfig;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user