/**
 * ExecutionEnv - 执行环境
 * 参考 Rust 实现: crates/executors/src/env.rs
 */
import * as path from 'node:path';
export const AGENT_SUBPROCESS_BLOCKED_ENV_KEYS = [
    'DATABASE_URL',
    'AGENT_TOWER_DATABASE_URL',
    'AGENT_TOWER_DATA_DIR',
    'AGENT_TOWER_WEB_DIR',
    'DATA_DIR',
];
export const AGENT_TOWER_MCP_IDENTITY_ENV_KEYS = [
    'AGENT_TOWER_SESSION_ID',
    'AGENT_TOWER_INVOCATION_ID',
    'AGENT_TOWER_TEAM_RUN_ID',
    'AGENT_TOWER_MEMBER_ID',
];
export const AGENT_TOWER_MCP_SERVICE_ENV_KEYS = [
    'AGENT_TOWER_URL',
    'AGENT_TOWER_PORT',
];
const AGENT_SUBPROCESS_EXTERNAL_ENV_BLOCKED_KEYS = new Set([
    ...AGENT_SUBPROCESS_BLOCKED_ENV_KEYS,
    ...AGENT_TOWER_MCP_IDENTITY_ENV_KEYS,
    ...AGENT_TOWER_MCP_SERVICE_ENV_KEYS,
]);
export function filterAgentSubprocessExternalEnv(overrides) {
    const filtered = {};
    for (const [key, value] of Object.entries(overrides)) {
        if (!AGENT_SUBPROCESS_EXTERNAL_ENV_BLOCKED_KEYS.has(key)) {
            filtered[key] = value;
        }
    }
    return filtered;
}
/**
 * 执行环境 - 管理环境变量和仓库上下文
 */
export class ExecutionEnv {
    vars = new Map();
    repoContext;
    commitReminder;
    constructor(repoContext, commitReminder = false) {
        this.repoContext = repoContext;
        this.commitReminder = commitReminder;
    }
    /**
     * 创建默认执行环境
     */
    static default(workingDir) {
        return new ExecutionEnv({ workspaceRoot: workingDir, repoNames: [] }, false);
    }
    /**
     * 插入环境变量
     */
    set(key, value) {
        this.vars.set(key, value);
        return this;
    }
    /**
     * 获取环境变量
     */
    get(key) {
        return this.vars.get(key);
    }
    /**
     * 检查是否包含某个环境变量
     */
    has(key) {
        return this.vars.has(key);
    }
    /**
     * 合并其他环境变量（传入的会覆盖现有的）
     */
    merge(other) {
        for (const [key, value] of Object.entries(other)) {
            this.vars.set(key, value);
        }
        return this;
    }
    /**
     * 应用 CmdOverrides 中的环境变量
     */
    withProfile(cmd) {
        if (cmd?.env) {
            const newEnv = this.clone();
            newEnv.merge(filterAgentSubprocessExternalEnv(cmd.env));
            return newEnv;
        }
        return this;
    }
    /**
     * 克隆当前环境
     */
    clone() {
        const newEnv = new ExecutionEnv(this.repoContext, this.commitReminder);
        for (const [key, value] of this.vars) {
            newEnv.vars.set(key, value);
        }
        return newEnv;
    }
    /**
     * 转换为普通对象
     */
    toObject() {
        const result = {};
        for (const [key, value] of this.vars) {
            result[key] = value;
        }
        return result;
    }
    /**
     * 获取完整的环境变量（包含 process.env）
     * 过滤掉会阻止 Agent CLI 嵌套启动的环境变量、继承自父进程的
     * TeamRun/MCP 身份变量，以及 Agent Tower 服务自身 DB/data/web 目录变量。
     * TeamRun/MCP 身份变量仍可通过 ExecutionEnv 显式注入到具体 invocation。
     * 当 provider 设置了 ANTHROPIC_* 变量时，清除 process.env 中残留的同类变量，
     * 避免 Claude Code 优先使用错误的认证信息
     */
    getFullEnv() {
        const providerVars = this.toObject();
        const hasProviderAnthropicVars = Object.keys(providerVars).some(k => k.startsWith('ANTHROPIC_'));
        const env = {
            ...process.env,
        };
        // 如果 provider 设置了任何 ANTHROPIC_* 变量，先清除 process.env 中所有 ANTHROPIC_* 残留
        // 再用 provider 的值覆盖，确保不会混用不同 provider 的认证信息
        if (hasProviderAnthropicVars) {
            for (const key of Object.keys(env)) {
                if (key.startsWith('ANTHROPIC_')) {
                    delete env[key];
                }
            }
        }
        for (const key of AGENT_TOWER_MCP_IDENTITY_ENV_KEYS) {
            delete env[key];
        }
        Object.assign(env, providerVars);
        // Claude Code 检测 CLAUDECODE 环境变量来阻止嵌套启动
        delete env.CLAUDECODE;
        for (const key of AGENT_SUBPROCESS_BLOCKED_ENV_KEYS) {
            delete env[key];
        }
        return env;
    }
    /**
     * 获取仓库路径列表
     */
    getRepoPaths() {
        return this.repoContext.repoNames.map(name => path.join(this.repoContext.workspaceRoot, name));
    }
}
//# sourceMappingURL=execution-env.js.map