import "./manifest-CslkSMd8.mjs";
import "./metrics-DMk3mFyO.mjs";
import "./sync-PxvZXhSt.mjs";
import path from "node:path";
import { access, readFile, readdir } from "node:fs/promises";
import { parse } from "yaml";
//#region src/lib/slugify.ts
const NON_WORD_SEPARATOR_REGEX = /[^\w\s-]/g;
const REPEATED_HYPHEN_REGEX = /-+/g;
const SPACE_OR_UNDERSCORE_REGEX = /[_\s]+/g;
function slugify(value) {
	return value.normalize("NFKD").replace(NON_WORD_SEPARATOR_REGEX, "").trim().replace(SPACE_OR_UNDERSCORE_REGEX, "-").replace(REPEATED_HYPHEN_REGEX, "-").toLowerCase();
}
//#endregion
//#region src/forge.ts
const FIXED_MARKER_FILES = {
	portfolio: "portfolio.yaml",
	product: "product.yaml"
};
const TITLE_CASE_NAMES = {
	backlogDirectory: "Backlog",
	bucketsFile: "Buckets.md",
	decisionsDirectory: "Decisions",
	epicFile: "Epic.md",
	epicsDirectory: "Epics",
	featuresDirectory: "Features",
	initiativeFile: "Initiative.md",
	initiativesDirectory: "Initiatives",
	portfolioFile: "Portfolio.md",
	productFile: "Product.md",
	progressFile: "Progress.md",
	reviewFile: "Review.md",
	stackFile: "Stack.md",
	summaryFile: "Summary.md",
	tasksFile: "Tasks.md"
};
const KEBAB_CASE_NAMES = {
	backlogDirectory: "backlog",
	bucketsFile: "buckets.md",
	decisionsDirectory: "decisions",
	epicFile: "epic.md",
	epicsDirectory: "epics",
	featuresDirectory: "features",
	initiativeFile: "initiative.md",
	initiativesDirectory: "initiatives",
	portfolioFile: "portfolio.md",
	productFile: "product.md",
	progressFile: "progress.md",
	reviewFile: "review.md",
	stackFile: "stack.md",
	summaryFile: "summary.md",
	tasksFile: "tasks.md"
};
async function discoverForgeProducts(forgeRoot) {
	const normalizedForgeRoot = path.resolve(forgeRoot);
	const productMarkerPaths = await collectMarkerPaths(normalizedForgeRoot, FIXED_MARKER_FILES.product);
	return (await Promise.all(productMarkerPaths.map((productMarkerPath) => readForgeProduct(normalizedForgeRoot, productMarkerPath)))).sort((left, right) => left.relativeProductRoot.localeCompare(right.relativeProductRoot));
}
function formatForgeArtifactName(kind, id, title, namingCase) {
	return namingCase === "title" ? `${id} ${title}` : `${id.toLowerCase()}-${slugify(title)}`;
}
function getForgeNames(namingCase) {
	return namingCase === "title" ? TITLE_CASE_NAMES : KEBAB_CASE_NAMES;
}
function getForgeProductPaths(productRoot, namingCase) {
	const names = getForgeNames(namingCase);
	return {
		backlogDirectory: path.join(productRoot, names.backlogDirectory),
		decisionsDirectory: path.join(productRoot, names.decisionsDirectory),
		epicsDirectory: path.join(productRoot, names.epicsDirectory),
		initiativesDirectory: path.join(productRoot, names.initiativesDirectory),
		portfolioMarkerFile: path.join(productRoot, FIXED_MARKER_FILES.portfolio),
		productFile: path.join(productRoot, names.productFile),
		productMarkerFile: path.join(productRoot, FIXED_MARKER_FILES.product),
		stackFile: path.join(productRoot, names.stackFile)
	};
}
async function readForgeProduct(forgeRoot, productMarkerPath) {
	const productRoot = path.dirname(productMarkerPath);
	const marker = await readMarkerFile(productMarkerPath);
	const portfolioMarker = await findNearestPortfolioMarker(forgeRoot, productRoot);
	return {
		marker,
		portfolio: portfolioMarker?.marker ?? null,
		portfolioMarkerPath: portfolioMarker?.markerPath ?? null,
		portfolioRoot: portfolioMarker?.root ?? null,
		productMarkerPath,
		productRoot,
		relativeProductRoot: path.relative(forgeRoot, productRoot)
	};
}
async function findNearestPortfolioMarker(forgeRoot, productRoot) {
	let currentDirectory = path.dirname(productRoot);
	while (currentDirectory.startsWith(forgeRoot) && currentDirectory !== forgeRoot) {
		const markerPath = path.join(currentDirectory, FIXED_MARKER_FILES.portfolio);
		if (await pathExists(markerPath)) return {
			marker: await readMarkerFile(markerPath),
			markerPath,
			root: currentDirectory
		};
		currentDirectory = path.dirname(currentDirectory);
	}
	const forgeRootMarkerPath = path.join(forgeRoot, FIXED_MARKER_FILES.portfolio);
	if (await pathExists(forgeRootMarkerPath)) return {
		marker: await readMarkerFile(forgeRootMarkerPath),
		markerPath: forgeRootMarkerPath,
		root: forgeRoot
	};
	return null;
}
async function collectMarkerPaths(rootDirectory, markerFileName) {
	const markerPaths = [];
	const directoriesToVisit = [rootDirectory];
	while (directoriesToVisit.length > 0) {
		const currentDirectory = directoriesToVisit.pop();
		if (!currentDirectory) continue;
		const entries = await readdir(currentDirectory, { withFileTypes: true });
		for (const entry of entries) {
			const entryPath = path.join(currentDirectory, entry.name);
			if (entry.isDirectory()) {
				if (entry.name === ".git" || entry.name === "node_modules") continue;
				directoriesToVisit.push(entryPath);
				continue;
			}
			if (entry.isFile() && entry.name === markerFileName) markerPaths.push(entryPath);
		}
	}
	return markerPaths;
}
async function readMarkerFile(filePath) {
	const parsed = parse(await readFile(filePath, "utf8"));
	if (!isRecord(parsed)) throw new Error(`Invalid marker file at ${filePath}: expected an object`);
	const id = readRequiredString(parsed, "id", filePath);
	const name = readRequiredString(parsed, "name", filePath);
	return {
		context: readOptionalString(parsed, "context"),
		id,
		name,
		portfolio: readOptionalString(parsed, "portfolio"),
		stage: readOptionalString(parsed, "stage"),
		status: readOptionalString(parsed, "status")
	};
}
function readOptionalString(value, key) {
	const fieldValue = value[key];
	return typeof fieldValue === "string" && fieldValue.length > 0 ? fieldValue : void 0;
}
function readRequiredString(value, key, filePath) {
	const fieldValue = value[key];
	if (typeof fieldValue !== "string" || fieldValue.length === 0) throw new Error(`Invalid marker file at ${filePath}: '${key}' must be a non-empty string`);
	return fieldValue;
}
async function pathExists(filePath) {
	try {
		await access(filePath);
		return true;
	} catch {
		return false;
	}
}
function isRecord(value) {
	return typeof value === "object" && value !== null && !Array.isArray(value);
}
//#endregion
//#region src/smith.ts
function formatPlanFolderName(sequence, date, title, namingCase) {
	const formattedSequence = sequence.toString().padStart(3, "0");
	return namingCase === "title" ? `${formattedSequence} - ${date} - ${title}` : `${formattedSequence}-${date}-${slugify(title)}`;
}
function formatSmithArtifactFileName(kind, id, title, namingCase) {
	if (kind === "proposal") return namingCase === "title" ? `${id} - ${title}.md` : `${id}-${slugify(title)}.md`;
	return namingCase === "title" ? `${id} ${title}.md` : `${id.toLowerCase()}-${slugify(title)}.md`;
}
function getPlanDocumentNames(namingCase) {
	return namingCase === "title" ? {
		plan: "Plan.md",
		progress: "Progress.md",
		research: "Research.md",
		review: "Review.md",
		summary: "Summary.md",
		tasks: "Tasks.md"
	} : {
		plan: "plan.md",
		progress: "progress.md",
		research: "research.md",
		review: "review.md",
		summary: "summary.md",
		tasks: "tasks.md"
	};
}
function getSmithArtifactLayout(smithRoot, stateRoot) {
	return {
		architectureFile: `${smithRoot}/architecture.md`,
		changelogFile: `${stateRoot}/changelog.md`,
		changesDirectory: `${stateRoot}/changes`,
		issuesDirectory: `${smithRoot}/issues`,
		notesDirectory: `${stateRoot}/notes`,
		plansDirectory: `${stateRoot}/plans`,
		proposalsDirectory: `${smithRoot}/proposals`,
		specsDirectory: `${smithRoot}/specs`,
		stateFile: `${stateRoot}/state.md`
	};
}
//#endregion
//#region src/index.ts
function getAnvilPackageStatus() {
	return {
		forge: {
			phase: "active",
			summary: "Forge helpers provide marker-based product discovery and case-aware artifact naming from the main Anvil package."
		},
		smith: {
			phase: "active",
			summary: "Smith helpers provide case-aware layout and naming helpers from the main Anvil package."
		},
		summary: "Anvil is the main user-facing package for manifest loading, validation, workspace orchestration, and internal Forge or Smith helpers."
	};
}
//#endregion
export { getSmithArtifactLayout as a, getForgeNames as c, getPlanDocumentNames as i, getForgeProductPaths as l, formatPlanFolderName as n, discoverForgeProducts as o, formatSmithArtifactFileName as r, formatForgeArtifactName as s, getAnvilPackageStatus as t };

//# sourceMappingURL=src-BF36DaJ9.mjs.map