import { __toCommonJS } from "../../../_virtual/_rolldown/runtime.js";
import { init_write_file_atomic, writeTextAtomicSync } from "../../infra/write-file-atomic.js";
import { createLogger } from "../../utils/logger/index.js";
import { init_logger } from "../../utils/logger.js";
import { init_installer, installer_exports } from "./installer.js";
import { join } from "path";
import { existsSync, readFileSync } from "fs";
//#region src/agent/skills/config.ts
/**
* Skill Configuration Manager
* 
* Handles skill-specific configuration and environment variables.
*
*/
init_logger();
init_write_file_atomic();
const log = createLogger("SkillConfig");
/**
* Resolve skill configuration from multiple sources
* 
* Priority (highest to lowest):
* 1. Environment variable overrides (XOPC_SKILL_<NAME>_<KEY>)
* 2. Config file entries
* 3. Skill defaults
*/
function resolveSkillConfig(skill, skillsConfig) {
	const config = {};
	const entryConfig = skillsConfig?.entries?.[skill.name];
	if (entryConfig) {
		config.enabled = entryConfig.enabled;
		config.apiKey = entryConfig.apiKey;
		config.env = entryConfig.env ? { ...entryConfig.env } : void 0;
		config.config = entryConfig.config ? { ...entryConfig.config } : void 0;
	}
	const envPrefix = `XOPC_SKILL_${skill.name.toUpperCase().replace(/-/g, "_")}`;
	const enabledEnv = process.env[`${envPrefix}_ENABLED`];
	if (enabledEnv !== void 0) config.enabled = enabledEnv.toLowerCase() === "true" || enabledEnv === "1";
	const apiKeyEnv = process.env[`${envPrefix}_API_KEY`];
	if (apiKeyEnv) config.apiKey = apiKeyEnv;
	for (const [key, value] of Object.entries(process.env)) if (key.startsWith(`${envPrefix}_ENV_`)) {
		const envKey = key.slice(`${envPrefix}_ENV_`.length);
		if (!config.env) config.env = {};
		config.env[envKey] = value;
	}
	return config;
}
/**
* Apply environment variable overrides to a skill's environment
*/
function applySkillEnvOverrides(skill, baseEnv = {}, skillConfig) {
	const env = { ...baseEnv };
	if (skillConfig?.env) for (const [key, value] of Object.entries(skillConfig.env)) env[key] = value;
	const envPrefix = `XOPC_SKILL_${skill.name.toUpperCase().replace(/-/g, "_")}`;
	for (const [key, value] of Object.entries(process.env)) if (key.startsWith(`${envPrefix}_ENV_`)) {
		const envKey = key.slice(`${envPrefix}_ENV_`.length);
		env[envKey] = value;
	}
	return env;
}
/**
* Get the effective environment for a skill
*/
function getSkillEnvironment(skill, skillsConfig) {
	const config = resolveSkillConfig(skill, skillsConfig);
	return applySkillEnvOverrides(skill, process.env, config);
}
/**
* Create a skill configuration file manager
*/
function createSkillConfigManager(configDir) {
	const configPath = join(configDir, "skills.json");
	function loadConfig() {
		if (!existsSync(configPath)) return {};
		try {
			const content = readFileSync(configPath, "utf-8");
			return JSON.parse(content);
		} catch (err) {
			const em = err instanceof Error ? err.message : String(err);
			log.warn({
				error: err,
				errorMessage: em,
				path: configPath
			}, `Skills config load failed, using defaults: ${em}`);
			return {};
		}
	}
	function saveConfig(config) {
		try {
			writeTextAtomicSync(configPath, JSON.stringify(config, null, 2));
			log.info("Saved skills config");
		} catch (err) {
			const em = err instanceof Error ? err.message : String(err);
			log.error({
				error: err,
				errorMessage: em,
				path: configPath
			}, `Failed to save skills config: ${em}`);
		}
	}
	return {
		configPath,
		load: loadConfig,
		save: saveConfig,
		getSkillConfig: (skillName) => {
			return loadConfig().entries?.[skillName];
		},
		updateSkillConfig: (skillName, updates) => {
			const config = loadConfig();
			if (!config.entries) config.entries = {};
			const existing = config.entries[skillName] || {};
			config.entries[skillName] = {
				...existing,
				...updates
			};
			saveConfig(config);
		},
		setSkillEnabled: (skillName, enabled) => {
			const config = loadConfig();
			if (!config.entries) config.entries = {};
			const existing = config.entries[skillName] || {};
			config.entries[skillName] = {
				...existing,
				enabled
			};
			saveConfig(config);
			log.info({
				skillName,
				enabled
			}, "Updated skill enabled state");
		},
		setSkillApiKey: (skillName, apiKey) => {
			const config = loadConfig();
			if (!config.entries) config.entries = {};
			const existing = config.entries[skillName] || {};
			config.entries[skillName] = {
				...existing,
				apiKey
			};
			saveConfig(config);
			log.info({ skillName }, "Updated skill API key");
		}
	};
}
/**
* Check if a skill is enabled
*/
function isSkillEnabled(skill, skillsConfig) {
	if (resolveSkillConfig(skill, skillsConfig).enabled === false) return false;
	const requires = skill.metadata.xopc?.requires || skill.metadata.requires;
	if (requires?.bins) {
		const { hasBinary } = (init_installer(), __toCommonJS(installer_exports));
		for (const bin of requires.bins) if (!hasBinary(bin)) {
			log.debug({
				skill: skill.name,
				bin
			}, "Skill requirement not met");
			return false;
		}
	}
	return true;
}
/**
* Validate skill configuration
*/
function validateSkillConfig(config) {
	const errors = [];
	if (config.toolGating !== void 0 && typeof config.toolGating !== "boolean") errors.push("toolGating must be a boolean");
	if (config.agentWritePolicy !== void 0 && config.agentWritePolicy !== "global" && config.agentWritePolicy !== "workspace" && config.agentWritePolicy !== "both") errors.push("agentWritePolicy must be \"global\", \"workspace\", or \"both\"");
	const limits = config.limits;
	if (limits) {
		if (limits.maxCandidatesPerRoot !== void 0 && limits.maxCandidatesPerRoot < 1) errors.push("limits.maxCandidatesPerRoot must be at least 1");
		if (limits.maxSkillsLoadedPerSource !== void 0 && limits.maxSkillsLoadedPerSource < 1) errors.push("limits.maxSkillsLoadedPerSource must be at least 1");
		if (limits.maxSkillsInPrompt !== void 0 && limits.maxSkillsInPrompt < 1) errors.push("limits.maxSkillsInPrompt must be at least 1");
	}
	if (config.entries) for (const [skillName, skillConfig] of Object.entries(config.entries)) {
		if (skillConfig.apiKey && typeof skillConfig.apiKey !== "string") errors.push(`entries.${skillName}.apiKey must be a string`);
		if (skillConfig.env && typeof skillConfig.env !== "object") errors.push(`entries.${skillName}.env must be an object`);
	}
	return {
		valid: errors.length === 0,
		errors
	};
}
//#endregion
export { applySkillEnvOverrides, createSkillConfigManager, getSkillEnvironment, isSkillEnabled, resolveSkillConfig, validateSkillConfig };

//# sourceMappingURL=config.js.map