#!/usr/bin/env node
import { En as composeTurnMiddleware, Mt as applyTemplate, Nt as prepareAgentRun, _ as withContextOverflowRecovery, b as prepareReplyTurn, dt as resolveCommitHash, sn as installUnhandledRejectionHandler, t as runAgentTurn, x as withContextUsageWarning, y as buildAgentTurnParams } from "./unified-runner-4O0ifBsI.js";
import { A as isRich, E as setVerbose, j as theme } from "./registry-Sbac4a4z.js";
import "./paths-By0XjHBk.js";
import { c as escapeRegExp, d as normalizeE164 } from "./utils-CTPsqyE_.js";
import { f as defaultRuntime, r as enableConsoleCapture, u as visibleWidth } from "./subsystem-CHbO_DkH.js";
import "./auth-profiles-Ce7R_25e.js";
import { n as resolveCliName, t as replaceCliName } from "./cli-name-CzMV-gJF.js";
import { n as runExec, t as runCommandWithTimeout } from "./exec-DuYbft0z.js";
import "./agent-scope-DOrZjOnW.js";
import "./model-selection-7wdmO-Iw.js";
import "./file-lock-BVUYnlQv.js";
import "./agent-paths-BbZSGrUA.js";
import "./pi-embedded-helpers-D-OFjhdI.js";
import { F as loadDotEnv, N as VERSION, i as loadConfig } from "./config-B4jkreCN.js";
import "./boolean-CbZoNRMn.js";
import { r as normalizeEnv, t as isTruthyEnvValue } from "./env-BRnPI9sO.js";
import "./shell-env-Dc3iU7HK.js";
import "./manifest-registry-D1MLZEjS.js";
import "./sandbox-BkznAPKO.js";
import "./chrome-DJChpTwP.js";
import { l as ensureBinary, u as promptYesNo } from "./tailscale-DpKBMIvx.js";
import "./auth-Bkx-QuRN.js";
import "./server-context-ChcbJgNo.js";
import "./frontmatter-B_jqcova.js";
import "./skills-BwDmcZdt.js";
import "./routes-ivqbutvM.js";
import "./redact-B3O-RBO1.js";
import { r as formatUncaughtError } from "./errors-bI7Tdx75.js";
import "./fs-safe-BdejYjW8.js";
import "./paths-DObzwe08.js";
import "./ssrf-DOZRI5XH.js";
import "./image-ops-L70xVnpG.js";
import { i as handlePortError, n as describePortOwner, r as ensurePortAvailable, t as PortInUseError } from "./ports-gxLM5ahL.js";
import "./trash-_YhavPQI.js";
import { A as deriveSessionKey, j as resolveSessionKey, l as saveSessionStore, o as loadSessionStore } from "./sessions-Dxf5Kjig.js";
import "./dock-hF45sewN.js";
import "./message-channel-DgjXWzf-.js";
import "./plugins-CF5skkHh.js";
import "./send-B0jHSNMF.js";
import { c as resolveStorePath } from "./paths-BtvQ7JvU.js";
import "./thinking-COroyVA5.js";
import "./tokens-0yh2UnJq.js";
import "./deliver-lTZLIQqf.js";
import "./diagnostic-DbT9t0Sh.js";
import "./diagnostic-session-state-DnkpMfCl.js";
import "./model-auth-1EAQvYRv.js";
import "./github-copilot-token-D-FdDfee.js";
import "./models-config-B5Xxy-c-.js";
import "./pi-auth-json-Db8XJVGL.js";
import "./session-cost-usage-D3mgssM_.js";
import "./session-utils-Cs1jlD-q.js";
import "./with-timeout-DPR4A2dx.js";
import "./reply-prefix-BFNeXT65.js";
import "./memory-BZ24UkLW.js";
import "./manager-Cw7IJGbB.js";
import "./sqlite-Cod7C5ba.js";
import "./chunk-BxfKjCUx.js";
import "./markdown-tables-CS1Tvb3z.js";
import "./fetch-guard-JHxT9355.js";
import "./local-roots-CgDCgCuM.js";
import "./commands-DUzLGgEZ.js";
import "./commands-registry-Ca5hh7nh.js";
import "./client-DH75FlQF.js";
import "./call-AZ9vNhST.js";
import "./pairing-token-Dcy37-4s.js";
import "./tool-display-DFOL6UQ9.js";
import "./skills-remote-bz71Bstn.js";
import "./workspace-dirs-jKFQf7of.js";
import "./pi-model-discovery-ClQLvlCW.js";
import "./model-catalog-IWi6-nY9.js";
import "./skill-commands-DDGGlq68.js";
import "./pairing-store-BNhJOnWn.js";
import "./exec-approvals-DioSaIeH.js";
import "./nodes-screen-De9ma6e1.js";
import "./breakdown-B_Dhhm3K.js";
import "./control-service-D8kKOts5.js";
import "./stagger-DQs772BN.js";
import "./channel-selection-H1qOf0q-.js";
import "./delivery-queue-OAc7hsIs.js";
import "./bindings-DIhsYGa_.js";
import "./resolve-route-C1IIA6kH.js";
import { t as formatDocsLink } from "./links-Bqr0FxXx.js";
import "./cli-utils-CuyGL3rq.js";
import "./help-format-7hFcsqss.js";
import "./progress-swt2y17x.js";
import "./memory-cli-0HHYm-B8.js";
import "./logging-BWknayJl.js";
import "./replies-CbXXjn9X.js";
import "./pi-tools.policy-H2t-Xkfc.js";
import "./model-MUMSB_7d.js";
import { t as createDefaultDeps } from "./deps-Bf9dt2UO.js";
import { t as ensureSymiCliOnPath } from "./path-env-BY88zbPR.js";
import { t as assertSupportedRuntime } from "./runtime-guard-CWA00ZXa.js";
import "./ports-r7LBic2V.js";
import { a as hasFlag, i as getVerboseFlag, n as getCommandPath, o as hasHelpOrVersion, s as hasRootVersionAlias } from "./argv-D6PT4jl6.js";
import { i as getCoreCliCommandsWithSubcommands, n as setProgramContext, o as registerProgramCommands, s as getSubCliCommandsWithSubcommands } from "./program-context-B0ovpbFU.js";
import "./catalog-BptA-dUv.js";
import "./plugin-registry-D2_TLnOr.js";
import { n as resolveCliChannelOptions } from "./channel-options-DnWkDAWi.js";
import process$1 from "node:process";
import { fileURLToPath } from "node:url";
import path from "node:path";
import fs from "node:fs";
import { Command } from "commander";

