feat: add MCP OAuth authentication frontend wiring and banner

- Add McpOauthRequiredEvent and McpOauthStaticClientConfigEvent to sidecar contracts
- Add PendingMcpAuthRecord domain type with status tracking (pending/authenticating/failed/done)
- Add pendingMcpAuth field to SessionRecord for session-level auth state
- Wire onMcpOAuthRequired callback through sidecarProcess, runTurnPending, and AryxAppService
- Handle mcp-oauth-required events: set session pendingMcpAuth, clear on turn finalize/cancel
- Add dismissSessionMcpAuth IPC channel with preload binding and handler registration
- Create McpAuthBanner component (amber-themed, shows server name/URL, dismiss button)
- Integrate McpAuthBanner into ChatPane with placeholder text and App.tsx callback
- Update test fixtures for new RunTurnPendingCommand.onMcpOAuthRequired field

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
David Kaya
2026-03-27 19:09:11 +01:00
co-authored by Copilot
parent 192c28f721
commit f9757d5ce2
14 changed files with 196 additions and 2 deletions
+19
View File
@@ -0,0 +1,19 @@
export type McpAuthStatus = 'pending' | 'authenticating' | 'authenticated' | 'failed';
export interface McpOauthStaticClientConfig {
clientId: string;
publicClient?: boolean;
}
export interface PendingMcpAuthRecord {
id: string;
status: McpAuthStatus;
agentId?: string;
agentName?: string;
serverName: string;
serverUrl: string;
staticClientConfig?: McpOauthStaticClientConfig;
requestedAt: string;
completedAt?: string;
errorMessage?: string;
}
+2
View File
@@ -13,6 +13,7 @@ import {
import type { SessionRunRecord } from '@shared/domain/runTimeline';
import type { PendingUserInputRecord } from '@shared/domain/userInput';
import type { PendingPlanReviewRecord } from '@shared/domain/planReview';
import type { PendingMcpAuthRecord } from '@shared/domain/mcpAuth';
import type { InteractionMode } from '@shared/contracts/sidecar';
export type ChatRole = 'system' | 'user' | 'assistant';
@@ -54,6 +55,7 @@ export interface SessionRecord {
pendingApprovalQueue?: PendingApprovalRecord[];
pendingUserInput?: PendingUserInputRecord;
pendingPlanReview?: PendingPlanReviewRecord;
pendingMcpAuth?: PendingMcpAuthRecord;
runs: SessionRunRecord[];
}