import { o as resolveRequiredHomeDir } from "./home-dir-DxcD0hdR.js";
import { i as normalizeEnvVarKey, n as isDangerousHostEnvOverrideVarName, r as isDangerousHostEnvVarName } from "./host-env-security-CYywiDsR.js";
import { d as resolveConfigDir } from "./utils-FLBGJBzj.js";
import { t as createSubsystemLogger } from "./subsystem-CO3EU02N.js";
import { n as listKnownProviderAuthEnvVarNames } from "./provider-env-vars-YJJfP41l.js";
import fs from "node:fs";
import path from "node:path";
import os from "node:os";
import dotenv from "dotenv";
//#region src/infra/dotenv.ts
const logger = createSubsystemLogger("infra:dotenv");
const BLOCKED_PROVIDER_AUTH_WORKSPACE_DOTENV_KEYS = [
	"AI_GATEWAY_API_KEY",
	"ANTHROPIC_API_KEY",
	"ANTHROPIC_OAUTH_TOKEN",
	"ARCEEAI_API_KEY",
	"AZURE_OPENAI_API_KEY",
	"AZURE_SPEECH_API_KEY",
	"AZURE_SPEECH_KEY",
	"AZURE_SPEECH_REGION",
	"BRAVE_API_KEY",
	"BYTEPLUS_API_KEY",
	"BYTEPLUS_SEED_SPEECH_API_KEY",
	"CEREBRAS_API_KEY",
	"CHUTES_API_KEY",
	"CHUTES_OAUTH_TOKEN",
	"CLOUDFLARE_AI_GATEWAY_API_KEY",
	"COMFY_API_KEY",
	"COMFY_CLOUD_API_KEY",
	"COPILOT_GITHUB_TOKEN",
	"DASHSCOPE_API_KEY",
	"DEEPGRAM_API_KEY",
	"DEEPINFRA_API_KEY",
	"DEEPSEEK_API_KEY",
	"ELEVENLABS_API_KEY",
	"EXA_API_KEY",
	"FAL_API_KEY",
	"FAL_KEY",
	"FIRECRAWL_API_KEY",
	"FIREWORKS_API_KEY",
	"GEMINI_API_KEY",
	"GH_TOKEN",
	"GITHUB_TOKEN",
	"GOOGLE_API_KEY",
	"GOOGLE_CLOUD_API_KEY",
	"GRADIUM_API_KEY",
	"GROQ_API_KEY",
	"HF_TOKEN",
	"HUGGINGFACE_HUB_TOKEN",
	"INWORLD_API_KEY",
	"KILOCODE_API_KEY",
	"KIMICODE_API_KEY",
	"KIMI_API_KEY",
	"LITELLM_API_KEY",
	"LM_API_TOKEN",
	"MINIMAX_API_KEY",
	"MINIMAX_CODE_PLAN_KEY",
	"MINIMAX_CODING_API_KEY",
	"MINIMAX_OAUTH_TOKEN",
	"MISTRAL_API_KEY",
	"MODELSTUDIO_API_KEY",
	"MOONSHOT_API_KEY",
	"NVIDIA_API_KEY",
	"OLLAMA_API_KEY",
	"OPENAI_API_KEY",
	"OPENCODE_API_KEY",
	"OPENCODE_ZEN_API_KEY",
	"OPENROUTER_API_KEY",
	"PERPLEXITY_API_KEY",
	"QIANFAN_API_KEY",
	"QWEN_API_KEY",
	"RUNWAY_API_KEY",
	"RUNWAYML_API_SECRET",
	"SENSEAUDIO_API_KEY",
	"SGLANG_API_KEY",
	"SPEECH_KEY",
	"SPEECH_REGION",
	"STEPFUN_API_KEY",
	"SYNTHETIC_API_KEY",
	"TAVILY_API_KEY",
	"TOGETHER_API_KEY",
	"TOKENHUB_API_KEY",
	"VENICE_API_KEY",
	"VLLM_API_KEY",
	"VOLCANO_ENGINE_API_KEY",
	"VOLCENGINE_TTS_API_KEY",
	"VOLCENGINE_TTS_APPID",
	"VOLCENGINE_TTS_TOKEN",
	"VOYAGE_API_KEY",
	"VYDRA_API_KEY",
	"XAI_API_KEY",
	"XIAOMI_API_KEY",
	"XI_API_KEY",
	"ZAI_API_KEY",
	"Z_AI_API_KEY"
];
const BLOCKED_WORKSPACE_DOTENV_KEYS = new Set([
	...BLOCKED_PROVIDER_AUTH_WORKSPACE_DOTENV_KEYS,
	"ALL_PROXY",
	"BROWSER_EXECUTABLE_PATH",
	"CLAWHUB_AUTH_TOKEN",
	"CLAWHUB_CONFIG_PATH",
	"CLAWHUB_TOKEN",
	"CLAWHUB_URL",
	"CLOUDSDK_PYTHON",
	"COMSPEC",
	"HTTP_PROXY",
	"HTTPS_PROXY",
	"HOMEBREW_BREW_FILE",
	"HOMEBREW_PREFIX",
	"IRC_HOST",
	"LOCALAPPDATA",
	"MATTERMOST_URL",
	"MATRIX_HOMESERVER",
	"MINIMAX_API_HOST",
	"NODE_TLS_REJECT_UNAUTHORIZED",
	"NO_PROXY",
	"NPM_EXECPATH",
	"OPENAI_API_KEYS",
	"NODMIX_AGENT_DIR",
	"NODMIX_ALLOW_PLUGIN_INSTALL_OVERRIDES",
	"NODMIX_ALLOW_INSECURE_PRIVATE_WS",
	"NODMIX_ALLOW_PROJECT_LOCAL_BIN",
	"NODMIX_BROWSER_EXECUTABLE_PATH",
	"NODMIX_BROWSER_CONTROL_MODULE",
	"NODMIX_BUNDLED_HOOKS_DIR",
	"NODMIX_BUNDLED_PLUGINS_DIR",
	"NODMIX_BUNDLED_SKILLS_DIR",
	"NODMIX_CACHE_TRACE",
	"NODMIX_CACHE_TRACE_FILE",
	"NODMIX_CACHE_TRACE_MESSAGES",
	"NODMIX_CACHE_TRACE_PROMPT",
	"NODMIX_CACHE_TRACE_SYSTEM",
	"NODMIX_CONFIG_PATH",
	"NODMIX_GATEWAY_PASSWORD",
	"NODMIX_GATEWAY_PORT",
	"NODMIX_GATEWAY_SECRET",
	"NODMIX_GATEWAY_TOKEN",
	"NODMIX_GATEWAY_URL",
	"NODMIX_HOME",
	"NODMIX_LIVE_ANTHROPIC_KEY",
	"NODMIX_LIVE_ANTHROPIC_KEYS",
	"NODMIX_LIVE_GEMINI_KEY",
	"NODMIX_LIVE_OPENAI_KEY",
	"NODMIX_MPM_CATALOG_PATHS",
	"NODMIX_NODE_EXEC_FALLBACK",
	"NODMIX_NODE_EXEC_HOST",
	"NODMIX_OAUTH_DIR",
	"NODMIX_PINNED_PYTHON",
	"NODMIX_PINNED_WRITE_PYTHON",
	"NODMIX_PLUGIN_INSTALL_OVERRIDES",
	"NODMIX_PLUGIN_CATALOG_PATHS",
	"NODMIX_PROFILE",
	"NODMIX_RAW_STREAM",
	"NODMIX_RAW_STREAM_PATH",
	"NODMIX_SHOW_SECRETS",
	"NODMIX_SKIP_BROWSER_CONTROL_SERVER",
	"NODMIX_STATE_DIR",
	"NODMIX_TEST_TAILSCALE_BINARY",
	"PATH",
	"PI_CODING_AGENT_DIR",
	"PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH",
	"PROGRAMFILES",
	"PROGRAMFILES(X86)",
	"PROGRAMW6432",
	"STATE_DIRECTORY",
	"SYNOLOGY_CHAT_INCOMING_URL",
	"SYNOLOGY_NAS_HOST",
	"UV_PYTHON"
]);
const BLOCKED_WORKSPACE_DOTENV_SUFFIXES = [
	"_API_HOST",
	"_BASE_URL",
	"_HOMESERVER"
];
const BLOCKED_WORKSPACE_DOTENV_PREFIXES = [
	"ANTHROPIC_API_KEY_",
	"CLAWHUB_",
	"OPENAI_API_KEY_",
	"NODMIX_",
	"NODMIX_CLAWHUB_",
	"NODMIX_DISABLE_",
	"NODMIX_SKIP_",
	"NODMIX_UPDATE_"
];
function shouldBlockWorkspaceRuntimeDotEnvKey(key) {
	return isDangerousHostEnvVarName(key) || isDangerousHostEnvOverrideVarName(key);
}
function shouldBlockRuntimeDotEnvKey(key) {
	return false;
}
function buildProviderAuthWorkspaceDotEnvBlocklist() {
	const keys = new Set(BLOCKED_PROVIDER_AUTH_WORKSPACE_DOTENV_KEYS);
	for (const rawKey of listKnownProviderAuthEnvVarNames({ includeUntrustedWorkspacePlugins: false })) {
		const key = normalizeEnvVarKey(rawKey, { portable: true });
		if (key) keys.add(key.toUpperCase());
	}
	return keys;
}
function shouldBlockWorkspaceDotEnvKey(key, getProviderAuthBlockedKeys) {
	const upper = key.toUpperCase();
	return shouldBlockWorkspaceRuntimeDotEnvKey(upper) || BLOCKED_WORKSPACE_DOTENV_KEYS.has(upper) || BLOCKED_WORKSPACE_DOTENV_PREFIXES.some((prefix) => upper.startsWith(prefix)) || BLOCKED_WORKSPACE_DOTENV_SUFFIXES.some((suffix) => upper.endsWith(suffix)) || getProviderAuthBlockedKeys().has(upper);
}
function readDotEnvFile(params) {
	let content;
	try {
		content = fs.readFileSync(params.filePath, "utf8");
	} catch (error) {
		if (!params.quiet) {
			if ((error && typeof error === "object" && "code" in error ? String(error.code) : void 0) !== "ENOENT") logger.warn(`Failed to read ${params.filePath}: ${String(error)}`, { error });
		}
		return null;
	}
	let parsed;
	try {
		parsed = dotenv.parse(content);
	} catch (error) {
		if (!params.quiet) logger.warn(`Failed to parse ${params.filePath}: ${String(error)}`, { error });
		return null;
	}
	const entries = [];
	for (const [rawKey, value] of Object.entries(parsed)) {
		const key = normalizeEnvVarKey(rawKey, { portable: true });
		if (!key || params.shouldBlockKey(key)) continue;
		entries.push({
			key,
			value
		});
	}
	return {
		filePath: params.filePath,
		entries
	};
}
function loadWorkspaceDotEnvFile(filePath, opts) {
	let providerAuthBlockedKeys;
	const getProviderAuthBlockedKeys = () => {
		providerAuthBlockedKeys ??= buildProviderAuthWorkspaceDotEnvBlocklist();
		return providerAuthBlockedKeys;
	};
	const parsed = readDotEnvFile({
		filePath,
		shouldBlockKey: (key) => shouldBlockWorkspaceDotEnvKey(key, getProviderAuthBlockedKeys),
		quiet: opts?.quiet ?? true
	});
	if (!parsed) return;
	for (const { key, value } of parsed.entries) {
		if (process.env[key] !== void 0) continue;
		process.env[key] = value;
	}
}
function loadParsedDotEnvFiles(files) {
	const preExistingKeys = new Set(Object.keys(process.env));
	const conflicts = /* @__PURE__ */ new Map();
	const firstSeen = /* @__PURE__ */ new Map();
	for (const file of files) for (const { key, value } of file.entries) {
		if (preExistingKeys.has(key)) continue;
		const previous = firstSeen.get(key);
		if (previous) {
			if (previous.value !== value) {
				const conflictKey = `${previous.filePath}\u0000${file.filePath}`;
				const existing = conflicts.get(conflictKey);
				if (existing) existing.keys.add(key);
				else conflicts.set(conflictKey, {
					keptPath: previous.filePath,
					ignoredPath: file.filePath,
					keys: new Set([key])
				});
			}
			continue;
		}
		firstSeen.set(key, {
			value,
			filePath: file.filePath
		});
		if (process.env[key] === void 0) process.env[key] = value;
	}
	for (const conflict of conflicts.values()) {
		const keys = [...conflict.keys].toSorted();
		if (keys.length === 0) continue;
		logger.warn(`Conflicting values in ${conflict.keptPath} and ${conflict.ignoredPath} for ${keys.join(", ")}; keeping ${conflict.keptPath}.`, {
			keptPath: conflict.keptPath,
			ignoredPath: conflict.ignoredPath,
			keys
		});
	}
}
function loadGlobalRuntimeDotEnvFiles(opts) {
	const quiet = opts?.quiet ?? true;
	const stateEnvPath = opts?.stateEnvPath ?? path.join(resolveConfigDir(process.env), ".env");
	const defaultStateEnvPath = path.join(resolveRequiredHomeDir(process.env, os.homedir), ".nodmix", ".env");
	const hasExplicitNonDefaultStateDir = process.env.NODMIX_STATE_DIR?.trim() !== void 0 && path.resolve(stateEnvPath) !== path.resolve(defaultStateEnvPath);
	const parsedFiles = [readDotEnvFile({
		filePath: stateEnvPath,
		shouldBlockKey: shouldBlockRuntimeDotEnvKey,
		quiet
	})];
	if (!hasExplicitNonDefaultStateDir) parsedFiles.push(readDotEnvFile({
		filePath: path.join(resolveRequiredHomeDir(process.env, os.homedir), ".config", "nodmix", "gateway.env"),
		shouldBlockKey: shouldBlockRuntimeDotEnvKey,
		quiet
	}));
	loadParsedDotEnvFiles(parsedFiles.filter((file) => file !== null));
}
function loadDotEnv(opts) {
	const quiet = opts?.quiet ?? true;
	loadWorkspaceDotEnvFile(path.join(process.cwd(), ".env"), { quiet });
	loadGlobalRuntimeDotEnvFiles({ quiet });
}
//#endregion
export { loadGlobalRuntimeDotEnvFiles as n, loadWorkspaceDotEnvFile as r, loadDotEnv as t };