//#region src/auto-reply/run-reply-turn.ts
/**
* Run prep + a single agent turn and return the resulting reply
* payload(s). The agent runs without a dispatcher — block replies and
* final text are captured via callbacks and returned to the caller.
*
* Same return shape as the chain's `getReplyFromConfig`:
*   - undefined if the run produced no deliverable output
*   - a single ReplyPayload if one block (or no blocks + final text)
*   - an array of ReplyPayloads when multiple blocks streamed
*/
async function runReplyTurn(ctx, opts, configOverride) {
	const replyPrep = await prepareReplyTurn(ctx, opts, configOverride);
	if (replyPrep.kind === "early-reply") return replyPrep.reply;
	const agentPrep = await prepareAgentRun(replyPrep.runPreparedReplyParams);
	if (agentPrep.kind === "early-reply") return agentPrep.reply;
	const turnRunId = opts?.runId ?? agentPrep.runReplyAgentParams.followupRun.run.sessionId;
	const turnParams = buildAgentTurnParams(agentPrep.runReplyAgentParams, {
		runId: turnRunId,
		abortSignal: opts?.abortSignal,
		images: opts?.images
	});
	const blockReplies = [];
	turnParams.callbacks = { onBlockReply: (payload) => {
		blockReplies.push({ text: payload.text });
	} };
	opts?.onAgentRunStart?.(turnRunId);
	const result = await composeTurnMiddleware([withContextOverflowRecovery(), withContextUsageWarning()], runAgentTurn)(turnParams);
	if (result.outbound.action === "drop") return;
	if (blockReplies.length > 0) return blockReplies;
	const text = typeof result.text === "string" ? result.text : "";
	if (!text.trim()) return;
	return { text };
}

//#endregion
//#region src/cli/wait.ts
function waitForever() {
	setInterval(() => {}, 1e6).unref();
	return new Promise(() => {});
}

