feat: remoe codex references after merging of main branch

This commit is contained in:
Kacper
2025-12-13 20:38:05 +01:00
parent 7c6d9d3723
commit 7fe3dff655
17 changed files with 43 additions and 411 deletions

View File

@@ -2,7 +2,6 @@ import type { LucideIcon } from "lucide-react";
import { import {
Key, Key,
Terminal, Terminal,
Atom,
Palette, Palette,
LayoutGrid, LayoutGrid,
Settings2, Settings2,
@@ -20,7 +19,6 @@ export interface NavigationItem {
export const NAV_ITEMS: NavigationItem[] = [ export const NAV_ITEMS: NavigationItem[] = [
{ id: "api-keys", label: "API Keys", icon: Key }, { id: "api-keys", label: "API Keys", icon: Key },
{ id: "claude", label: "Claude", icon: Terminal }, { id: "claude", label: "Claude", icon: Terminal },
{ id: "codex", label: "Codex", icon: Atom },
{ id: "appearance", label: "Appearance", icon: Palette }, { id: "appearance", label: "Appearance", icon: Palette },
{ id: "kanban", label: "Kanban Display", icon: LayoutGrid }, { id: "kanban", label: "Kanban Display", icon: LayoutGrid },
{ id: "keyboard", label: "Keyboard Shortcuts", icon: Settings2 }, { id: "keyboard", label: "Keyboard Shortcuts", icon: Settings2 },

View File

@@ -59,7 +59,7 @@ export function FeatureDefaultsSection({
<p className="text-xs text-muted-foreground"> <p className="text-xs text-muted-foreground">
When enabled, the Add Feature dialog will show only AI profiles When enabled, the Add Feature dialog will show only AI profiles
and hide advanced model tweaking options (Claude SDK, thinking and hide advanced model tweaking options (Claude SDK, thinking
levels, and OpenAI Codex CLI). This creates a cleaner, less levels). This creates a cleaner, less
overwhelming UI. You can always disable this to access advanced overwhelming UI. You can always disable this to access advanced
settings. settings.
</p> </p>

View File

@@ -2,7 +2,7 @@ import { useState, useCallback } from "react";
import { toast } from "sonner"; import { toast } from "sonner";
interface UseCliInstallationOptions { interface UseCliInstallationOptions {
cliType: "claude" | "codex"; cliType: "claude";
installApi: () => Promise<any>; installApi: () => Promise<any>;
onProgressEvent?: (callback: (progress: any) => void) => (() => void) | undefined; onProgressEvent?: (callback: (progress: any) => void) => (() => void) | undefined;
onSuccess?: () => void; onSuccess?: () => void;

View File

@@ -1,7 +1,7 @@
import { useState, useCallback } from "react"; import { useState, useCallback } from "react";
interface UseCliStatusOptions { interface UseCliStatusOptions {
cliType: "claude" | "codex"; cliType: "claude";
statusApi: () => Promise<any>; statusApi: () => Promise<any>;
setCliStatus: (status: any) => void; setCliStatus: (status: any) => void;
setAuthStatus: (status: any) => void; setAuthStatus: (status: any) => void;
@@ -33,7 +33,6 @@ export function useCliStatus({
setCliStatus(cliStatus); setCliStatus(cliStatus);
if (result.auth) { if (result.auth) {
if (cliType === "claude") {
// Validate method is one of the expected values, default to "none" // Validate method is one of the expected values, default to "none"
const validMethods = [ const validMethods = [
"oauth_token_env", "oauth_token_env",
@@ -63,35 +62,6 @@ export function useCliStatus({
hasEnvApiKey: result.auth.hasEnvApiKey, hasEnvApiKey: result.auth.hasEnvApiKey,
}; };
setAuthStatus(authStatus); setAuthStatus(authStatus);
} else {
// Codex auth status mapping
const mapAuthMethod = (method?: string): any => {
switch (method) {
case "cli_verified":
return "cli_verified";
case "cli_tokens":
return "cli_tokens";
case "auth_file":
return "api_key";
case "env_var":
return "env";
default:
return "none";
}
};
const method = mapAuthMethod(result.auth.method);
const authStatus = {
authenticated: result.auth.authenticated,
method,
apiKeyValid:
method === "cli_verified" || method === "cli_tokens"
? undefined
: result.auth.authenticated,
};
console.log(`[${cliType} Setup] Auth Status:`, authStatus);
setAuthStatus(authStatus);
}
} }
} }
} catch (error) { } catch (error) {

View File

@@ -4,7 +4,7 @@ import { getElectronAPI } from "@/lib/electron";
type AuthState = "idle" | "running" | "success" | "error" | "manual"; type AuthState = "idle" | "running" | "success" | "error" | "manual";
interface UseOAuthAuthenticationOptions { interface UseOAuthAuthenticationOptions {
cliType: "claude" | "codex"; cliType: "claude";
enabled?: boolean; enabled?: boolean;
} }
@@ -70,11 +70,8 @@ export function useOAuthAuthentication({
} }
try { try {
// Call the appropriate auth API based on cliType // Call the auth API
const result = const result = await api.setup.authClaude();
cliType === "claude"
? await api.setup.authClaude()
: await api.setup.authCodex?.();
// Cleanup subscription // Cleanup subscription
if (unsubscribeRef.current) { if (unsubscribeRef.current) {

View File

@@ -40,19 +40,6 @@ export function WelcomeStep({ onNext }: WelcomeStepProps) {
</CardContent> </CardContent>
</Card> </Card>
<Card className="bg-card/50 border-border hover:border-brand-500/50 transition-colors">
<CardHeader className="pb-3">
<CardTitle className="text-base flex items-center gap-2">
<Terminal className="w-5 h-5 text-green-500" />
Codex CLI
</CardTitle>
</CardHeader>
<CardContent>
<p className="text-sm text-muted-foreground">
OpenAI&apos;s GPT-5.1 Codex for advanced code generation tasks
</p>
</CardContent>
</Card>
</div> </div>
<Button <Button

View File

@@ -200,7 +200,7 @@ export function WikiView() {
{ {
icon: Cpu, icon: Cpu,
title: "Multi-Model Support", title: "Multi-Model Support",
description: "Claude Haiku/Sonnet/Opus + OpenAI Codex models. Choose the right model for each task.", description: "Claude Haiku/Sonnet/Opus models. Choose the right model for each task.",
}, },
{ {
icon: Brain, icon: Brain,

View File

@@ -287,22 +287,6 @@ export interface ElectronAPI {
}; };
error?: string; error?: string;
}>; }>;
checkCodexCli?: () => Promise<{
success: boolean;
status?: string;
method?: string;
version?: string;
path?: string;
hasApiKey?: boolean;
recommendation?: string;
installCommands?: {
macos?: string;
windows?: string;
linux?: string;
npm?: string;
};
error?: string;
}>;
model?: { model?: {
getAvailable: () => Promise<{ getAvailable: () => Promise<{
success: boolean; success: boolean;
@@ -315,11 +299,6 @@ export interface ElectronAPI {
error?: string; error?: string;
}>; }>;
}; };
testOpenAIConnection?: (apiKey?: string) => Promise<{
success: boolean;
message?: string;
error?: string;
}>;
worktree?: WorktreeAPI; worktree?: WorktreeAPI;
git?: GitAPI; git?: GitAPI;
suggestions?: SuggestionsAPI; suggestions?: SuggestionsAPI;
@@ -347,32 +326,11 @@ export interface ElectronAPI {
}; };
error?: string; error?: string;
}>; }>;
getCodexStatus: () => Promise<{
success: boolean;
status?: string;
method?: string;
version?: string;
path?: string;
auth?: {
authenticated: boolean;
method: string; // Can be: "cli_verified", "cli_tokens", "auth_file", "env_var", "none"
hasAuthFile: boolean;
hasEnvKey: boolean;
hasStoredApiKey?: boolean;
hasEnvApiKey?: boolean;
};
error?: string;
}>;
installClaude: () => Promise<{ installClaude: () => Promise<{
success: boolean; success: boolean;
message?: string; message?: string;
error?: string; error?: string;
}>; }>;
installCodex: () => Promise<{
success: boolean;
message?: string;
error?: string;
}>;
authClaude: () => Promise<{ authClaude: () => Promise<{
success: boolean; success: boolean;
token?: string; token?: string;
@@ -383,12 +341,6 @@ export interface ElectronAPI {
message?: string; message?: string;
output?: string; output?: string;
}>; }>;
authCodex: (apiKey?: string) => Promise<{
success: boolean;
requiresManualAuth?: boolean;
command?: string;
error?: string;
}>;
storeApiKey: ( storeApiKey: (
provider: string, provider: string,
apiKey: string apiKey: string
@@ -396,12 +348,8 @@ export interface ElectronAPI {
getApiKeys: () => Promise<{ getApiKeys: () => Promise<{
success: boolean; success: boolean;
hasAnthropicKey: boolean; hasAnthropicKey: boolean;
hasOpenAIKey: boolean;
hasGoogleKey: boolean; hasGoogleKey: boolean;
}>; }>;
configureCodexMcp: (
projectPath: string
) => Promise<{ success: boolean; configPath?: string; error?: string }>;
getPlatform: () => Promise<{ getPlatform: () => Promise<{
success: boolean; success: boolean;
platform: string; platform: string;
@@ -838,22 +786,11 @@ const getMockElectronAPI = (): ElectronAPI => {
recommendation: "Claude CLI checks are unavailable in the web preview.", recommendation: "Claude CLI checks are unavailable in the web preview.",
}), }),
checkCodexCli: async () => ({
success: false,
status: "not_installed",
recommendation: "Codex CLI checks are unavailable in the web preview.",
}),
model: { model: {
getAvailable: async () => ({ success: true, models: [] }), getAvailable: async () => ({ success: true, models: [] }),
checkProviders: async () => ({ success: true, providers: {} }), checkProviders: async () => ({ success: true, providers: {} }),
}, },
testOpenAIConnection: async () => ({
success: false,
error: "OpenAI connection test is only available in the Electron app.",
}),
// Mock Setup API // Mock Setup API
setup: createMockSetupAPI(), setup: createMockSetupAPI(),
@@ -903,32 +840,11 @@ interface SetupAPI {
}; };
error?: string; error?: string;
}>; }>;
getCodexStatus: () => Promise<{
success: boolean;
status?: string;
method?: string;
version?: string;
path?: string;
auth?: {
authenticated: boolean;
method: string; // Can be: "cli_verified", "cli_tokens", "auth_file", "env_var", "none"
hasAuthFile: boolean;
hasEnvKey: boolean;
hasStoredApiKey?: boolean;
hasEnvApiKey?: boolean;
};
error?: string;
}>;
installClaude: () => Promise<{ installClaude: () => Promise<{
success: boolean; success: boolean;
message?: string; message?: string;
error?: string; error?: string;
}>; }>;
installCodex: () => Promise<{
success: boolean;
message?: string;
error?: string;
}>;
authClaude: () => Promise<{ authClaude: () => Promise<{
success: boolean; success: boolean;
token?: string; token?: string;
@@ -939,12 +855,6 @@ interface SetupAPI {
message?: string; message?: string;
output?: string; output?: string;
}>; }>;
authCodex: (apiKey?: string) => Promise<{
success: boolean;
requiresManualAuth?: boolean;
command?: string;
error?: string;
}>;
storeApiKey: ( storeApiKey: (
provider: string, provider: string,
apiKey: string apiKey: string
@@ -952,12 +862,8 @@ interface SetupAPI {
getApiKeys: () => Promise<{ getApiKeys: () => Promise<{
success: boolean; success: boolean;
hasAnthropicKey: boolean; hasAnthropicKey: boolean;
hasOpenAIKey: boolean;
hasGoogleKey: boolean; hasGoogleKey: boolean;
}>; }>;
configureCodexMcp: (
projectPath: string
) => Promise<{ success: boolean; configPath?: string; error?: string }>;
getPlatform: () => Promise<{ getPlatform: () => Promise<{
success: boolean; success: boolean;
platform: string; platform: string;
@@ -991,20 +897,6 @@ function createMockSetupAPI(): SetupAPI {
}; };
}, },
getCodexStatus: async () => {
console.log("[Mock] Getting Codex status");
return {
success: true,
status: "not_installed",
auth: {
authenticated: false,
method: "none",
hasAuthFile: false,
hasEnvKey: false,
},
};
},
installClaude: async () => { installClaude: async () => {
console.log("[Mock] Installing Claude CLI"); console.log("[Mock] Installing Claude CLI");
// Simulate installation delay // Simulate installation delay
@@ -1016,16 +908,6 @@ function createMockSetupAPI(): SetupAPI {
}; };
}, },
installCodex: async () => {
console.log("[Mock] Installing Codex CLI");
await new Promise((resolve) => setTimeout(resolve, 1000));
return {
success: false,
error:
"CLI installation is only available in the Electron app. Please run the command manually.",
};
},
authClaude: async () => { authClaude: async () => {
console.log("[Mock] Auth Claude CLI"); console.log("[Mock] Auth Claude CLI");
return { return {
@@ -1035,18 +917,6 @@ function createMockSetupAPI(): SetupAPI {
}; };
}, },
authCodex: async (apiKey?: string) => {
console.log("[Mock] Auth Codex CLI", { hasApiKey: !!apiKey });
if (apiKey) {
return { success: true };
}
return {
success: true,
requiresManualAuth: true,
command: "codex auth login",
};
},
storeApiKey: async (provider: string, apiKey: string) => { storeApiKey: async (provider: string, apiKey: string) => {
console.log("[Mock] Storing API key for:", provider); console.log("[Mock] Storing API key for:", provider);
// In mock mode, we just pretend to store it (it's already in the app store) // In mock mode, we just pretend to store it (it's already in the app store)
@@ -1058,19 +928,10 @@ function createMockSetupAPI(): SetupAPI {
return { return {
success: true, success: true,
hasAnthropicKey: false, hasAnthropicKey: false,
hasOpenAIKey: false,
hasGoogleKey: false, hasGoogleKey: false,
}; };
}, },
configureCodexMcp: async (projectPath: string) => {
console.log("[Mock] Configuring Codex MCP for:", projectPath);
return {
success: true,
configPath: `${projectPath}/.codex/config.toml`,
};
},
getPlatform: async () => { getPlatform: async () => {
return { return {
success: true, success: true,

View File

@@ -371,25 +371,6 @@ export class HttpApiClient implements ElectronAPI {
return this.get("/api/setup/claude-status"); return this.get("/api/setup/claude-status");
} }
async checkCodexCli(): Promise<{
success: boolean;
status?: string;
method?: string;
version?: string;
path?: string;
hasApiKey?: boolean;
recommendation?: string;
installCommands?: {
macos?: string;
windows?: string;
linux?: string;
npm?: string;
};
error?: string;
}> {
return this.get("/api/setup/codex-status");
}
// Model API // Model API
model = { model = {
getAvailable: async (): Promise<{ getAvailable: async (): Promise<{
@@ -408,14 +389,6 @@ export class HttpApiClient implements ElectronAPI {
}, },
}; };
async testOpenAIConnection(apiKey?: string): Promise<{
success: boolean;
message?: string;
error?: string;
}> {
return this.post("/api/setup/test-openai", { apiKey });
}
// Setup API // Setup API
setup = { setup = {
getClaudeStatus: (): Promise<{ getClaudeStatus: (): Promise<{
@@ -440,35 +413,12 @@ export class HttpApiClient implements ElectronAPI {
error?: string; error?: string;
}> => this.get("/api/setup/claude-status"), }> => this.get("/api/setup/claude-status"),
getCodexStatus: (): Promise<{
success: boolean;
status?: string;
method?: string;
version?: string;
path?: string;
auth?: {
authenticated: boolean;
method: string;
hasAuthFile: boolean;
hasEnvKey: boolean;
hasStoredApiKey?: boolean;
hasEnvApiKey?: boolean;
};
error?: string;
}> => this.get("/api/setup/codex-status"),
installClaude: (): Promise<{ installClaude: (): Promise<{
success: boolean; success: boolean;
message?: string; message?: string;
error?: string; error?: string;
}> => this.post("/api/setup/install-claude"), }> => this.post("/api/setup/install-claude"),
installCodex: (): Promise<{
success: boolean;
message?: string;
error?: string;
}> => this.post("/api/setup/install-codex"),
authClaude: (): Promise<{ authClaude: (): Promise<{
success: boolean; success: boolean;
token?: string; token?: string;
@@ -480,15 +430,6 @@ export class HttpApiClient implements ElectronAPI {
output?: string; output?: string;
}> => this.post("/api/setup/auth-claude"), }> => this.post("/api/setup/auth-claude"),
authCodex: (
apiKey?: string
): Promise<{
success: boolean;
requiresManualAuth?: boolean;
command?: string;
error?: string;
}> => this.post("/api/setup/auth-codex", { apiKey }),
storeApiKey: ( storeApiKey: (
provider: string, provider: string,
apiKey: string apiKey: string
@@ -500,18 +441,9 @@ export class HttpApiClient implements ElectronAPI {
getApiKeys: (): Promise<{ getApiKeys: (): Promise<{
success: boolean; success: boolean;
hasAnthropicKey: boolean; hasAnthropicKey: boolean;
hasOpenAIKey: boolean;
hasGoogleKey: boolean; hasGoogleKey: boolean;
}> => this.get("/api/setup/api-keys"), }> => this.get("/api/setup/api-keys"),
configureCodexMcp: (
projectPath: string
): Promise<{
success: boolean;
configPath?: string;
error?: string;
}> => this.post("/api/setup/configure-codex-mcp", { projectPath }),
getPlatform: (): Promise<{ getPlatform: (): Promise<{
success: boolean; success: boolean;
platform: string; platform: string;

View File

@@ -246,20 +246,11 @@ export interface FeatureImagePath {
} }
// Available models for feature execution // Available models for feature execution
// Claude models
export type ClaudeModel = "opus" | "sonnet" | "haiku"; export type ClaudeModel = "opus" | "sonnet" | "haiku";
// OpenAI/Codex models export type AgentModel = ClaudeModel;
export type OpenAIModel =
| "gpt-5.2"
| "gpt-5.1-codex-max"
| "gpt-5.1-codex"
| "gpt-5.1-codex-mini"
| "gpt-5.1";
// Combined model type
export type AgentModel = ClaudeModel | OpenAIModel;
// Model provider type // Model provider type
export type ModelProvider = "claude" | "codex"; export type ModelProvider = "claude";
// Thinking level (budget_tokens) options // Thinking level (budget_tokens) options
export type ThinkingLevel = "none" | "low" | "medium" | "high" | "ultrathink"; export type ThinkingLevel = "none" | "low" | "medium" | "high" | "ultrathink";
@@ -659,36 +650,6 @@ const DEFAULT_AI_PROFILES: AIProfile[] = [
isBuiltIn: true, isBuiltIn: true,
icon: "Zap", icon: "Zap",
}, },
{
id: "profile-gpt52",
name: "GPT-5.2",
description: "GPT-5.2 - Latest OpenAI model for advanced coding tasks.",
model: "gpt-5.2",
thinkingLevel: "none",
provider: "codex",
isBuiltIn: true,
icon: "Sparkles",
},
{
id: "profile-codex-power",
name: "Codex Power",
description: "GPT-5.1 Codex Max for deep coding tasks via OpenAI CLI.",
model: "gpt-5.1-codex-max",
thinkingLevel: "none",
provider: "codex",
isBuiltIn: true,
icon: "Cpu",
},
{
id: "profile-codex-fast",
name: "Codex Fast",
description: "GPT-5.1 Codex Mini for lightweight and quick edits.",
model: "gpt-5.1-codex-mini",
thinkingLevel: "none",
provider: "codex",
isBuiltIn: true,
icon: "Rocket",
},
]; ];
const initialState: AppState = { const initialState: AppState = {

View File

@@ -471,24 +471,6 @@ export interface ElectronAPI {
error?: string; error?: string;
}>; }>;
// Codex CLI Detection API
checkCodexCli: () => Promise<{
success: boolean;
status?: string;
method?: string;
version?: string;
path?: string;
hasApiKey?: boolean;
recommendation?: string;
installCommands?: {
macos?: string;
windows?: string;
linux?: string;
npm?: string;
};
error?: string;
}>;
// Model Management APIs // Model Management APIs
model: { model: {
// Get all available models from all providers // Get all available models from all providers
@@ -641,7 +623,7 @@ export interface ModelDefinition {
id: string; id: string;
name: string; name: string;
modelString: string; modelString: string;
provider: "claude" | "codex"; provider: "claude";
description?: string; description?: string;
tier?: "basic" | "standard" | "premium"; tier?: "basic" | "standard" | "premium";
default?: boolean; default?: boolean;

View File

@@ -2437,16 +2437,7 @@ export async function setupFirstRun(page: Page): Promise<void> {
progress: 0, progress: 0,
output: [], output: [],
}, },
codexCliStatus: null,
codexAuthStatus: null,
codexInstallProgress: {
isInstalling: false,
currentStep: "",
progress: 0,
output: [],
},
skipClaudeSetup: false, skipClaudeSetup: false,
skipCodexSetup: false,
}, },
version: 0, version: 0,
}; };
@@ -2460,7 +2451,7 @@ export async function setupFirstRun(page: Page): Promise<void> {
currentProject: null, currentProject: null,
theme: "dark", theme: "dark",
sidebarOpen: true, sidebarOpen: true,
apiKeys: { anthropic: "", google: "", openai: "" }, apiKeys: { anthropic: "", google: "" },
chatSessions: [], chatSessions: [],
chatHistoryOpen: false, chatHistoryOpen: false,
maxConcurrency: 3, maxConcurrency: 3,
@@ -2488,7 +2479,6 @@ export async function setupComplete(page: Page): Promise<void> {
setupComplete: true, setupComplete: true,
currentStep: "complete", currentStep: "complete",
skipClaudeSetup: false, skipClaudeSetup: false,
skipCodexSetup: false,
}, },
version: 0, version: 0,
}; };
@@ -2530,14 +2520,6 @@ export async function clickClaudeContinue(page: Page): Promise<void> {
await button.click(); await button.click();
} }
/**
* Click continue on Codex setup step
*/
export async function clickCodexContinue(page: Page): Promise<void> {
const button = await getByTestId(page, "codex-next-button");
await button.click();
}
/** /**
* Click finish on setup complete step * Click finish on setup complete step
*/ */

View File

@@ -38,13 +38,6 @@ DATA_DIR=./data
# OPTIONAL - Additional AI Providers # OPTIONAL - Additional AI Providers
# ============================================ # ============================================
# OpenAI API key for GPT/Codex models (gpt-5.2, gpt-5.1-codex, etc.)
# Codex CLI must be installed: npm install -g @openai/codex@latest
OPENAI_API_KEY=
# Optional: Override Codex CLI path (auto-detected by default)
# CODEX_CLI_PATH=/usr/local/bin/codex
# Google API key (for future Gemini support) # Google API key (for future Gemini support)
GOOGLE_API_KEY= GOOGLE_API_KEY=

View File

@@ -24,7 +24,7 @@ export abstract class BaseProvider {
} }
/** /**
* Get the provider name (e.g., "claude", "codex", "cursor") * Get the provider name (e.g., "claude", "cursor")
*/ */
abstract getName(): string; abstract getName(): string;

View File

@@ -76,7 +76,7 @@ export class ProviderFactory {
/** /**
* Get provider by name (for direct access if needed) * Get provider by name (for direct access if needed)
* *
* @param name Provider name (e.g., "claude", "codex", "cursor") * @param name Provider name (e.g., "claude", "cursor")
* @returns Provider instance or null if not found * @returns Provider instance or null if not found
*/ */
static getProviderByName(name: string): BaseProvider | null { static getProviderByName(name: string): BaseProvider | null {

View File

@@ -1,5 +1,5 @@
/** /**
* Configuration fixtures for testing Codex config manager * Configuration fixtures for testing
*/ */
export const tomlConfigFixture = ` export const tomlConfigFixture = `
@@ -15,11 +15,3 @@ enabled_tools = ["UpdateFeatureStatus"]
[mcp_servers.automaker-tools.env] [mcp_servers.automaker-tools.env]
AUTOMAKER_PROJECT_PATH = "/path/to/project" AUTOMAKER_PROJECT_PATH = "/path/to/project"
`; `;
export const codexAuthJsonFixture = {
token: {
access_token: "test-access-token",
refresh_token: "test-refresh-token",
id_token: "test-id-token",
},
};

View File

@@ -37,26 +37,3 @@ export const claudeProviderMessageFixture: ProviderMessage = {
}, },
}; };
export const codexThinkingMessageFixture = {
type: "item.completed",
item: {
type: "reasoning",
text: "I need to analyze the problem first...",
},
};
export const codexCommandExecutionFixture = {
type: "item.completed",
item: {
type: "command_execution",
command: "ls -la",
aggregated_output: "total 12\ndrwxr-xr-x 3 user user 4096 Dec 13",
},
};
export const codexErrorFixture = {
type: "error",
data: {
message: "Authentication failed",
},
};