/**
 * Git credential handling via PTY.
 *
 * Detects credential prompts (password, passphrase, username, PIN) in PTY output,
 * forwards them to the client via credential_prompt messages, and writes the
 * client's response back to PTY stdin.
 */
import { logger } from "../../utils/logger.js";
const CREDENTIAL_TIMEOUT_MS = 90_000;
export const CREDENTIAL_PATTERNS = [
    { pattern: /Password.*:/i, type: "password" },
    { pattern: /Enter passphrase for key/i, type: "passphrase" },
    { pattern: /Username for/i, type: "username" },
    { pattern: /Enter PIN for/i, type: "pin" },
];
/**
 * Detect a credential prompt in PTY output data.
 * Returns the prompt type and the full prompt text, or null if no prompt detected.
 */
export function detectCredentialPrompt(data) {
    for (const { pattern, type } of CREDENTIAL_PATTERNS) {
        if (pattern.test(data)) {
            return { type, prompt: data.trim() };
        }
    }
    return null;
}
const pendingCredentials = new Map();
/**
 * Request credentials from the client by sending a credential_prompt event
 * and waiting for a credential_response. Times out after 90 seconds.
 *
 * @param requestId The request ID to correlate prompt with response
 * @param promptType The type of credential being requested
 * @param prompt The raw prompt text from the PTY
 * @param send Function to send messages to the client
 * @returns The credential response from the client
 */
export function requestCredential(requestId, promptType, prompt, send) {
    return new Promise((resolve) => {
        const timer = setTimeout(() => {
            pendingCredentials.delete(requestId);
            resolve({ value: "", cancelled: true });
        }, CREDENTIAL_TIMEOUT_MS);
        pendingCredentials.set(requestId, { resolve, timer });
        const event = {
            type: "credential_prompt",
            requestId,
            payload: {
                promptType,
                prompt,
            },
        };
        send(event);
        logger.info(`Credential prompt sent: ${promptType} (requestId=${requestId})`);
    });
}
/**
 * Resolve a pending credential request with the client's response.
 * Called when a credential_response message is received.
 *
 * @param requestId The request ID from the credential_response
 * @param value The credential value entered by the user
 * @param cancelled Whether the user cancelled the prompt
 * @returns true if the request was found and resolved, false otherwise
 */
export function resolveCredential(requestId, value, cancelled) {
    const pending = pendingCredentials.get(requestId);
    if (!pending) {
        return false;
    }
    clearTimeout(pending.timer);
    pendingCredentials.delete(requestId);
    pending.resolve({ value, cancelled });
    return true;
}
/**
 * Check if there is a pending credential request for the given request ID.
 */
export function hasPendingCredential(requestId) {
    return pendingCredentials.has(requestId);
}
/**
 * Clear all pending credential requests. Used during shutdown.
 */
export function clearPendingCredentials() {
    for (const [, pending] of pendingCredentials) {
        clearTimeout(pending.timer);
        pending.resolve({ value: "", cancelled: true });
    }
    pendingCredentials.clear();
}
//# sourceMappingURL=credentials.js.map