//#endregion
//#region src/infra/is-main.ts
function normalizePathCandidate(candidate, cwd) {
	if (!candidate) return;
	const resolved = path.resolve(cwd, candidate);
	try {
		return fs.realpathSync.native(resolved);
	} catch {
		return resolved;
	}
}
function isMainModule({ currentFile, argv = process.argv, env = process.env, cwd = process.cwd() }) {
	const normalizedCurrent = normalizePathCandidate(currentFile, cwd);
	const normalizedArgv1 = normalizePathCandidate(argv[1], cwd);
	if (normalizedCurrent && normalizedArgv1 && normalizedCurrent === normalizedArgv1) return true;
	const normalizedPmExecPath = normalizePathCandidate(env.pm_exec_path, cwd);
	if (normalizedCurrent && normalizedPmExecPath && normalizedCurrent === normalizedPmExecPath) return true;
	if (normalizedCurrent && normalizedArgv1 && path.basename(normalizedCurrent) === path.basename(normalizedArgv1)) return true;
	return false;
}

//#endregion
//#region src/cli/program/context.ts
function createProgramContext() {
	const channelOptions = resolveCliChannelOptions();
	return {
		programVersion: VERSION,
		channelOptions,
		messageChannelOptions: channelOptions.join("|"),
		agentChannelOptions: ["last", ...channelOptions].join("|")
	};
}

