import { b as getLogger } from './paths-2M_UxD_H.js';
import { existsSync, readdirSync, readFileSync } from 'node:fs';
import { resolve, join } from 'node:path';
import { execFileSync } from 'node:child_process';
import { h as hooks } from './registry2-BSyCTA3q.js';

//#region ../core/dist/adapters/discovery.js
/**
* Adapter discovery: scans packages/adapters/ for installed provider adapters.
* Reads adapter manifests and detects active providers in the current environment.
*
* @task T5240
*/
/**
* Scan the packages/adapters/ directory for adapter packages.
* Each adapter must have a manifest.json at its root.
*/
function discoverAdapterManifests(projectRoot) {
	const adaptersDir = resolve(projectRoot, "packages", "adapters");
	if (!existsSync(adaptersDir)) return [];
	const manifests = [];
	let entries;
	try {
		entries = readdirSync(adaptersDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
	} catch {
		return [];
	}
	for (const dir of entries) {
		const adapterDir = join(adaptersDir, dir);
		const manifestPath = join(adapterDir, "manifest.json");
		if (!existsSync(manifestPath)) continue;
		try {
			const raw = readFileSync(manifestPath, "utf-8");
			const manifest = JSON.parse(raw);
			manifest.packagePath = resolve(adapterDir);
			manifests.push(manifest);
		} catch {}
	}
	return manifests;
}
/**
* Detect whether a provider is active in the current environment
* by checking its detection patterns.
*/
function detectProvider(patterns) {
	for (const pattern of patterns) if (matchDetectionPattern(pattern)) return true;
	return false;
}
function matchDetectionPattern(pattern) {
	switch (pattern.type) {
		case "env": return process.env[pattern.pattern] !== void 0;
		case "file": return existsSync(pattern.pattern);
		case "process": {
			const processName = pattern.pattern.toLowerCase();
			return (process.env.TERM_PROGRAM ?? "").toLowerCase().includes(processName) || (process.env.EDITOR ?? "").toLowerCase().includes(processName);
		}
		case "cli": try {
			execFileSync("which", [pattern.pattern], {
				stdio: "ignore",
				timeout: 3e3
			});
			return true;
		} catch {
			return false;
		}
		default: return false;
	}
}

//#region ../core/dist/adapters/adapter-registry.js
/**
* Dynamic adapter loading utilities.
*
* Replaces the former static ADAPTER_REGISTRY with discovery-based loading.
* Adapters are found via discoverAdapterManifests() and loaded dynamically
* using each manifest's packagePath and entryPoint.
*
* Zero hardcoded adapter package names — everything derives from manifests.
*
* @task T5698
*/
/**
* Validate that a loaded module export implements the CLEOProviderAdapter interface.
* Checks for required methods and properties without relying on instanceof.
*/
function isValidAdapter(adapter) {
	if (adapter === null || typeof adapter !== "object") return false;
	const obj = adapter;
	return typeof obj.id === "string" && typeof obj.name === "string" && typeof obj.version === "string" && typeof obj.initialize === "function" && typeof obj.dispose === "function" && typeof obj.healthCheck === "function" && obj.capabilities !== null && typeof obj.capabilities === "object";
}
/**
* Dynamically load and instantiate an adapter from its manifest.
*
* Uses the manifest's packagePath to resolve the adapter module,
* then looks for a `createAdapter()` factory or a default export class.
*
* @param manifest - The adapter manifest with a resolved packagePath
* @returns A CLEOProviderAdapter instance
* @throws If the module cannot be loaded or does not export a valid adapter
*/
async function loadAdapterFromManifest(manifest) {
	const adapterModule = await import(join(manifest.packagePath, manifest.entryPoint));
	if (typeof adapterModule.createAdapter === "function") {
		const adapter = adapterModule.createAdapter();
		if (isValidAdapter(adapter)) return adapter;
		throw new Error(`createAdapter() in ${manifest.id} did not return a valid CLEOProviderAdapter`);
	}
	if (adapterModule.default) {
		const DefaultExport = adapterModule.default;
		if (typeof DefaultExport === "function") {
			const adapter = new DefaultExport();
			if (isValidAdapter(adapter)) return adapter;
		} else if (isValidAdapter(DefaultExport)) return DefaultExport;
	}
	throw new Error(`Adapter module for ${manifest.id} does not export createAdapter() or a valid default`);
}
//#endregion
//#region ../core/dist/adapters/manager.js
/**
* AdapterManager: central registry for provider adapters.
* Handles adapter lifecycle (discovery, initialization, health, disposal)
* and tracks the active adapter for the current session.
*
* @task T5240
*/
var log = getLogger("adapter-manager");
/**
* Central adapter manager. Singleton per process.
*
* Lifecycle:
*   1. discover() — scan for adapter packages and their manifests
*   2. activate(id) — load, initialize, and set as active adapter
*   3. getActive() — return the current active adapter
*   4. dispose() — clean up all initialized adapters
*/
var AdapterManager = class AdapterManager {
	static instance = null;
	adapters = /* @__PURE__ */ new Map();
	manifests = /* @__PURE__ */ new Map();
	hookCleanups = /* @__PURE__ */ new Map();
	activeId = null;
	projectRoot;
	constructor(projectRoot) {
		this.projectRoot = projectRoot;
	}
	static getInstance(projectRoot) {
		if (!AdapterManager.instance) AdapterManager.instance = new AdapterManager(projectRoot);
		return AdapterManager.instance;
	}
	/** Reset singleton (for testing). */
	static resetInstance() {
		AdapterManager.instance = null;
	}
	/**
	* Discover adapter manifests from packages/adapters/.
	* Returns manifests found (does not load adapter code yet).
	*/
	discover() {
		const found = discoverAdapterManifests(this.projectRoot);
		for (const manifest of found) this.manifests.set(manifest.id, manifest);
		log.info({ count: found.length }, "Discovered adapter manifests");
		return found;
	}
	/**
	* Auto-detect which adapters match the current environment
	* and return their manifest IDs.
	*/
	detectActive() {
		const detected = [];
		for (const [id, manifest] of this.manifests) if (detectProvider(manifest.detectionPatterns)) detected.push(id);
		log.info({ detected }, "Detected active providers");
		return detected;
	}
	/**
	* Load and initialize an adapter by manifest ID.
	* Dynamically imports from the manifest's packagePath — no hardcoded adapters.
	*/
	async activate(adapterId) {
		const manifest = this.manifests.get(adapterId);
		if (!manifest) throw new Error(`Adapter manifest not found: ${adapterId}`);
		const existing = this.adapters.get(adapterId);
		if (existing) {
			this.activeId = adapterId;
			return existing;
		}
		try {
			const adapter = await loadAdapterFromManifest(manifest);
			await adapter.initialize(this.projectRoot);
			this.adapters.set(adapterId, adapter);
			this.activeId = adapterId;
			if (adapter.hooks) await this.wireAdapterHooks(adapterId, adapter);
			log.info({
				adapterId,
				provider: manifest.provider
			}, "Adapter activated");
			return adapter;
		} catch (err) {
			log.error({
				adapterId,
				err
			}, "Failed to activate adapter");
			throw err;
		}
	}
	/** Get the currently active adapter, or null if none. */
	getActive() {
		if (!this.activeId) return null;
		return this.adapters.get(this.activeId) ?? null;
	}
	/** Get the active adapter's ID, or null. */
	getActiveId() {
		return this.activeId;
	}
	/** Get a specific adapter by ID. */
	get(adapterId) {
		return this.adapters.get(adapterId) ?? null;
	}
	/** Get the manifest for a specific adapter. */
	getManifest(adapterId) {
		return this.manifests.get(adapterId) ?? null;
	}
	/** List all known adapters with summary info. */
	listAdapters() {
		const result = [];
		for (const [id, manifest] of this.manifests) {
			const adapter = this.adapters.get(id);
			result.push({
				id,
				name: manifest.name,
				version: manifest.version,
				provider: manifest.provider,
				healthy: !!adapter,
				active: id === this.activeId
			});
		}
		return result;
	}
	/** Run health check on all initialized adapters. */
	async healthCheckAll() {
		const results = /* @__PURE__ */ new Map();
		for (const [id, adapter] of this.adapters) try {
			const status = await adapter.healthCheck();
			results.set(id, status);
		} catch (err) {
			results.set(id, {
				healthy: false,
				provider: this.manifests.get(id)?.provider ?? "unknown",
				details: { error: err instanceof Error ? err.message : String(err) }
			});
		}
		return results;
	}
	/** Health check a single adapter. */
	async healthCheck(adapterId) {
		const adapter = this.adapters.get(adapterId);
		if (!adapter) return {
			healthy: false,
			provider: this.manifests.get(adapterId)?.provider ?? "unknown",
			details: { error: "Adapter not initialized" }
		};
		try {
			return await adapter.healthCheck();
		} catch (err) {
			return {
				healthy: false,
				provider: this.manifests.get(adapterId)?.provider ?? "unknown",
				details: { error: err instanceof Error ? err.message : String(err) }
			};
		}
	}
	/** Dispose all initialized adapters. */
	async dispose() {
		for (const [id, adapter] of this.adapters) try {
			await this.cleanupAdapterHooks(id, adapter);
			await adapter.dispose();
			log.info({ adapterId: id }, "Adapter disposed");
		} catch (err) {
			log.error({
				adapterId: id,
				err
			}, "Failed to dispose adapter");
		}
		this.adapters.clear();
		this.hookCleanups.clear();
		this.activeId = null;
	}
	/** Dispose a single adapter. */
	async disposeAdapter(adapterId) {
		const adapter = this.adapters.get(adapterId);
		if (!adapter) return;
		try {
			await this.cleanupAdapterHooks(adapterId, adapter);
			await adapter.dispose();
		} catch (err) {
			log.error({
				adapterId,
				err
			}, "Failed to dispose adapter");
		}
		this.adapters.delete(adapterId);
		if (this.activeId === adapterId) this.activeId = null;
	}
	/**
	* Wire an adapter's hook event map into CLEO's HookRegistry.
	* Creates bridging handlers at priority 50 for each mapped event.
	*/
	async wireAdapterHooks(adapterId, adapter) {
		if (!adapter.hooks) return;
		try {
			await adapter.hooks.registerNativeHooks(this.projectRoot);
		} catch (err) {
			log.error({
				adapterId,
				err
			}, "Failed to register native hooks");
		}
		const eventMap = adapter.hooks.getEventMap?.();
		if (!eventMap) return;
		const cleanups = [];
		for (const [_providerEvent, caampEvent] of Object.entries(eventMap)) {
			const hookId = `adapter-${adapterId}-${caampEvent}`;
			const unregister = hooks.register({
				id: hookId,
				event: caampEvent,
				priority: 50,
				handler: async (_projectRoot, payload) => {
					log.debug({
						adapterId,
						event: caampEvent,
						payload
					}, "Adapter hook dispatched");
				}
			});
			cleanups.push(unregister);
		}
		this.hookCleanups.set(adapterId, cleanups);
	}
	/**
	* Clean up hook registrations for an adapter.
	*/
	async cleanupAdapterHooks(adapterId, adapter) {
		const cleanups = this.hookCleanups.get(adapterId);
		if (cleanups) {
			for (const fn of cleanups) fn();
			this.hookCleanups.delete(adapterId);
		}
		try {
			await adapter.hooks?.unregisterNativeHooks();
		} catch (err) {
			log.error({
				adapterId,
				err
			}, "Failed to unregister native hooks");
		}
	}
};

export { AdapterManager as A };
//# sourceMappingURL=adapters-D2gEs_5L.js.map
