mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-05-05 15:31:27 +00:00
Introduces a new Arena system for running multiple AI agents in parallel terminal sessions with support for iTerm and Tmux backends. Core: - Add ArenaManager and ArenaAgentClient for orchestrating multi-agent sessions - Add terminal backends (ITermBackend, TmuxBackend) with feature detection - Add git worktree service for isolated agent workspaces - Add arena event system for real-time status updates CLI: - Add /arena command with start, stop, status, and select subcommands - Add Arena dialogs (Select, Start, Status, Stop) - Add ArenaCards component for displaying parallel agent outputs - Consolidate message components into StatusMessages and ConversationMessages - Add MultiSelect component for agent selection Config: - Add arena-related settings to schema and config Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
113 lines
3.1 KiB
TypeScript
113 lines
3.1 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2025 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
import { useCallback } from 'react';
|
|
import { SettingScope } from '../../config/settings.js';
|
|
import type { AuthType, ApprovalMode } from '@qwen-code/qwen-code-core';
|
|
import type { ArenaDialogType } from './useArenaCommand.js';
|
|
// OpenAICredentials type (previously imported from OpenAIKeyPrompt)
|
|
interface OpenAICredentials {
|
|
apiKey: string;
|
|
baseUrl?: string;
|
|
model?: string;
|
|
}
|
|
|
|
export interface DialogCloseOptions {
|
|
// Theme dialog
|
|
isThemeDialogOpen: boolean;
|
|
handleThemeSelect: (theme: string | undefined, scope: SettingScope) => void;
|
|
|
|
// Approval mode dialog
|
|
isApprovalModeDialogOpen: boolean;
|
|
handleApprovalModeSelect: (
|
|
mode: ApprovalMode | undefined,
|
|
scope: SettingScope,
|
|
) => void;
|
|
|
|
// Auth dialog
|
|
isAuthDialogOpen: boolean;
|
|
handleAuthSelect: (
|
|
authType: AuthType | undefined,
|
|
credentials?: OpenAICredentials,
|
|
) => Promise<void>;
|
|
pendingAuthType: AuthType | undefined;
|
|
|
|
// Editor dialog
|
|
isEditorDialogOpen: boolean;
|
|
exitEditorDialog: () => void;
|
|
|
|
// Settings dialog
|
|
isSettingsDialogOpen: boolean;
|
|
closeSettingsDialog: () => void;
|
|
|
|
// Arena dialogs
|
|
activeArenaDialog: ArenaDialogType;
|
|
closeArenaDialog: () => void;
|
|
|
|
// Folder trust dialog
|
|
isFolderTrustDialogOpen: boolean;
|
|
|
|
// Welcome back dialog
|
|
showWelcomeBackDialog: boolean;
|
|
handleWelcomeBackClose: () => void;
|
|
}
|
|
|
|
/**
|
|
* Hook that handles closing dialogs when Ctrl+C is pressed.
|
|
* This mimics the ESC key behavior by calling the same handlers that ESC uses.
|
|
* Returns true if a dialog was closed, false if no dialogs were open.
|
|
*/
|
|
export function useDialogClose(options: DialogCloseOptions) {
|
|
const closeAnyOpenDialog = useCallback((): boolean => {
|
|
// Check each dialog in priority order and close using the same logic as ESC key
|
|
|
|
if (options.isThemeDialogOpen) {
|
|
// Mimic ESC behavior: onSelect(undefined, selectedScope) - keeps current theme
|
|
options.handleThemeSelect(undefined, SettingScope.User);
|
|
return true;
|
|
}
|
|
|
|
if (options.isApprovalModeDialogOpen) {
|
|
// Mimic ESC behavior: onSelect(undefined, selectedScope) - keeps current mode
|
|
options.handleApprovalModeSelect(undefined, SettingScope.User);
|
|
return true;
|
|
}
|
|
|
|
if (options.isEditorDialogOpen) {
|
|
// Mimic ESC behavior: call onExit() directly
|
|
options.exitEditorDialog();
|
|
return true;
|
|
}
|
|
|
|
if (options.isSettingsDialogOpen) {
|
|
// Mimic ESC behavior: onSelect(undefined, selectedScope)
|
|
options.closeSettingsDialog();
|
|
return true;
|
|
}
|
|
|
|
if (options.activeArenaDialog !== null) {
|
|
options.closeArenaDialog();
|
|
return true;
|
|
}
|
|
|
|
if (options.isFolderTrustDialogOpen) {
|
|
// FolderTrustDialog doesn't expose close function, but ESC would prevent exit
|
|
// We follow the same pattern - prevent exit behavior
|
|
return true;
|
|
}
|
|
|
|
if (options.showWelcomeBackDialog) {
|
|
// WelcomeBack has its own close handler
|
|
options.handleWelcomeBackClose();
|
|
return true;
|
|
}
|
|
|
|
// No dialog was open
|
|
return false;
|
|
}, [options]);
|
|
|
|
return { closeAnyOpenDialog };
|
|
}
|