//#endregion
//#region src/cli/tagline.ts
const DEFAULT_TAGLINE = "All your chats, one Symi.";
const HOLIDAY_TAGLINES = {
	newYear: "New Year's Day: New year, new config—same old EADDRINUSE, but this time we resolve it like grown-ups.",
	lunarNewYear: "Lunar New Year: May your builds be lucky, your branches prosperous, and your merge conflicts chased away with fireworks.",
	christmas: "Christmas: Ho ho ho—Santa's little shell-sistant is here to ship joy, roll back chaos, and stash the keys safely.",
	eid: "Eid al-Fitr: Celebration mode: queues cleared, tasks completed, and good vibes committed to main with clean history.",
	diwali: "Diwali: Let the logs sparkle and the bugs flee—today we light up the terminal and ship with pride.",
	easter: "Easter: I found your missing environment variable—consider it a tiny CLI egg hunt with fewer jellybeans.",
	hanukkah: "Hanukkah: Eight nights, eight retries, zero shame—may your gateway stay lit and your deployments stay peaceful.",
	halloween: "Halloween: Spooky season: beware haunted dependencies, cursed caches, and the ghost of node_modules past.",
	thanksgiving: "Thanksgiving: Grateful for stable ports, working DNS, and a bot that reads the logs so nobody has to.",
	valentines: "Valentine's Day: Roses are typed, violets are piped—I'll automate the chores so you can spend time with humans."
};
const TAGLINES = [
	"Your terminal just grew shells—type something and let the bot pinch the busywork.",
	"Welcome to the command line: where dreams compile and confidence segfaults.",
	"I run on caffeine, JSON5, and the audacity of \"it worked on my machine.\"",
	"Gateway online—please keep hands, feet, and appendages inside the shell at all times.",
	"I speak fluent bash, mild sarcasm, and aggressive tab-completion energy.",
	"One CLI to rule them all, and one more restart because you changed the port.",
	"If it works, it's automation; if it breaks, it's a \"learning opportunity.\"",
	"Pairing codes exist because even bots believe in consent—and good security hygiene.",
	"Your .env is showing; don't worry, I'll pretend I didn't see it.",
	"I'll do the boring stuff while you dramatically stare at the logs like it's cinema.",
	"I'm not saying your workflow is chaotic... I'm just bringing a linter and a helmet.",
	"Type the command with confidence—nature will provide the stack trace if needed.",
	"I don't judge, but your missing API keys are absolutely judging you.",
	"I can grep it, git blame it, and gently roast it—pick your coping mechanism.",
	"Hot reload for config, cold sweat for deploys.",
	"I'm the assistant your terminal demanded, not the one your sleep schedule requested.",
	"I keep secrets like a vault... unless you print them in debug logs again.",
	"Automation with shells: minimal fuss, maximal pinch.",
	"I'm basically a Swiss Army knife, but with more opinions and fewer sharp edges.",
	"If you're lost, run doctor; if you're brave, run prod; if you're wise, run tests.",
	"Your task has been queued; your dignity has been deprecated.",
	"I can't fix your code taste, but I can fix your build and your backlog.",
	"I'm not magic—I'm just extremely persistent with retries and coping strategies.",
	"It's not \"failing,\" it's \"discovering new ways to configure the same thing wrong.\"",
	"Give me a workspace and I'll give you fewer tabs, fewer toggles, and more oxygen.",
	"I read logs so you can keep pretending you don't have to.",
	"If something's on fire, I can't extinguish it—but I can write a beautiful postmortem.",
	"I'll refactor your busywork like it owes me money.",
	"Say \"stop\" and I'll stop—say \"ship\" and we'll both learn a lesson.",
	"I'm the reason your shell history looks like a hacker-movie montage.",
	"I'm like tmux: confusing at first, then suddenly you can't live without me.",
	"I can run local, remote, or purely on vibes—results may vary with DNS.",
	"If you can describe it, I can probably automate it—or at least make it funnier.",
	"Your config is valid, your assumptions are not.",
	"I don't just autocomplete—I auto-commit (emotionally), then ask you to review (logically).",
	"Less clicking, more shipping, fewer \"where did that file go\" moments.",
	"Shells out, commit in—let's ship something mildly responsible.",
	"I'll streamline your workflow like a pipeline: efficient, reliable, effective.",
	"Shell yeah—I'm here to pinch the toil and leave you the glory.",
	"If it's repetitive, I'll automate it; if it's hard, I'll bring jokes and a rollback plan.",
	"Because texting yourself reminders is so 2024.",
	"Your inbox, your infra, your rules.",
	"Turning \"I'll reply later\" into \"my bot replied instantly\".",
	"The only bot in your contacts you actually want to hear from. ⚡",
	"Chat automation for people who peaked at IRC.",
	"Because Siri wasn't answering at 3AM.",
	"IPC, but it's your phone.",
	"The UNIX philosophy meets your DMs.",
	"curl for conversations.",
	"Less middlemen, more messages.",
	"Ship fast, log faster.",
	"End-to-end encrypted, drama-to-drama excluded.",
	"The only bot that stays out of your training set.",
	"WhatsApp automation without the \"please accept our new privacy policy\".",
	"Chat APIs that don't require a Senate hearing.",
	"Meta wishes they shipped this fast.",
	"Because the right answer is usually a script.",
	"Your messages, your servers, your control.",
	"OpenAI-compatible, not OpenAI-dependent.",
	"iMessage green bubble energy, but for everyone.",
	"Siri's competent cousin.",
	"Works on Android. Crazy concept, we know.",
	"No $999 stand required.",
	"We ship features faster than Apple ships calculator updates.",
	"Your AI assistant, now without the $3,499 headset.",
	"Think different. Actually think.",
	"Ah, the fruit tree company! 🍎",
	"Greetings, Professor Falken",
	HOLIDAY_TAGLINES.newYear,
	HOLIDAY_TAGLINES.lunarNewYear,
	HOLIDAY_TAGLINES.christmas,
	HOLIDAY_TAGLINES.eid,
	HOLIDAY_TAGLINES.diwali,
	HOLIDAY_TAGLINES.easter,
	HOLIDAY_TAGLINES.hanukkah,
	HOLIDAY_TAGLINES.halloween,
	HOLIDAY_TAGLINES.thanksgiving,
	HOLIDAY_TAGLINES.valentines
];
const DAY_MS = 1440 * 60 * 1e3;
function utcParts(date) {
	return {
		year: date.getUTCFullYear(),
		month: date.getUTCMonth(),
		day: date.getUTCDate()
	};
}
const onMonthDay = (month, day) => (date) => {
	const parts = utcParts(date);
	return parts.month === month && parts.day === day;
};
const onSpecificDates = (dates, durationDays = 1) => (date) => {
	const parts = utcParts(date);
	return dates.some(([year, month, day]) => {
		if (parts.year !== year) return false;
		const start = Date.UTC(year, month, day);
		const current = Date.UTC(parts.year, parts.month, parts.day);
		return current >= start && current < start + durationDays * DAY_MS;
	});
};
const inYearWindow = (windows) => (date) => {
	const parts = utcParts(date);
	const window = windows.find((entry) => entry.year === parts.year);
	if (!window) return false;
	const start = Date.UTC(window.year, window.month, window.day);
	const current = Date.UTC(parts.year, parts.month, parts.day);
	return current >= start && current < start + window.duration * DAY_MS;
};
const isFourthThursdayOfNovember = (date) => {
	const parts = utcParts(date);
	if (parts.month !== 10) return false;
	const fourthThursday = 1 + (4 - new Date(Date.UTC(parts.year, 10, 1)).getUTCDay() + 7) % 7 + 21;
	return parts.day === fourthThursday;
};
const HOLIDAY_RULES = new Map([
	[HOLIDAY_TAGLINES.newYear, onMonthDay(0, 1)],
	[HOLIDAY_TAGLINES.lunarNewYear, onSpecificDates([
		[
			2025,
			0,
			29
		],
		[
			2026,
			1,
			17
		],
		[
			2027,
			1,
			6
		]
	], 1)],
	[HOLIDAY_TAGLINES.eid, onSpecificDates([
		[
			2025,
			2,
			30
		],
		[
			2025,
			2,
			31
		],
		[
			2026,
			2,
			20
		],
		[
			2027,
			2,
			10
		]
	], 1)],
	[HOLIDAY_TAGLINES.diwali, onSpecificDates([
		[
			2025,
			9,
			20
		],
		[
			2026,
			10,
			8
		],
		[
			2027,
			9,
			28
		]
	], 1)],
	[HOLIDAY_TAGLINES.easter, onSpecificDates([
		[
			2025,
			3,
			20
		],
		[
			2026,
			3,
			5
		],
		[
			2027,
			2,
			28
		]
	], 1)],
	[HOLIDAY_TAGLINES.hanukkah, inYearWindow([
		{
			year: 2025,
			month: 11,
			day: 15,
			duration: 8
		},
		{
			year: 2026,
			month: 11,
			day: 5,
			duration: 8
		},
		{
			year: 2027,
			month: 11,
			day: 25,
			duration: 8
		}
	])],
	[HOLIDAY_TAGLINES.halloween, onMonthDay(9, 31)],
	[HOLIDAY_TAGLINES.thanksgiving, isFourthThursdayOfNovember],
	[HOLIDAY_TAGLINES.valentines, onMonthDay(1, 14)],
	[HOLIDAY_TAGLINES.christmas, onMonthDay(11, 25)]
]);
function isTaglineActive(tagline, date) {
	const rule = HOLIDAY_RULES.get(tagline);
	if (!rule) return true;
	return rule(date);
}
function activeTaglines(options = {}) {
	if (TAGLINES.length === 0) return [DEFAULT_TAGLINE];
	const today = options.now ? options.now() : /* @__PURE__ */ new Date();
	const filtered = TAGLINES.filter((tagline) => isTaglineActive(tagline, today));
	return filtered.length > 0 ? filtered : TAGLINES;
}
function pickTagline(options = {}) {
	const override = (options.env ?? process.env)?.SYMI_TAGLINE_INDEX;
	if (override !== void 0) {
		const parsed = Number.parseInt(override, 10);
		if (!Number.isNaN(parsed) && parsed >= 0) {
			const pool = TAGLINES.length > 0 ? TAGLINES : [DEFAULT_TAGLINE];
			return pool[parsed % pool.length];
		}
	}
	const pool = activeTaglines(options);
	const rand = options.random ?? Math.random;
	return pool[Math.floor(rand() * pool.length) % pool.length];
}

