import { g as resolveStateDir } from "./paths-mmi2xb99.js";
import { m as resolveUserPath } from "./utils-3Lue6wVm.js";
import { r as loadConfig } from "./config-VoJVjSgT.js";
import { c as resolveDefaultAgentId, s as resolveAgentWorkspaceDir } from "./agent-scope-u760_XKU.js";
import { i as normalizeRuntimeAttachmentPolicy } from "./access-policy-Bz60GPHK.js";
import fs from "node:fs";
import path from "node:path";
import { execFileSync } from "node:child_process";
import YAML from "yaml";

//#region ../../src/knowledge/disciplines.ts
function nowIso() {
	return (/* @__PURE__ */ new Date()).toISOString();
}
function resolveDefaultWorkspaceDir() {
	const cfg = loadConfig();
	return resolveAgentWorkspaceDir(cfg, resolveDefaultAgentId(cfg));
}
function resolveDisciplineSourceDir(workspaceDir = resolveDefaultWorkspaceDir()) {
	return path.join(resolveUserPath(workspaceDir), "knowledge", "disciplines");
}
function resolveDisciplineRegistryPath(stateDir = resolveStateDir(process.env)) {
	return path.join(stateDir, "knowledge", "disciplines.json");
}
function asRecord(value) {
	return value && typeof value === "object" && !Array.isArray(value) ? value : null;
}
function stringValue(value) {
	return typeof value === "string" && value.trim() ? value.trim() : void 0;
}
function stringArray(value) {
	if (!Array.isArray(value)) return [];
	return Array.from(new Set(value.map((entry) => stringValue(entry)).filter((entry) => !!entry)));
}
function selectedCollections(value) {
	if (!Array.isArray(value)) return [];
	const out = [];
	for (const entry of value) {
		if (typeof entry === "string" && entry.trim()) {
			out.push(entry.trim());
			continue;
		}
		const record = asRecord(entry);
		const collectionId = record ? stringValue(record.collectionId) ?? stringValue(record.id) : void 0;
		if (collectionId) out.push(collectionId);
	}
	return Array.from(new Set(out));
}
function artifactKindsFromPaths(paths) {
	return Array.from(new Set(paths.map((entry) => path.basename(entry).replace(/\.[^.]+$/, "").trim()).filter(Boolean)));
}
function discoverArtifactPaths(disciplineDir) {
	const artifactsDir = path.join(disciplineDir, "artifacts");
	if (!fs.existsSync(artifactsDir)) return [];
	return fs.readdirSync(artifactsDir, { withFileTypes: true }).filter((entry) => entry.isFile()).map((entry) => path.join(artifactsDir, entry.name)).sort();
}
function parseDisciplineYaml(filePath) {
	const raw = fs.readFileSync(filePath, "utf8");
	const record = asRecord(YAML.parse(raw));
	if (!record) throw new Error("discipline.yaml must contain an object");
	return record;
}
function disciplineQmdCollections(id, disciplineDir) {
	const collectionBase = id.startsWith("discipline-") ? id : `discipline-${id}`;
	return [{
		id: `${collectionBase}-source`,
		role: "source",
		path: disciplineDir,
		mask: "**/*.md"
	}, {
		id: `${collectionBase}-artifacts`,
		role: "artifacts",
		path: path.join(disciplineDir, "artifacts"),
		mask: "**/*.md"
	}];
}
function updateQmdCollection(collection, issues) {
	if (!fs.existsSync(collection.path)) {
		if (collection.role === "artifacts") return false;
		issues.push({
			level: "warning",
			path: collection.path,
			message: `QMD collection path does not exist: ${collection.path}`
		});
		return false;
	}
	const removeCandidates = [collection.id];
	const legacyDuplicatePrefix = collection.id.startsWith("discipline-") ? `discipline-${collection.id}` : void 0;
	if (legacyDuplicatePrefix) removeCandidates.push(legacyDuplicatePrefix);
	for (const candidate of Array.from(new Set(removeCandidates))) try {
		execFileSync("qmd", [
			"collection",
			"remove",
			candidate
		], { stdio: "ignore" });
	} catch {}
	try {
		execFileSync("qmd", [
			"collection",
			"add",
			collection.path,
			"--name",
			collection.id,
			"--mask",
			collection.mask
		], { stdio: "ignore" });
		return true;
	} catch (err) {
		try {
			execFileSync("qmd", [
				"update",
				"-c",
				collection.id
			], { stdio: "ignore" });
			return true;
		} catch {
			issues.push({
				level: "warning",
				path: collection.path,
				message: `Failed to update QMD collection ${collection.id}: ${err instanceof Error ? err.message : String(err)}`
			});
			return false;
		}
	}
}
function normalizeStatus(value) {
	return stringValue(value) ?? "draft";
}
function normalizeRuntimePolicy(value) {
	const raw = typeof value === "string" ? value : void 0;
	if (!raw) return;
	return normalizeRuntimeAttachmentPolicy(raw);
}
function recordFromYaml(disciplineDir, yamlPath, yaml, issues) {
	const id = stringValue(yaml.id);
	const name = stringValue(yaml.name) ?? id;
	if (!id) {
		issues.push({
			level: "error",
			path: yamlPath,
			message: "Discipline is missing required id"
		});
		return null;
	}
	if (!name) {
		issues.push({
			level: "error",
			disciplineId: id,
			path: yamlPath,
			message: "Discipline is missing required name"
		});
		return null;
	}
	const collections = selectedCollections(yaml.selectedCollections);
	if (collections.length === 0) issues.push({
		level: "error",
		disciplineId: id,
		path: yamlPath,
		message: "Discipline must select at least one collection"
	});
	const runtimeAttachmentPolicy = normalizeRuntimePolicy(yaml.runtimeAttachmentPolicy);
	if (typeof yaml.runtimeAttachmentPolicy === "string" && yaml.runtimeAttachmentPolicy && !runtimeAttachmentPolicy) issues.push({
		level: "warning",
		disciplineId: id,
		path: yamlPath,
		message: `Unsupported runtimeAttachmentPolicy ${JSON.stringify(yaml.runtimeAttachmentPolicy)}`
	});
	const explicitArtifacts = stringArray(yaml.artifactPaths);
	const artifactPaths = explicitArtifacts.length > 0 ? explicitArtifacts.map(resolveUserPath) : discoverArtifactPaths(disciplineDir);
	for (const artifactPath of artifactPaths) if (!fs.existsSync(artifactPath)) issues.push({
		level: "warning",
		disciplineId: id,
		path: yamlPath,
		message: `Artifact path does not exist: ${artifactPath}`
	});
	const freshness = asRecord(yaml.freshness);
	const sourceSnapshot = stringValue(yaml.sourceSnapshot) ?? stringValue(yaml.source_snapshot);
	const runtimePolicy = runtimeAttachmentPolicy ?? "attach-on-demand";
	const qmdCollections = disciplineQmdCollections(id, disciplineDir);
	const generatedCollectionIds = qmdCollections.map((collection) => collection.id);
	return {
		id,
		name,
		description: stringValue(yaml.description),
		selectedCollections: Array.from(new Set([...generatedCollectionIds, ...collections])),
		authoredCollections: collections,
		qmdCollections,
		status: normalizeStatus(yaml.status),
		createdAt: stringValue(yaml.createdAt) ?? stringValue(yaml.created_at),
		updatedAt: stringValue(yaml.updatedAt) ?? stringValue(yaml.updated_at) ?? nowIso(),
		latestRunId: stringValue(yaml.latestRunId) ?? stringValue(yaml.latest_run_id),
		artifactKinds: stringArray(yaml.artifactKinds).length ? stringArray(yaml.artifactKinds) : artifactKindsFromPaths(artifactPaths),
		evidencePolicy: stringValue(yaml.evidencePolicy) ?? "cite-sources",
		freshnessLabel: stringValue(yaml.freshnessLabel) ?? stringValue(freshness?.state),
		sourceSnapshot,
		runtimeAttachmentPolicy: runtimePolicy,
		notesMarkdown: stringValue(yaml.notesMarkdown) ?? stringValue(yaml.notes),
		artifactPaths
	};
}
function buildDisciplineRegistry(options = {}) {
	const workspaceDir = resolveUserPath(options.workspaceDir ?? resolveDefaultWorkspaceDir());
	const stateDir = options.stateDir ?? resolveStateDir(process.env);
	const sourceDir = resolveDisciplineSourceDir(workspaceDir);
	const registryPath = resolveDisciplineRegistryPath(stateDir);
	const issues = [];
	const disciplines = [];
	const qmdCollectionsUpdated = [];
	if (!fs.existsSync(sourceDir)) issues.push({
		level: "warning",
		path: sourceDir,
		message: "Discipline source directory does not exist"
	});
	else {
		const entries = fs.readdirSync(sourceDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).sort((a, b) => a.name.localeCompare(b.name));
		for (const entry of entries) {
			const disciplineDir = path.join(sourceDir, entry.name);
			const yamlPath = path.join(disciplineDir, "discipline.yaml");
			if (!fs.existsSync(yamlPath)) {
				issues.push({
					level: "warning",
					path: disciplineDir,
					message: "Missing discipline.yaml"
				});
				continue;
			}
			try {
				const record = recordFromYaml(disciplineDir, yamlPath, parseDisciplineYaml(yamlPath), issues);
				if (record) disciplines.push(record);
			} catch (err) {
				issues.push({
					level: "error",
					path: yamlPath,
					message: err instanceof Error ? err.message : String(err)
				});
			}
		}
	}
	const seen = /* @__PURE__ */ new Set();
	for (const discipline of disciplines) {
		if (seen.has(discipline.id)) issues.push({
			level: "error",
			disciplineId: discipline.id,
			message: `Duplicate discipline id: ${discipline.id}`
		});
		seen.add(discipline.id);
	}
	if (options.buildQmdCollections) {
		for (const discipline of disciplines) for (const collection of discipline.qmdCollections) if (updateQmdCollection(collection, issues)) qmdCollectionsUpdated.push(collection.id);
	}
	const wroteRegistry = Boolean(options.write);
	if (options.write) {
		fs.mkdirSync(path.dirname(registryPath), { recursive: true });
		const tmp = `${registryPath}.tmp-${process.pid}`;
		fs.writeFileSync(tmp, JSON.stringify({ disciplines }, null, 2) + "\n");
		fs.renameSync(tmp, registryPath);
	}
	return {
		workspaceDir,
		sourceDir,
		registryPath,
		disciplines,
		issues,
		wroteRegistry,
		qmdCollectionsUpdated
	};
}
function findDiscipline(id, options = {}) {
	return buildDisciplineRegistry({
		...options,
		write: false
	}).disciplines.find((discipline) => discipline.id === id) ?? null;
}

//#endregion
export { resolveDisciplineSourceDir as a, resolveDisciplineRegistryPath as i, findDiscipline as n, resolveDefaultWorkspaceDir as r, buildDisciplineRegistry as t };