import { j as authJsonPath } from './src-CidJbygh.js';
import { g as getState } from './state-fxN45gBp.js';
import { b as asRecord, c as asString, a as asNumber, e as asStringRecord, d as asStringArray } from './coercion-TNFJisCC.js';
import { o as opencodeFetch } from './http-D8YVIqJa.js';
import { g as getCurrentConfig } from './config-CO8OSXtU.js';
import { existsSync, readFileSync } from 'node:fs';

//#region src/lib/server/opencode/catalog.ts
/**
* Provider catalog assembly.
*
* Pulls catalog/auth/config/configured-provider data from the OpenCode server
* (and the on-disk config), merges them, and emits ProviderView records the
* UI renders directly.
*/
/**
* Map of provider ID → credential type, as found in OpenCode's auth.json.
* OpenCode's /provider response only reports env-var-detected providers in
* `connected`; auth.json-stored credentials (API keys + OAuth tokens) are
* loaded on-demand and don't appear there. We surface them here so the UI
* can treat them as connected and show the right badge.
*/
function readAuthedProviders() {
	const out = /* @__PURE__ */ new Map();
	try {
		const path = authJsonPath(getState());
		if (!existsSync(path)) return out;
		const data = JSON.parse(readFileSync(path, "utf-8"));
		for (const [id, entry] of Object.entries(data ?? {})) {
			const type = entry?.type === "oauth" ? "oauth" : "api";
			out.set(id, type);
		}
	} catch {}
	return out;
}
async function loadProviderPage() {
	try {
		const [catalog, auth, ocConfig, configured] = await Promise.all([
			opencodeFetch("/provider"),
			opencodeFetch("/provider/auth"),
			opencodeFetch("/config"),
			opencodeFetch("/config/providers")
		]);
		const diskConfig = await getCurrentConfig();
		const config = {
			...ocConfig,
			provider: {
				...ocConfig.provider ?? {},
				...diskConfig.provider ?? {}
			},
			disabled_providers: diskConfig.disabled_providers ?? ocConfig.disabled_providers,
			enabled_providers: diskConfig.enabled_providers ?? ocConfig.enabled_providers
		};
		const views = buildProviderViews(catalog, auth, config, configured, readAuthedProviders());
		return {
			available: true,
			providers: views,
			currentModel: config.model,
			currentSmallModel: config.small_model,
			defaultModels: catalog.default,
			allowlistActive: Array.isArray(config.enabled_providers) && config.enabled_providers.length > 0,
			providerCountLabel: `${views.length} providers indexed from OpenCode`,
			stats: {
				total: views.length,
				connected: views.filter((p) => p.connected).length,
				configured: views.filter((p) => p.configured).length,
				disabled: views.filter((p) => p.disabled).length
			}
		};
	} catch (error) {
		return {
			available: false,
			error: error instanceof Error ? error.message : "Unable to reach the OpenCode server.",
			providers: [],
			defaultModels: {},
			allowlistActive: false,
			providerCountLabel: "The OpenCode server is currently unavailable.",
			stats: {
				total: 0,
				connected: 0,
				configured: 0,
				disabled: 0
			}
		};
	}
}
async function loadSetupProviderPage() {
	try {
		const [catalog, auth] = await Promise.all([opencodeFetch("/provider"), opencodeFetch("/provider/auth")]);
		return {
			available: true,
			providers: Array.isArray(catalog.all) ? catalog.all : [],
			auth,
			connected: Array.from(new Set([...catalog.connected ?? [], ...readConnectedProviderIdsFromAuthJson()])),
			selectedModels: readSelectedModels()
		};
	} catch {
		return {
			available: false,
			providers: []
		};
	}
}
function readSelectedModels() {
	try {
		const path = `${getState().configDir}/assistant/opencode.json`;
		if (!existsSync(path)) return {};
		const data = JSON.parse(readFileSync(path, "utf-8"));
		return {
			...typeof data.model === "string" && data.model ? { llm: data.model } : {},
			...typeof data.small_model === "string" && data.small_model ? { small: data.small_model } : {}
		};
	} catch {
		return {};
	}
}
function readConnectedProviderIdsFromAuthJson() {
	try {
		const path = authJsonPath(getState());
		if (!existsSync(path)) return [];
		const data = JSON.parse(readFileSync(path, "utf-8"));
		return Object.keys(data ?? {});
	} catch {
		return [];
	}
}
function extractAndSortModels(...sources) {
	let entries = {};
	for (const source of sources) {
		const record = asModelRecord(source);
		if (record) {
			entries = record;
			break;
		}
	}
	return Object.entries(entries).map(([id, model]) => ({
		id,
		name: model.name ?? id
	})).sort((left, right) => left.name.localeCompare(right.name));
}
function buildProviderViews(catalog, auth, config, configured, authed) {
	const catalogMap = new Map(catalog.all.map((p) => [p.id, p]));
	const envConnected = new Set(catalog.connected);
	const connected = new Set([...envConnected, ...authed.keys()]);
	const disabled = new Set(config.disabled_providers ?? []);
	const allowlist = config.enabled_providers ? new Set(config.enabled_providers) : void 0;
	const configuredMap = new Map(configured.providers.map((p) => [p.id, p]));
	const providerIds = new Set([
		...catalog.all.map((p) => p.id),
		...Object.keys(config.provider ?? {}),
		...configured.providers.map((p) => p.id)
	]);
	return Array.from(providerIds).map((providerId) => {
		const entry = catalogMap.get(providerId);
		const configEntry = asRecord(config.provider?.[providerId]);
		const resolvedEntry = configuredMap.get(providerId);
		const rawOptions = {
			...asRecord(resolvedEntry?.options),
			...asRecord(configEntry?.options)
		};
		const authMethods = (auth[providerId] ?? []).map((method, index) => ({
			index,
			type: method.type,
			label: method.label,
			prompts: method.prompts ?? []
		}));
		const models = extractAndSortModels(resolvedEntry?.models, configEntry?.models, entry?.models);
		const currentModelId = splitModel(config.model, providerId);
		const currentSmallModelId = splitModel(config.small_model, providerId);
		const enabled = allowlist ? allowlist.has(providerId) && !disabled.has(providerId) : !disabled.has(providerId);
		const isConnected = connected.has(providerId);
		const isEnvConnected = envConnected.has(providerId);
		const authedType = authed.get(providerId);
		const credentialType = !isConnected ? void 0 : isEnvConnected ? "env" : authedType ? authedType : configEntry ? "config" : "custom";
		return {
			id: providerId,
			name: resolvedEntry?.name ?? asString(configEntry?.name) ?? entry?.name ?? providerId,
			source: resolvedEntry?.source ?? (entry ? configEntry ? "config" : "catalog" : "custom"),
			env: resolvedEntry?.env ?? asStringArray(configEntry?.env) ?? entry?.env ?? [],
			connected: isConnected,
			configured: Boolean(resolvedEntry || configEntry),
			disabled: !enabled,
			activeMainModel: Boolean(currentModelId),
			activeSmallModel: Boolean(currentSmallModelId),
			recommendedModelId: currentModelId ?? configured.default[providerId] ?? catalog.default[providerId] ?? models[0]?.id ?? "",
			modelCount: models.length,
			models,
			authMethods,
			credentialType,
			options: {
				baseURL: asString(rawOptions.baseURL),
				headers: asStringRecord(rawOptions.headers),
				timeout: asNumber(rawOptions.timeout),
				setCacheKey: rawOptions.setCacheKey === true,
				enterpriseUrl: asString(rawOptions.enterpriseUrl)
			},
			supportsOauth: authMethods.some((m) => m.type === "oauth"),
			supportsApiAuth: authMethods.some((m) => m.type === "api")
		};
	}).sort((left, right) => {
		if (left.connected !== right.connected) return left.connected ? -1 : 1;
		if (left.activeMainModel !== right.activeMainModel) return left.activeMainModel ? -1 : 1;
		if (left.configured !== right.configured) return left.configured ? -1 : 1;
		if (left.disabled !== right.disabled) return left.disabled ? 1 : -1;
		return left.name.localeCompare(right.name);
	});
}
function splitModel(model, providerId) {
	if (!model?.startsWith(`${providerId}/`)) return void 0;
	return model.slice(providerId.length + 1);
}
function asModelRecord(value) {
	return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
}

export { loadSetupProviderPage as a, loadProviderPage as l };
//# sourceMappingURL=catalog-DEv1nsOT.js.map
