refactor: rename SessionProvider to LLMProvider

This commit is contained in:
Haileyesus
2026-04-11 13:59:50 +03:00
parent c981212257
commit 40f7fcef14
25 changed files with 87 additions and 84 deletions

View File

@@ -19,7 +19,7 @@ import type {
PendingPermissionRequest, PendingPermissionRequest,
PermissionMode, PermissionMode,
} from '../types/types'; } from '../types/types';
import type { Project, ProjectSession, SessionProvider } from '../../../types/app'; import type { Project, ProjectSession, LLMProvider } from '../../../types/app';
import { escapeRegExp } from '../utils/chatFormatting'; import { escapeRegExp } from '../utils/chatFormatting';
import { useFileMentions } from './useFileMentions'; import { useFileMentions } from './useFileMentions';
import { type SlashCommand, useSlashCommands } from './useSlashCommands'; import { type SlashCommand, useSlashCommands } from './useSlashCommands';
@@ -33,7 +33,7 @@ interface UseChatComposerStateArgs {
selectedProject: Project | null; selectedProject: Project | null;
selectedSession: ProjectSession | null; selectedSession: ProjectSession | null;
currentSessionId: string | null; currentSessionId: string | null;
provider: SessionProvider; provider: LLMProvider;
permissionMode: PermissionMode | string; permissionMode: PermissionMode | string;
cyclePermissionMode: () => void; cyclePermissionMode: () => void;
cursorModel: string; cursorModel: string;

View File

@@ -2,7 +2,7 @@ import { useCallback, useEffect, useRef, useState } from 'react';
import { authenticatedFetch } from '../../../utils/api'; import { authenticatedFetch } from '../../../utils/api';
import { CLAUDE_MODELS, CODEX_MODELS, CURSOR_MODELS, GEMINI_MODELS } from '../../../../shared/modelConstants'; import { CLAUDE_MODELS, CODEX_MODELS, CURSOR_MODELS, GEMINI_MODELS } from '../../../../shared/modelConstants';
import type { PendingPermissionRequest, PermissionMode } from '../types/types'; import type { PendingPermissionRequest, PermissionMode } from '../types/types';
import type { ProjectSession, SessionProvider } from '../../../types/app'; import type { ProjectSession, LLMProvider } from '../../../types/app';
interface UseChatProviderStateArgs { interface UseChatProviderStateArgs {
selectedSession: ProjectSession | null; selectedSession: ProjectSession | null;
@@ -11,8 +11,8 @@ interface UseChatProviderStateArgs {
export function useChatProviderState({ selectedSession }: UseChatProviderStateArgs) { export function useChatProviderState({ selectedSession }: UseChatProviderStateArgs) {
const [permissionMode, setPermissionMode] = useState<PermissionMode>('default'); const [permissionMode, setPermissionMode] = useState<PermissionMode>('default');
const [pendingPermissionRequests, setPendingPermissionRequests] = useState<PendingPermissionRequest[]>([]); const [pendingPermissionRequests, setPendingPermissionRequests] = useState<PendingPermissionRequest[]>([]);
const [provider, setProvider] = useState<SessionProvider>(() => { const [provider, setProvider] = useState<LLMProvider>(() => {
return (localStorage.getItem('selected-provider') as SessionProvider) || 'claude'; return (localStorage.getItem('selected-provider') as LLMProvider) || 'claude';
}); });
const [cursorModel, setCursorModel] = useState<string>(() => { const [cursorModel, setCursorModel] = useState<string>(() => {
return localStorage.getItem('cursor-model') || CURSOR_MODELS.DEFAULT; return localStorage.getItem('cursor-model') || CURSOR_MODELS.DEFAULT;

View File

@@ -1,7 +1,7 @@
import { useEffect, useRef } from 'react'; import { useEffect, useRef } from 'react';
import type { Dispatch, MutableRefObject, SetStateAction } from 'react'; import type { Dispatch, MutableRefObject, SetStateAction } from 'react';
import type { PendingPermissionRequest } from '../types/types'; import type { PendingPermissionRequest } from '../types/types';
import type { Project, ProjectSession, SessionProvider } from '../../../types/app'; import type { Project, ProjectSession, LLMProvider } from '../../../types/app';
import type { SessionStore, NormalizedMessage } from '../../../stores/useSessionStore'; import type { SessionStore, NormalizedMessage } from '../../../stores/useSessionStore';
type PendingViewSession = { type PendingViewSession = {
@@ -48,7 +48,7 @@ type LatestChatMessage = {
interface UseChatRealtimeHandlersArgs { interface UseChatRealtimeHandlersArgs {
latestMessage: LatestChatMessage | null; latestMessage: LatestChatMessage | null;
provider: SessionProvider; provider: LLMProvider;
selectedProject: Project | null; selectedProject: Project | null;
selectedSession: ProjectSession | null; selectedSession: ProjectSession | null;
currentSessionId: string | null; currentSessionId: string | null;

View File

@@ -2,7 +2,7 @@ import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } fr
import type { MutableRefObject } from 'react'; import type { MutableRefObject } from 'react';
import { authenticatedFetch } from '../../../utils/api'; import { authenticatedFetch } from '../../../utils/api';
import type { ChatMessage, Provider } from '../types/types'; import type { ChatMessage, Provider } from '../types/types';
import type { Project, ProjectSession, SessionProvider } from '../../../types/app'; import type { Project, ProjectSession, LLMProvider } from '../../../types/app';
import { createCachedDiffCalculator, type DiffCalculator } from '../utils/messageTransforms'; import { createCachedDiffCalculator, type DiffCalculator } from '../utils/messageTransforms';
import { normalizedToChatMessages } from './useChatMessages'; import { normalizedToChatMessages } from './useChatMessages';
import type { SessionStore, NormalizedMessage } from '../../../stores/useSessionStore'; import type { SessionStore, NormalizedMessage } from '../../../stores/useSessionStore';
@@ -40,7 +40,7 @@ interface ScrollRestoreState {
function chatMessageToNormalized( function chatMessageToNormalized(
msg: ChatMessage, msg: ChatMessage,
sessionId: string, sessionId: string,
provider: SessionProvider, provider: LLMProvider,
): NormalizedMessage | null { ): NormalizedMessage | null {
const id = `local_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`; const id = `local_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
const ts = msg.timestamp instanceof Date const ts = msg.timestamp instanceof Date
@@ -151,7 +151,7 @@ export function useChatSessionState({
// When a real session ID arrives and we have a pending user message, flush it to the store // When a real session ID arrives and we have a pending user message, flush it to the store
const prevActiveSessionRef = useRef<string | null>(null); const prevActiveSessionRef = useRef<string | null>(null);
if (activeSessionId && activeSessionId !== prevActiveSessionRef.current && pendingUserMessage) { if (activeSessionId && activeSessionId !== prevActiveSessionRef.current && pendingUserMessage) {
const prov = (localStorage.getItem('selected-provider') as SessionProvider) || 'claude'; const prov = (localStorage.getItem('selected-provider') as LLMProvider) || 'claude';
const normalized = chatMessageToNormalized(pendingUserMessage, activeSessionId, prov); const normalized = chatMessageToNormalized(pendingUserMessage, activeSessionId, prov);
if (normalized) { if (normalized) {
sessionStore.appendRealtime(activeSessionId, normalized); sessionStore.appendRealtime(activeSessionId, normalized);
@@ -189,7 +189,7 @@ export function useChatSessionState({
setPendingUserMessage(msg); setPendingUserMessage(msg);
return; return;
} }
const prov = (localStorage.getItem('selected-provider') as SessionProvider) || 'claude'; const prov = (localStorage.getItem('selected-provider') as LLMProvider) || 'claude';
const normalized = chatMessageToNormalized(msg, activeSessionId, prov); const normalized = chatMessageToNormalized(msg, activeSessionId, prov);
if (normalized) { if (normalized) {
sessionStore.appendRealtime(activeSessionId, normalized); sessionStore.appendRealtime(activeSessionId, normalized);
@@ -240,7 +240,7 @@ export function useChatSessionState({
try { try {
const slot = await sessionStore.fetchMore(selectedSession.id, { const slot = await sessionStore.fetchMore(selectedSession.id, {
provider: sessionProvider as SessionProvider, provider: sessionProvider as LLMProvider,
projectName: selectedProject.name, projectName: selectedProject.name,
projectPath: selectedProject.fullPath || selectedProject.path || '', projectPath: selectedProject.fullPath || selectedProject.path || '',
limit: MESSAGES_PER_PAGE, limit: MESSAGES_PER_PAGE,
@@ -374,7 +374,7 @@ export function useChatSessionState({
// Fetch from server → store updates → chatMessages re-derives automatically // Fetch from server → store updates → chatMessages re-derives automatically
setIsLoadingSessionMessages(true); setIsLoadingSessionMessages(true);
sessionStore.fetchFromServer(selectedSession.id, { sessionStore.fetchFromServer(selectedSession.id, {
provider: (selectedSession.__provider || provider) as SessionProvider, provider: (selectedSession.__provider || provider) as LLMProvider,
projectName: selectedProject.name, projectName: selectedProject.name,
projectPath: selectedProject.fullPath || selectedProject.path || '', projectPath: selectedProject.fullPath || selectedProject.path || '',
limit: MESSAGES_PER_PAGE, limit: MESSAGES_PER_PAGE,
@@ -410,7 +410,7 @@ export function useChatSessionState({
// Skip store refresh during active streaming // Skip store refresh during active streaming
if (!isLoading) { if (!isLoading) {
await sessionStore.refreshFromServer(selectedSession.id, { await sessionStore.refreshFromServer(selectedSession.id, {
provider: (selectedSession.__provider || provider) as SessionProvider, provider: (selectedSession.__provider || provider) as LLMProvider,
projectName: selectedProject.name, projectName: selectedProject.name,
projectPath: selectedProject.fullPath || selectedProject.path || '', projectPath: selectedProject.fullPath || selectedProject.path || '',
}); });
@@ -468,7 +468,7 @@ export function useChatSessionState({
try { try {
// Load all messages into the store for search navigation // Load all messages into the store for search navigation
const slot = await sessionStore.fetchFromServer(selectedSession.id, { const slot = await sessionStore.fetchFromServer(selectedSession.id, {
provider: sessionProvider as SessionProvider, provider: sessionProvider as LLMProvider,
projectName: selectedProject.name, projectName: selectedProject.name,
projectPath: selectedProject.fullPath || selectedProject.path || '', projectPath: selectedProject.fullPath || selectedProject.path || '',
limit: null, limit: null,
@@ -655,7 +655,7 @@ export function useChatSessionState({
try { try {
const slot = await sessionStore.fetchFromServer(requestSessionId, { const slot = await sessionStore.fetchFromServer(requestSessionId, {
provider: sessionProvider as SessionProvider, provider: sessionProvider as LLMProvider,
projectName: selectedProject.name, projectName: selectedProject.name,
projectPath: selectedProject.fullPath || selectedProject.path || '', projectPath: selectedProject.fullPath || selectedProject.path || '',
limit: null, limit: null,

View File

@@ -1,6 +1,6 @@
import type { Project, ProjectSession, SessionProvider } from '../../../types/app'; import type { Project, ProjectSession, LLMProvider } from '../../../types/app';
export type Provider = SessionProvider; export type Provider = LLMProvider;
export type PermissionMode = 'default' | 'acceptEdits' | 'bypassPermissions' | 'plan'; export type PermissionMode = 'default' | 'acceptEdits' | 'bypassPermissions' | 'plan';

View File

@@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next';
import { useTasksSettings } from '../../../contexts/TasksSettingsContext'; import { useTasksSettings } from '../../../contexts/TasksSettingsContext';
import { QuickSettingsPanel } from '../../quick-settings-panel'; import { QuickSettingsPanel } from '../../quick-settings-panel';
import type { ChatInterfaceProps, Provider } from '../types/types'; import type { ChatInterfaceProps, Provider } from '../types/types';
import type { SessionProvider } from '../../../types/app'; import type { LLMProvider } from '../../../types/app';
import { useChatProviderState } from '../hooks/useChatProviderState'; import { useChatProviderState } from '../hooks/useChatProviderState';
import { useChatSessionState } from '../hooks/useChatSessionState'; import { useChatSessionState } from '../hooks/useChatSessionState';
import { useChatRealtimeHandlers } from '../hooks/useChatRealtimeHandlers'; import { useChatRealtimeHandlers } from '../hooks/useChatRealtimeHandlers';
@@ -206,9 +206,9 @@ function ChatInterface({
// so missed streaming events are shown. Also reset isLoading. // so missed streaming events are shown. Also reset isLoading.
const handleWebSocketReconnect = useCallback(async () => { const handleWebSocketReconnect = useCallback(async () => {
if (!selectedProject || !selectedSession) return; if (!selectedProject || !selectedSession) return;
const providerVal = (localStorage.getItem('selected-provider') as SessionProvider) || 'claude'; const providerVal = (localStorage.getItem('selected-provider') as LLMProvider) || 'claude';
await sessionStore.refreshFromServer(selectedSession.id, { await sessionStore.refreshFromServer(selectedSession.id, {
provider: (selectedSession.__provider || providerVal) as SessionProvider, provider: (selectedSession.__provider || providerVal) as LLMProvider,
projectName: selectedProject.name, projectName: selectedProject.name,
projectPath: selectedProject.fullPath || selectedProject.path || '', projectPath: selectedProject.fullPath || selectedProject.path || '',
}); });

View File

@@ -2,7 +2,7 @@ import { useTranslation } from 'react-i18next';
import { useCallback, useRef } from 'react'; import { useCallback, useRef } from 'react';
import type { Dispatch, RefObject, SetStateAction } from 'react'; import type { Dispatch, RefObject, SetStateAction } from 'react';
import type { ChatMessage } from '../../types/types'; import type { ChatMessage } from '../../types/types';
import type { Project, ProjectSession, SessionProvider } from '../../../../types/app'; import type { Project, ProjectSession, LLMProvider } from '../../../../types/app';
import { getIntrinsicMessageKey } from '../../utils/messageKeys'; import { getIntrinsicMessageKey } from '../../utils/messageKeys';
import MessageComponent from './MessageComponent'; import MessageComponent from './MessageComponent';
import ProviderSelectionEmptyState from './ProviderSelectionEmptyState'; import ProviderSelectionEmptyState from './ProviderSelectionEmptyState';
@@ -15,8 +15,8 @@ interface ChatMessagesPaneProps {
chatMessages: ChatMessage[]; chatMessages: ChatMessage[];
selectedSession: ProjectSession | null; selectedSession: ProjectSession | null;
currentSessionId: string | null; currentSessionId: string | null;
provider: SessionProvider; provider: LLMProvider;
setProvider: (provider: SessionProvider) => void; setProvider: (provider: LLMProvider) => void;
textareaRef: RefObject<HTMLTextAreaElement>; textareaRef: RefObject<HTMLTextAreaElement>;
claudeModel: string; claudeModel: string;
setClaudeModel: (model: string) => void; setClaudeModel: (model: string) => void;

View File

@@ -8,14 +8,14 @@ import {
CODEX_MODELS, CODEX_MODELS,
GEMINI_MODELS, GEMINI_MODELS,
} from "../../../../../shared/modelConstants"; } from "../../../../../shared/modelConstants";
import type { ProjectSession, SessionProvider } from "../../../../types/app"; import type { ProjectSession, LLMProvider } from "../../../../types/app";
import { NextTaskBanner } from "../../../task-master"; import { NextTaskBanner } from "../../../task-master";
type ProviderSelectionEmptyStateProps = { type ProviderSelectionEmptyStateProps = {
selectedSession: ProjectSession | null; selectedSession: ProjectSession | null;
currentSessionId: string | null; currentSessionId: string | null;
provider: SessionProvider; provider: LLMProvider;
setProvider: (next: SessionProvider) => void; setProvider: (next: LLMProvider) => void;
textareaRef: React.RefObject<HTMLTextAreaElement>; textareaRef: React.RefObject<HTMLTextAreaElement>;
claudeModel: string; claudeModel: string;
setClaudeModel: (model: string) => void; setClaudeModel: (model: string) => void;
@@ -32,7 +32,7 @@ type ProviderSelectionEmptyStateProps = {
}; };
type ProviderDef = { type ProviderDef = {
id: SessionProvider; id: LLMProvider;
name: string; name: string;
infoKey: string; infoKey: string;
accent: string; accent: string;
@@ -75,7 +75,7 @@ const PROVIDERS: ProviderDef[] = [
}, },
]; ];
function getModelConfig(p: SessionProvider) { function getModelConfig(p: LLMProvider) {
if (p === "claude") return CLAUDE_MODELS; if (p === "claude") return CLAUDE_MODELS;
if (p === "codex") return CODEX_MODELS; if (p === "codex") return CODEX_MODELS;
if (p === "gemini") return GEMINI_MODELS; if (p === "gemini") return GEMINI_MODELS;
@@ -83,7 +83,7 @@ function getModelConfig(p: SessionProvider) {
} }
function getModelValue( function getModelValue(
p: SessionProvider, p: LLMProvider,
c: string, c: string,
cu: string, cu: string,
co: string, co: string,
@@ -119,7 +119,7 @@ export default function ProviderSelectionEmptyState({
defaultValue: "Start the next task", defaultValue: "Start the next task",
}); });
const selectProvider = (next: SessionProvider) => { const selectProvider = (next: LLMProvider) => {
setProvider(next); setProvider(next);
localStorage.setItem("selected-provider", next); localStorage.setItem("selected-provider", next);
setTimeout(() => textareaRef.current?.focus(), 100); setTimeout(() => textareaRef.current?.focus(), 100);

View File

@@ -1,11 +1,11 @@
import type { SessionProvider } from '../../types/app'; import type { LLMProvider } from '../../types/app';
import ClaudeLogo from './ClaudeLogo'; import ClaudeLogo from './ClaudeLogo';
import CodexLogo from './CodexLogo'; import CodexLogo from './CodexLogo';
import CursorLogo from './CursorLogo'; import CursorLogo from './CursorLogo';
import GeminiLogo from './GeminiLogo'; import GeminiLogo from './GeminiLogo';
type SessionProviderLogoProps = { type SessionProviderLogoProps = {
provider?: SessionProvider | string | null; provider?: LLMProvider | string | null;
className?: string; className?: string;
}; };

View File

@@ -1,8 +1,8 @@
import { Check, ChevronLeft, ChevronRight, Loader2 } from 'lucide-react'; import { Check, ChevronLeft, ChevronRight, Loader2 } from 'lucide-react';
import { useCallback, useEffect, useRef, useState } from 'react'; import { useCallback, useEffect, useRef, useState } from 'react';
import type { LLMProvider } from '../../../types/app';
import { authenticatedFetch } from '../../../utils/api'; import { authenticatedFetch } from '../../../utils/api';
import { useProviderAuthStatus } from '../../provider-auth/hooks/useProviderAuthStatus'; import { useProviderAuthStatus } from '../../provider-auth/hooks/useProviderAuthStatus';
import type { CliProvider } from '../../provider-auth/types';
import ProviderLoginModal from '../../provider-auth/view/ProviderLoginModal'; import ProviderLoginModal from '../../provider-auth/view/ProviderLoginModal';
import AgentConnectionsStep from './subcomponents/AgentConnectionsStep'; import AgentConnectionsStep from './subcomponents/AgentConnectionsStep';
import GitConfigurationStep from './subcomponents/GitConfigurationStep'; import GitConfigurationStep from './subcomponents/GitConfigurationStep';
@@ -22,14 +22,14 @@ export default function Onboarding({ onComplete }: OnboardingProps) {
const [gitEmail, setGitEmail] = useState(''); const [gitEmail, setGitEmail] = useState('');
const [isSubmitting, setIsSubmitting] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false);
const [errorMessage, setErrorMessage] = useState(''); const [errorMessage, setErrorMessage] = useState('');
const [activeLoginProvider, setActiveLoginProvider] = useState<CliProvider | null>(null); const [activeLoginProvider, setActiveLoginProvider] = useState<LLMProvider | null>(null);
const { const {
providerAuthStatus, providerAuthStatus,
checkProviderAuthStatus, checkProviderAuthStatus,
refreshProviderAuthStatuses, refreshProviderAuthStatuses,
} = useProviderAuthStatus(); } = useProviderAuthStatus();
const previousActiveLoginProviderRef = useRef<CliProvider | null | undefined>(undefined); const previousActiveLoginProviderRef = useRef<LLMProvider | null | undefined>(undefined);
const loadGitConfig = useCallback(async () => { const loadGitConfig = useCallback(async () => {
try { try {
@@ -69,7 +69,7 @@ export default function Onboarding({ onComplete }: OnboardingProps) {
} }
}, [activeLoginProvider, refreshProviderAuthStatuses]); }, [activeLoginProvider, refreshProviderAuthStatuses]);
const handleProviderLoginOpen = (provider: CliProvider) => { const handleProviderLoginOpen = (provider: LLMProvider) => {
setActiveLoginProvider(provider); setActiveLoginProvider(provider);
}; };

View File

@@ -1,9 +1,10 @@
import { Check } from 'lucide-react'; import { Check } from 'lucide-react';
import SessionProviderLogo from '../../../llm-logo-provider/SessionProviderLogo'; import SessionProviderLogo from '../../../llm-logo-provider/SessionProviderLogo';
import type { CliProvider, ProviderAuthStatus } from '../../../provider-auth/types'; import type { LLMProvider } from '../../../../types/app';
import type { ProviderAuthStatus } from '../../../provider-auth/types';
type AgentConnectionCardProps = { type AgentConnectionCardProps = {
provider: CliProvider; provider: LLMProvider;
title: string; title: string;
status: ProviderAuthStatus; status: ProviderAuthStatus;
connectedClassName: string; connectedClassName: string;

View File

@@ -1,9 +1,10 @@
import type { CliProvider, ProviderAuthStatusMap } from '../../../provider-auth/types'; import type { LLMProvider } from '../../../../types/app';
import type { ProviderAuthStatusMap } from '../../../provider-auth/types';
import AgentConnectionCard from './AgentConnectionCard'; import AgentConnectionCard from './AgentConnectionCard';
type AgentConnectionsStepProps = { type AgentConnectionsStepProps = {
providerStatuses: ProviderAuthStatusMap; providerStatuses: ProviderAuthStatusMap;
onOpenProviderLogin: (provider: CliProvider) => void; onOpenProviderLogin: (provider: LLMProvider) => void;
}; };
const providerCards = [ const providerCards = [

View File

@@ -1,12 +1,12 @@
import { useCallback, useState } from 'react'; import { useCallback, useState } from 'react';
import { authenticatedFetch } from '../../../utils/api'; import { authenticatedFetch } from '../../../utils/api';
import type { LLMProvider } from '../../../types/app';
import { import {
CLI_AUTH_STATUS_ENDPOINTS, CLI_AUTH_STATUS_ENDPOINTS,
CLI_PROVIDERS, CLI_PROVIDERS,
createInitialProviderAuthStatusMap, createInitialProviderAuthStatusMap,
} from '../types'; } from '../types';
import type { import type {
CliProvider,
ProviderAuthStatus, ProviderAuthStatus,
ProviderAuthStatusMap, ProviderAuthStatusMap,
} from '../types'; } from '../types';
@@ -47,7 +47,7 @@ export function useProviderAuthStatus(
createInitialProviderAuthStatusMap(initialLoading) createInitialProviderAuthStatusMap(initialLoading)
)); ));
const setProviderLoading = useCallback((provider: CliProvider) => { const setProviderLoading = useCallback((provider: LLMProvider) => {
setProviderAuthStatus((previous) => ({ setProviderAuthStatus((previous) => ({
...previous, ...previous,
[provider]: { [provider]: {
@@ -58,14 +58,14 @@ export function useProviderAuthStatus(
})); }));
}, []); }, []);
const setProviderStatus = useCallback((provider: CliProvider, status: ProviderAuthStatus) => { const setProviderStatus = useCallback((provider: LLMProvider, status: ProviderAuthStatus) => {
setProviderAuthStatus((previous) => ({ setProviderAuthStatus((previous) => ({
...previous, ...previous,
[provider]: status, [provider]: status,
})); }));
}, []); }, []);
const checkProviderAuthStatus = useCallback(async (provider: CliProvider) => { const checkProviderAuthStatus = useCallback(async (provider: LLMProvider) => {
setProviderLoading(provider); setProviderLoading(provider);
try { try {
@@ -96,7 +96,7 @@ export function useProviderAuthStatus(
} }
}, [setProviderLoading, setProviderStatus]); }, [setProviderLoading, setProviderStatus]);
const refreshProviderAuthStatuses = useCallback(async (providers: CliProvider[] = CLI_PROVIDERS) => { const refreshProviderAuthStatuses = useCallback(async (providers: LLMProvider[] = CLI_PROVIDERS) => {
await Promise.all(providers.map((provider) => checkProviderAuthStatus(provider))); await Promise.all(providers.map((provider) => checkProviderAuthStatus(provider)));
}, [checkProviderAuthStatus]); }, [checkProviderAuthStatus]);

View File

@@ -1,4 +1,4 @@
export type CliProvider = 'claude' | 'cursor' | 'codex' | 'gemini'; import type { LLMProvider } from '../../types/app';
export type ProviderAuthStatus = { export type ProviderAuthStatus = {
authenticated: boolean; authenticated: boolean;
@@ -8,11 +8,11 @@ export type ProviderAuthStatus = {
loading: boolean; loading: boolean;
}; };
export type ProviderAuthStatusMap = Record<CliProvider, ProviderAuthStatus>; export type ProviderAuthStatusMap = Record<LLMProvider, ProviderAuthStatus>;
export const CLI_PROVIDERS: CliProvider[] = ['claude', 'cursor', 'codex', 'gemini']; export const CLI_PROVIDERS: LLMProvider[] = ['claude', 'cursor', 'codex', 'gemini'];
export const CLI_AUTH_STATUS_ENDPOINTS: Record<CliProvider, string> = { export const CLI_AUTH_STATUS_ENDPOINTS: Record<LLMProvider, string> = {
claude: '/api/cli/claude/status', claude: '/api/cli/claude/status',
cursor: '/api/cli/cursor/status', cursor: '/api/cli/cursor/status',
codex: '/api/cli/codex/status', codex: '/api/cli/codex/status',

View File

@@ -1,12 +1,12 @@
import { ExternalLink, KeyRound, X } from 'lucide-react'; import { ExternalLink, KeyRound, X } from 'lucide-react';
import StandaloneShell from '../../standalone-shell/view/StandaloneShell'; import StandaloneShell from '../../standalone-shell/view/StandaloneShell';
import { DEFAULT_PROJECT_FOR_EMPTY_SHELL, IS_PLATFORM } from '../../../constants/config'; import { DEFAULT_PROJECT_FOR_EMPTY_SHELL, IS_PLATFORM } from '../../../constants/config';
import type { CliProvider } from '../types'; import type { LLMProvider } from '../../../types/app';
type ProviderLoginModalProps = { type ProviderLoginModalProps = {
isOpen: boolean; isOpen: boolean;
onClose: () => void; onClose: () => void;
provider?: CliProvider; provider?: LLMProvider;
onComplete?: (exitCode: number) => void; onComplete?: (exitCode: number) => void;
customCommand?: string; customCommand?: string;
isAuthenticated?: boolean; isAuthenticated?: boolean;
@@ -17,7 +17,7 @@ const getProviderCommand = ({
customCommand, customCommand,
isAuthenticated: _isAuthenticated, isAuthenticated: _isAuthenticated,
}: { }: {
provider: CliProvider; provider: LLMProvider;
customCommand?: string; customCommand?: string;
isAuthenticated: boolean; isAuthenticated: boolean;
}) => { }) => {
@@ -40,7 +40,7 @@ const getProviderCommand = ({
return 'gemini status'; return 'gemini status';
}; };
const getProviderTitle = (provider: CliProvider) => { const getProviderTitle = (provider: LLMProvider) => {
if (provider === 'claude') return 'Claude CLI Login'; if (provider === 'claude') return 'Claude CLI Login';
if (provider === 'cursor') return 'Cursor CLI Login'; if (provider === 'cursor') return 'Cursor CLI Login';
if (provider === 'codex') return 'Codex CLI Login'; if (provider === 'codex') return 'Codex CLI Login';

View File

@@ -1,8 +1,9 @@
import type { Dispatch, SetStateAction } from 'react'; import type { Dispatch, SetStateAction } from 'react';
import type { CliProvider, ProviderAuthStatus } from '../../provider-auth/types'; import type { LLMProvider } from '../../../types/app';
import type { ProviderAuthStatus } from '../../provider-auth/types';
export type SettingsMainTab = 'agents' | 'appearance' | 'git' | 'api' | 'tasks' | 'notifications' | 'plugins' | 'about'; export type SettingsMainTab = 'agents' | 'appearance' | 'git' | 'api' | 'tasks' | 'notifications' | 'plugins' | 'about';
export type AgentProvider = CliProvider; export type AgentProvider = LLMProvider;
export type AgentCategory = 'account' | 'permissions' | 'mcp'; export type AgentCategory = 'account' | 'permissions' | 'mcp';
export type ProjectSortOrder = 'name' | 'date'; export type ProjectSortOrder = 'name' | 'date';
export type SaveStatus = 'success' | 'error' | null; export type SaveStatus = 'success' | 'error' | null;

View File

@@ -2,7 +2,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import type React from 'react'; import type React from 'react';
import type { TFunction } from 'i18next'; import type { TFunction } from 'i18next';
import { api } from '../../../utils/api'; import { api } from '../../../utils/api';
import type { Project, ProjectSession, SessionProvider } from '../../../types/app'; import type { Project, ProjectSession, LLMProvider } from '../../../types/app';
import type { import type {
AdditionalSessionsByProject, AdditionalSessionsByProject,
DeleteProjectConfirmation, DeleteProjectConfirmation,
@@ -545,7 +545,7 @@ export function useSidebarController({
}, [onRefresh]); }, [onRefresh]);
const updateSessionSummary = useCallback( const updateSessionSummary = useCallback(
async (_projectName: string, sessionId: string, summary: string, provider: SessionProvider) => { async (_projectName: string, sessionId: string, summary: string, provider: LLMProvider) => {
const trimmed = summary.trim(); const trimmed = summary.trim();
if (!trimmed) { if (!trimmed) {
setEditingSession(null); setEditingSession(null);

View File

@@ -1,9 +1,9 @@
import type { LoadingProgress, Project, ProjectSession, SessionProvider } from '../../../types/app'; import type { LoadingProgress, Project, ProjectSession, LLMProvider } from '../../../types/app';
export type ProjectSortOrder = 'name' | 'date'; export type ProjectSortOrder = 'name' | 'date';
export type SessionWithProvider = ProjectSession & { export type SessionWithProvider = ProjectSession & {
__provider: SessionProvider; __provider: LLMProvider;
}; };
export type AdditionalSessionsByProject = Record<string, ProjectSession[]>; export type AdditionalSessionsByProject = Record<string, ProjectSession[]>;
@@ -18,7 +18,7 @@ export type SessionDeleteConfirmation = {
projectName: string; projectName: string;
sessionId: string; sessionId: string;
sessionTitle: string; sessionTitle: string;
provider: SessionProvider; provider: LLMProvider;
}; };
export type SidebarProps = { export type SidebarProps = {

View File

@@ -6,7 +6,7 @@ import { useUiPreferences } from '../../../hooks/useUiPreferences';
import { useSidebarController } from '../hooks/useSidebarController'; import { useSidebarController } from '../hooks/useSidebarController';
import { useTaskMaster } from '../../../contexts/TaskMasterContext'; import { useTaskMaster } from '../../../contexts/TaskMasterContext';
import { useTasksSettings } from '../../../contexts/TasksSettingsContext'; import { useTasksSettings } from '../../../contexts/TasksSettingsContext';
import type { Project, SessionProvider } from '../../../types/app'; import type { Project, LLMProvider } from '../../../types/app';
import type { MCPServerStatus, SidebarProps } from '../types/types'; import type { MCPServerStatus, SidebarProps } from '../types/types';
import SidebarCollapsed from './subcomponents/SidebarCollapsed'; import SidebarCollapsed from './subcomponents/SidebarCollapsed';
import SidebarContent from './subcomponents/SidebarContent'; import SidebarContent from './subcomponents/SidebarContent';
@@ -177,7 +177,7 @@ function Sidebar({
setEditingSession(null); setEditingSession(null);
setEditingSessionName(''); setEditingSessionName('');
}, },
onSaveEditingSession: (projectName: string, sessionId: string, summary: string, provider: SessionProvider) => { onSaveEditingSession: (projectName: string, sessionId: string, summary: string, provider: LLMProvider) => {
void updateSessionSummary(projectName, sessionId, summary, provider); void updateSessionSummary(projectName, sessionId, summary, provider);
}, },
t, t,
@@ -235,7 +235,7 @@ function Sidebar({
isSearching={isSearching} isSearching={isSearching}
searchProgress={searchProgress} searchProgress={searchProgress}
onConversationResultClick={(projectName: string, sessionId: string, provider: string, messageTimestamp?: string | null, messageSnippet?: string | null) => { onConversationResultClick={(projectName: string, sessionId: string, provider: string, messageTimestamp?: string | null, messageSnippet?: string | null) => {
const resolvedProvider = (provider || 'claude') as SessionProvider; const resolvedProvider = (provider || 'claude') as LLMProvider;
const project = projects.find(p => p.name === projectName); const project = projects.find(p => p.name === projectName);
const searchTarget = { __searchTargetTimestamp: messageTimestamp || null, __searchTargetSnippet: messageSnippet || null }; const searchTarget = { __searchTargetTimestamp: messageTimestamp || null, __searchTargetSnippet: messageSnippet || null };
const sessionObj = { const sessionObj = {

View File

@@ -2,7 +2,7 @@ import { Check, ChevronDown, ChevronRight, Edit3, Folder, FolderOpen, Star, Tras
import type { TFunction } from 'i18next'; import type { TFunction } from 'i18next';
import { Button } from '../../../../shared/view/ui'; import { Button } from '../../../../shared/view/ui';
import { cn } from '../../../../lib/utils'; import { cn } from '../../../../lib/utils';
import type { Project, ProjectSession, SessionProvider } from '../../../../types/app'; import type { Project, ProjectSession, LLMProvider } from '../../../../types/app';
import type { MCPServerStatus, SessionWithProvider } from '../../types/types'; import type { MCPServerStatus, SessionWithProvider } from '../../types/types';
import { getTaskIndicatorStatus } from '../../utils/utils'; import { getTaskIndicatorStatus } from '../../utils/utils';
import TaskIndicator from './TaskIndicator'; import TaskIndicator from './TaskIndicator';
@@ -38,14 +38,14 @@ type SidebarProjectItemProps = {
projectName: string, projectName: string,
sessionId: string, sessionId: string,
sessionTitle: string, sessionTitle: string,
provider: SessionProvider, provider: LLMProvider,
) => void; ) => void;
onLoadMoreSessions: (project: Project) => void; onLoadMoreSessions: (project: Project) => void;
onNewSession: (project: Project) => void; onNewSession: (project: Project) => void;
onEditingSessionNameChange: (value: string) => void; onEditingSessionNameChange: (value: string) => void;
onStartEditingSession: (sessionId: string, initialName: string) => void; onStartEditingSession: (sessionId: string, initialName: string) => void;
onCancelEditingSession: () => void; onCancelEditingSession: () => void;
onSaveEditingSession: (projectName: string, sessionId: string, summary: string, provider: SessionProvider) => void; onSaveEditingSession: (projectName: string, sessionId: string, summary: string, provider: LLMProvider) => void;
t: TFunction; t: TFunction;
}; };

View File

@@ -1,6 +1,6 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import type { TFunction } from 'i18next'; import type { TFunction } from 'i18next';
import type { LoadingProgress, Project, ProjectSession, SessionProvider } from '../../../../types/app'; import type { LoadingProgress, Project, ProjectSession, LLMProvider } from '../../../../types/app';
import type { import type {
LoadingSessionsByProject, LoadingSessionsByProject,
MCPServerStatus, MCPServerStatus,
@@ -42,14 +42,14 @@ export type SidebarProjectListProps = {
projectName: string, projectName: string,
sessionId: string, sessionId: string,
sessionTitle: string, sessionTitle: string,
provider: SessionProvider, provider: LLMProvider,
) => void; ) => void;
onLoadMoreSessions: (project: Project) => void; onLoadMoreSessions: (project: Project) => void;
onNewSession: (project: Project) => void; onNewSession: (project: Project) => void;
onEditingSessionNameChange: (value: string) => void; onEditingSessionNameChange: (value: string) => void;
onStartEditingSession: (sessionId: string, initialName: string) => void; onStartEditingSession: (sessionId: string, initialName: string) => void;
onCancelEditingSession: () => void; onCancelEditingSession: () => void;
onSaveEditingSession: (projectName: string, sessionId: string, summary: string, provider: SessionProvider) => void; onSaveEditingSession: (projectName: string, sessionId: string, summary: string, provider: LLMProvider) => void;
t: TFunction; t: TFunction;
}; };

View File

@@ -1,7 +1,7 @@
import { ChevronDown, Plus } from 'lucide-react'; import { ChevronDown, Plus } from 'lucide-react';
import type { TFunction } from 'i18next'; import type { TFunction } from 'i18next';
import { Button } from '../../../../shared/view/ui'; import { Button } from '../../../../shared/view/ui';
import type { Project, ProjectSession, SessionProvider } from '../../../../types/app'; import type { Project, ProjectSession, LLMProvider } from '../../../../types/app';
import type { SessionWithProvider } from '../../types/types'; import type { SessionWithProvider } from '../../types/types';
import SidebarSessionItem from './SidebarSessionItem'; import SidebarSessionItem from './SidebarSessionItem';
@@ -18,14 +18,14 @@ type SidebarProjectSessionsProps = {
onEditingSessionNameChange: (value: string) => void; onEditingSessionNameChange: (value: string) => void;
onStartEditingSession: (sessionId: string, initialName: string) => void; onStartEditingSession: (sessionId: string, initialName: string) => void;
onCancelEditingSession: () => void; onCancelEditingSession: () => void;
onSaveEditingSession: (projectName: string, sessionId: string, summary: string, provider: SessionProvider) => void; onSaveEditingSession: (projectName: string, sessionId: string, summary: string, provider: LLMProvider) => void;
onProjectSelect: (project: Project) => void; onProjectSelect: (project: Project) => void;
onSessionSelect: (session: SessionWithProvider, projectName: string) => void; onSessionSelect: (session: SessionWithProvider, projectName: string) => void;
onDeleteSession: ( onDeleteSession: (
projectName: string, projectName: string,
sessionId: string, sessionId: string,
sessionTitle: string, sessionTitle: string,
provider: SessionProvider, provider: LLMProvider,
) => void; ) => void;
onLoadMoreSessions: (project: Project) => void; onLoadMoreSessions: (project: Project) => void;
onNewSession: (project: Project) => void; onNewSession: (project: Project) => void;

View File

@@ -3,7 +3,7 @@ import type { TFunction } from 'i18next';
import { Badge, Button } from '../../../../shared/view/ui'; import { Badge, Button } from '../../../../shared/view/ui';
import { cn } from '../../../../lib/utils'; import { cn } from '../../../../lib/utils';
import { formatTimeAgo } from '../../../../utils/dateUtils'; import { formatTimeAgo } from '../../../../utils/dateUtils';
import type { Project, ProjectSession, SessionProvider } from '../../../../types/app'; import type { Project, ProjectSession, LLMProvider } from '../../../../types/app';
import type { SessionWithProvider } from '../../types/types'; import type { SessionWithProvider } from '../../types/types';
import { createSessionViewModel } from '../../utils/utils'; import { createSessionViewModel } from '../../utils/utils';
import SessionProviderLogo from '../../../llm-logo-provider/SessionProviderLogo'; import SessionProviderLogo from '../../../llm-logo-provider/SessionProviderLogo';
@@ -18,14 +18,14 @@ type SidebarSessionItemProps = {
onEditingSessionNameChange: (value: string) => void; onEditingSessionNameChange: (value: string) => void;
onStartEditingSession: (sessionId: string, initialName: string) => void; onStartEditingSession: (sessionId: string, initialName: string) => void;
onCancelEditingSession: () => void; onCancelEditingSession: () => void;
onSaveEditingSession: (projectName: string, sessionId: string, summary: string, provider: SessionProvider) => void; onSaveEditingSession: (projectName: string, sessionId: string, summary: string, provider: LLMProvider) => void;
onProjectSelect: (project: Project) => void; onProjectSelect: (project: Project) => void;
onSessionSelect: (session: SessionWithProvider, projectName: string) => void; onSessionSelect: (session: SessionWithProvider, projectName: string) => void;
onDeleteSession: ( onDeleteSession: (
projectName: string, projectName: string,
sessionId: string, sessionId: string,
sessionTitle: string, sessionTitle: string,
provider: SessionProvider, provider: LLMProvider,
) => void; ) => void;
t: TFunction; t: TFunction;
}; };

View File

@@ -8,7 +8,7 @@
*/ */
import { useCallback, useMemo, useRef, useState } from 'react'; import { useCallback, useMemo, useRef, useState } from 'react';
import type { SessionProvider } from '../types/app'; import type { LLMProvider } from '../types/app';
import { authenticatedFetch } from '../utils/api'; import { authenticatedFetch } from '../utils/api';
// ─── NormalizedMessage (mirrors server/adapters/types.js) ──────────────────── // ─── NormalizedMessage (mirrors server/adapters/types.js) ────────────────────
@@ -33,7 +33,7 @@ export interface NormalizedMessage {
id: string; id: string;
sessionId: string; sessionId: string;
timestamp: string; timestamp: string;
provider: SessionProvider; provider: LLMProvider;
kind: MessageKind; kind: MessageKind;
// kind-specific fields (flat for simplicity) // kind-specific fields (flat for simplicity)
@@ -169,7 +169,7 @@ export function useSessionStore() {
const fetchFromServer = useCallback(async ( const fetchFromServer = useCallback(async (
sessionId: string, sessionId: string,
opts: { opts: {
provider?: SessionProvider; provider?: LLMProvider;
projectName?: string; projectName?: string;
projectPath?: string; projectPath?: string;
limit?: number | null; limit?: number | null;
@@ -228,7 +228,7 @@ export function useSessionStore() {
const fetchMore = useCallback(async ( const fetchMore = useCallback(async (
sessionId: string, sessionId: string,
opts: { opts: {
provider?: SessionProvider; provider?: LLMProvider;
projectName?: string; projectName?: string;
projectPath?: string; projectPath?: string;
limit?: number; limit?: number;
@@ -303,7 +303,7 @@ export function useSessionStore() {
const refreshFromServer = useCallback(async ( const refreshFromServer = useCallback(async (
sessionId: string, sessionId: string,
opts: { opts: {
provider?: SessionProvider; provider?: LLMProvider;
projectName?: string; projectName?: string;
projectPath?: string; projectPath?: string;
} = {}, } = {},
@@ -357,7 +357,7 @@ export function useSessionStore() {
* Update or create a streaming message (accumulated text so far). * Update or create a streaming message (accumulated text so far).
* Uses a well-known ID so subsequent calls replace the same message. * Uses a well-known ID so subsequent calls replace the same message.
*/ */
const updateStreaming = useCallback((sessionId: string, accumulatedText: string, msgProvider: SessionProvider) => { const updateStreaming = useCallback((sessionId: string, accumulatedText: string, msgProvider: LLMProvider) => {
const slot = getSlot(sessionId); const slot = getSlot(sessionId);
const streamId = `__streaming_${sessionId}`; const streamId = `__streaming_${sessionId}`;
const msg: NormalizedMessage = { const msg: NormalizedMessage = {

View File

@@ -1,4 +1,4 @@
export type SessionProvider = 'claude' | 'cursor' | 'codex' | 'gemini'; export type LLMProvider = 'claude' | 'cursor' | 'codex' | 'gemini';
export type AppTab = 'chat' | 'files' | 'shell' | 'git' | 'tasks' | 'preview' | `plugin:${string}`; export type AppTab = 'chat' | 'files' | 'shell' | 'git' | 'tasks' | 'preview' | `plugin:${string}`;
@@ -12,7 +12,7 @@ export interface ProjectSession {
updated_at?: string; updated_at?: string;
lastActivity?: string; lastActivity?: string;
messageCount?: number; messageCount?: number;
__provider?: SessionProvider; __provider?: LLMProvider;
__projectName?: string; __projectName?: string;
[key: string]: unknown; [key: string]: unknown;
} }