import { t as log } from "./logger-64IDYXNy.js";
import "./agent-harness-runtime-ta-eBGs-.js";
import { t as CODEX_PLUGINS_MARKETPLACE_NAME, u as resolveCodexPluginsPolicy } from "./config-Djl26ZbX.js";
import "node:path";
import "node:fs/promises";
const MAX_SERIALIZED_ERROR_MESSAGE_LENGTH = 500;
var CodexAppInventoryCache = class {
	constructor(options = {}) {
		this.entries = /* @__PURE__ */ new Map();
		this.inFlight = /* @__PURE__ */ new Map();
		this.refreshTokens = /* @__PURE__ */ new Map();
		this.diagnostics = /* @__PURE__ */ new Map();
		this.revision = 0;
		this.ttlMs = options.ttlMs ?? 36e5;
	}
	read(params) {
		const nowMs = params.nowMs ?? Date.now();
		const entry = this.entries.get(params.key);
		if (!entry) {
			const refreshScheduled = params.suppressRefresh ? false : this.scheduleRefresh(params);
			return {
				state: "missing",
				key: params.key,
				revision: this.revision,
				refreshScheduled,
				...this.diagnostics.get(params.key) ? { diagnostic: this.diagnostics.get(params.key) } : {}
			};
		}
		const state = entry.invalidated || entry.expiresAtMs <= nowMs ? "stale" : "fresh";
		const refreshScheduled = state === "fresh" && !params.forceRefetch ? false : this.scheduleRefresh(params);
		return {
			state,
			key: params.key,
			revision: entry.revision,
			snapshot: stripEntryState(entry),
			refreshScheduled,
			...entry.lastError ? { diagnostic: entry.lastError } : {}
		};
	}
	refreshNow(params) {
		return this.refresh(params);
	}
	invalidate(key, reason, nowMs = Date.now()) {
		this.revision += 1;
		const diagnostic = {
			message: reason,
			atMs: nowMs
		};
		const entry = this.entries.get(key);
		if (entry) {
			entry.invalidated = true;
			entry.lastError = diagnostic;
			entry.revision = this.revision;
		} else this.diagnostics.set(key, diagnostic);
		return this.revision;
	}
	clear() {
		this.entries.clear();
		this.inFlight.clear();
		this.refreshTokens.clear();
		this.diagnostics.clear();
		this.revision = 0;
	}
	getRevision() {
		return this.revision;
	}
	scheduleRefresh(params) {
		if (this.inFlight.has(params.key) && !params.forceRefetch) return true;
		const promise = this.refresh(params);
		this.inFlight.set(params.key, promise);
		promise.catch(() => void 0);
		return true;
	}
	async refresh(params) {
		const existing = this.inFlight.get(params.key);
		if (existing && !params.forceRefetch) return existing;
		const refreshToken = (this.refreshTokens.get(params.key) ?? 0) + 1;
		this.refreshTokens.set(params.key, refreshToken);
		const promise = this.refreshUncoalesced(params, refreshToken);
		this.inFlight.set(params.key, promise);
		try {
			return await promise;
		} finally {
			if (this.inFlight.get(params.key) === promise) this.inFlight.delete(params.key);
		}
	}
	async refreshUncoalesced(params, refreshToken) {
		const nowMs = params.nowMs ?? Date.now();
		try {
			const apps = await listAllApps(params.request, params.forceRefetch ?? false);
			this.revision += 1;
			const snapshot = {
				key: params.key,
				apps,
				fetchedAtMs: nowMs,
				expiresAtMs: nowMs + this.ttlMs,
				revision: this.revision
			};
			if (this.refreshTokens.get(params.key) === refreshToken) {
				this.entries.set(params.key, {
					...snapshot,
					invalidated: false
				});
				this.diagnostics.delete(params.key);
			}
			return snapshot;
		} catch (error) {
			const diagnostic = {
				message: sanitizeErrorMessage(error instanceof Error ? error.message : String(error)),
				atMs: nowMs
			};
			this.diagnostics.set(params.key, diagnostic);
			const entry = this.entries.get(params.key);
			if (entry) entry.lastError = diagnostic;
			log.warn("codex app inventory refresh failed", {
				forceRefetch: params.forceRefetch === true,
				keyFingerprint: fingerprintInventoryCacheKey(params.key),
				error: serializeCodexAppInventoryError(error)
			});
			throw error;
		}
	}
};
function serializeCodexAppInventoryError(error) {
	const record = isRecord(error) ? error : void 0;
	const data = record && "data" in record ? redactErrorData(record.data) : void 0;
	return {
		name: error instanceof Error ? error.name : typeof record?.name === "string" ? record.name : void 0,
		message: sanitizeErrorMessage(error instanceof Error ? error.message : String(error)),
		...typeof record?.code === "number" ? { code: record.code } : {},
		...data !== void 0 ? { data } : {}
	};
}
const defaultCodexAppInventoryCache = new CodexAppInventoryCache();
function buildCodexAppInventoryCacheKey(input) {
	return JSON.stringify({
		codexHome: input.codexHome ?? null,
		endpoint: input.endpoint ?? null,
		authProfileId: input.authProfileId ?? null,
		accountId: input.accountId ?? null,
		envApiKeyFingerprint: input.envApiKeyFingerprint ?? null,
		appServerVersion: input.appServerVersion ?? null
	});
}
async function listAllApps(request, forceRefetch) {
	const apps = [];
	let cursor;
	do {
		const response = await request("app/list", {
			cursor,
			limit: 100,
			forceRefetch
		});
		apps.push(...response.data);
		cursor = response.nextCursor;
	} while (cursor);
	return apps;
}
function stripEntryState(entry) {
	const { invalidated: _invalidated, ...snapshot } = entry;
	return snapshot;
}
function fingerprintInventoryCacheKey(key) {
	let hash = 0;
	for (let index = 0; index < key.length; index += 1) hash = hash * 31 + key.charCodeAt(index) >>> 0;
	return hash.toString(16).padStart(8, "0");
}
function isRecord(value) {
	return Boolean(value && typeof value === "object" && !Array.isArray(value));
}
function redactErrorData(value, depth = 0) {
	if (value === void 0) return;
	if (value === null || typeof value === "boolean" || typeof value === "number") return value;
	if (depth > 6) return "[truncated]";
	if (Array.isArray(value)) return value.map((entry) => redactErrorData(entry, depth + 1) ?? null);
	if (isRecord(value)) {
		const redacted = {};
		for (const [key, entry] of Object.entries(value)) redacted[key] = isSensitiveErrorDataKey(key) ? "<redacted>" : redactErrorData(entry, depth + 1) ?? null;
		return redacted;
	}
	if (typeof value === "string" && value.length > 500) return `${value.slice(0, 500)}...`;
	if (typeof value === "string") return value;
	if (typeof value === "bigint") return value.toString();
	if (typeof value === "symbol") return value.description ? `Symbol(${value.description})` : "Symbol()";
	if (typeof value === "function") return value.name ? `[function ${value.name}]` : "[function]";
	return "[unserializable]";
}
function sanitizeErrorMessage(message) {
	const htmlStart = message.search(/<html[\s>]/i);
	const redacted = (htmlStart >= 0 ? `${message.slice(0, htmlStart).trimEnd()} [HTML response body omitted]` : message).replace(/([?&][^=\s"'<>]*(?:api[_-]?key|authorization|cookie|credential|password|secret|token|tk)[^=\s"'<>]*=)[^&\s"'<>]+/gi, "$1<redacted>");
	return redacted.length > MAX_SERIALIZED_ERROR_MESSAGE_LENGTH ? `${redacted.slice(0, MAX_SERIALIZED_ERROR_MESSAGE_LENGTH)}...` : redacted;
}
function isSensitiveErrorDataKey(key) {
	return /api[_-]?key|authorization|cookie|credential|password|secret|token/i.test(key);
}
//#endregion
//#region extensions/codex/src/app-server/plugin-inventory.ts
async function readCodexPluginInventory(params) {
	const policy = params.policy ?? resolveCodexPluginsPolicy(params.pluginConfig);
	if (!policy.enabled) return {
		policy,
		records: [],
		diagnostics: [{
			code: "disabled",
			message: "Native Codex plugin support is disabled."
		}]
	};
	const appInventory = readCachedAppInventory(params);
	const marketplaceEntry = (await params.request("plugin/list", { cwds: [] })).marketplaces.find((marketplace) => marketplace.name === CODEX_PLUGINS_MARKETPLACE_NAME);
	if (!marketplaceEntry) return {
		policy,
		records: [],
		diagnostics: policy.pluginPolicies.filter((pluginPolicy) => pluginPolicy.enabled).map((pluginPolicy) => ({
			code: "marketplace_missing",
			plugin: pluginPolicy,
			message: `Codex marketplace ${CODEX_PLUGINS_MARKETPLACE_NAME} was not found.`
		})),
		...appInventory ? { appInventory } : {}
	};
	const marketplace = marketplaceRef(marketplaceEntry);
	const diagnostics = [];
	const records = [];
	if (appInventory?.state === "missing") diagnostics.push({
		code: "app_inventory_missing",
		message: "Cached Codex app inventory is missing; plugin apps are excluded for this setup."
	});
	else if (appInventory?.state === "stale") diagnostics.push({
		code: "app_inventory_stale",
		message: "Cached Codex app inventory is stale; using stale app readiness and refreshing."
	});
	for (const pluginPolicy of policy.pluginPolicies) {
		if (!pluginPolicy.enabled) continue;
		const summary = findPluginSummary(marketplaceEntry, pluginPolicy.pluginName);
		if (!summary) {
			diagnostics.push({
				code: "plugin_missing",
				plugin: pluginPolicy,
				message: `${pluginPolicy.pluginName} was not found in ${CODEX_PLUGINS_MARKETPLACE_NAME}.`
			});
			continue;
		}
		const detail = await readPluginDetail(params, marketplace, pluginPolicy, diagnostics);
		const ownedAppIds = detail?.apps.map((app) => app.id).filter(Boolean).toSorted() ?? [];
		const appOwnership = resolveAppOwnership({
			detail,
			appInventory,
			summary
		});
		if (appOwnership === "ambiguous") diagnostics.push({
			code: "app_ownership_ambiguous",
			plugin: pluginPolicy,
			message: `${pluginPolicy.pluginName} has only display-name app matches; apps are not exposed until ownership is stable.`
		});
		if (summary.installed && !summary.enabled) diagnostics.push({
			code: "plugin_disabled",
			plugin: pluginPolicy,
			message: `${pluginPolicy.pluginName} is installed in Codex but disabled.`
		});
		const apps = resolveOwnedApps({
			pluginPolicy,
			detail,
			appInventory
		});
		records.push({
			policy: pluginPolicy,
			summary,
			...detail ? { detail } : {},
			activationRequired: !summary.installed || !summary.enabled,
			authRequired: apps.some((app) => app.needsAuth || !app.accessible),
			appOwnership,
			ownedAppIds,
			apps
		});
	}
	return {
		policy,
		marketplace,
		records,
		diagnostics,
		...appInventory ? { appInventory } : {}
	};
}
function findOpenAiCuratedPluginSummary(listed, pluginName) {
	const marketplaceEntry = listed.marketplaces.find((marketplace) => marketplace.name === CODEX_PLUGINS_MARKETPLACE_NAME);
	if (!marketplaceEntry) return;
	const summary = findPluginSummary(marketplaceEntry, pluginName);
	return summary ? {
		marketplace: marketplaceRef(marketplaceEntry),
		summary
	} : void 0;
}
function pluginReadParams(marketplace, pluginName) {
	return {
		...marketplace.path ? { marketplacePath: marketplace.path } : {},
		...marketplace.remoteMarketplaceName ? { remoteMarketplaceName: marketplace.remoteMarketplaceName } : {},
		pluginName
	};
}
function readCachedAppInventory(params) {
	if (!params.appCache || !params.appCacheKey) return;
	const request = async (method, requestParams) => await params.request(method, requestParams);
	return params.appCache.read({
		key: params.appCacheKey,
		request,
		nowMs: params.nowMs,
		suppressRefresh: params.suppressAppInventoryRefresh
	});
}
async function readPluginDetail(params, marketplace, pluginPolicy, diagnostics) {
	if (params.readPluginDetails === false) return;
	try {
		return (await params.request("plugin/read", pluginReadParams(marketplace, pluginPolicy.pluginName))).plugin;
	} catch (error) {
		diagnostics.push({
			code: "plugin_detail_unavailable",
			plugin: pluginPolicy,
			message: `${pluginPolicy.pluginName} detail unavailable: ${error instanceof Error ? error.message : String(error)}`
		});
		return;
	}
}
function resolveAppOwnership(params) {
	if (params.detail && params.detail.apps.length > 0) return "proven";
	return (params.appInventory?.snapshot?.apps ?? []).filter((app) => app.pluginDisplayNames.some((displayName) => displayName === params.summary.name)).length > 0 ? "ambiguous" : "none";
}
function resolveOwnedApps(params) {
	const detailApps = params.detail?.apps ?? [];
	if (detailApps.length === 0) return [];
	if (params.appInventory?.state === "missing") {
		log.warn("codex plugin inventory missing app inventory for detail apps", {
			configKey: params.pluginPolicy.configKey,
			pluginName: params.pluginPolicy.pluginName,
			appIds: detailApps.map((app) => app.id).toSorted()
		});
		return [];
	}
	const appInfoById = new Map((params.appInventory?.snapshot?.apps ?? []).map((app) => [app.id, app]));
	return detailApps.map((app) => {
		const info = appInfoById.get(app.id);
		if (!info) return {
			id: app.id,
			name: app.name,
			accessible: false,
			enabled: false,
			needsAuth: true
		};
		return {
			id: app.id,
			name: app.name,
			accessible: info.isAccessible,
			enabled: info.isEnabled,
			needsAuth: app.needsAuth || !info.isAccessible
		};
	}).toSorted((left, right) => left.id.localeCompare(right.id));
}
function findPluginSummary(marketplace, pluginName) {
	return marketplace.plugins.find((plugin) => plugin.name === pluginName || plugin.id === pluginName || plugin.id === `${pluginName}@${marketplace.name}` || pluginNameFromPluginId(plugin.id, marketplace.name) === pluginName);
}
function pluginNameFromPluginId(pluginId, marketplaceName) {
	const trimmed = pluginId.trim();
	if (!trimmed) return;
	const marketplaceSuffix = `@${marketplaceName}`;
	return (trimmed.endsWith(marketplaceSuffix) ? trimmed.slice(0, -marketplaceSuffix.length) : trimmed).split("/").at(-1)?.trim() || void 0;
}
function marketplaceRef(marketplace) {
	return {
		name: CODEX_PLUGINS_MARKETPLACE_NAME,
		...marketplace.path ? { path: marketplace.path } : {},
		...!marketplace.path ? { remoteMarketplaceName: marketplace.name } : {}
	};
}
//#endregion
//#region extensions/codex/src/app-server/plugin-activation.ts
async function ensureCodexPluginActivation(params) {
	if (params.identity.marketplaceName !== "openai-curated") return activationFailure(params.identity, "marketplace_missing", { message: "Only " + CODEX_PLUGINS_MARKETPLACE_NAME + " plugins can be activated." });
	const listed = await params.request("plugin/list", { cwds: [] });
	const resolved = findOpenAiCuratedPluginSummary(listed, params.identity.pluginName);
	if (!resolved) {
		if (!listed.marketplaces.some((marketplace) => marketplace.name === "openai-curated")) return activationFailure(params.identity, "marketplace_missing", { message: `Codex marketplace ${CODEX_PLUGINS_MARKETPLACE_NAME} was not found.` });
		return activationFailure(params.identity, "plugin_missing", { message: `${params.identity.pluginName} was not found in ${CODEX_PLUGINS_MARKETPLACE_NAME}.` });
	}
	if (resolved.summary.installed && resolved.summary.enabled && !params.installEvenIfActive) return {
		identity: params.identity,
		ok: true,
		reason: "already_active",
		installAttempted: false,
		marketplace: resolved.marketplace,
		diagnostics: []
	};
	const installResponse = await params.request("plugin/install", pluginReadParams(resolved.marketplace, params.identity.pluginName));
	const refreshDiagnostics = [];
	let refreshFailed = false;
	try {
		const refreshResult = await refreshCodexPluginRuntimeState({
			request: params.request,
			appCache: params.appCache,
			appCacheKey: params.appCacheKey
		});
		refreshDiagnostics.push(...refreshResult.diagnostics);
	} catch (error) {
		refreshFailed = true;
		refreshDiagnostics.push({ message: `Codex plugin runtime refresh failed after install: ${error instanceof Error ? error.message : String(error)}` });
	}
	const authRequired = installResponse.appsNeedingAuth.length > 0;
	return {
		identity: params.identity,
		ok: !authRequired && !refreshFailed,
		reason: refreshFailed ? "refresh_failed" : authRequired ? "auth_required" : resolved.summary.installed && resolved.summary.enabled ? "already_active" : "installed",
		installAttempted: true,
		marketplace: resolved.marketplace,
		installResponse,
		diagnostics: [...refreshDiagnostics, ...installResponse.appsNeedingAuth.map((app) => ({ message: `${app.name} requires app authentication before plugin tools are exposed.` }))]
	};
}
async function refreshCodexPluginRuntimeState(params) {
	const diagnostics = [];
	await params.request("plugin/list", { cwds: [] });
	await params.request("skills/list", {
		cwds: [],
		forceReload: true
	});
	try {
		await params.request("hooks/list", { cwds: [] });
	} catch (error) {
		diagnostics.push({ message: `Codex hooks refresh skipped: ${error instanceof Error ? error.message : String(error)}` });
	}
	await params.request("config/mcpServer/reload", void 0);
	if (params.appCache && params.appCacheKey) {
		params.appCache.invalidate(params.appCacheKey, "Codex plugin activation changed app inventory");
		const request = async (method, requestParams) => await params.request(method, requestParams);
		try {
			await params.appCache.refreshNow({
				key: params.appCacheKey,
				request,
				forceRefetch: true
			});
		} catch (error) {
			diagnostics.push({ message: `Codex app inventory refresh skipped: ${error instanceof Error ? error.message : String(error)}` });
		}
	}
	return { diagnostics };
}
function activationFailure(identity, reason, diagnostic) {
	return {
		identity,
		ok: false,
		reason,
		installAttempted: false,
		diagnostics: [diagnostic]
	};
}
//#endregion
export { defaultCodexAppInventoryCache as a, buildCodexAppInventoryCacheKey as i, pluginReadParams as n, serializeCodexAppInventoryError as o, readCodexPluginInventory as r, ensureCodexPluginActivation as t };
