merge main

This commit is contained in:
DennisYu07 2026-03-19 17:12:19 +08:00
commit 6f914e4f4e
228 changed files with 28059 additions and 2618 deletions

View file

@ -54,6 +54,7 @@ import { useAuthCommand } from './auth/useAuth.js';
import { useEditorSettings } from './hooks/useEditorSettings.js';
import { useSettingsCommand } from './hooks/useSettingsCommand.js';
import { useModelCommand } from './hooks/useModelCommand.js';
import { useArenaCommand } from './hooks/useArenaCommand.js';
import { useApprovalModeCommand } from './hooks/useApprovalModeCommand.js';
import { useResumeCommand } from './hooks/useResumeCommand.js';
import { useSlashCommandProcessor } from './hooks/slashCommandProcessor.js';
@ -98,6 +99,7 @@ import {
} from './hooks/useExtensionUpdates.js';
import { useCodingPlanUpdates } from './hooks/useCodingPlanUpdates.js';
import { ShellFocusContext } from './contexts/ShellFocusContext.js';
import { useAgentViewState } from './contexts/AgentViewContext.js';
import { t } from '../i18n/index.js';
import { useWelcomeBack } from './hooks/useWelcomeBack.js';
import { useDialogClose } from './hooks/useDialogClose.js';
@ -507,6 +509,8 @@ export const AppContainer = (props: AppContainerProps) => {
const { isModelDialogOpen, openModelDialog, closeModelDialog } =
useModelCommand();
const { activeArenaDialog, openArenaDialog, closeArenaDialog } =
useArenaCommand();
const {
isResumeDialogOpen,
@ -546,6 +550,7 @@ export const AppContainer = (props: AppContainerProps) => {
openEditorDialog,
openSettingsDialog,
openModelDialog,
openArenaDialog,
openPermissionsDialog,
openApprovalModeDialog,
quit: (messages: HistoryItem[]) => {
@ -570,6 +575,7 @@ export const AppContainer = (props: AppContainerProps) => {
openEditorDialog,
openSettingsDialog,
openModelDialog,
openArenaDialog,
setDebugMessage,
dispatchExtensionStateUpdate,
openPermissionsDialog,
@ -706,12 +712,15 @@ export const AppContainer = (props: AppContainerProps) => {
// Track whether suggestions are visible for Tab key handling
const [hasSuggestionsVisible, setHasSuggestionsVisible] = useState(false);
// Auto-accept indicator
const agentViewState = useAgentViewState();
// Auto-accept indicator — disabled on agent tabs (agents handle their own)
const showAutoAcceptIndicator = useAutoAcceptIndicator({
config,
addItem: historyManager.addItem,
onApprovalModeChange: handleApprovalModeChange,
shouldBlockTab: () => hasSuggestionsVisible,
disabled: agentViewState.activeView !== 'main',
});
const { messageQueue, addMessage, clearQueue, getQueuedMessagesText } =
@ -724,9 +733,26 @@ export const AppContainer = (props: AppContainerProps) => {
// Callback for handling final submit (must be after addMessage from useMessageQueue)
const handleFinalSubmit = useCallback(
(submittedValue: string) => {
// Route to active in-process agent if viewing a sub-agent tab.
if (agentViewState.activeView !== 'main') {
const agent = agentViewState.agents.get(agentViewState.activeView);
if (agent) {
agent.interactiveAgent.enqueueMessage(submittedValue.trim());
return;
}
}
addMessage(submittedValue);
},
[addMessage],
[addMessage, agentViewState],
);
const handleArenaModelsSelected = useCallback(
(models: string[]) => {
const value = models.join(',');
buffer.setText(`/arena start --models ${value} `);
closeArenaDialog();
},
[buffer, closeArenaDialog],
);
// Welcome back functionality (must be after handleFinalSubmit)
@ -802,10 +828,17 @@ export const AppContainer = (props: AppContainerProps) => {
}
}, [buffer, terminalWidth, terminalHeight]);
// Compute available terminal height based on controls measurement
// agentViewState is declared earlier (before handleFinalSubmit) so it
// is available for input routing. Referenced here for layout computation.
// Compute available terminal height based on controls measurement.
// When in-process agents are present the AgentTabBar renders an extra
// row at the top of the layout; subtract it so downstream consumers
// (shell, transcript, etc.) don't overestimate available space.
const tabBarHeight = agentViewState.agents.size > 0 ? 1 : 0;
const availableTerminalHeight = Math.max(
0,
terminalHeight - controlsHeight - staticExtraHeight - 2,
terminalHeight - controlsHeight - staticExtraHeight - 2 - tabBarHeight,
);
config.setShellExecutionConfig({
@ -1059,10 +1092,16 @@ export const AppContainer = (props: AppContainerProps) => {
[historyManager, setShowCommandMigrationNudge, config.storage],
);
const { elapsedTime, currentLoadingPhrase } = useLoadingIndicator(
streamingState,
settings.merged.ui?.customWittyPhrases,
);
const currentCandidatesTokens = Object.values(
sessionStats.metrics?.models ?? {},
).reduce((acc, model) => acc + (model.tokens?.candidates ?? 0), 0);
const { elapsedTime, currentLoadingPhrase, taskStartTokens } =
useLoadingIndicator(
streamingState,
settings.merged.ui?.customWittyPhrases,
currentCandidatesTokens,
);
useAttentionNotifications({
isFocused,
@ -1085,6 +1124,8 @@ export const AppContainer = (props: AppContainerProps) => {
exitEditorDialog,
isSettingsDialogOpen,
closeSettingsDialog,
activeArenaDialog,
closeArenaDialog,
isFolderTrustDialogOpen,
showWelcomeBackDialog,
handleWelcomeBackClose,
@ -1342,6 +1383,7 @@ export const AppContainer = (props: AppContainerProps) => {
isThemeDialogOpen ||
isSettingsDialogOpen ||
isModelDialogOpen ||
activeArenaDialog !== null ||
isPermissionsDialogOpen ||
isAuthDialogOpen ||
isAuthenticating ||
@ -1392,6 +1434,7 @@ export const AppContainer = (props: AppContainerProps) => {
quittingMessages,
isSettingsDialogOpen,
isModelDialogOpen,
activeArenaDialog,
isPermissionsDialogOpen,
isApprovalModeDialogOpen,
isResumeDialogOpen,
@ -1468,6 +1511,8 @@ export const AppContainer = (props: AppContainerProps) => {
isMcpDialogOpen,
// Feedback dialog
isFeedbackDialogOpen,
// Per-task token tracking
taskStartTokens,
}),
[
isThemeDialogOpen,
@ -1485,6 +1530,7 @@ export const AppContainer = (props: AppContainerProps) => {
quittingMessages,
isSettingsDialogOpen,
isModelDialogOpen,
activeArenaDialog,
isPermissionsDialogOpen,
isApprovalModeDialogOpen,
isResumeDialogOpen,
@ -1562,6 +1608,8 @@ export const AppContainer = (props: AppContainerProps) => {
isMcpDialogOpen,
// Feedback dialog
isFeedbackDialogOpen,
// Per-task token tracking
taskStartTokens,
],
);
@ -1581,6 +1629,9 @@ export const AppContainer = (props: AppContainerProps) => {
exitEditorDialog,
closeSettingsDialog,
closeModelDialog,
openArenaDialog,
closeArenaDialog,
handleArenaModelsSelected,
dismissCodingPlanUpdate,
closePermissionsDialog,
setShellModeActive,
@ -1630,6 +1681,9 @@ export const AppContainer = (props: AppContainerProps) => {
exitEditorDialog,
closeSettingsDialog,
closeModelDialog,
openArenaDialog,
closeArenaDialog,
handleArenaModelsSelected,
dismissCodingPlanUpdate,
closePermissionsDialog,
setShellModeActive,