everything-dev
Version:
A consolidated product package for building Module Federation apps with oRPC APIs.
1,030 lines • 51.3 kB
JavaScript
#!/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