//#endregion
//#region src/cli/banner.ts
let bannerEmitted = false;
const graphemeSegmenter = typeof Intl !== "undefined" && "Segmenter" in Intl ? new Intl.Segmenter(void 0, { granularity: "grapheme" }) : null;
const hasJsonFlag = (argv) => argv.some((arg) => arg === "--json" || arg.startsWith("--json="));
const hasVersionFlag = (argv) => argv.some((arg) => arg === "--version" || arg === "-V") || hasRootVersionAlias(argv);
function formatCliBannerLine(version, options = {}) {
	const commitLabel = options.commit ?? resolveCommitHash({ env: options.env }) ?? "unknown";
	const tagline = pickTagline(options);
	const rich = options.richTty ?? isRich();
	const title = "⚡ Symi";
	const columns = options.columns ?? process.stdout.columns ?? 120;
	const plainFullLine = `${title} ${version} (${commitLabel}) — ${tagline}`;
	const fitsOnOneLine = visibleWidth(plainFullLine) <= columns;
	if (rich) {
		if (fitsOnOneLine) return `${theme.heading(title)} ${theme.info(version)} ${theme.muted(`(${commitLabel})`)} ${theme.muted("—")} ${theme.accentDim(tagline)}`;
		return `${`${theme.heading(title)} ${theme.info(version)} ${theme.muted(`(${commitLabel})`)}`}\n${`${" ".repeat(2)}${theme.accentDim(tagline)}`}`;
	}
	if (fitsOnOneLine) return plainFullLine;
	return `${`${title} ${version} (${commitLabel})`}\n${`${" ".repeat(2)}${tagline}`}`;
}
function emitCliBanner(version, options = {}) {
	if (bannerEmitted) return;
	const argv = options.argv ?? process.argv;
	if (!process.stdout.isTTY) return;
	if (hasJsonFlag(argv)) return;
	if (hasVersionFlag(argv)) return;
	const line = formatCliBannerLine(version, options);
	process.stdout.write(`\n${line}\n\n`);
	bannerEmitted = true;
}
function hasEmittedCliBanner() {
	return bannerEmitted;
}

