import { t as coerceErrorMessage } from "./error-coercion-CKFmnpjH.js";
import { r as root } from "./fs-safe-gVoExnQ2.js";
import { t as assertExperimentalClawsEnabled } from "./experimental-BMzbGmT5.js";
import { a as writeRuntimeJson, r as defaultRuntime } from "./runtime-LRpY2Icg.js";
import { s as readConfigFileSnapshot } from "./io.runtime-CNGn9TXj.js";
import { o as listAgentIds, p as resolveAgentWorkspaceDir } from "./agent-scope-config-adSj-fCz.js";
import { r as normalizeConfiguredMcpServers } from "./mcp-config-normalize-UxJz0-IT.js";
import "./config-D_ojUgx2.js";
import { d as isCanonicalClawHubPackageName, i as MAX_MANAGED_FILE_BYTES, m as portableClawPathKey, n as readClawManifestFile, p as isSafeClawRelativePath, v as CLAW_OUTPUT_STABILITY } from "./reader-XynHInDB.js";
import { i as buildClawAddPlan, n as logClawExperimentalWarning, t as formatClawDiagnostics } from "./claws-cli-output-BSdI6eFO.js";
import { tmpdir } from "node:os";
import { basename, dirname, isAbsolute, join, parse, relative, resolve, sep } from "node:path";
import { chmod, link, lstat, mkdir, mkdtemp, readFile, readdir, realpath, rm, rmdir, stat, unlink, writeFile } from "node:fs/promises";
import { createHash } from "node:crypto";
import * as tar from "tar";
//#region src/claws/project.ts
const CLAW_PROJECT_RESULT_SCHEMA_VERSION = "openclaw.clawProject.v1";
const MAX_PACKAGE_JSON_BYTES = 256 * 1024;
const MAX_PROJECT_ENTRIES = 4096;
const AGENT_ID_PATTERN = /^[a-z][a-z0-9_-]{0,63}$/;
var ClawProjectError = class extends Error {
	constructor(code, message) {
		super(message);
		this.code = code;
		this.name = "ClawProjectError";
	}
};
function diagnostic(code, path, message) {
	return {
		level: "error",
		code,
		phase: "policy",
		path,
		message
	};
}
function defaultSlug(value) {
	return value.toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^[^a-z]+/, "").replace(/-+$/g, "").slice(0, 64) || "my-claw";
}
function displayName(agentId) {
	return agentId.split(/[-_]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
}
async function pathState(path) {
	const entry = await lstat(path).catch(() => void 0);
	if (!entry) return "missing";
	if (!entry.isDirectory()) return "occupied";
	return (await readdir(path)).length === 0 ? "empty-directory" : "occupied";
}
async function isFile(path) {
	return lstat(path).then((entry) => entry.isFile()).catch(() => false);
}
async function isConfinedManifestFile(root) {
	const manifestPath = resolve(root, "CLAW.md");
	const entry = await lstat(manifestPath).catch(() => void 0);
	if (entry?.isFile()) return true;
	if (!entry?.isSymbolicLink()) return false;
	const [rootReal, targetReal] = await Promise.all([realpath(root).catch(() => void 0), realpath(manifestPath).catch(() => void 0)]);
	if (!rootReal || !targetReal) return false;
	const targetRelative = relative(rootReal, targetReal);
	if (targetRelative === "" || targetRelative === ".." || targetRelative.startsWith(`..${sep}`) || isAbsolute(targetRelative) || isExcludedProjectSource(targetRelative)) return false;
	return lstat(targetReal).then((target) => target.isFile()).catch(() => false);
}
async function discoverClawProjectRoot(projectPath) {
	const input = resolve(projectPath);
	const inputStat = await lstat(input).catch(() => void 0);
	if (!inputStat) throw new ClawProjectError("project_not_found", `Could not resolve Claw project path ${JSON.stringify(input)}.`);
	let current = inputStat.isDirectory() ? input : dirname(input);
	const roots = [];
	const filesystemRoot = parse(current).root;
	while (true) {
		if (await isFile(resolve(current, "package.json")) && await isConfinedManifestFile(current)) roots.push(await realpath(current));
		if (current === filesystemRoot) break;
		current = dirname(current);
	}
	if (roots.length === 0) throw new ClawProjectError("project_not_found", `No Claw project containing package.json and CLAW.md was found from ${JSON.stringify(input)}.`);
	if (roots.length > 1) throw new ClawProjectError("ambiguous_project_root", `Multiple Claw project roots contain ${JSON.stringify(input)}: ${roots.join(", ")}.`);
	return roots[0];
}
function projectPathKey(value, caseInsensitive) {
	const normalized = value.normalize("NFC");
	return caseInsensitive ? normalized.toLowerCase() : normalized;
}
function isExcludedProjectSource(value) {
	return portableClawPathKey(value).split("/").some((segment) => segment === ".git" || segment === "node_modules");
}
async function isCaseInsensitiveProjectRoot(root) {
	const [canonical, folded] = await Promise.all([lstat(resolve(root, "CLAW.md")).catch(() => void 0), lstat(resolve(root, "claw.md")).catch(() => void 0)]);
	return Boolean(canonical && folded && canonical.dev === folded.dev && canonical.ino === folded.ino);
}
async function collectExcludedPaths(root, selectedPaths) {
	const excluded = [];
	const caseInsensitive = await isCaseInsensitiveProjectRoot(root);
	const selectedPathKeys = new Set([...selectedPaths].map((path) => projectPathKey(path, caseInsensitive)));
	let entryCount = 0;
	const visit = async (directory) => {
		const entries = await readdir(resolve(root, directory), { withFileTypes: true });
		for (const entry of entries) {
			entryCount += 1;
			if (entryCount > MAX_PROJECT_ENTRIES) throw new ClawProjectError("project_too_many_entries", `Claw projects may contain at most ${MAX_PROJECT_ENTRIES} entries outside excluded dependency and source-control trees.`);
			const path = directory ? `${directory}/${entry.name}` : entry.name;
			if (entry.isDirectory()) if (entry.name === ".git" || entry.name === "node_modules") excluded.push(`${path}/`);
			else await visit(path);
			else if (!selectedPathKeys.has(projectPathKey(path, caseInsensitive))) excluded.push(path);
		}
	};
	await visit("");
	return excluded.toSorted((left, right) => Buffer.compare(Buffer.from(left), Buffer.from(right)));
}
async function createClawProject(projectPath, options = {}) {
	const root = resolve(projectPath);
	const initialState = await pathState(root);
	if (initialState === "occupied") throw new ClawProjectError("project_target_not_empty", `Claw project target ${JSON.stringify(root)} must be absent or empty.`);
	const agentId = options.agentId ?? defaultSlug(basename(root));
	if (!AGENT_ID_PATTERN.test(agentId)) throw new ClawProjectError("invalid_agent_id", `Agent id ${JSON.stringify(agentId)} must match ${AGENT_ID_PATTERN}.`);
	const name = options.name ?? agentId;
	if (!isCanonicalClawHubPackageName(name)) throw new ClawProjectError("invalid_package_name", `Package name ${JSON.stringify(name)} must be a canonical ClawHub package name.`);
	const packageJson = {
		name,
		version: "0.1.0",
		openclaw: { claw: "CLAW.md" }
	};
	const clawMarkdown = [
		"---",
		"schemaVersion: 1",
		"agent:",
		`  id: ${JSON.stringify(agentId)}`,
		`  name: ${JSON.stringify(displayName(agentId))}`,
		"---",
		`You are ${displayName(agentId)}, a purpose-built OpenClaw agent.`,
		""
	].join("\n");
	const packageJsonPath = resolve(root, "package.json");
	const clawMarkdownPath = resolve(root, "CLAW.md");
	const createdPaths = [];
	await mkdir(root, { recursive: true });
	try {
		await writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`, {
			encoding: "utf8",
			flag: "wx"
		});
		createdPaths.push(packageJsonPath);
		await writeFile(clawMarkdownPath, clawMarkdown, {
			encoding: "utf8",
			flag: "wx"
		});
		createdPaths.push(clawMarkdownPath);
	} catch (error) {
		await Promise.allSettled(createdPaths.map((path) => unlink(path)));
		if (initialState === "missing") await rmdir(root).catch(() => void 0);
		throw error;
	}
	return {
		root,
		packageJson,
		filesWritten: ["package.json", "CLAW.md"]
	};
}
async function validateClawProject(projectPath) {
	let root$1;
	try {
		root$1 = await discoverClawProjectRoot(projectPath);
	} catch (error) {
		return {
			ok: false,
			root: resolve(projectPath),
			diagnostics: [diagnostic(error instanceof ClawProjectError ? error.code : "project_discovery_failed", "$", coerceErrorMessage(error))]
		};
	}
	let packageValue;
	try {
		const read = await (await root(root$1)).read("package.json", {
			hardlinks: "reject",
			maxBytes: MAX_PACKAGE_JSON_BYTES,
			nonBlockingRead: true,
			symlinks: "reject"
		});
		packageValue = JSON.parse(read.buffer.toString("utf8"));
	} catch (error) {
		return {
			ok: false,
			root: root$1,
			diagnostics: [diagnostic("invalid_project_package", "package.json", `Could not read a safe project package.json: ${error.message}`)]
		};
	}
	const record = packageValue && typeof packageValue === "object" && !Array.isArray(packageValue) ? packageValue : void 0;
	const openclaw = record?.openclaw && typeof record.openclaw === "object" && !Array.isArray(record.openclaw) ? record.openclaw : void 0;
	const scripts = record?.scripts;
	const diagnostics = [];
	if (openclaw?.claw !== "CLAW.md") diagnostics.push(diagnostic("project_manifest_must_be_claw_markdown", "package.json.openclaw.claw", "A Claw project must set openclaw.claw to \"CLAW.md\"."));
	if (scripts !== void 0 && (typeof scripts !== "object" || scripts === null || Array.isArray(scripts) || Object.keys(scripts).length > 0)) diagnostics.push(diagnostic("project_scripts_forbidden", "package.json.scripts", "Claw projects cannot declare package scripts or lifecycle hooks."));
	if (diagnostics.length > 0) return {
		ok: false,
		root: root$1,
		diagnostics
	};
	const claw = await readClawManifestFile(root$1);
	if (!claw.ok) return {
		ok: false,
		root: root$1,
		diagnostics: claw.diagnostics
	};
	const excludedSource = [...claw.snapshot.openClawProfile ? [{
		path: claw.snapshot.openClawProfile.sourcePath,
		diagnosticPath: "$.metadata.openclaw.config"
	}] : [], ...claw.snapshot.workspaceSources.map((source) => ({
		path: source.sourcePath,
		diagnosticPath: "$.workspace"
	}))].find((source) => isExcludedProjectSource(source.path));
	if (excludedSource) return {
		ok: false,
		root: root$1,
		diagnostics: [diagnostic("project_excluded_source", excludedSource.diagnosticPath, `Selected project source ${JSON.stringify(excludedSource.path)} cannot come from .git or node_modules.`)]
	};
	const reservedPackageSource = claw.snapshot.workspaceSources.find((source) => source.sourcePath.normalize("NFC").toLowerCase() === "package.json");
	if (reservedPackageSource) return {
		ok: false,
		root: root$1,
		diagnostics: [diagnostic("project_invalid", "$.workspace.files", `Workspace source ${JSON.stringify(reservedPackageSource.sourcePath)} collides with generated package metadata.`)]
	};
	const selectedPathList = [
		"package.json",
		"CLAW.md",
		...claw.packageBootstrap ? ["BOOTSTRAP.md"] : [],
		...claw.snapshot.openClawProfile ? [claw.snapshot.openClawProfile.sourcePath] : [],
		...claw.snapshot.workspaceSources.map((source) => source.sourcePath)
	];
	const portableSelectedPaths = /* @__PURE__ */ new Map();
	for (const path of selectedPathList) {
		const key = portableClawPathKey(path);
		const existing = portableSelectedPaths.get(key);
		if (existing && existing !== path) return {
			ok: false,
			root: root$1,
			diagnostics: [diagnostic("project_path_collision", "$", `Selected project paths ${JSON.stringify(existing)} and ${JSON.stringify(path)} collide on portable filesystems.`)]
		};
		portableSelectedPaths.set(key, path);
	}
	const selectedPaths = new Set(selectedPathList);
	let excludedPaths;
	try {
		excludedPaths = await collectExcludedPaths(root$1, selectedPaths);
	} catch (error) {
		return {
			ok: false,
			root: root$1,
			diagnostics: [diagnostic(error instanceof ClawProjectError ? error.code : "project_enumeration_failed", "$", coerceErrorMessage(error))]
		};
	}
	return {
		ok: true,
		root: root$1,
		packageJson: {
			name: claw.source.name,
			version: claw.source.version,
			...typeof record?.type === "string" ? { type: record.type } : {},
			openclaw: { claw: "CLAW.md" }
		},
		claw,
		excludedPaths,
		diagnostics: claw.diagnostics
	};
}
//#endregion
//#region src/claws/project-build.ts
const CLAW_BUILD_RESULT_SCHEMA_VERSION = "openclaw.clawBuild.v1";
const ZLIB_FILTERED_STRATEGY = 1;
async function writeStagedFile(stagingRoot, path, content) {
	const target = resolve(stagingRoot, path);
	const targetRelative = relative(stagingRoot, target);
	if (!isSafeClawRelativePath(path) || targetRelative === ".." || targetRelative.startsWith(`..${sep}`) || isAbsolute(targetRelative)) throw new ClawProjectError("unsafe_build_path", `Cannot package unsafe path ${JSON.stringify(path)}.`);
	await mkdir(dirname(target), {
		recursive: true,
		mode: 493
	});
	await writeFile(target, content, {
		flag: "wx",
		mode: 420
	});
	await chmod(target, 420);
}
async function readSelectedProjectFile(projectRoot, path) {
	return (await (await root(projectRoot)).read(path, {
		hardlinks: "reject",
		maxBytes: MAX_MANAGED_FILE_BYTES,
		nonBlockingRead: true,
		symlinks: path === "CLAW.md" ? "follow-within-root" : "reject"
	})).buffer;
}
function assertValidatedBytes(path, bytes, expected) {
	const digest = `sha256:${createHash("sha256").update(bytes).digest("hex")}`;
	if (bytes.byteLength !== expected.byteLength || digest !== expected.digest) throw new ClawProjectError("project_changed_during_build", `Claw project input ${JSON.stringify(path)} changed after validation; retry the build from a stable snapshot.`);
}
async function extractBuiltClawArtifact(artifact) {
	const temporaryDirectory = await mkdtemp(join(tmpdir(), "openclaw-claw-artifact-"));
	try {
		await tar.x({
			cwd: temporaryDirectory,
			file: resolve(artifact),
			strict: true
		});
		const packageRoot = join(temporaryDirectory, "package");
		if (!(await lstat(packageRoot)).isDirectory()) throw new Error("artifact does not contain a package directory");
		return {
			temporaryDirectory,
			packageRoot,
			dispose: () => rm(temporaryDirectory, {
				recursive: true,
				force: true
			})
		};
	} catch (error) {
		await rm(temporaryDirectory, {
			recursive: true,
			force: true
		});
		throw new ClawProjectError("artifact_verification_failed", `Could not extract built Claw artifact: ${error.message}`);
	}
}
async function buildClawProject(projectPath, outputPath) {
	const project = await validateClawProject(projectPath);
	if (!project.ok) throw new ClawProjectError("project_invalid", project.diagnostics.map((item) => `${item.code}: ${item.message}`).join("\n"));
	const artifact = resolve(outputPath);
	if (!artifact.toLowerCase().endsWith(".tgz")) throw new ClawProjectError("invalid_artifact_path", "Claw build output must end in .tgz.");
	if (await lstat(artifact).catch(() => void 0)) throw new ClawProjectError("artifact_exists", `Refusing to overwrite existing artifact ${JSON.stringify(artifact)}.`);
	if (!(await stat(dirname(artifact)).catch(() => void 0))?.isDirectory()) throw new ClawProjectError("artifact_parent_missing", `Artifact parent directory ${JSON.stringify(dirname(artifact))} does not exist.`);
	const temporaryDirectory = await mkdtemp(join(dirname(artifact), ".openclaw-claw-build-"));
	const stagingRoot = join(temporaryDirectory, "staging");
	const temporaryArtifact = join(temporaryDirectory, "claw.tgz");
	try {
		await mkdir(stagingRoot, { mode: 493 });
		const files = /* @__PURE__ */ new Map();
		files.set("package.json", `${JSON.stringify(project.packageJson, null, 2)}\n`);
		const clawMarkdown = await readSelectedProjectFile(project.root, "CLAW.md");
		assertValidatedBytes("CLAW.md", clawMarkdown, project.claw.snapshot.manifest);
		files.set("CLAW.md", clawMarkdown);
		if (project.claw.packageBootstrap) {
			const bootstrap = await readSelectedProjectFile(project.root, "BOOTSTRAP.md");
			assertValidatedBytes("BOOTSTRAP.md", bootstrap, project.claw.packageBootstrap);
			files.set("BOOTSTRAP.md", bootstrap);
		}
		if (project.claw.openClawProfile) {
			const profileSnapshot = project.claw.snapshot.openClawProfile;
			if (!profileSnapshot) throw new ClawProjectError("project_invalid", "Validated OpenClaw profile is missing its source snapshot.");
			const profile = await readSelectedProjectFile(project.root, profileSnapshot.sourcePath);
			assertValidatedBytes(profileSnapshot.sourcePath, profile, profileSnapshot);
			files.set(profileSnapshot.sourcePath, profile);
		}
		for (const source of project.claw.snapshot.workspaceSources) {
			const bytes = await readSelectedProjectFile(project.root, source.sourcePath);
			assertValidatedBytes(source.sourcePath, bytes, source);
			files.set(source.sourcePath, bytes);
		}
		const fileNames = [...files.keys()].toSorted((left, right) => Buffer.compare(Buffer.from(left), Buffer.from(right)));
		for (const fileName of fileNames) await writeStagedFile(stagingRoot, fileName, files.get(fileName));
		const tarInputNames = fileNames.map((fileName) => fileName.startsWith("@") ? `./${fileName}` : fileName);
		await tar.c({
			cwd: stagingRoot,
			file: temporaryArtifact,
			gzip: {
				level: 9,
				portable: true,
				strategy: ZLIB_FILTERED_STRATEGY
			},
			mtime: /* @__PURE__ */ new Date(0),
			portable: true,
			prefix: "package"
		}, tarInputNames);
		const archiveEntries = [];
		await tar.t({
			file: temporaryArtifact,
			onentry: (entry) => archiveEntries.push({
				path: entry.path,
				type: entry.type
			})
		});
		const expectedEntries = fileNames.map((path) => ({
			path: `package/${path}`,
			type: "File"
		}));
		if (JSON.stringify(archiveEntries) !== JSON.stringify(expectedEntries)) throw new ClawProjectError("artifact_contents_mismatch", "Built artifact contents differ from the validated project selection.");
		const packed = await readFile(temporaryArtifact);
		const integrity = `sha256:${createHash("sha256").update(packed).digest("hex")}`;
		const extracted = await extractBuiltClawArtifact(temporaryArtifact);
		try {
			const reread = await readClawManifestFile(extracted.packageRoot);
			if (!reread.ok) throw new ClawProjectError("artifact_verification_failed", reread.diagnostics.map((item) => `${item.code}: ${item.message}`).join("\n"));
			if (reread.source.name !== project.packageJson.name || reread.source.version !== project.packageJson.version) throw new ClawProjectError("artifact_identity_mismatch", "Built artifact identity differs from the validated project.");
		} finally {
			await extracted.dispose();
		}
		try {
			await link(temporaryArtifact, artifact);
		} catch (error) {
			if (error.code === "EEXIST") throw new ClawProjectError("artifact_exists", `Refusing to overwrite existing artifact ${JSON.stringify(artifact)}.`);
			throw new ClawProjectError("artifact_atomic_publish_failed", `Could not atomically publish artifact ${JSON.stringify(artifact)}: ${error.message}`);
		}
		return {
			schemaVersion: CLAW_BUILD_RESULT_SCHEMA_VERSION,
			projectSchemaVersion: CLAW_PROJECT_RESULT_SCHEMA_VERSION,
			artifact,
			integrity,
			byteLength: packed.byteLength,
			files: fileNames,
			excludedPaths: project.excludedPaths,
			claw: {
				name: project.packageJson.name,
				version: project.packageJson.version
			}
		};
	} finally {
		await rm(temporaryDirectory, {
			recursive: true,
			force: true
		});
	}
}
//#endregion
//#region src/cli/claws-cli.project.ts
const CLAW_DEV_RESULT_SCHEMA_VERSION = "openclaw.clawDev.v1";
function reportProjectError(error, fallbackCode, schemaVersion, json, runtime) {
	const code = error instanceof ClawProjectError ? error.code : fallbackCode;
	const message = error instanceof Error ? error.message : String(error);
	if (json) writeRuntimeJson(runtime, {
		schemaVersion,
		stability: CLAW_OUTPUT_STABILITY,
		ok: false,
		error: {
			code,
			message
		}
	});
	else runtime.error(message);
	runtime.exit(1);
}
function logDevPlanSummary(plan, runtime) {
	runtime.log(`Agent: ${plan.agent.finalId}`);
	runtime.log(`Workspace: ${plan.agent.workspace}`);
	runtime.log(`Actions: ${plan.summary.totalActions}`);
	runtime.log(`Capability escalations: ${plan.capabilityChanges.length}`);
	runtime.log(`Blocked actions: ${plan.summary.blockedActions}`);
}
async function prepareDev(projectPath, opts) {
	const temporaryDirectory = await mkdtemp(join(tmpdir(), "openclaw-claw-dev-"));
	try {
		const build = await buildClawProject(projectPath, join(temporaryDirectory, "claw.tgz"));
		const extracted = await extractBuiltClawArtifact(build.artifact);
		try {
			const result = await readClawManifestFile(extracted.packageRoot);
			if (!result.ok) throw new ClawProjectError("artifact_verification_failed", formatClawDiagnostics(result.diagnostics));
			const configSnapshot = await readConfigFileSnapshot({
				observe: false,
				skipPluginValidation: true
			});
			if (!configSnapshot.valid) throw new ClawProjectError("config_unavailable", "OpenClaw config is invalid; fix it before previewing a Claw project.");
			const config = configSnapshot.resolved;
			const existingMcpServers = normalizeConfiguredMcpServers(config.mcp?.servers);
			const existingAgentIds = listAgentIds(config);
			return {
				build,
				plan: await buildClawAddPlan({
					manifest: result.manifest,
					clawMarkdownBody: result.clawMarkdownBody,
					packageBootstrap: result.packageBootstrap,
					openClawProfile: result.openClawProfile,
					source: {
						...result.source,
						integrityKind: "artifact",
						integrity: build.integrity,
						byteLength: build.byteLength
					},
					diagnostics: result.diagnostics,
					context: {
						...opts.agentId ? { agentId: opts.agentId } : {},
						...opts.workspace ? { workspace: opts.workspace } : {},
						existingAgentIds,
						existingWorkspacePaths: existingAgentIds.map((agentId) => resolveAgentWorkspaceDir(config, agentId)),
						existingMcpServers,
						sourceReferenceRoot: `claw-artifact:${build.integrity}`
					}
				})
			};
		} finally {
			await extracted.dispose();
		}
	} finally {
		await rm(temporaryDirectory, {
			recursive: true,
			force: true
		});
	}
}
async function runClawsCreateCommand(projectPath, opts, runtime = defaultRuntime) {
	assertExperimentalClawsEnabled();
	try {
		const result = await createClawProject(projectPath, {
			...opts.name ? { name: opts.name } : {},
			...opts.agentId ? { agentId: opts.agentId } : {}
		});
		if (opts.json) {
			writeRuntimeJson(runtime, {
				schemaVersion: CLAW_PROJECT_RESULT_SCHEMA_VERSION,
				stability: CLAW_OUTPUT_STABILITY,
				ok: true,
				...result
			});
			return;
		}
		logClawExperimentalWarning(runtime);
		runtime.log(`Created Claw project: ${result.root}`);
		runtime.log(`Package: ${result.packageJson.name}@${result.packageJson.version}`);
	} catch (error) {
		reportProjectError(error, "project_create_failed", CLAW_PROJECT_RESULT_SCHEMA_VERSION, opts.json, runtime);
	}
}
async function runClawsValidateCommand(projectPath, opts, runtime = defaultRuntime) {
	assertExperimentalClawsEnabled();
	const result = await validateClawProject(projectPath);
	if (!result.ok) {
		if (opts.json) writeRuntimeJson(runtime, {
			schemaVersion: CLAW_PROJECT_RESULT_SCHEMA_VERSION,
			stability: CLAW_OUTPUT_STABILITY,
			ok: false,
			root: result.root,
			diagnostics: result.diagnostics
		});
		else runtime.error(formatClawDiagnostics(result.diagnostics));
		runtime.exit(1);
		return;
	}
	if (opts.json) {
		writeRuntimeJson(runtime, {
			schemaVersion: CLAW_PROJECT_RESULT_SCHEMA_VERSION,
			stability: CLAW_OUTPUT_STABILITY,
			ok: true,
			root: result.root,
			source: result.claw.source,
			manifest: result.claw.manifest,
			...result.claw.openClawProfile ? { openClawProfile: result.claw.openClawProfile } : {},
			excludedPaths: result.excludedPaths,
			diagnostics: result.diagnostics
		});
		return;
	}
	logClawExperimentalWarning(runtime);
	runtime.log(`Valid Claw project: ${result.root}`);
	runtime.log(`Package: ${result.packageJson.name}@${result.packageJson.version}`);
	for (const path of result.excludedPaths) runtime.log(`Excluded: ${path}`);
}
async function runClawsBuildCommand(projectPath, opts, runtime = defaultRuntime) {
	assertExperimentalClawsEnabled();
	try {
		const result = await buildClawProject(projectPath, opts.out);
		if (opts.json) {
			writeRuntimeJson(runtime, {
				...result,
				stability: CLAW_OUTPUT_STABILITY,
				ok: true
			});
			return;
		}
		logClawExperimentalWarning(runtime);
		runtime.log(`Built Claw: ${result.claw.name}@${result.claw.version}`);
		runtime.log(`Artifact: ${result.artifact}`);
		runtime.log(`Integrity: ${result.integrity}`);
		runtime.log(`Excluded project paths: ${result.excludedPaths.length}`);
	} catch (error) {
		reportProjectError(error, "project_build_failed", CLAW_BUILD_RESULT_SCHEMA_VERSION, opts.json, runtime);
	}
}
async function runClawsDevCommand(projectPath, opts, runtime = defaultRuntime) {
	assertExperimentalClawsEnabled();
	let prepared;
	try {
		prepared = await prepareDev(projectPath, opts);
	} catch (error) {
		reportProjectError(error, "project_dev_failed", CLAW_DEV_RESULT_SCHEMA_VERSION, opts.json, runtime);
		return;
	}
	const { build, plan } = prepared;
	if (opts.json) writeRuntimeJson(runtime, {
		schemaVersion: CLAW_DEV_RESULT_SCHEMA_VERSION,
		stability: CLAW_OUTPUT_STABILITY,
		offline: true,
		mutationAllowed: false,
		build: {
			integrity: build.integrity,
			byteLength: build.byteLength,
			files: build.files,
			excludedPaths: build.excludedPaths,
			claw: build.claw
		},
		plan
	});
	else {
		logClawExperimentalWarning(runtime);
		runtime.log(`Claw dev preview: ${build.claw.name}@${build.claw.version}`);
		runtime.log(`Artifact integrity: ${build.integrity}`);
		logDevPlanSummary(plan, runtime);
		if (plan.blockers.length > 0) runtime.error(formatClawDiagnostics(plan.blockers));
	}
	if (plan.blockers.length > 0) runtime.exit(1);
}
//#endregion
export { runClawsBuildCommand, runClawsCreateCommand, runClawsDevCommand, runClawsValidateCommand };
