import { c as normalizeOptionalString, s as normalizeOptionalLowercaseString } from "./string-coerce-mnp54Vah.js";
import { y as resolveStateDir } from "./paths-CQLGtQnw.js";
import { i as formatErrorMessage } from "./errors-MtvAMHJ_.js";
import { _ as uniqueStrings, d as normalizeTrimmedStringList } from "./string-normalization-WNUDCpXX.js";
import { c as isBundledSourceOverlayPath } from "./discovery-DNEMFbgL.js";
import { c as isRecord$1 } from "./utils-BQafJ6e6.js";
import { t as createSubsystemLogger } from "./subsystem-Cycdnc1p.js";
import { n as getCachedPluginModuleLoader } from "./plugin-module-loader-cache-Dqfn3Jk_.js";
import { t as listChannelCatalogEntries } from "./channel-catalog-registry-GS1I_5v1.js";
import { h as resolveExistingPluginModulePath, m as loadChannelPluginModule } from "./bundled-DdLma9vJ.js";
import { r as listBundledChannelIds } from "./bootstrap-registry-Cr7zaQQF.js";
import { i as hasNonEmptyString } from "./channel-target-DZLt4jQB.js";
import fs from "node:fs";
import path from "node:path";
import os from "node:os";
//#region src/channels/plugins/package-state-probes.ts
const log = createSubsystemLogger("channels");
const sourcePackageStateLoaderCache = /* @__PURE__ */ new Map();
function isSourceModulePath(modulePath) {
	return /\.(?:c|m)?tsx?$/iu.test(modulePath);
}
function loadChannelPackageStateModule(params) {
	try {
		return loadChannelPluginModule(params);
	} catch (error) {
		if (!isSourceModulePath(params.modulePath)) throw error;
		return getCachedPluginModuleLoader({
			cache: sourcePackageStateLoaderCache,
			modulePath: params.modulePath,
			importerUrl: import.meta.url,
			tryNative: true,
			cacheScopeKey: "channel-package-state"
		})(params.modulePath);
	}
}
function hasNonEmptyEnvValue(env, key) {
	return typeof env?.[key] === "string" && env[key].trim().length > 0;
}
function resolveSourceBundledPluginRoot(rootDir) {
	const pluginRoot = path.resolve(rootDir);
	const extensionsDir = path.dirname(pluginRoot);
	if (path.basename(extensionsDir) !== "extensions") return null;
	const packageRoot = path.dirname(extensionsDir);
	if (path.basename(packageRoot) === "dist" || path.basename(packageRoot) === "dist-runtime") return null;
	return {
		packageRoot,
		dirName: path.basename(pluginRoot)
	};
}
function isBundledSourceOverlayPluginRoot(rootDir) {
	const pluginRoot = path.resolve(rootDir);
	return isBundledSourceOverlayPath({ sourcePath: pluginRoot }) || path.basename(path.dirname(pluginRoot)) === "extensions" && isBundledSourceOverlayPath({ sourcePath: path.dirname(pluginRoot) });
}
function listBuiltBundledPackageStateModules(params) {
	if (isBundledSourceOverlayPluginRoot(params.rootDir)) return [];
	const sourceRoot = resolveSourceBundledPluginRoot(params.rootDir);
	if (!sourceRoot) return [];
	const locations = [];
	for (const rootDir of [path.join(sourceRoot.packageRoot, "dist", "extensions", sourceRoot.dirName), path.join(sourceRoot.packageRoot, "dist-runtime", "extensions", sourceRoot.dirName)]) {
		const modulePath = resolveExistingPluginModulePath(rootDir, params.specifier);
		if (fs.existsSync(modulePath) && !isSourceModulePath(modulePath)) locations.push({
			modulePath,
			rootDir
		});
	}
	return locations;
}
function resolveChannelPackageStateModuleLocation(params) {
	return {
		modulePath: resolveExistingPluginModulePath(params.entry.rootDir, params.specifier),
		rootDir: params.entry.rootDir
	};
}
function listChannelPackageStateModuleLocations(params) {
	const source = resolveChannelPackageStateModuleLocation(params);
	return [...listBuiltBundledPackageStateModules({
		rootDir: params.entry.rootDir,
		specifier: params.specifier
	}).filter((location) => location.modulePath !== source.modulePath), source];
}
function resolveChannelPackageStateMetadata(entry, metadataKey) {
	const metadata = entry.channel[metadataKey];
	if (!metadata || typeof metadata !== "object") return null;
	const specifier = normalizeOptionalString(metadata.specifier) ?? "";
	const exportName = normalizeOptionalString(metadata.exportName) ?? "";
	const envMetadata = "env" in metadata ? metadata.env : void 0;
	const allOf = normalizeTrimmedStringList(envMetadata?.allOf);
	const anyOf = normalizeTrimmedStringList(envMetadata?.anyOf);
	const env = allOf.length > 0 || anyOf.length > 0 ? {
		allOf,
		anyOf
	} : void 0;
	if ((!specifier || !exportName) && !env) return null;
	return {
		...specifier ? { specifier } : {},
		...exportName ? { exportName } : {},
		...env ? { env } : {}
	};
}
function listChannelPackageStateCatalog(metadataKey, discovery) {
	return listChannelCatalogEntries({
		origin: "bundled",
		discovery
	}).filter((entry) => Boolean(resolveChannelPackageStateMetadata(entry, metadataKey)));
}
function resolveChannelPackageStateChecker(params) {
	const metadata = resolveChannelPackageStateMetadata(params.entry, params.metadataKey);
	if (!metadata) return null;
	if (metadata.env) return ({ env }) => {
		const allOf = metadata.env?.allOf ?? [];
		const anyOf = metadata.env?.anyOf ?? [];
		return allOf.every((key) => hasNonEmptyEnvValue(env, key)) && (anyOf.length === 0 || anyOf.some((key) => hasNonEmptyEnvValue(env, key)));
	};
	let loadError;
	for (const location of listChannelPackageStateModuleLocations({
		entry: params.entry,
		specifier: metadata.specifier
	})) try {
		const checker = loadChannelPackageStateModule({
			modulePath: location.modulePath,
			rootDir: location.rootDir
		})[metadata.exportName];
		if (typeof checker !== "function") throw new Error(`missing ${params.metadataKey} export ${metadata.exportName}`);
		return checker;
	} catch (error) {
		loadError = error;
	}
	if (loadError) {
		const detail = formatErrorMessage(loadError);
		log.warn(`[channels] failed to load ${params.metadataKey} checker for ${params.entry.pluginId}: ${detail}`);
	}
	return null;
}
function resolvePackageStateChannelId(entry) {
	return normalizeOptionalString(entry.channel.id);
}
function listBundledChannelIdsForPackageState(metadataKey, discovery) {
	return listChannelPackageStateCatalog(metadataKey, discovery).map((entry) => resolvePackageStateChannelId(entry)).filter((channelId) => Boolean(channelId)).toSorted((left, right) => left.localeCompare(right));
}
function hasBundledChannelPackageState(params) {
	const requestedChannelId = normalizeOptionalString(params.channelId);
	const entry = listChannelPackageStateCatalog(params.metadataKey, params.discovery).find((candidate) => resolvePackageStateChannelId(candidate) === requestedChannelId);
	if (!entry) return false;
	const checker = resolveChannelPackageStateChecker({
		entry,
		metadataKey: params.metadataKey
	});
	return checker ? checker({
		cfg: params.cfg,
		env: params.env
	}) : false;
}
//#endregion
//#region src/channels/plugins/persisted-auth-state.ts
function listBundledChannelIdsWithPersistedAuthState(discovery) {
	return listBundledChannelIdsForPackageState("persistedAuthState", discovery);
}
function hasBundledChannelPersistedAuthState(params) {
	return hasBundledChannelPackageState({
		metadataKey: "persistedAuthState",
		channelId: params.channelId,
		cfg: params.cfg,
		env: params.env,
		discovery: params.discovery
	});
}
//#endregion
//#region src/channels/config-presence.ts
const IGNORED_CHANNEL_CONFIG_KEYS = new Set(["defaults", "modelByChannel"]);
function hasMeaningfulChannelConfig(value) {
	if (!isRecord$1(value)) return false;
	return Object.keys(value).some((key) => key !== "enabled");
}
function listExplicitlyDisabledChannelIdsForConfig(cfg) {
	const channels = isRecord$1(cfg.channels) ? cfg.channels : null;
	if (!channels) return [];
	return Object.entries(channels).filter(([, value]) => isRecord$1(value) && value.enabled === false).map(([channelId]) => normalizeOptionalLowercaseString(channelId)).filter((channelId) => Boolean(channelId));
}
function listChannelEnvPrefixes(channelIds) {
	return channelIds.map((channelId) => [`${channelId.replace(/[^a-z0-9]+/gi, "_").toUpperCase()}_`, channelId]);
}
function hasPersistedChannelState(env) {
	return fs.existsSync(resolveStateDir(env, os.homedir));
}
let persistedAuthStateChannelIds = null;
function listPersistedAuthStateChannelIds(options) {
	const override = options.persistedAuthStateProbe?.listChannelIds();
	if (override) return override;
	if (options.discovery) return listBundledChannelIdsWithPersistedAuthState(options.discovery);
	if (persistedAuthStateChannelIds) return persistedAuthStateChannelIds;
	persistedAuthStateChannelIds = listBundledChannelIdsWithPersistedAuthState();
	return persistedAuthStateChannelIds;
}
function hasPersistedAuthState(params) {
	const override = params.options.persistedAuthStateProbe;
	if (override) return override.hasState(params);
	return hasBundledChannelPersistedAuthState({
		channelId: params.channelId,
		cfg: params.cfg,
		env: params.env,
		discovery: params.options.discovery
	});
}
function listPotentialConfiguredChannelIds(cfg, env = process.env, options = {}) {
	return uniqueStrings(listPotentialConfiguredChannelPresenceSignals(cfg, env, options).map((signal) => signal.channelId));
}
function listPotentialConfiguredChannelPresenceSignals(cfg, env = process.env, options = {}) {
	const signals = [];
	const seenSignals = /* @__PURE__ */ new Set();
	const addSignal = (channelId, source) => {
		const key = `${source}:${channelId}`;
		if (seenSignals.has(key)) return;
		seenSignals.add(key);
		signals.push({
			channelId,
			source
		});
	};
	const configuredChannelIds = /* @__PURE__ */ new Set();
	const channelEnvPrefixes = listChannelEnvPrefixes(options.channelIds ?? listBundledChannelIds(env, options.discovery));
	const channels = isRecord$1(cfg.channels) ? cfg.channels : null;
	if (channels) for (const [key, value] of Object.entries(channels)) {
		if (IGNORED_CHANNEL_CONFIG_KEYS.has(key)) continue;
		if (hasMeaningfulChannelConfig(value)) {
			configuredChannelIds.add(key);
			addSignal(key, "config");
		}
	}
	for (const [key, value] of Object.entries(env)) {
		if (!hasNonEmptyString(value)) continue;
		for (const [prefix, channelId] of channelEnvPrefixes) if (key.startsWith(prefix)) {
			configuredChannelIds.add(channelId);
			addSignal(channelId, "env");
		}
	}
	if (options.includePersistedAuthState !== false && hasPersistedChannelState(env)) {
		for (const channelId of listPersistedAuthStateChannelIds(options)) if (hasPersistedAuthState({
			channelId,
			cfg,
			env,
			options
		})) {
			configuredChannelIds.add(channelId);
			addSignal(channelId, "persisted-auth");
		}
	}
	return signals.filter((signal) => configuredChannelIds.has(signal.channelId));
}
//#endregion
//#region src/secrets/channel-env-var-names.ts
const UNSAFE_CHANNEL_ENV_VAR_TRIGGER_NAMES = new Set([
	"CI",
	"HOME",
	"LANG",
	"LC_ALL",
	"LC_CTYPE",
	"LOGNAME",
	"NODE_ENV",
	"OLDPWD",
	"PATH",
	"PWD",
	"SHELL",
	"SSH_AUTH_SOCK",
	"TEMP",
	"TERM",
	"TMP",
	"TMPDIR",
	"USER"
]);
function isSafeChannelEnvVarTriggerName(key) {
	const normalized = key.trim().toUpperCase();
	return /^[A-Z][A-Z0-9_]*$/.test(normalized) && !UNSAFE_CHANNEL_ENV_VAR_TRIGGER_NAMES.has(normalized);
}
//#endregion
//#region packages/model-catalog-core/src/configured-model-refs.ts
function isRecord(value) {
	return typeof value === "object" && value !== null && !Array.isArray(value);
}
const AGENT_MODEL_CONFIG_KEYS = [
	"model",
	"imageModel",
	"imageGenerationModel",
	"videoGenerationModel",
	"musicGenerationModel",
	"voiceModel",
	"pdfModel"
];
function collectConfiguredModelRefs(config, options = {}) {
	const refs = [];
	const pushModelRef = (path, value) => {
		if (typeof value === "string" && value.trim()) refs.push({
			path,
			value: value.trim()
		});
	};
	const collectModelConfig = (path, value) => {
		if (typeof value === "string") {
			pushModelRef(path, value);
			return;
		}
		if (!isRecord(value)) return;
		pushModelRef(`${path}.primary`, value.primary);
		if (Array.isArray(value.fallbacks)) for (const [index, entry] of value.fallbacks.entries()) pushModelRef(`${path}.fallbacks.${index}`, entry);
	};
	const collectFromAgent = (path, agent) => {
		if (!isRecord(agent)) return;
		for (const key of AGENT_MODEL_CONFIG_KEYS) collectModelConfig(`${path}.${key}`, agent[key]);
		pushModelRef(`${path}.heartbeat.model`, isRecord(agent.heartbeat) ? agent.heartbeat.model : void 0);
		collectModelConfig(`${path}.subagents.model`, isRecord(agent.subagents) ? agent.subagents.model : void 0);
		if (isRecord(agent.compaction)) {
			pushModelRef(`${path}.compaction.model`, agent.compaction.model);
			pushModelRef(`${path}.compaction.memoryFlush.model`, isRecord(agent.compaction.memoryFlush) ? agent.compaction.memoryFlush.model : void 0);
		}
		if (isRecord(agent.models)) for (const modelRef of Object.keys(agent.models)) pushModelRef(`${path}.models.${modelRef}`, modelRef);
	};
	const root = isRecord(config) ? config : {};
	const agents = isRecord(root.agents) ? root.agents : {};
	collectFromAgent("agents.defaults", agents.defaults);
	if (Array.isArray(agents.list)) for (const [index, entry] of agents.list.entries()) collectFromAgent(`agents.list.${index}`, entry);
	if (options.includeChannelModelOverrides !== false) {
		const channels = isRecord(root.channels) ? root.channels : {};
		const modelByChannel = isRecord(channels.modelByChannel) ? channels.modelByChannel : {};
		for (const [channelId, channelMap] of Object.entries(modelByChannel)) {
			if (!isRecord(channelMap)) continue;
			for (const [targetId, modelRef] of Object.entries(channelMap)) pushModelRef(`channels.modelByChannel.${channelId}.${targetId}`, modelRef);
		}
	}
	const hooks = isRecord(root.hooks) ? root.hooks : {};
	if (Array.isArray(hooks.mappings)) for (const [index, mapping] of hooks.mappings.entries()) pushModelRef(`hooks.mappings.${index}.model`, isRecord(mapping) ? mapping.model : void 0);
	pushModelRef("hooks.gmail.model", isRecord(hooks.gmail) ? hooks.gmail.model : void 0);
	pushModelRef("messages.tts.summaryModel", isRecord(root.messages) && isRecord(root.messages.tts) ? root.messages.tts.summaryModel : void 0);
	pushModelRef("channels.discord.voice.model", isRecord(root.channels) && isRecord(root.channels.discord) && isRecord(root.channels.discord.voice) ? root.channels.discord.voice.model : void 0);
	return refs;
}
//#endregion
export { listExplicitlyDisabledChannelIdsForConfig as a, hasBundledChannelPackageState as c, hasMeaningfulChannelConfig as i, listBundledChannelIdsForPackageState as l, collectConfiguredModelRefs as n, listPotentialConfiguredChannelIds as o, isSafeChannelEnvVarTriggerName as r, listPotentialConfiguredChannelPresenceSignals as s, AGENT_MODEL_CONFIG_KEYS as t };