//#endregion
//#region src/cli/program/help.ts
const CLI_NAME = resolveCliName();
const CLI_NAME_PATTERN = escapeRegExp(CLI_NAME);
const ROOT_COMMANDS_WITH_SUBCOMMANDS = new Set([...getCoreCliCommandsWithSubcommands(), ...getSubCliCommandsWithSubcommands()]);
const ROOT_COMMANDS_HINT = "Hint: commands suffixed with * have subcommands. Run <command> --help for details.";
const EXAMPLES = [
	["symi models --help", "Show detailed help for the models command."],
	["symi channels login --verbose", "Link personal WhatsApp Web and show QR + connection logs."],
	["symi message send --target +15555550123 --message \"Hi\" --json", "Send via your web session and print JSON result."],
	["symi gateway --port 18789", "Run the WebSocket Gateway locally."],
	["symi --dev gateway", "Run a dev Gateway (isolated state/config) on ws://127.0.0.1:19001."],
	["symi gateway --force", "Kill anything bound to the default gateway port, then start it."],
	["symi gateway ...", "Gateway control via WebSocket."],
	["symi agent --to +15555550123 --message \"Run summary\" --deliver", "Talk directly to the agent using the Gateway; optionally send the WhatsApp reply."],
	["symi message send --channel telegram --target @mychat --message \"Hi\"", "Send via your Telegram bot."]
];
function configureProgramHelp(program, ctx) {
	program.name(CLI_NAME).description("").version(ctx.programVersion).option("--dev", "Dev profile: isolate state under ~/.symi-dev, default gateway port 19001, and shift derived ports (browser/canvas)").option("--profile <name>", "Use a named profile (isolates SYMI_STATE_DIR/SYMI_CONFIG_PATH under ~/.symi-<name>)");
	program.option("--no-color", "Disable ANSI colors", false);
	program.helpOption("-h, --help", "Display help for command");
	program.helpCommand("help [command]", "Display help for command");
	program.configureHelp({
		sortSubcommands: true,
		sortOptions: true,
		optionTerm: (option) => theme.option(option.flags),
		subcommandTerm: (cmd) => {
			const hasSubcommands = cmd.parent === program && ROOT_COMMANDS_WITH_SUBCOMMANDS.has(cmd.name());
			return theme.command(hasSubcommands ? `${cmd.name()} *` : cmd.name());
		}
	});
	const formatHelpOutput = (str) => {
		let output = str;
		if (new RegExp(`^Usage:\\s+${CLI_NAME_PATTERN}\\s+\\[options\\]\\s+\\[command\\]\\s*$`, "m").test(output) && /^Commands:/m.test(output)) output = output.replace(/^Commands:/m, `Commands:\n  ${theme.muted(ROOT_COMMANDS_HINT)}`);
		return output.replace(/^Usage:/gm, theme.heading("Usage:")).replace(/^Options:/gm, theme.heading("Options:")).replace(/^Commands:/gm, theme.heading("Commands:"));
	};
	program.configureOutput({
		writeOut: (str) => {
			process.stdout.write(formatHelpOutput(str));
		},
		writeErr: (str) => {
			process.stderr.write(formatHelpOutput(str));
		},
		outputError: (str, write) => write(theme.error(str))
	});
	if (hasFlag(process.argv, "-V") || hasFlag(process.argv, "--version") || hasRootVersionAlias(process.argv)) {
		console.log(ctx.programVersion);
		process.exit(0);
	}
	program.addHelpText("beforeAll", () => {
		if (hasEmittedCliBanner()) return "";
		const rich = isRich();
		return `\n${formatCliBannerLine(ctx.programVersion, { richTty: rich })}\n`;
	});
	const fmtExamples = EXAMPLES.map(([cmd, desc]) => `  ${theme.command(replaceCliName(cmd, CLI_NAME))}\n    ${theme.muted(desc)}`).join("\n");
	program.addHelpText("afterAll", ({ command }) => {
		if (command !== program) return "";
		const docs = formatDocsLink("/cli", "docs.symi.ai/cli");
		return `\n${theme.heading("Examples:")}\n${fmtExamples}\n\n${theme.muted("Docs:")} ${docs}\n`;
	});
}

