diff --git a/shared/src/sessionSummary.ts b/shared/src/sessionSummary.ts index 4b693ada7..fd5096dc6 100644 --- a/shared/src/sessionSummary.ts +++ b/shared/src/sessionSummary.ts @@ -1,4 +1,4 @@ -import type { ModelMode } from './modes' +import type { ModelMode, PermissionMode } from './modes' import type { Session, WorktreeMetadata } from './schemas' export type SessionSummaryMetadata = { @@ -19,6 +19,7 @@ export type SessionSummary = { metadata: SessionSummaryMetadata | null todoProgress: { completed: number; total: number } | null pendingRequestsCount: number + permissionMode?: PermissionMode modelMode?: ModelMode } @@ -48,6 +49,7 @@ export function toSessionSummary(session: Session): SessionSummary { metadata, todoProgress, pendingRequestsCount, + permissionMode: session.permissionMode, modelMode: session.modelMode } } diff --git a/web/src/App.tsx b/web/src/App.tsx index 1a038f6cb..3d4984056 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -2,7 +2,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { Outlet, useLocation, useMatchRoute, useRouter } from '@tanstack/react-router' import { useQueryClient } from '@tanstack/react-query' import { getTelegramWebApp, isTelegramApp } from '@/hooks/useTelegram' -import { initializeTheme } from '@/hooks/useTheme' +import { initializeTheme, useTheme } from '@/hooks/useTheme' import { useAuth } from '@/hooks/useAuth' import { useAuthSource } from '@/hooks/useAuthSource' import { useServerUrl } from '@/hooks/useServerUrl' @@ -41,6 +41,7 @@ export function App() { } function AppInner() { + useTheme() const { t } = useTranslation() const { serverUrl, baseUrl, setServerUrl, clearServerUrl } = useServerUrl() const { authSource, isLoading: isAuthSourceLoading, setAccessToken } = useAuthSource(baseUrl) diff --git a/web/src/components/SessionHeader.tsx b/web/src/components/SessionHeader.tsx index 3728b2670..21b8f23a4 100644 --- a/web/src/components/SessionHeader.tsx +++ b/web/src/components/SessionHeader.tsx @@ -1,12 +1,14 @@ import { useId, useMemo, useRef, useState } from 'react' import type { Session } from '@/types/api' import type { ApiClient } from '@/api/client' +import { getPermissionModeLabel, getPermissionModeTone, isPermissionModeAllowedForFlavor } from '@hapi/protocol' import { isTelegramApp } from '@/hooks/useTelegram' import { useSessionActions } from '@/hooks/mutations/useSessionActions' import { SessionActionMenu } from '@/components/SessionActionMenu' import { RenameSessionDialog } from '@/components/RenameSessionDialog' import { ConfirmDialog } from '@/components/ui/ConfirmDialog' import { useTranslation } from '@/lib/use-translation' +import { getFlavorBadgeClass, PERMISSION_TONE_BADGE } from '@/lib/agentFlavorUtils' function getSessionTitle(session: Session): string { if (session.metadata?.name) { @@ -70,6 +72,19 @@ export function SessionHeader(props: { const { session, api, onSessionDeleted } = props const title = useMemo(() => getSessionTitle(session), [session]) const worktreeBranch = session.metadata?.worktree?.branch + const flavor = session.metadata?.flavor?.trim() ?? null + const flavorLabel = flavor || 'unknown' + const flavorBadgeClass = getFlavorBadgeClass(flavor) + const permMode = session.permissionMode + && session.permissionMode !== 'default' + && isPermissionModeAllowedForFlavor(session.permissionMode, flavor) + ? session.permissionMode + : null + const permissionLabel = permMode ? getPermissionModeLabel(permMode).toLowerCase() : null + const permissionBadgeClass = permMode + ? PERMISSION_TONE_BADGE[getPermissionModeTone(permMode)] + : null + const showModelModeBadge = !flavor || flavor === 'claude' const [menuOpen, setMenuOpen] = useState(false) const [menuAnchorPoint, setMenuAnchorPoint] = useState<{ x: number; y: number }>({ x: 0, y: 0 }) @@ -128,21 +143,29 @@ export function SessionHeader(props: { - {/* Session info - two lines: title and path */} + {/* Session info - two lines: title and badges */}