Restore features lost during main merge and fix workspace setup flow

Restores all features dropped when merging main into dev:
- Keyboard shortcuts (send, dictation-confirm) with full e2e chain
- Feature toggles (plan/fast mode) in agent status bar
- Sidebar kebab menu (Remove Project) on project rows
- Combined model selector (sticky header, sizing, favorites sort, search)
- Question form Enter key submit with guard
- Input focus restoration (composer + AgentStatusBar onDropdownClose)
- Draft-agent feature toggles and focus restoration
- Provider diagnostics UI (settings section, diagnostic sheet, status badge)
- Provider diagnostics server (snapshot manager, diagnostic utils, RPC)

Fixes dev-branch regressions:
- New workspace button now opens composer in setup dialog via beginWorkspaceSetup
- Setup tab auto-opens when workspace setup is running
This commit is contained in:
Mohamed Boudra
2026-04-05 21:10:16 +07:00
parent 8e482b1613
commit 4dca672711
26 changed files with 2002 additions and 147 deletions
+17 -5
View File
@@ -103,7 +103,7 @@ export interface MessageInputProps {
export interface MessageInputRef {
focus: () => void;
blur: () => void;
runKeyboardAction: (action: MessageInputKeyboardActionKind) => void;
runKeyboardAction: (action: MessageInputKeyboardActionKind) => boolean;
/**
* Web-only: return the underlying DOM element for focus assertions/retries.
* May return null if not mounted or on native.
@@ -247,26 +247,35 @@ export const MessageInput = forwardRef<MessageInputRef, MessageInputProps>(funct
runKeyboardAction: (action) => {
if (action === "focus") {
textInputRef.current?.focus();
return;
return true;
}
if (action === "send" || action === "dictation-confirm") {
if (isDictatingRef.current) {
sendAfterTranscriptRef.current = true;
confirmDictation();
return true;
}
return false;
}
if (action === "voice-toggle") {
handleToggleRealtimeVoiceShortcut();
return;
return true;
}
if (action === "voice-mute-toggle") {
if (isRealtimeVoiceForCurrentAgent) {
voice?.toggleMute();
}
return;
return true;
}
if (action === "dictation-cancel") {
if (isDictatingRef.current) {
cancelDictation();
}
return;
return true;
}
if (action === "dictation-toggle") {
@@ -276,7 +285,10 @@ export const MessageInput = forwardRef<MessageInputRef, MessageInputProps>(funct
} else {
void startDictationIfAvailable();
}
return true;
}
return false;
},
getNativeElement: () => {
if (!IS_WEB) return null;