UNPKG

everything-dev

Version:

A consolidated product package for building Module Federation apps with oRPC APIs.

1,030 lines • 51.3 kB
#!/usr/bin/env node
const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
const require_fastkv = require('./fastkv.cjs');
const require_network = require('./network.cjs');
const require_config = require('./config.cjs');
const require_theme = require('./utils/theme.cjs');
const require_docker = require('./infra/docker.cjs');
const require_bundle_fs_resolve = require('./bundle-fs-resolve.cjs');
const require_timing = require('./cli/timing.cjs');
const require_near_cli = require('./near-cli.cjs');
const require_progress = require('./progress.cjs');
const require_init = require('./commands/init.cjs');
const require_framework_version = require('./cli/framework-version.cjs');
const require_status = require('./cli/status.cjs');
const require_plugin = require('./plugin.cjs');
const require_catalog = require('./cli/catalog.cjs');
const require_help = require('./cli/help.cjs');
const require_parse = require('./cli/parse.cjs');
const require_prompts = require('./cli/prompts.cjs');
const require_banner = require('./utils/banner.cjs');
let node_fs = require("node:fs");
let node_path = require("node:path");
let node_fs_promises = require("node:fs/promises");
let _clack_prompts = require("@clack/prompts");
_clack_prompts = require_runtime.__toESM(_clack_prompts, 1);
let every_plugin = require("every-plugin");

