//#region src/extensions/normalize-manifest.ts
function isRecord(x) {
	return typeof x === "object" && x !== null && !Array.isArray(x);
}
function normalizeReload(raw) {
	if (!isRecord(raw)) return void 0;
	const configPrefixes = Array.isArray(raw.configPrefixes) ? raw.configPrefixes.filter((x) => typeof x === "string") : void 0;
	const supportsHotReload = typeof raw.supportsHotReload === "boolean" ? raw.supportsHotReload : void 0;
	if (!configPrefixes?.length && supportsHotReload === void 0) return void 0;
	return {
		...configPrefixes?.length ? { configPrefixes } : {},
		...supportsHotReload !== void 0 ? { supportsHotReload } : {}
	};
}
function normalizeEngines(raw) {
	if (!isRecord(raw)) return void 0;
	const xopc = typeof raw.xopc === "string" && raw.xopc.length > 0 ? raw.xopc : void 0;
	if (!xopc) return void 0;
	return { xopc };
}
function normalizeManifestCommands(raw) {
	if (!Array.isArray(raw)) return void 0;
	const out = [];
	for (const item of raw) {
		if (!isRecord(item)) continue;
		const name = typeof item.name === "string" ? item.name.trim() : "";
		const description = typeof item.description === "string" ? item.description : "";
		if (!name || !description) continue;
		const aliases = Array.isArray(item.aliases) ? item.aliases.filter((x) => typeof x === "string") : void 0;
		const scope = Array.isArray(item.scope) ? item.scope.filter((x) => x === "global" || x === "private" || x === "group") : void 0;
		const examples = Array.isArray(item.examples) ? item.examples.filter((x) => typeof x === "string") : void 0;
		out.push({
			name,
			description,
			...aliases?.length ? { aliases } : {},
			...scope?.length ? { scope } : {},
			...examples?.length ? { examples } : {}
		});
	}
	return out.length > 0 ? out : void 0;
}
/**
* Normalize raw JSON manifest into ExtensionManifest with stable optional fields.
*/
function normalizeExtensionManifest(raw) {
	const id = String(raw.id ?? "");
	return {
		id,
		name: typeof raw.name === "string" && raw.name.length > 0 ? raw.name : id,
		description: typeof raw.description === "string" ? raw.description : void 0,
		version: typeof raw.version === "string" ? raw.version : void 0,
		kind: raw.kind,
		main: typeof raw.main === "string" ? raw.main : void 0,
		configSchema: isRecord(raw.configSchema) ? raw.configSchema : void 0,
		dependencies: isRecord(raw.dependencies) ? raw.dependencies : void 0,
		enabledByDefault: typeof raw.enabledByDefault === "boolean" ? raw.enabledByDefault : void 0,
		providers: Array.isArray(raw.providers) ? raw.providers.filter((x) => typeof x === "string") : void 0,
		speechProviders: Array.isArray(raw.speechProviders) ? raw.speechProviders.filter((x) => typeof x === "string") : void 0,
		mediaUnderstandingProviders: Array.isArray(raw.mediaUnderstandingProviders) ? raw.mediaUnderstandingProviders.filter((x) => typeof x === "string") : void 0,
		providerAuthEnvVars: normalizeStringArrayMap(raw.providerAuthEnvVars),
		providerAuthChoices: normalizeProviderAuthChoices(raw.providerAuthChoices),
		modelSupport: normalizeModelSupport(raw.modelSupport),
		autoEnableWhenConfiguredProviders: Array.isArray(raw.autoEnableWhenConfiguredProviders) ? raw.autoEnableWhenConfiguredProviders.filter((x) => typeof x === "string") : void 0,
		channels: Array.isArray(raw.channels) ? raw.channels.filter((x) => typeof x === "string") : void 0,
		channelEnvVars: normalizeStringArrayMap(raw.channelEnvVars),
		activation: normalizeActivation(raw.activation),
		contracts: normalizeContracts(raw.contracts),
		setup: normalizeSetup(raw.setup),
		reload: normalizeReload(raw.reload),
		engines: normalizeEngines(raw.engines),
		commands: normalizeManifestCommands(raw.commands),
		ui: normalizeUiManifest(raw.ui)
	};
}
const VALID_UI_PERMISSIONS = new Set([
	"agent.send",
	"agent.subscribe",
	"session.read",
	"session.write",
	"config.read",
	"config.write",
	"storage",
	"notification",
	"clipboard",
	"theme",
	"workspace.read",
	"workspace.write"
]);
function normalizeUiManifest(raw) {
	if (raw === void 0 || raw === null) return void 0;
	if (!isRecord(raw)) return void 0;
	const main = typeof raw.main === "string" && raw.main.length > 0 ? raw.main : void 0;
	const icon = typeof raw.icon === "string" && raw.icon.length > 0 ? raw.icon : void 0;
	let permissions;
	if (Array.isArray(raw.permissions)) {
		const p = raw.permissions.filter((x) => typeof x === "string" && VALID_UI_PERMISSIONS.has(x));
		permissions = p.length ? p : void 0;
	}
	const contributions = normalizeUiContributions(raw.contributions);
	if (!main && !icon && !permissions && !contributions) return void 0;
	return {
		...main !== void 0 ? { main } : {},
		...icon !== void 0 ? { icon } : {},
		...permissions !== void 0 ? { permissions } : {},
		...contributions !== void 0 ? { contributions } : {}
	};
}
function normalizeUiContributions(raw) {
	if (!isRecord(raw)) return void 0;
	const sidebarPanels = normalizeSidebarPanels(raw.sidebarPanels);
	const settingsPanels = normalizeSettingsPanels(raw.settingsPanels);
	const chatWidgets = normalizeChatWidgets(raw.chatWidgets);
	const pages = normalizePages(raw.pages);
	const commands = normalizeCommands(raw.commands);
	const statusBarItems = normalizeStatusBarItems(raw.statusBarItems);
	const out = {
		...sidebarPanels ? { sidebarPanels } : {},
		...settingsPanels ? { settingsPanels } : {},
		...chatWidgets ? { chatWidgets } : {},
		...pages ? { pages } : {},
		...commands ? { commands } : {},
		...statusBarItems ? { statusBarItems } : {}
	};
	return Object.keys(out).length ? out : void 0;
}
function normalizeSidebarPanels(raw) {
	if (!Array.isArray(raw)) return void 0;
	const out = [];
	for (const item of raw) {
		if (!isRecord(item)) continue;
		const id = item.id;
		const title = item.title;
		const entrypoint = item.entrypoint;
		if (typeof id !== "string" || typeof title !== "string" || typeof entrypoint !== "string") continue;
		out.push({
			id,
			title,
			entrypoint,
			icon: typeof item.icon === "string" ? item.icon : void 0,
			defaultVisible: typeof item.defaultVisible === "boolean" ? item.defaultVisible : void 0,
			when: typeof item.when === "string" && item.when.length > 0 ? item.when : void 0
		});
	}
	return out.length ? out : void 0;
}
function normalizeSettingsPanels(raw) {
	if (!Array.isArray(raw)) return void 0;
	const out = [];
	for (const item of raw) {
		if (!isRecord(item)) continue;
		const id = item.id;
		const title = item.title;
		const entrypoint = item.entrypoint;
		if (typeof id !== "string" || typeof title !== "string" || typeof entrypoint !== "string") continue;
		out.push({
			id,
			title,
			entrypoint,
			order: typeof item.order === "number" ? item.order : void 0
		});
	}
	return out.length ? out : void 0;
}
function normalizeChatWidgetMatch(raw) {
	if (!isRecord(raw)) return void 0;
	const toolName = typeof raw.toolName === "string" ? raw.toolName : void 0;
	const contentType = typeof raw.contentType === "string" ? raw.contentType : void 0;
	let metadata;
	if (isRecord(raw.metadata)) metadata = { ...raw.metadata };
	if (!toolName && !contentType && !metadata) return void 0;
	return {
		toolName,
		contentType,
		metadata
	};
}
function normalizeChatWidgets(raw) {
	if (!Array.isArray(raw)) return void 0;
	const out = [];
	for (const item of raw) {
		if (!isRecord(item)) continue;
		const id = item.id;
		const title = item.title;
		const entrypoint = item.entrypoint;
		if (typeof id !== "string" || typeof title !== "string" || typeof entrypoint !== "string") continue;
		const match = normalizeChatWidgetMatch(item.match);
		if (!match) continue;
		out.push({
			id,
			title,
			entrypoint,
			match,
			maxHeight: typeof item.maxHeight === "number" ? item.maxHeight : void 0,
			interactive: typeof item.interactive === "boolean" ? item.interactive : void 0
		});
	}
	return out.length ? out : void 0;
}
function normalizePages(raw) {
	if (!Array.isArray(raw)) return void 0;
	const out = [];
	for (const item of raw) {
		if (!isRecord(item)) continue;
		const id = item.id;
		const title = item.title;
		const path = item.path;
		const entrypoint = item.entrypoint;
		if (typeof id !== "string" || typeof title !== "string" || typeof path !== "string" || typeof entrypoint !== "string") continue;
		out.push({
			id,
			title,
			path,
			entrypoint,
			showInNav: typeof item.showInNav === "boolean" ? item.showInNav : void 0,
			navIcon: typeof item.navIcon === "string" ? item.navIcon : void 0,
			when: typeof item.when === "string" && item.when.length > 0 ? item.when : void 0
		});
	}
	return out.length ? out : void 0;
}
function normalizeCommands(raw) {
	if (!Array.isArray(raw)) return void 0;
	const out = [];
	for (const item of raw) {
		if (!isRecord(item)) continue;
		const id = item.id;
		const title = item.title;
		if (typeof id !== "string" || typeof title !== "string") continue;
		out.push({
			id,
			title,
			shortcut: typeof item.shortcut === "string" ? item.shortcut : void 0,
			opensPanel: typeof item.opensPanel === "string" ? item.opensPanel : void 0,
			chatAlias: typeof item.chatAlias === "string" && item.chatAlias.length > 0 ? item.chatAlias : void 0,
			when: typeof item.when === "string" && item.when.length > 0 ? item.when : void 0
		});
	}
	return out.length ? out : void 0;
}
function normalizeStatusBarItems(raw) {
	if (!Array.isArray(raw)) return void 0;
	const out = [];
	for (const item of raw) {
		if (!isRecord(item)) continue;
		const id = item.id;
		const entrypoint = item.entrypoint;
		if (typeof id !== "string" || typeof entrypoint !== "string") continue;
		const position = item.position;
		out.push({
			id,
			entrypoint,
			position: position === "left" || position === "right" ? position : void 0,
			width: typeof item.width === "number" ? item.width : void 0,
			when: typeof item.when === "string" && item.when.length > 0 ? item.when : void 0
		});
	}
	return out.length ? out : void 0;
}
function normalizeStringArrayMap(raw) {
	if (!isRecord(raw)) return void 0;
	const out = {};
	for (const [k, v] of Object.entries(raw)) if (Array.isArray(v)) {
		const arr = v.filter((x) => typeof x === "string");
		if (arr.length) out[k] = arr;
	}
	return Object.keys(out).length ? out : void 0;
}
function normalizeProviderAuthChoices(raw) {
	if (!Array.isArray(raw)) return void 0;
	const out = [];
	for (const item of raw) {
		if (!isRecord(item)) continue;
		const provider = item.provider;
		const method = item.method;
		const choiceId = item.choiceId;
		const choiceLabel = item.choiceLabel;
		if (typeof provider !== "string" || typeof choiceId !== "string" || typeof choiceLabel !== "string" || method !== "api-key" && method !== "oauth" && method !== "cli" && method !== "env") continue;
		out.push({
			provider,
			method,
			choiceId,
			choiceLabel,
			choiceHint: typeof item.choiceHint === "string" ? item.choiceHint : void 0,
			groupId: typeof item.groupId === "string" ? item.groupId : void 0,
			groupLabel: typeof item.groupLabel === "string" ? item.groupLabel : void 0,
			groupHint: typeof item.groupHint === "string" ? item.groupHint : void 0,
			cliFlag: typeof item.cliFlag === "string" ? item.cliFlag : void 0,
			cliOption: typeof item.cliOption === "string" ? item.cliOption : void 0,
			cliDescription: typeof item.cliDescription === "string" ? item.cliDescription : void 0
		});
	}
	return out.length ? out : void 0;
}
function normalizeModelSupport(raw) {
	if (!isRecord(raw)) return void 0;
	const modelPrefixes = Array.isArray(raw.modelPrefixes) ? raw.modelPrefixes.filter((x) => typeof x === "string") : void 0;
	const modelPatterns = Array.isArray(raw.modelPatterns) ? raw.modelPatterns.filter((x) => typeof x === "string") : void 0;
	if (!modelPrefixes?.length && !modelPatterns?.length) return void 0;
	return {
		modelPrefixes,
		modelPatterns
	};
}
function normalizeActivation(raw) {
	if (!isRecord(raw)) return void 0;
	const onStartup = typeof raw.onStartup === "boolean" ? raw.onStartup : void 0;
	const onProviders = Array.isArray(raw.onProviders) ? raw.onProviders.filter((x) => typeof x === "string") : void 0;
	const onCommands = Array.isArray(raw.onCommands) ? raw.onCommands.filter((x) => typeof x === "string") : void 0;
	const onChannels = Array.isArray(raw.onChannels) ? raw.onChannels.filter((x) => typeof x === "string") : void 0;
	const capRaw = raw.onCapabilities;
	const onCapabilities = Array.isArray(capRaw) ? capRaw.filter((x) => x === "provider" || x === "channel" || x === "tool" || x === "hook") : void 0;
	if (onStartup === void 0 && !onProviders?.length && !onCommands?.length && !onChannels?.length && !onCapabilities?.length) return;
	return {
		onStartup,
		onProviders,
		onCommands,
		onChannels,
		onCapabilities
	};
}
function normalizeContracts(raw) {
	if (!isRecord(raw)) return void 0;
	const pick = (k) => Array.isArray(raw[k]) ? raw[k].filter((x) => typeof x === "string") : void 0;
	const c = {
		mediaUnderstandingProviders: pick("mediaUnderstandingProviders"),
		speechProviders: pick("speechProviders"),
		imageGenerationProviders: pick("imageGenerationProviders"),
		webSearchProviders: pick("webSearchProviders"),
		memoryProviders: pick("memoryProviders")
	};
	if (!c.mediaUnderstandingProviders?.length && !c.speechProviders?.length && !c.imageGenerationProviders?.length && !c.webSearchProviders?.length && !c.memoryProviders?.length) return;
	return c;
}
function normalizeSetup(raw) {
	if (!isRecord(raw)) return void 0;
	const requiresRuntime = typeof raw.requiresRuntime === "boolean" ? raw.requiresRuntime : void 0;
	let providers;
	if (Array.isArray(raw.providers)) {
		providers = [];
		for (const p of raw.providers) {
			if (!isRecord(p) || typeof p.id !== "string") continue;
			providers.push({
				id: p.id,
				authMethods: Array.isArray(p.authMethods) ? p.authMethods.filter((x) => typeof x === "string") : void 0,
				envVars: Array.isArray(p.envVars) ? p.envVars.filter((x) => typeof x === "string") : void 0
			});
		}
		if (providers.length === 0) providers = void 0;
	}
	if (!providers && requiresRuntime === void 0) return void 0;
	return {
		providers,
		requiresRuntime
	};
}
//#endregion
export { normalizeExtensionManifest, normalizeUiManifest };

//# sourceMappingURL=normalize-manifest.js.map