File size: 2,202 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
/**
 * Shared utility for checking Codex CLI authentication status
 *
 * Uses 'codex login status' command to verify authentication.
 * Never assumes authenticated - only returns true if CLI confirms.
 */

import { spawnProcess } from '@automaker/platform';
import { findCodexCliPath } from '@automaker/platform';
import { createLogger } from '@automaker/utils';

const logger = createLogger('CodexAuth');

const CODEX_COMMAND = 'codex';
const OPENAI_API_KEY_ENV = 'OPENAI_API_KEY';

export interface CodexAuthCheckResult {
  authenticated: boolean;
  method: 'api_key_env' | 'cli_authenticated' | 'none';
}

/**
 * Check Codex authentication status using 'codex login status' command
 *
 * @param cliPath Optional CLI path. If not provided, will attempt to find it.
 * @returns Authentication status and method
 */
export async function checkCodexAuthentication(
  cliPath?: string | null
): Promise<CodexAuthCheckResult> {
  const resolvedCliPath = cliPath || (await findCodexCliPath());
  const hasApiKey = !!process.env[OPENAI_API_KEY_ENV];

  // If CLI is not installed, cannot be authenticated
  if (!resolvedCliPath) {
    logger.info('CLI not found');
    return { authenticated: false, method: 'none' };
  }

  try {
    const result = await spawnProcess({
      command: resolvedCliPath || CODEX_COMMAND,
      args: ['login', 'status'],
      cwd: process.cwd(),
      env: {
        ...process.env,
        TERM: 'dumb', // Avoid interactive output
      },
    });

    // Check both stdout and stderr for "logged in" - Codex CLI outputs to stderr
    const combinedOutput = (result.stdout + result.stderr).toLowerCase();
    const isLoggedIn = combinedOutput.includes('logged in');

    if (result.exitCode === 0 && isLoggedIn) {
      // Determine auth method based on what we know
      const method = hasApiKey ? 'api_key_env' : 'cli_authenticated';
      logger.info(`✓ Authenticated (${method})`);
      return { authenticated: true, method };
    }

    logger.info('Not authenticated');
    return { authenticated: false, method: 'none' };
  } catch (error) {
    logger.error('Failed to check authentication:', error);
    return { authenticated: false, method: 'none' };
  }
}