File size: 4,433 Bytes
1dbc34b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | import { useState, useCallback } from 'react';
import { createLogger } from '@automaker/utils/logger';
import type { ModelProvider } from '@automaker/types';
import type { CliStatus, ClaudeAuthStatus, CodexAuthStatus } from '@/store/setup-store';
interface CliStatusApiResponse {
success: boolean;
status?: string;
installed?: boolean;
method?: string;
version?: string;
path?: string;
auth?: {
authenticated: boolean;
method: string;
hasCredentialsFile?: boolean;
hasToken?: boolean;
hasStoredOAuthToken?: boolean;
hasStoredApiKey?: boolean;
hasEnvApiKey?: boolean;
hasEnvOAuthToken?: boolean;
hasCliAuth?: boolean;
hasRecentActivity?: boolean;
hasAuthFile?: boolean;
hasApiKey?: boolean;
hasOAuthToken?: boolean;
};
error?: string;
}
interface UseCliStatusOptions {
cliType: ModelProvider;
statusApi: () => Promise<CliStatusApiResponse>;
setCliStatus: (status: CliStatus | null) => void;
setAuthStatus: (status: ClaudeAuthStatus | CodexAuthStatus | null) => void;
}
const VALID_AUTH_METHODS = {
claude: [
'oauth_token_env',
'oauth_token',
'api_key',
'api_key_env',
'credentials_file',
'cli_authenticated',
'none',
],
codex: ['cli_authenticated', 'api_key', 'api_key_env', 'none'],
} as const;
// Create logger outside of the hook to avoid re-creating it on every render
const logger = createLogger('CliStatus');
export function useCliStatus({
cliType,
statusApi,
setCliStatus,
setAuthStatus,
}: UseCliStatusOptions) {
const [isChecking, setIsChecking] = useState(false);
const checkStatus = useCallback(async () => {
logger.info(`Starting status check for ${cliType}...`);
setIsChecking(true);
try {
const result = await statusApi();
logger.info(`Raw status result for ${cliType}:`, result);
if (result.success) {
// Handle both response formats:
// - Claude API returns {status: 'installed' | 'not_installed'}
// - Codex API returns {installed: boolean}
const isInstalled =
typeof result.installed === 'boolean' ? result.installed : result.status === 'installed';
const cliStatus = {
installed: isInstalled,
path: result.path || null,
version: result.version || null,
method: result.method || 'none',
};
logger.info(`CLI Status for ${cliType}:`, cliStatus);
setCliStatus(cliStatus);
if (result.auth) {
if (cliType === 'claude') {
// Validate method is one of the expected Claude values, default to "none"
const validMethods = VALID_AUTH_METHODS.claude;
type ClaudeAuthMethod = (typeof validMethods)[number];
const method: ClaudeAuthMethod = validMethods.includes(
result.auth.method as ClaudeAuthMethod
)
? (result.auth.method as ClaudeAuthMethod)
: 'none';
setAuthStatus({
authenticated: result.auth.authenticated,
method,
hasCredentialsFile: false,
oauthTokenValid: result.auth.hasStoredOAuthToken || result.auth.hasEnvOAuthToken,
apiKeyValid: result.auth.hasStoredApiKey || result.auth.hasEnvApiKey,
hasEnvOAuthToken: result.auth.hasEnvOAuthToken,
hasEnvApiKey: result.auth.hasEnvApiKey,
});
} else {
// Validate method is one of the expected Codex values, default to "none"
const validMethods = VALID_AUTH_METHODS.codex;
type CodexAuthMethod = (typeof validMethods)[number];
const method: CodexAuthMethod = validMethods.includes(
result.auth.method as CodexAuthMethod
)
? (result.auth.method as CodexAuthMethod)
: 'none';
setAuthStatus({
authenticated: result.auth.authenticated,
method,
hasAuthFile: result.auth.hasAuthFile ?? false,
hasApiKey: result.auth.hasApiKey ?? false,
hasEnvApiKey: result.auth.hasEnvApiKey ?? false,
});
}
}
}
} catch (error) {
logger.error(`Failed to check status for ${cliType}:`, error);
} finally {
setIsChecking(false);
}
}, [cliType, statusApi, setCliStatus, setAuthStatus]);
return { isChecking, checkStatus };
}
|