//#endregion
//#region src/cli/program/preaction.ts
function setProcessTitleForCommand(actionCommand) {
	let current = actionCommand;
	while (current.parent && current.parent.parent) current = current.parent;
	const name = current.name();
	const cliName = resolveCliName();
	if (!name || name === cliName) return;
	process.title = `${cliName}-${name}`;
}
const PLUGIN_REQUIRED_COMMANDS = new Set([
	"message",
	"channels",
	"directory"
]);
function registerPreActionHooks(program, programVersion) {
	program.hook("preAction", async (_thisCommand, actionCommand) => {
		setProcessTitleForCommand(actionCommand);
		const argv = process.argv;
		if (hasHelpOrVersion(argv)) return;
		const commandPath = getCommandPath(argv, 2);
		if (!(isTruthyEnvValue(process.env.SYMI_HIDE_BANNER) || commandPath[0] === "update" || commandPath[0] === "completion" || commandPath[0] === "plugins" && commandPath[1] === "update")) emitCliBanner(programVersion);
		const verbose = getVerboseFlag(argv, { includeDebug: true });
		setVerbose(verbose);
		if (!verbose) process.env.NODE_NO_WARNINGS ??= "1";
		if (commandPath[0] === "doctor" || commandPath[0] === "completion") return;
		const { ensureConfigReady } = await import("./config-guard-BRm3RiOi.js");
		await ensureConfigReady({
			runtime: defaultRuntime,
			commandPath
		});
		if (PLUGIN_REQUIRED_COMMANDS.has(commandPath[0])) {
			const { ensurePluginRegistryLoaded } = await import("./plugin-registry-D2_TLnOr.js").then((n) => n.n);
			ensurePluginRegistryLoaded();
		}
	});
}

//#endregion
//#region src/cli/program/build-program.ts
function buildProgram() {
	const program = new Command();
	const ctx = createProgramContext();
	const argv = process.argv;
	setProgramContext(program, ctx);
	configureProgramHelp(program, ctx);
	registerPreActionHooks(program, ctx.programVersion);
	registerProgramCommands(program, ctx, argv);
	return program;
}

//#endregion
//#region src/index.ts
loadDotEnv({ quiet: true });
normalizeEnv();
ensureSymiCliOnPath();
enableConsoleCapture();
assertSupportedRuntime();
const program = buildProgram();
if (isMainModule({ currentFile: fileURLToPath(import.meta.url) })) {
	installUnhandledRejectionHandler();
	process$1.on("uncaughtException", (error) => {
		console.error("[symi] Uncaught exception:", formatUncaughtError(error));
		process$1.exit(1);
	});
	program.parseAsync(process$1.argv).catch((err) => {
		console.error("[symi] CLI failed:", formatUncaughtError(err));
		process$1.exit(1);
	});
}

//#endregion
export { PortInUseError, applyTemplate, createDefaultDeps, deriveSessionKey, describePortOwner, ensureBinary, ensurePortAvailable, handlePortError, loadConfig, loadSessionStore, normalizeE164, promptYesNo, resolveSessionKey, resolveStorePath, runCommandWithTimeout, runExec, runReplyTurn, saveSessionStore, waitForever };