import { ae as importHostOpenCode, R as detectHostOpenCode, j as authJsonPath, p as checkDocker, n as buildComposeOptions } from './src-CidJbygh.js';
import { g as getState } from './state-fxN45gBp.js';
import { d as getRequestId, r as requireAdmin, p as parseJsonBody, e as errorResponse, k as jsonResponse } from './helpers-kzwksNq1.js';
import { w as withSerialQueue } from './serial-queue-D9FEpYVv.js';
import { o as opencodeFetch } from './http-D8YVIqJa.js';
import { c as composeRestart } from './docker-CTjWsP_Q.js';
import { existsSync, readFileSync } from 'node:fs';
import './chunk-CLZ62Ad-.js';
import 'node:module';
import './provider-constants-DPrj3yBX.js';
import './dist-DOFcG0Zp.js';
import 'node:path';
import 'buffer';
import 'fs';
import 'path';
import 'node:child_process';
import 'node:url';
import 'node:crypto';
import 'events';
import 'node:events';
import 'node:stream';
import 'node:string_decoder';
import 'assert';
import 'zlib';
import 'node:assert';
import 'node:fs/promises';
import 'node:os';
import './endpoints-UdQGgKsR.js';

//#region src/routes/admin/providers/import-host/+server.ts
/**
* POST /admin/providers/import-host
*
* Copies host OpenCode config + auth into OP_HOME, then pushes each
* imported credential to the running OpenCode server so the providers
* appear connected immediately (no restart required).
*
* - opencode.json: stripped of plugin/mcp/permission keys, merged with
*   existing OP_HOME config. Provider conflicts preserved by default.
* - auth.json: byte-copied and chmodded 0o600. Never logged.
* - Live push: best-effort PUT to OpenCode /auth/{id} per credential.
*   If OpenCode is unreachable, the file copy still applies and OpenCode
*   will pick up the credentials on next restart.
* - Service restart: assistant is restarted after the import so opencode.json
*   provider blocks are re-read (live push only updates the auth store, not
*   config).
*
* Body (optional JSON):
*   { overwriteConflicts?: boolean }   — default false
*
* Auth: admin token required.
*/
/**
* Restart services that hold provider state in startup config.
* Best-effort: the file-level import is the durable part; this is the polish
* that makes the change visible without the user having to bounce things by hand.
* OpenCode caches opencode.json provider blocks at startup, so imported
* provider config needs a fresh assistant process.
*/
async function restartProviderConsumers() {
	const services = ["assistant"];
	if (!(await checkDocker()).ok) return {
		restarted: [],
		failed: services.map((s) => ({
			service: s,
			error: "docker unavailable"
		}))
	};
	const opts = buildComposeOptions(getState());
	const restarted = [];
	const failed = [];
	for (const service of services) try {
		const r = await composeRestart([service], opts);
		if (r.ok) restarted.push(service);
		else failed.push({
			service,
			error: r.stderr || `exit ${r.code}`
		});
	} catch (err) {
		failed.push({
			service,
			error: err instanceof Error ? err.message : String(err)
		});
	}
	return {
		restarted,
		failed
	};
}
/** Push each auth.json entry to OpenCode's /auth/{id} so the running process sees them. */
async function pushAuthToOpenCode(authPath) {
	let raw;
	try {
		raw = JSON.parse(readFileSync(authPath, "utf-8"));
	} catch {
		return {
			pushed: 0,
			failed: []
		};
	}
	if (!raw || typeof raw !== "object" || Array.isArray(raw)) return {
		pushed: 0,
		failed: []
	};
	let pushed = 0;
	const failed = [];
	for (const [providerId, value] of Object.entries(raw)) try {
		await opencodeFetch(`/auth/${encodeURIComponent(providerId)}`, {
			method: "PUT",
			body: JSON.stringify(value)
		});
		pushed++;
	} catch {
		failed.push(providerId);
	}
	return {
		pushed,
		failed
	};
}
var POST = async (event) => {
	const requestId = getRequestId(event);
	const authError = requireAdmin(event, requestId);
	if (authError) return authError;
	return withSerialQueue("admin:providers:import-host", async () => {
		const state = getState();
		let overwriteConflicts = false;
		if ((event.request.headers.get("content-type") ?? "").includes("application/json")) {
			const parsed = await parseJsonBody(event.request);
			if (!("error" in parsed)) overwriteConflicts = parsed.data.overwriteConflicts === true;
		}
		let result;
		try {
			result = importHostOpenCode(state, { overwriteConflicts });
		} catch (err) {
			return errorResponse(500, "import_failed", err instanceof Error ? err.message : "Import failed", {}, requestId);
		}
		const hostStatus = detectHostOpenCode();
		let livePush = {
			pushed: 0,
			failed: []
		};
		const importedAuthPath = authJsonPath(state);
		if (existsSync(importedAuthPath)) livePush = await pushAuthToOpenCode(importedAuthPath);
		else if (hostStatus.authPath) livePush = await pushAuthToOpenCode(hostStatus.authPath);
		const restart = await restartProviderConsumers();
		return jsonResponse(200, {
			ok: true,
			imported: result.imported,
			conflicts: result.conflicts,
			livePushed: livePush.pushed,
			livePushFailed: livePush.failed,
			restarted: restart.restarted,
			restartFailed: restart.failed
		}, requestId);
	});
};

export { POST };
//# sourceMappingURL=_server.ts-CecMDzNO.js.map