//#region src/cli.ts
function printConfigView(result) {
	console.log();
	console.log(require_theme.colors.cyan(require_theme.frames.top(52)));
	console.log(`  ${require_theme.icons.app} ${require_theme.gradients.cyber("CONFIG")}`);
	console.log(require_theme.colors.cyan(require_theme.frames.bottom(52)));
	console.log();
	console.log(`  ${require_theme.colors.dim("Account")}  ${require_theme.colors.cyan(result.account)}`);
	console.log(`  ${require_theme.colors.dim("Domain")}   ${require_theme.colors.white(result.domain ?? "not configured")}`);
	if (result.staging) console.log(`  ${require_theme.colors.dim("Staging")}  ${require_theme.colors.magenta(result.staging.domain)}`);
	console.log();
}
function formatTimeAgo(isoTimestamp) {
	const diffMs = Date.now() - new Date(isoTimestamp).getTime();
	const diffMins = Math.floor(diffMs / 6e4);
	if (diffMins < 1) return "just now";
	if (diffMins < 60) return `${diffMins} minute${diffMins > 1 ? "s" : ""} ago`;
	const diffHours = Math.floor(diffMins / 60);
	if (diffHours < 24) return `${diffHours} hour${diffHours > 1 ? "s" : ""} ago`;
	const diffDays = Math.floor(diffHours / 24);
	if (diffDays < 30) return `${diffDays} day${diffDays > 1 ? "s" : ""} ago`;
	return isoTimestamp.split("T")[0] ?? isoTimestamp;
}
const RETIRED_BOOTSTRAP_STUBS = [
	"ui/src/entry.ts",
	"ui/src/hydrate.tsx",
	"ui/src/router.server.tsx",
	"ui/src/compose.ts"
];
/**
* Hand-modified bootstrap stubs retire as conflicted (backed up, then
* deleted) — print the mechanical port into the authored seams (ADR 0023).
*/
function printStubMigrationGuide(retiredConflicted) {
	if ((retiredConflicted ?? []).filter((f) => RETIRED_BOOTSTRAP_STUBS.includes(f)).length === 0) return;
	console.log(`  ${require_theme.colors.yellow("Port your stub customizations into the authored seams:")}`);
	console.log(`    ${require_theme.colors.dim("- defaultErrorComponent / defaultPendingComponent / defaultNotFoundComponent")}`);
	console.log(`    ${require_theme.colors.dim("  → set them inside the createRouter factory in ui/src/router.tsx (after ...opts)")}`);
	console.log(`    ${require_theme.colors.dim("- apiConnectionError copy + SSR locale config (locales, defaultLocale, cookieName)")}`);
	console.log(`    ${require_theme.colors.dim("  → export apiConnectionError / appLocale from ui/src/app.ts (see the scaffold template)")}`);
	console.log(`    ${require_theme.colors.dim("  backed-up originals: .bos/sync-backup/<timestamp>/")}`);
}
function printTimingSummary(timings) {
	if (!timings || timings.length === 0) return;
	console.log(`  ${require_theme.colors.dim("Timings:")}`);
	for (const timing of timings) console.log(`    ${require_theme.colors.dim(timing.name.padEnd(22))} ${require_timing.formatDuration(timing.durationMs)}`);
	console.log(`    ${require_theme.colors.dim("total".padEnd(22))} ${require_timing.formatDuration(require_timing.sumPhaseDurations(timings))}`);
}
function printStartSummary(summary) {
	console.log();
	console.log(`  ${require_theme.colors.dim("Config Source:")}  ${summary.configSource}`);
	if (summary.configSourceHttp) console.log(`                  ${require_theme.colors.dim(summary.configSourceHttp)}`);
	console.log(`  ${require_theme.colors.dim("Account:")}        ${summary.account}`);
	console.log(`  ${require_theme.colors.dim("Domain:")}         ${summary.domain ?? "not configured"}`);
	console.log();
	console.log(`  ${require_theme.colors.dim("Modules:")}`);
	console.log(`    ${require_theme.colors.dim("HOST")}  → ${summary.modules.host ?? "local"}`);
	console.log(`    ${require_theme.colors.dim("UI")}   → ${summary.modules.ui ?? "local"}`);
	console.log(`    ${require_theme.colors.dim("API")}  → ${summary.modules.api ?? "local"}`);
	if (summary.modules.auth) console.log(`    ${require_theme.colors.dim("AUTH")}  → ${summary.modules.auth}`);
	if (summary.warnings.length > 0) {
		console.log();
		for (const w of summary.warnings) console.log(`  ${require_theme.colors.yellow(w)}`);
	}
	console.log();
}
function clearSpinnerStopLine() {
	if (!process.stdout.isTTY) return;
	process.stdout.write("\x1B[1A\x1B[2K\x1B[1G");
}
async function warnIfOutdated(client, command) {
	if (![
		"dev",
		"build",
		"start"
	].includes(command)) return;
	try {
		const status = await client.status();
		if (status.status === "error" || !status.packages) return;
		const frameworkPackages = ["everything-dev", "every-plugin"];
		const linked = status.packages.filter((p) => p.isLinked);
		const outdated = status.packages.filter((p) => !p.isLinked && p.installed && p.latest && require_status.compareSemver(p.installed, p.latest) < 0 && frameworkPackages.includes(p.name));
		if (linked.length > 0) for (const pkg of linked) console.log(require_theme.colors.dim(`    ${pkg.name} is linked locally (v${pkg.installed})`));
		if (outdated.length === 0) return;
		const warn = (line) => {
			if (command === "dev" || command === "start") process.stderr.write(`${line}\n`);
			else console.log(line);
		};
		warn("");
		warn(require_theme.colors.yellow(`  ! Outdated packages detected:`));
		for (const pkg of outdated) warn(require_theme.colors.dim(`    ${pkg.name}  ${pkg.installed} → ${pkg.latest}`));
		warn(require_theme.colors.dim(`    Run ${require_theme.colors.cyan("bos upgrade")} to update packages and sync template files.`));
		warn("");
	} catch {}
}
async function main() {
	const args = process.argv.slice(2);
	if (args.includes("--help") || args.includes("-h")) {
		require_help.printHelp();
		return;
	}
	const invocationArgs = args.length > 0 ? args : ["dev"];
	const command = invocationArgs[0] ?? "dev";
	const commandMatch = require_catalog.findCommandDescriptor(invocationArgs);
	if (!commandMatch) {
		console.error(`Unknown command: ${command}`);
		process.exit(1);
	}
	const { descriptor, consumed } = commandMatch;
	const commandArgs = invocationArgs.slice(consumed);
	let parsedInput;
	try {
		parsedInput = require_parse.parseCommandInput(descriptor, commandArgs);
	} catch (error) {
		console.error(`[CLI] ${error instanceof Error ? error.message : String(error)}`);
		process.exit(1);
	}
	const bootInput = parsedInput;
	const cwdConfigPath = require_config.findConfigPath();
	const configPath = bootInput.configPath ?? cwdConfigPath;
	require_bundle_fs_resolve.installBundleFetchFromEnv({ configPath });
	const projectDir = cwdConfigPath ? (0, node_path.dirname)(cwdConfigPath) : void 0;
	const edResolved = projectDir ? require_framework_version.resolveFrameworkPackage(projectDir, "everything-dev") : void 0;
	const displayVersion = edResolved?.installedVersion ? `${edResolved.installedVersion}${edResolved.isLinked ? " (linked)" : ""}` : void 0;
	if (!process.env.BOS_NO_BANNER) require_banner.printBanner("everything-dev", displayVersion);
	const pluginRuntime = (0, every_plugin.createPluginRuntime)({
		registry: { bos: { module: require_plugin.default } },
		secrets: {}
	});
	const client = (await pluginRuntime.usePlugin.bind(pluginRuntime)("bos", {
		variables: {
			configPath: configPath ?? void 0,
			configDir: cwdConfigPath ? (0, node_path.dirname)(cwdConfigPath) : void 0
		},
		secrets: {}
	})).createClient();
	warnIfOutdated(client, command);
	try {
		const input = parsedInput;
		const rollbackInput = input;
		if (descriptor.key === "rollback" && !rollbackInput.listOnly && !rollbackInput.version && !rollbackInput.previous) {
			const listing = await client.rollback({
				...rollbackInput,
				listOnly: true
			});
			if (listing.status !== "list" || !listing.history?.length) {
				console.error(listing.error ?? "No publish history found");
				process.exit(1);
			}
			console.log();
			const selection = await _clack_prompts.select({
				message: "Roll back to which publish?",
				options: listing.history.map((entry) => ({
					value: String(entry.blockHeight),
					label: `${entry.blockTimestamp}  (block ${entry.blockHeight})`,
					hint: entry.summary
				}))
			});
			if (_clack_prompts.isCancel(selection)) return;
			rollbackInput.version = selection;
		}
		if (descriptor.key === "keyPublish") {
			const keyPublishInput = input;
			if (keyPublishInput.removeOldKeys === void 0) {
				if (process.stdin.isTTY) {
					const authored = configPath ? await require_config.readAuthoredConfigInput((0, node_path.dirname)(configPath)) : null;
					const account = keyPublishInput.env === "staging" ? authored?.staging?.account ?? authored?.account : authored?.account;
					let listed = null;
					if (account) {
						const network = require_network.getNetworkIdForAccount(account);
						const contract = require_fastkv.getRegistryNamespaceForAccount(account, keyPublishInput.registry);
						try {
							listed = await require_near_cli.listPublishKeys({
								account,
								contract,
								network
							});
						} catch {
							listed = null;
						}
					}
					if (listed?.length) {
						const removeOldKeys = await _clack_prompts.confirm({
							message: `Remove ${listed.length} existing publish key${listed.length > 1 ? "s" : ""}?`,
							initialValue: true
						});
						if (_clack_prompts.isCancel(removeOldKeys)) return;
						keyPublishInput.removeOldKeys = removeOldKeys;
					} else keyPublishInput.removeOldKeys = true;
				} else keyPublishInput.removeOldKeys = true;
			}
		}
		if (descriptor.key === "dev") {
			const devSpinner = _clack_prompts.spinner();
			devSpinner.start("Starting dev environment");
			const devPhaseLabels = {
				"shared deps": "Preparing config...",
				install: "Installing dependencies...",
				build: "Building...",
				"resolve config": "Resolving config...",
				ports: "Finding available ports...",
				"docker compose up": "Starting local Postgres...",
				"generate artifacts": "Generating code artifacts..."
			};
			const onDevProgress = (event) => {
				const label = devPhaseLabels[event.phase] ?? event.phase;
				if (event.status === "running") devSpinner.message(label);
			};
			require_progress.pluginEvents.on("progress", onDevProgress);
			let result;
			try {
				result = await client.dev(input);
			} finally {
				require_progress.pluginEvents.off("progress", onDevProgress);
			}
			if (result.status === "error") {
				devSpinner.stop("Failed");
				console.error(`[CLI] ${result.description}`);
				process.exit(1);
			}
			devSpinner.stop();
			clearSpinnerStopLine();
			const session = result.session;
			if (session) {
				const { devApp } = await Promise.resolve().then(() => require("./dev-session.cjs"));
				devApp(projectDir ?? process.cwd(), session.orchestrator, session.services, session.runtimeConfig, session.envGenerated, session.shellEnv);
			}
			return;
		}
		if (descriptor.key === "start") {
			const startSpinner = _clack_prompts.spinner();
			startSpinner.start("Starting production environment");
			const startPhaseLabels = {
				config: "Preparing config...",
				"generate artifacts": "Generating code artifacts..."
			};
			const onStartProgress = (event) => {
				const label = startPhaseLabels[event.phase] ?? event.phase;
				if (event.status === "running") startSpinner.message(label);
			};
			require_progress.pluginEvents.on("progress", onStartProgress);
			let result;
			try {
				result = await client.start(input);
			} finally {
				require_progress.pluginEvents.off("progress", onStartProgress);
			}
			if (result.status === "error") {
				startSpinner.stop("Failed");
				console.error(`[CLI] ${result.error || "Unknown error"}`);
				process.exit(1);
			}
			startSpinner.stop("Ready");
			const session = result.session;
			const summary = result.summary;
			if (session) {
				if (summary) printStartSummary(summary);
				const { startApp } = await Promise.resolve().then(() => require("./dev-session.cjs"));
				startApp(projectDir ?? process.cwd(), session.orchestrator, session.services, session.runtimeConfig, session.envGenerated, session.shellEnv);
			}
			return;
		}
		if (descriptor.key === "init") {
			let initInput = { ...input };
			if (!initInput.noInteractive) {
				const basic = await require_prompts.promptInitBasic({
					extends: initInput.extends,
					account: initInput.account,
					domain: initInput.domain
				});
				let parentPluginKeys = [];
				let parentConfig = null;
				const fetchSpinner = _clack_prompts.spinner();
				fetchSpinner.start("Fetching parent config");
				try {
					const parent = await require_init.fetchInitParent(basic.extendsAccount, basic.extendsGateway);
					parentConfig = parent.parentConfig;
					parentPluginKeys = parent.parentPluginKeys;
				} catch {
					fetchSpinner.stop("Config not found");
					console.error(`[CLI] No config found at bos://${basic.extendsAccount}/${basic.extendsGateway}`);
					process.exit(1);
				}
				fetchSpinner.stop("Config fetched");
				if (typeof parentConfig?.title === "string" && parentConfig.title.trim() && typeof parentConfig?.description === "string" && parentConfig.description.trim()) {
					const shouldContinue = await _clack_prompts.confirm({
						message: `You will be extending ${parentConfig.title} - ${parentConfig.description}. Continue?`,
						initialValue: true
					});
					if (_clack_prompts.isCancel(shouldContinue) || !shouldContinue) process.exit(0);
				}
				const overrides = await require_prompts.promptInitOverrides({
					parentPluginKeys,
					plugins: initInput.plugins,
					overrides: initInput.overrides,
					level: initInput.level
				});
				const directory = initInput.directory || basic.domain || basic.extendsGateway;
				initInput = {
					...initInput,
					extends: `bos://${basic.extendsAccount}/${basic.extendsGateway}`,
					directory,
					account: basic.account,
					domain: basic.domain || void 0,
					plugins: overrides.plugins,
					overrides: overrides.overrides,
					level: overrides.level ?? initInput.level,
					noInteractive: true
				};
			}
			const initSpinner = _clack_prompts.spinner();
			initSpinner.start("Initializing project");
			const phaseLabels = {
				"parent config": "Fetching parent config...",
				"template source": "Resolving template source...",
				"scaffold project": "Creating project scaffold...",
				"copy files": "Copying template files...",
				"personalize config": "Personalizing config...",
				"write snapshot": "Writing snapshot...",
				"resolve config": "Resolving config...",
				"generate env/docker": "Generating environment config...",
				"create env file": "Creating .env file...",
				"install dependencies": "Installing dependencies...",
				"generate types": "Generating types...",
				"generate migrations": "Generating database migrations...",
				"generate code artifacts": "Generating code artifacts..."
			};
			const onProgress = (event) => {
				const label = phaseLabels[event.phase] ?? event.phase;
				if (event.status === "running") initSpinner.message(label);
			};
			require_progress.pluginEvents.on("progress", onProgress);
			let result;
			try {
				result = await client.init(initInput);
			} finally {
				require_progress.pluginEvents.off("progress", onProgress);
			}
			if (result.status === "error") {
				initSpinner.stop("Failed");
				console.error(`[CLI] ${result.error || "Unknown error"}`);
				process.exit(1);
			}
			initSpinner.stop("Project initialized");
			console.log(`  ${require_theme.colors.dim("Extends:")} ${result.extends}`);
			console.log(`  ${require_theme.colors.dim("Directory:")} ${result.directory}`);
			if (result.account) console.log(`  ${require_theme.colors.dim("Account:")} ${result.account}`);
			if (result.domain) console.log(`  ${require_theme.colors.dim("Domain:")} ${result.domain}`);
			if (result.overrides && result.overrides.length > 0) console.log(`  ${require_theme.colors.dim("Overrides:")} ${result.overrides.join(", ")}`);
			if (result.plugins && result.plugins.length > 0) console.log(`  ${require_theme.colors.dim("Plugins:")} ${result.plugins.join(", ")}`);
			console.log(`  ${require_theme.colors.dim("Files copied:")} ${result.filesCopied}`);
			printTimingSummary(result.timings);
			console.log();
			console.log(require_theme.colors.dim("  Next steps:"));
			console.log(require_theme.colors.dim(`    cd ${result.directory}`));
			if (!initInput.noInstall) console.log(require_theme.colors.dim("    pnpm run dev"));
			else {
				console.log(require_theme.colors.dim("    pnpm install"));
				console.log(require_theme.colors.dim("    pnpm run dev"));
			}
			console.log();
			if (initInput.noInteractive !== true && !initInput.noInstall && result.targetDir) {
				if (await _clack_prompts.confirm({
					message: "Run docker compose up -d --wait?",
					initialValue: true
				}) === true) {
					const dockerSpinner = _clack_prompts.spinner();
					dockerSpinner.start("Starting Docker services");
					const compose = await require_docker.runDockerComposeUp(result.targetDir);
					if (compose.ok) dockerSpinner.stop("Docker services ready");
					else {
						dockerSpinner.stop("Docker services not started");
						_clack_prompts.log.warn(`docker compose up -d --wait failed${compose.tail ? `:\n${compose.tail}` : ""}`);
					}
				}
			}
			return;
		}
		const result = await client[descriptor.key](input);
		if (descriptor.key === "dbStudio") {
			if (result.status === "error") {
				console.error(`[CLI] ${result.error || "Unknown error"}`);
				process.exit(1);
			}
			return;
		}
		if (descriptor.key === "dbDoctor") {
			if (result.status === "error") {
				console.error(`[CLI] ${result.error || "Diagnosis failed"}`);
				process.exit(1);
			}
			const statusIcon = (() => {
				switch (result.diagnosis) {
					case "healthy": return "✓";
					case "empty": return "○";
					case "unapplied": return "○";
					case "untracked-existing-schema": return "○";
					case "drift-safe-repair": return "⚠";
					case "drift-manual": return "✗";
					default: return "?";
				}
			})();
			console.log(`\n${statusIcon}  ${result.plugin}`);
			console.log(`  ${require_theme.colors.dim(`Journal:`)} ${result.journalSchema}.${result.journalTable}`);
			console.log(`  ${require_theme.colors.dim(`Local migrations:`)} ${result.localMigrationCount}`);
			console.log(`  ${require_theme.colors.dim(`Applied hashes:`)} ${result.appliedHashCount}`);
			if (result.expectedTables.length > 0) console.log(`  ${require_theme.colors.dim(`Expected tables:`)} ${result.expectedTables.join(", ")}`);
			if (result.missingTables.length > 0) console.log(`  ${require_theme.colors.yellow(`Missing tables:`)} ${result.missingTables.join(", ")}`);
			console.log(`  ${require_theme.colors.dim(`Diagnosis:`)} ${result.diagnosis}`);
			if (result.workspaceDir) console.log(`  ${require_theme.colors.dim(`Workspace:`)} ${result.workspaceDir}`);
			console.log();
			return;
		}
		if (descriptor.key === "dbRepair") {
			if (result.status === "refused") {
				console.log(`\n${require_theme.colors.yellow("!")}  Repair refused for ${result.diagnosis?.plugin ?? result.message}`);
				console.log(`  ${result.message}`);
				console.log();
				process.exit(0);
			}
			if (result.status === "error") {
				console.error(`\n${require_theme.colors.error("✗")}  Repair failed`);
				console.error(`  ${result.message}`);
				console.error();
				process.exit(1);
			}
			console.log(`\n${require_theme.colors.green("✓")}  Repair complete`);
			console.log(`  ${result.message}`);
			console.log();
			return;
		}
		if (descriptor.key === "config") {
			if (!result.config) {
				console.error(require_config.MISSING_CONFIG_MESSAGE);
				process.exit(1);
			}
			printConfigView(result.config);
			process.stdout.write(`${JSON.stringify(result.config, null, 2)}\n`);
			return;
		}
		if (descriptor.key === "sync") {
			if (input.json) {
				console.log(JSON.stringify(result, null, 2));
				return;
			}
			console.log();
			if (result.status === "error") {
				console.error(`[CLI] ${result.error || "Unknown error"}`);
				process.exit(1);
			}
			if (result.status === "dry-run") console.log(require_theme.colors.cyan(`${require_theme.icons.ok} Dry run — no files written`));
			else console.log(require_theme.colors.green(`${require_theme.icons.ok} Synced`));
			const hasRetirement = (result.retired?.length ?? 0) > 0 || (result.retiredConflicted?.length ?? 0) > 0;
			if (result.updated.length > 0 || result.added.length > 0 || result.conflicted.length > 0 || hasRetirement) {
				console.log(`  ${require_theme.colors.dim("Sync results:")} ${result.updated.length} updated, ${result.added.length} added, ${result.conflicted.length} conflicted`);
				if (result.updated.length > 0) for (const f of result.updated) console.log(`    ${require_theme.colors.dim(f)}`);
				if (result.added.length > 0) for (const f of result.added) console.log(`    ${require_theme.colors.dim(f)}`);
				if (result.conflicted.length > 0) {
					console.log(`  ${require_theme.colors.yellow("Conflicted")} (template applied, your changes backed up):`);
					if (result.backupDir) console.log(`    ${require_theme.colors.dim(result.backupDir)}`);
					for (const f of result.conflicted) console.log(`    ${require_theme.colors.dim(f)}`);
				}
				if (hasRetirement) {
					console.log(`  ${require_theme.colors.yellow("Retired")} (replaced by generated stubs — ADR 0023):`);
					if (result.retiredBackupDir) console.log(`    ${require_theme.colors.dim(result.retiredBackupDir)}`);
					for (const f of result.retiredConflicted ?? []) console.log(`    ${require_theme.colors.dim(`${f} (backed up)`)}`);
					for (const f of result.retired ?? []) console.log(`    ${require_theme.colors.dim(f)}`);
					printStubMigrationGuide(result.retiredConflicted);
				}
			}
			if (result.updated.length === 0 && result.added.length === 0 && result.conflicted.length === 0 && !hasRetirement) console.log(`  ${require_theme.colors.dim("Already up to date")}`);
			console.log();
			return;
		}
		if (descriptor.key === "upgrade") {
			if (input.json) {
				console.log(JSON.stringify(result, null, 2));
				return;
			}
			console.log();
			if (result.status === "error") {
				console.error(`[CLI] ${result.error || "Unknown error"}`);
				process.exit(1);
			}
			if (result.status === "dry-run") console.log(require_theme.colors.cyan(`${require_theme.icons.ok} Dry run — no changes applied`));
			else console.log(require_theme.colors.green(`${require_theme.icons.ok} Upgrade complete`));
			const mainPkg = result.packages.find((p) => p.name === "everything-dev");
			const versionDelta = mainPkg?.from && mainPkg.from !== mainPkg.to ? `${mainPkg.from} → ${mainPkg.to}` : null;
			if (versionDelta) console.log(`  ${require_theme.colors.dim(`Upgraded everything-dev ${versionDelta}`)}`);
			for (const pkg of result.packages) {
				if (pkg.name === "everything-dev") continue;
				if (pkg.from && pkg.from !== pkg.to) console.log(`  ${require_theme.colors.dim(`${pkg.name}  ${pkg.from} → ${pkg.to}`)}`);
				else if (!pkg.from) console.log(`  ${require_theme.colors.dim(`${pkg.name}  ${pkg.to} (new)`)}`);
				else console.log(`  ${require_theme.colors.dim(`${pkg.name}  ${pkg.to} (up to date)`)}`);
			}
			if (result.changelogUrl) console.log(`  Changelog: ${result.changelogUrl}`);
			if (result.selectedPlugins && result.selectedPlugins.length > 0) console.log(`  Added plugins: ${result.selectedPlugins.join(", ")}`);
			if (result.sync) {
				const sync = result.sync;
				const hasRetirement = (sync.retired?.length ?? 0) > 0 || (sync.retiredConflicted?.length ?? 0) > 0;
				console.log(`  ${require_theme.colors.dim("Sync results:")}`);
				if (sync.updated.length > 0 || sync.added.length > 0 || sync.conflicted.length > 0 || hasRetirement) {
					console.log(`  ${sync.updated.length} updated, ${sync.added.length} added, ${sync.conflicted.length} conflicted`);
					if (sync.conflicted.length > 0) {
						console.log(`  ${require_theme.colors.yellow("Conflicted")} (template applied, your changes backed up):`);
						if (sync.backupDir) console.log(`    ${require_theme.colors.dim(sync.backupDir)}`);
						for (const f of sync.conflicted) console.log(`    ${require_theme.colors.dim(f)}`);
					}
					if (hasRetirement) {
						console.log(`  ${require_theme.colors.yellow("Retired")} (replaced by generated stubs — ADR 0023):`);
						if (sync.retiredBackupDir) console.log(`    ${require_theme.colors.dim(sync.retiredBackupDir)}`);
						for (const f of sync.retiredConflicted ?? []) console.log(`    ${require_theme.colors.dim(`${f} (backed up)`)}`);
						for (const f of sync.retired ?? []) console.log(`    ${require_theme.colors.dim(f)}`);
						printStubMigrationGuide(sync.retiredConflicted);
					}
				} else console.log(`  ${require_theme.colors.dim("Already up to date")}`);
			}
			if (result.migrated && result.migrated.length > 0) {
				console.log(`  Migrated: ${result.migrated.length} file(s)`);
				for (const f of result.migrated) console.log(`    ${require_theme.colors.dim(f)}`);
			}
			if (versionDelta || result.sync && result.sync.conflicted.length > 0) {
				console.log();
				console.log(require_theme.colors.dim("  For AI agents:"));
				const parentRepo = "nearbuilders/everything-dev";
				const somedelta = mainPkg?.from && mainPkg.to ? `v${mainPkg.from.replace(/^[\^~>=v]+/, "")}...v${mainPkg.to.replace(/^[\^~>=v]+/, "")}` : "";
				console.log(require_theme.colors.dim(`  This upgrade applied template changes${somedelta ? ` (${somedelta})` : ""}.`));
				if (result.sync && result.sync.conflicted.length > 0) {
					console.log(require_theme.colors.dim(`  ${result.sync.conflicted.length} file(s) had local conflicts — template version applied, backups at ${result.sync.backupDir || ".bos/sync-backup/"}.`));
					console.log(require_theme.colors.dim(`  If local changes should be preserved upstream, open a PR: https://github.com/${parentRepo}${somedelta ? `/compare/${somedelta}` : ""}`));
				}
				console.log(require_theme.colors.dim("  Load matching intent skills: pnpm dlx @tanstack/intent@latest load everything-dev#..."));
				console.log(require_theme.colors.dim("  Review AGENTS.md — local updates may need merging."));
			}
			console.log();
			return;
		}
		if (descriptor.key === "status") {
			console.log();
			if (result.status === "error") {
				console.error(`[CLI] ${result.error || "Unknown error"}`);
				process.exit(1);
			}
			console.log(require_theme.colors.cyan(require_theme.frames.top(52)));
			console.log(`  ${require_theme.icons.app} ${require_theme.gradients.cyber("STATUS")}`);
			console.log(require_theme.colors.cyan(require_theme.frames.bottom(52)));
			console.log();
			if (result.extends) console.log(`  ${require_theme.colors.dim("Extends:")}     ${result.extends}`);
			if (result.account) console.log(`  ${require_theme.colors.dim("Account:")}     ${result.account}`);
			if (result.domain) console.log(`  ${require_theme.colors.dim("Domain:")}      ${result.domain}`);
			console.log();
			console.log(`  ${require_theme.colors.dim("Packages:")}`);
			for (const pkg of result.packages) {
				const hasUpdate = pkg.installed && pkg.latest && require_status.compareSemver(pkg.installed, pkg.latest) < 0;
				const versionStr = hasUpdate ? `${pkg.installed}  →  ${pkg.latest}` : pkg.installed || "not installed";
				const label = hasUpdate ? require_theme.colors.yellow(versionStr) : require_theme.colors.dim(versionStr);
				console.log(`    ${require_theme.colors.dim(`${pkg.name}`)}  ${label}`);
			}
			console.log();
			if (result.lastSync) {
				const ago = formatTimeAgo(result.lastSync);
				console.log(`  ${require_theme.colors.dim("Last sync:")}   ${ago}`);
			} else console.log(`  ${require_theme.colors.dim("Last sync:")}   never`);
			const envLabel = result.envFile === "found" ? require_theme.colors.green("found") : result.envFile === "example-only" ? require_theme.colors.yellow("missing (only .env.example found)") : require_theme.colors.error("missing");
			console.log(`  ${require_theme.colors.dim(".env:")}         ${envLabel}`);
			if (result.parentReachable !== void 0) {
				const parentLabel = result.parentReachable ? require_theme.colors.green("reachable") : require_theme.colors.error("unreachable");
				console.log(`  ${require_theme.colors.dim("Parent:")}      ${parentLabel}`);
			}
			if (result.packages.some((p) => p.installed && p.latest && require_status.compareSemver(p.installed, p.latest) < 0)) {
				console.log();
				console.log(require_theme.colors.dim(`  Run ${require_theme.colors.cyan("bos upgrade")} to update packages and sync template files.`));
			}
			console.log();
			return;
		}
		if (descriptor.key === "ps") {
			const psResult = result;
			console.log();
			if (psResult.status === "error") {
				console.error(`[CLI] ${psResult.error || "Unknown error"}`);
				process.exit(1);
			}
			const entries = psResult.entries ?? [];
			if (entries.length === 0) {
				console.log(require_theme.colors.dim("  No tracked development processes running."));
				console.log();
				console.log(require_theme.colors.dim(`  Start one with ${require_theme.colors.cyan("bos dev")} and it will appear here.`));
				console.log();
				return;
			}
			console.log(require_theme.colors.cyan(require_theme.frames.top(60)));
			console.log(`  ${require_theme.icons.app} ${require_theme.gradients.cyber("PROCESSES")}`);
			console.log(require_theme.colors.cyan(require_theme.frames.bottom(60)));
			console.log();
			for (const entry of entries) {
				const ageMs = Date.now() - entry.startedAt;
				const ageStr = ageMs < 6e4 ? `${Math.floor(ageMs / 1e3)}s` : ageMs < 36e5 ? `${Math.floor(ageMs / 6e4)}m` : `${Math.floor(ageMs / 36e5)}h`;
				const roleTag = entry.role === "workspace-parent" ? require_theme.colors.magenta("parent") : entry.role === "workspace-child" ? require_theme.colors.blue("child") : require_theme.colors.dim("dev");
				console.log(`  ${require_theme.colors.green(`pid ${entry.pid}`)}  ${roleTag}  ${require_theme.colors.dim(ageStr)}`);
				console.log(`    ${require_theme.colors.dim("dir:")}    ${entry.configDir}`);
				if (entry.parentPid !== void 0) console.log(`    ${require_theme.colors.dim("parent:")} ${entry.parentPid}`);
				const portPairs = Object.entries(entry.ports ?? {}).filter(([, p]) => typeof p === "number").map(([k, v]) => `${k}=${v}`);
				if (portPairs.length > 0) console.log(`    ${require_theme.colors.dim("ports:")}  ${portPairs.join("  ")}`);
				if (entry.budget) console.log(`    ${require_theme.colors.dim("budget:")} [${entry.budget.min}, ${entry.budget.max}]`);
				console.log(`    ${require_theme.colors.dim("desc:")}   ${entry.description}`);
				console.log();
			}
			return;
		}
		if (descriptor.key === "logs") {
			const logsResult = result;
			const opts = input;
			for (const line of logsResult.lines) console.log(line);
			if (logsResult.lines.length === 0) console.log(require_theme.colors.dim(`  No matching log lines in ${logsResult.logFile}.`));
			if (opts.follow) {
				if (logsResult.logFile === "unknown" || !(0, node_fs.existsSync)(logsResult.logFile)) console.log(require_theme.colors.dim("  No log file to follow — nothing was found on disk."));
				else {
					const filter = opts.service;
					let byteOffset = 0;
					for (const line of logsResult.lines) byteOffset += Buffer.byteLength(line, "utf8") + 1;
					const followMatch = (line) => {
						if (!filter) return true;
						const source = /\] \[([^\]]+)\] \[(?:OUT|ERR)\] /.exec(line)?.[1];
						return source === filter || source === `plugin:${filter}`;
					};
					const watcher = (0, node_fs.watch)(logsResult.logFile, (event) => {
						if (event !== "change") return;
						(0, node_fs_promises.readFile)(logsResult.logFile, "utf8").then((text) => {
							const newLines = text.slice(byteOffset).split("\n").filter((line) => line.length > 0 && followMatch(line));
							byteOffset = Buffer.byteLength(text, "utf8");
							for (const line of newLines) console.log(line);
						}).catch(() => {
							watcher.close();
						});
					});
					console.log(require_theme.colors.dim("  Following — Ctrl+C to stop."));
					process.on("SIGINT", () => {
						watcher.close();
						process.exit(0);
					});
				}
			}
			return;
		}
		if (descriptor.key === "kill") {
			const killResult = result;
			console.log();
			if (killResult.status === "error") {
				console.error(`[CLI] ${killResult.error || "Unknown error"}`);
				process.exit(1);
			}
			if (killResult.killed.length > 0) {
				console.log(require_theme.colors.green(`${require_theme.icons.ok} Sent ${killResult.killed.length} kill signal(s)`));
				for (const k of killResult.killed) console.log(`  ${require_theme.colors.dim("pid")} ${k.pid}  ${require_theme.colors.dim(k.configDir)}`);
			}
			if (killResult.skipped.length > 0) {
				console.log(require_theme.colors.yellow(`${require_theme.icons.err} ${killResult.skipped.length} skipped`));
				for (const s of killResult.skipped) console.log(`  ${require_theme.colors.dim("pid")} ${s.pid}  ${require_theme.colors.dim(s.reason)}`);
			}
			if (killResult.killed.length === 0 && killResult.skipped.length === 0) {
				const opts = input;
				if (opts.all) console.log(require_theme.colors.dim("  No tracked processes to kill."));
				else {
					const configPath = require_config.findConfigPath();
					const dir = opts.configDir ?? (configPath ? (0, node_path.resolve)((0, node_path.dirname)(configPath)) : process.cwd());
					console.log(require_theme.colors.dim(`  No tracked processes for ${dir}`));
					console.log(require_theme.colors.dim(`  Use ${require_theme.colors.cyan("--all")} to kill across all directories.`));
				}
			}
			console.log();
			return;
		}
		if (descriptor.key === "typesGen") {
			console.log();
			if (result.status === "error") {
				console.error(`[CLI] ${result.error || "Unknown error"}`);
				process.exit(1);
			}
			console.log(require_theme.colors.green(`${require_theme.icons.ok} Types generated`));
			if (result.generated.length > 0) {
				console.log(`  ${require_theme.colors.dim("Written:")}`);
				for (const f of result.generated) console.log(`    ${require_theme.colors.dim(f)}`);
			}
			if (result.fetched.length > 0 || result.skipped.length > 0 || result.failed.length > 0) {
				console.log(`  ${require_theme.colors.dim("Contract sources:")}`);
				for (const entry of result.fetched) {
					const space = entry.indexOf(" ");
					const key = space !== -1 ? entry.slice(0, space) : entry;
					const rest = space !== -1 ? entry.slice(space + 1) : "";
					const restSpace = rest.indexOf(" ");
					const detail = restSpace !== -1 ? rest.slice(restSpace + 1) : "";
					console.log(`    ${key} ${require_theme.colors.cyan("remote")}${detail ? ` ${require_theme.colors.dim(detail)}` : ""}`);
				}
				for (const entry of result.skipped) {
					const space = entry.indexOf(" ");
					const key = space !== -1 ? entry.slice(0, space) : entry;
					const rest = space !== -1 ? entry.slice(space + 1) : "";
					if (rest === "no URL resolved") {
						console.log(`    ${key} ${require_theme.colors.dim("no URL resolved")}`);
						continue;
					}
					const restSpace = rest.indexOf(" ");
					const detail = restSpace !== -1 ? rest.slice(restSpace + 1) : "";
					console.log(`    ${key} ${require_theme.colors.dim("local")}${detail ? ` ${require_theme.colors.dim(detail)}` : ""}`);
				}
			}
			if (result.failed.length > 0) {
				console.log(`  ${require_theme.colors.yellow("Failed:")}`);
				for (const f of result.failed) {
					const colon = f.indexOf(": ");
					if (colon !== -1) console.log(`    ${require_theme.colors.error(f.slice(0, colon))}${require_theme.colors.dim(f.slice(colon))}`);
					else console.log(`    ${require_theme.colors.error(f)}`);
				}
			}
			console.log();
			return;
		}
		if (descriptor.key === "typecheck") {
			console.log();
			if (result.status === "error") {
				console.error(`[CLI] ${result.error || "Unknown error"}`);
				process.exit(1);
			}
			const failed = result.results.filter((r) => !r.passed);
			const passed = result.results.filter((r) => r.passed);
			console.log(require_theme.colors.cyan(require_theme.frames.top(52)));
			console.log(`  ${require_theme.icons.app} ${require_theme.gradients.cyber("TYPECHECK")}`);
			console.log(require_theme.colors.cyan(require_theme.frames.bottom(52)));
			console.log();
			for (const r of result.results) {
				const icon = r.passed ? require_theme.colors.green("✓") : require_theme.colors.error("✗");
				console.log(`  ${icon} ${r.workspace}`);
			}
			if (result.skipped.length > 0) console.log(`  ${require_theme.colors.dim(`Skipped: ${result.skipped.join(", ")}`)}`);
			console.log();
			if (failed.length > 0) {
				console.log(`  ${require_theme.colors.error(`${failed.length} failed`)}`);
				for (const f of failed) if (f.error) console.log(`    ${require_theme.colors.dim(f.error)}`);
				console.log();
				process.exit(1);
			}
			console.log(`  ${require_theme.colors.green(`${passed.length} passed`)}`);
			console.log();
			return;
		}
		if (descriptor.key === "mfCheck") {
			console.log();
			console.log(`  ${require_theme.colors.dim("Host")}   ${result.hostReachable ? require_theme.colors.green("OK  ") : require_theme.colors.error("FAIL")}  ${result.hostVersion ?? "unreachable"}${result.hostReason ? `  (${result.hostReason})` : ""}`);
			for (const r of result.remotes) {
				const tag = r.ok ? require_theme.colors.green("OK  ") : require_theme.colors.error("FAIL");
				console.log(`  ${require_theme.colors.dim(r.role.padEnd(10))} ${tag} ${r.url}  pluginVersion=${r.pluginVersion ?? "?"}${r.reason ? `  ↳ ${r.reason}` : ""}`);
			}
			console.log();
			if (result.status !== "ok") {
				console.log(require_theme.colors.error("  mf-compat: ✗ federation manifests NOT compatible — redeploy affected plugin(s) so pluginVersion and shared versions match host"));
				console.log();
				process.exit(1);
			}
			console.log(require_theme.colors.green("  mf-compat: ✓ all federation manifests compatible"));
			console.log();
			return;
		}
		if (result?.status === "error" && descriptor.key !== "publish" && descriptor.key !== "deploy") {
			console.error(`[CLI] ${result.error || "Unknown error"}`);
			process.exit(1);
		}
		if (descriptor.key === "login") {
			console.log();
			console.log(require_theme.colors.green(`${require_theme.icons.ok} Logged in to ${result.siteUrl}`));
			if (result.accountId) console.log(`  ${require_theme.colors.dim("Account:")} ${result.accountId}`);
			if (result.expiresAt) console.log(`  ${require_theme.colors.dim("Expires:")} ${result.expiresAt}`);
			if (result.warning) console.log(`  ${require_theme.colors.yellow("⚠")} ${result.warning}`);
			if (result.publishKey) console.log(`  ${require_theme.colors.dim("Publish key:")} ${result.publishKey.publicKey} ${require_theme.colors.dim(`(${result.publishKey.network}, exported to ${result.publishKey.exportedTo})`)}`);
			console.log();
			return;
		}
		if (descriptor.key === "logout") {
			console.log();
			console.log(require_theme.colors.green(`${require_theme.icons.ok} Logged out`));
			if (result.revokedApiKey) console.log(`  ${require_theme.colors.dim("Revoked API key")}`);
			if (result.removedPublishKey) console.log(`  ${require_theme.colors.dim("Removed exported publish key")}`);
			if (result.warning) console.log(`  ${require_theme.colors.yellow("⚠")} ${result.warning}`);
			console.log();
			return;
		}
		if (descriptor.key === "keyPublish") {
			process.stdout.write(`Generated publish key for ${result.account}\n`);
			process.stdout.write(`  Network: ${result.network}\n`);
			process.stdout.write(`  Allowance: ${result.allowance}\n`);
			process.stdout.write(`\n`);
			const secretName = result.env === "staging" ? "NEAR_TESTNET_PRIVATE_KEY" : "NEAR_PRIVATE_KEY";
			if (!process.stdout.isTTY) process.stderr.write(`  ⚠ Non-interactive stdout: this private key will be captured in any log or pipe (GitHub Actions logs persist stdout).\n`);
			process.stdout.write(`  Set this as ${secretName} in GitHub Actions or before calling publish:\n`);
			process.stdout.write(`${secretName}=${result.privateKey}\n`);
		}
		if (descriptor.key === "pluginAdd") {
			console.log();
			console.log(require_theme.colors.green(`${require_theme.icons.ok} Added plugin ${result.key}`));
			if (result.development) console.log(`  ${require_theme.colors.dim("Development:")} ${result.development}`);
			if (result.production) console.log(`  ${require_theme.colors.dim("Production:")} ${result.production}`);
			console.log();
			return;
		}
		if (descriptor.key === "pluginRemove") {
			console.log();
			console.log(require_theme.colors.green(`${require_theme.icons.ok} Removed plugin ${result.key}`));
			console.log();
			return;
		}
		if (descriptor.key === "pluginList") {
			console.log();
			console.log(require_theme.colors.cyan(require_theme.frames.top(52)));
			console.log(`  ${require_theme.icons.config} ${require_theme.gradients.cyber("PLUGINS")}`);
			console.log(require_theme.colors.cyan(require_theme.frames.bottom(52)));
			console.log();
			if (result.plugins.length === 0) console.log(require_theme.colors.dim("  No plugins configured"));
			else for (const pluginItem of result.plugins) {
				console.log(`  ${require_theme.colors.cyan(pluginItem.key)}`);
				if (pluginItem.development) console.log(`    ${require_theme.colors.dim("Development:")} ${pluginItem.development}`);
				if (pluginItem.production) console.log(`    ${require_theme.colors.dim("Production:")} ${pluginItem.production}`);
			}
			console.log();
			return;
		}
		if (descriptor.key === "pluginPublish") {
			console.log();
			console.log(require_theme.colors.green(`${require_theme.icons.ok} Published plugin ${result.key}`));
			if (result.path) console.log(`  ${require_theme.colors.dim("Path:")} ${result.path}`);
			if (result.production) console.log(`  ${require_theme.colors.dim("Production:")} ${result.production}`);
			if (result.version) console.log(`  ${require_theme.colors.dim("Version:")} ${result.version}`);
			if (result.fingerprint) console.log(`  ${require_theme.colors.dim("Fingerprint:")} ${result.fingerprint}`);
			console.log();
			return;
		}
		if (descriptor.key === "registryUse") {
			console.log();
			if (result.status === "error") {
				console.error(require_theme.colors.error(`${require_theme.icons.err} ${result.error || "Unknown error"}`));
				process.exit(1);
			}
			console.log(require_theme.colors.green(`${require_theme.icons.ok} ${result.status === "dry-run" ? "Dry run" : "Composed"} from ${result.from}`));
			for (const section of result.applied) console.log(`  ${require_theme.colors.green("+")} ${section}`);
			if (result.configPath) console.log(`  ${require_theme.colors.dim("Config:")} ${result.configPath}`);
			if (result.status === "updated") console.log(require_theme.colors.dim("  Run bos types gen to refresh generated types."));
			console.log();
			return;
		}
		if (descriptor.key === "publish") {
			if (result.status === "dry-run") {
				console.log();
				console.log(require_theme.colors.cyan(`${require_theme.icons.ok} Dry run complete`));
				console.log(`  ${require_theme.colors.dim("Registry URL:")} ${result.registryUrl}`);
				console.log();
				return;
			}
			if (result.status === "error") {
				console.log();
				console.log(require_theme.colors.error(`${require_theme.icons.err} Publish failed`));
				if (result.error) console.log(`  ${require_theme.colors.dim("Error:")} ${result.error}`);
				if (result.deployResults && result.deployResults.length > 0) {
					const failures = result.deployResults.filter((r) => !r.success);
					if (failures.length > 0) {
						console.log();
						for (const f of failures) {
							const errorLine = (f.error ?? "Failed").split("\n")[0];
							console.log(`  ${require_theme.colors.error(require_theme.icons.err)} ${f.key}: ${errorLine}`);
						}
					}
				}
				console.log();
				process.exit(1);
			}
			if (result.status === "published") {
				console.log();
				console.log(require_theme.colors.green(`${require_theme.icons.ok} Published successfully`));
				console.log(`  ${require_theme.colors.dim("Registry URL:")} ${result.registryUrl}`);
				if (result.txHash) console.log(`  ${require_theme.colors.dim("Transaction:")} ${result.txHash}`);
				if (result.built && result.built.length > 0) console.log(`  ${require_theme.colors.dim("Built:")} ${result.built.join(", ")}`);
				if (result.skipped && result.skipped.length > 0) console.log(`  ${require_theme.colors.dim("Skipped:")} ${result.skipped.join(", ")}`);
				if (result.deployResults) {
					const warnings = result.deployResults.flatMap((r) => r.warnings ?? []);
					if (warnings.length > 0) {
						console.log();
						console.log(`  ${require_theme.colors.yellow("⚠")} Build warnings:`);
						for (const w of warnings) console.log(`    ${require_theme.colors.dim(w)}`);
					}
				}
				console.log();
				return;
			}
		}
		if (descriptor.key === "rollback") {
			const rollbackResult = result;
			if (rollbackResult.status === "error") {
				console.log();
				console.log(require_theme.colors.error(`${require_theme.icons.err} Roll back failed`));
				if (rollbackResult.error) console.log(`  ${require_theme.colors.dim("Error:")} ${rollbackResult.error}`);
				if (rollbackResult.verification) {
					console.log();
					for (const check of rollbackResult.verification) {
						const mark = check.ok ? require_theme.colors.green(require_theme.icons.ok) : require_theme.colors.error(require_theme.icons.err);
						const reason = check.reason ? require_theme.colors.dim(` — ${check.reason}`) : "";
						console.log(`  ${mark} ${check.slot}${reason}`);
					}
				}
				console.log();
				process.exit(1);
			}
			if (rollbackResult.status === "dry-run") {
				console.log();
				console.log(require_theme.colors.cyan(`${require_theme.icons.ok} Rollback dry run complete`));
				console.log(`  ${require_theme.colors.dim("Registry URL:")} ${rollbackResult.registryUrl}`);
				console.log();
				return;
			}
			console.log();
			console.log(require_theme.colors.green(`${require_theme.icons.ok} Rolled back`));
			console.log(`  ${require_theme.colors.dim("Registry URL:")} ${rollbackResult.registryUrl}`);
			if (rollbackResult.txHash) console.log(`  ${require_theme.colors.dim("Transaction:")} ${rollbackResult.txHash}`);
			console.log();
			return;
		}
		if (descriptor.key === "deploy") {
			const deployResult = result;
			if (deployResult.status === "list") {
				console.log();
				console.log(require_theme.colors.cyan("Recent publishes (audit trail)"));
				for (const entry of deployResult.history ?? []) console.log(`  ${entry.blockTimestamp}  ${require_theme.colors.dim(`block ${entry.blockHeight}`)}${entry.publishedAt ? require_theme.colors.dim(`  ${entry.publishedAt}`) : ""}`);
				console.log();
				return;
			}
			if (deployResult.fingerprint) console.log(`  ${require_theme.colors.dim("Fingerprint:")} ${deployResult.fingerprint}`);
			if (deployResult.status === "dry-run") {
				console.log();
				console.log(require_theme.colors.cyan(`${require_theme.icons.ok} Dry run complete`));
				console.log(`  ${require_theme.colors.dim("Registry URL:")} ${deployResult.registryUrl}`);
				console.log();
				return;
			}
			if (deployResult.status === "error") {
				console.log();
				console.log(require_theme.colors.error(`${require_theme.icons.err} Deploy failed`));
				if (deployResult.error) console.log(`  ${require_theme.colors.dim("Error:")} ${deployResult.error}`);
				if (deployResult.deployResults && deployResult.deployResults.length > 0) {
					const failures = deployResult.deployResults.filter((r) => !r.success);
					if (failures.length > 0) {
						console.log();
						for (const f of failures) {
							const errorLine = (f.error ?? "Failed").split("\n")[0];
							console.log(`  ${require_theme.colors.error(require_theme.icons.err)} ${f.key}: ${errorLine}`);
						}
					}
				}
				console.log();
				process.exit(1);
			}
			if (deployResult.status === "deployed") {
				console.log();
				console.log(require_theme.colors.green(`${require_theme.icons.ok} Deployed successfully`));
				console.log(`  ${require_theme.colors.dim("Registry URL:")} ${deployResult.registryUrl}`);
				if (deployResult.txHash) console.log(`  ${require_theme.colors.dim("Transaction:")} ${deployResult.txHash}`);
				if (deployResult.built && deployResult.built.length > 0) console.log(`  ${require_theme.colors.dim("Built:")} ${deployResult.built.join(", ")}`);
				if (deployResult.skipped && deployResult.skipped.length > 0) console.log(`  ${require_theme.colors.dim("Skipped:")} ${deployResult.skipped.join(", ")}`);
				if (deployResult.deployResults) {
					const warnings = deployResult.deployResults.flatMap((r) => r.warnings ?? []);
					if (warnings.length > 0) {
						console.log();
						console.log(`  ${require_theme.colors.yellow("⚠")} Build warnings:`);
						for (const w of warnings) console.log(`    ${require_theme.colors.dim(w)}`);
					}
				}
				if (deployResult.image) console.log(`  ${require_theme.colors.dim("Image:")} ${deployResult.image}`);
				if (deployResult.service) console.log(`  ${require_theme.colors.dim("Railway:")} deployed ${deployResult.service}`);
				console.log();
				return;
			}
			if (deployResult.status === "published") {
				console.log();
				console.log(require_theme.colors.yellow(`${require_theme.icons.err} Config published, but a deploy leg failed`));
				console.log(`  ${require_theme.colors.dim("Registry URL:")} ${deployResult.registryUrl}`);
				if (deployResult.txHash) console.log(`  ${require_theme.colors.dim("Transaction:")} ${deployResult.txHash}`);
				if (deployResult.error) console.log(`  ${require_theme.colors.dim("Error:")} ${deployResult.error}`);
				console.log();
				process.exit(1);
			}
		}
		if (descriptor.key === "infraExport") {
			process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
			return;
		}
	} catch (error) {
		console.error(`[CLI] ${error instanceof Error ? error.message : String(error)}`);
		process.exit(1);
	}
}
main().catch((error) => {
	console.error("[CLI] Fatal error:", error);
	process.exit(1);
});

//#endregion
//# sourceMappingURL=cli.cjs.map