// @crash-shield-ignore-file — config/cache reader for Planu-controlled JSON; writer is this codebase, shape guaranteed by build/seed.
// hosts/gemini/adapter.ts — Gemini CLI host adapter (SPEC-591)
// Detects Gemini workspaces and activates Gemini-compatible Planu tool schemas.
import { access, readFile } from 'node:fs/promises';
import { join } from 'node:path';
// Surfaces that have no Gemini equivalent — each logs a warning once per session
const GEMINI_UNSUPPORTED_SURFACES = [
    'agent-teams',
    'plan-mode',
    'subagents',
    'worktrees',
];
/** Session-scoped set of surfaces already warned about (avoids duplicate logs) */
const warnedSurfaces = new Set();
/**
 * Detect whether a project root contains a Gemini CLI workspace.
 * A workspace is present if:
 *   1. .gemini/ directory exists at projectPath, OR
 *   2. Any GEMINI_* environment variable is set in the current process
 */
export async function detectGeminiWorkspace(projectPath) {
    const geminiDir = join(projectPath, '.gemini');
    const envVars = Object.keys(process.env).filter((k) => k.startsWith('GEMINI_'));
    let configDirExists = false;
    try {
        await access(geminiDir);
        configDirExists = true;
    }
    catch {
        // .gemini/ not found — not an error
    }
    // Try to read version from .gemini/config.json if present
    let version;
    if (configDirExists) {
        try {
            const configRaw = await readFile(join(geminiDir, 'config.json'), 'utf-8');
            const parsed = JSON.parse(configRaw);
            if (typeof parsed.version === 'string') {
                version = parsed.version;
            }
        }
        catch {
            // config.json missing or malformed — not critical
        }
    }
    const detected = configDirExists || envVars.length > 0;
    return {
        detected,
        configDir: configDirExists ? geminiDir : undefined,
        envVars,
        version,
    };
}
/**
 * Activate the Gemini adapter on startup.
 * - Validates the workspace is a Gemini environment
 * - Registers Gemini-compatible tool annotations
 * - Returns activation result with registered tool count and any warnings
 *
 * This is a lightweight activation: the actual schema translation happens
 * per-tool in tool-schema-translator.ts via getGeminiToolSchemas().
 */
export async function activateGeminiAdapter(projectPath) {
    const marker = await detectGeminiWorkspace(projectPath);
    if (!marker.detected) {
        return {
            activated: false,
            toolsRegistered: 0,
            warnings: ['Gemini workspace not detected — adapter not activated'],
        };
    }
    const warnings = [];
    // Log once-per-session warnings for unsupported surfaces
    for (const surface of GEMINI_UNSUPPORTED_SURFACES) {
        logFallbackWarning(surface, warnings);
    }
    // Gemini adapter activated — tool schema translation is handled lazily
    // via translateZodToGemini() in tool-schema-translator.ts
    return {
        activated: true,
        toolsRegistered: 0, // populated lazily when tools are requested
        warnings,
    };
}
/**
 * Log a once-per-session warning for a Planu surface that has no Gemini equivalent.
 * Subsequent calls for the same surface are silently ignored.
 * @internal exported for testing
 */
export function logFallbackWarning(surface, warningsOut) {
    const alreadyLogged = warnedSurfaces.has(surface);
    const descriptions = {
        'agent-teams': 'Agent Teams → single-agent inline execution',
        'plan-mode': 'Plan mode → direct tool execution without plan review',
        subagents: 'Subagents → sequential inline tool calls',
        worktrees: 'Worktrees → no worktree isolation (Gemini has no equivalent)',
    };
    if (!alreadyLogged) {
        warnedSurfaces.add(surface);
        const msg = `[Gemini adapter] No equivalent for "${surface}" — falling back: ${descriptions[surface]}`;
        console.warn(msg); // stderr — MCP stdout is reserved for protocol
        warningsOut?.push(msg);
    }
    return {
        surface,
        fallbackDescription: descriptions[surface],
        alreadyLogged,
    };
}
/**
 * Reset session-scoped warning state.
 * Called in tests to ensure isolation between test cases.
 * @internal
 */
export function resetFallbackWarnings() {
    warnedSurfaces.clear();
}
//# sourceMappingURL=adapter.js.map