import { o as visibleWidth, p as hasRootVersionAlias } from "./entry.js";
import { n as theme, t as isRich } from "./theme-DrO_HVcw.js";
import { createRequire } from "node:module";
import fs from "node:fs";
import path from "node:path";
import gradient from "gradient-string";

//#region src/infra/git-root.ts
const DEFAULT_GIT_DISCOVERY_MAX_DEPTH = 12;
function walkUpFrom(startDir, opts, resolveAtDir) {
	let current = path.resolve(startDir);
	const maxDepth = opts.maxDepth ?? DEFAULT_GIT_DISCOVERY_MAX_DEPTH;
	for (let i = 0; i < maxDepth; i += 1) {
		const resolved = resolveAtDir(current);
		if (resolved !== null && resolved !== void 0) return resolved;
		const parent = path.dirname(current);
		if (parent === current) break;
		current = parent;
	}
	return null;
}
function resolveGitDirFromMarker(repoRoot) {
	const gitPath = path.join(repoRoot, ".git");
	try {
		const stat = fs.statSync(gitPath);
		if (stat.isDirectory()) return gitPath;
		if (!stat.isFile()) return null;
		const match = fs.readFileSync(gitPath, "utf-8").match(/gitdir:\s*(.+)/i);
		if (!match?.[1]) return null;
		return path.resolve(repoRoot, match[1].trim());
	} catch {
		return null;
	}
}
function resolveGitHeadPath(startDir, opts = {}) {
	return walkUpFrom(startDir, opts, (repoRoot) => {
		const gitDir = resolveGitDirFromMarker(repoRoot);
		return gitDir ? path.join(gitDir, "HEAD") : null;
	});
}

//#endregion
//#region src/infra/git-commit.ts
const formatCommit = (value) => {
	if (!value) return null;
	const trimmed = value.trim();
	if (!trimmed) return null;
	return trimmed.length > 7 ? trimmed.slice(0, 7) : trimmed;
};
let cachedCommit;
const readCommitFromPackageJson = () => {
	try {
		const pkg = createRequire(import.meta.url)("../../package.json");
		return formatCommit(pkg.gitHead ?? pkg.githead ?? null);
	} catch {
		return null;
	}
};
const readCommitFromBuildInfo = () => {
	try {
		const require = createRequire(import.meta.url);
		for (const candidate of ["../build-info.json", "./build-info.json"]) try {
			const formatted = formatCommit(require(candidate).commit ?? null);
			if (formatted) return formatted;
		} catch {}
		return null;
	} catch {
		return null;
	}
};
const resolveCommitHash = (options = {}) => {
	if (cachedCommit !== void 0) return cachedCommit;
	const env = options.env ?? process.env;
	const normalized = formatCommit(env.GIT_COMMIT?.trim() || env.GIT_SHA?.trim());
	if (normalized) {
		cachedCommit = normalized;
		return cachedCommit;
	}
	const buildInfoCommit = readCommitFromBuildInfo();
	if (buildInfoCommit) {
		cachedCommit = buildInfoCommit;
		return cachedCommit;
	}
	const pkgCommit = readCommitFromPackageJson();
	if (pkgCommit) {
		cachedCommit = pkgCommit;
		return cachedCommit;
	}
	try {
		const headPath = resolveGitHeadPath(options.cwd ?? process.cwd());
		if (!headPath) {
			cachedCommit = null;
			return cachedCommit;
		}
		const head = fs.readFileSync(headPath, "utf-8").trim();
		if (!head) {
			cachedCommit = null;
			return cachedCommit;
		}
		if (head.startsWith("ref:")) {
			const ref = head.replace(/^ref:\s*/i, "").trim();
			const refPath = path.resolve(path.dirname(headPath), ref);
			cachedCommit = formatCommit(fs.readFileSync(refPath, "utf-8").trim());
			return cachedCommit;
		}
		cachedCommit = formatCommit(head);
		return cachedCommit;
	} catch {
		cachedCommit = null;
		return cachedCommit;
	}
};

//#endregion
//#region src/cli/tagline.ts
const DEFAULT_TAGLINE = "Forge your workflow. Command your data.";
const HOLIDAY_TAGLINES = {
	newYear: "New Year's Day: New year, fresh schema — same old EADDRINUSE, but this time we temper it like grown-ups.",
	lunarNewYear: "Lunar New Year: May your builds be lucky, your pipelines prosperous, and your merge conflicts hammered flat on the anvil.",
	christmas: "Christmas: Ho ho ho — Santa's iron-clad assistant is here to ship joy, roll back chaos, and forge the keys safely.",
	eid: "Eid al-Fitr: Celebration mode: queues cleared, deals closed, and good vibes committed to main with clean history.",
	diwali: "Diwali: Let the forge glow bright 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 ironclad.",
	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 an agent 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 iron claws — type something and watch it forge results.",
	"Hot metal, cold data, zero patience for manual entry.",
	"Tempered in TypeScript, quenched in production.",
	"Iron sharpens iron — and this CLI sharpens your workflow.",
	"Gateway online — please keep hands inside the forge at all times.",
	"I'll refactor your busywork like it owes me steel ingots.",
	"Forged in the fires of git rebase, cooled by the tears of resolved conflicts.",
	"The anvil is hot. Your pipeline is hotter.",
	"Strike while the deploy is hot.",
	"Built different. Literally — we use DuckDB.",
	"I speak fluent SQL, mild sarcasm, and aggressive pipeline-closing energy.",
	"One CLI to rule your contacts, your deals, and your sanity.",
	"If your CRM could bench press, this is what it would look like.",
	"Your CRM grew claws. Your leads never stood a chance.",
	"I don't just autocomplete — I auto-close deals (emotionally), then ask you to review (logically).",
	"Less clicking, more shipping, fewer \"where did that contact go\" moments.",
	"I can PIVOT your data, but I can't PIVOT your life choices.",
	"Your .env is showing; don't worry, the forge keeps secrets.",
	"If it's repetitive, I'll automate it; if it's hard, I'll bring SQL and a rollback plan.",
	"I don't judge, but your missing API keys are absolutely judging you.",
	"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.\"",
	"If it works, it's automation; if it breaks, it's a \"learning opportunity.\"",
	"I'll do the boring stuff while you dramatically stare at the logs like it's cinema.",
	"Type the command with confidence — nature will provide the stack trace if needed.",
	"I can grep it, git blame it, and gently roast it — pick your coping mechanism.",
	"Hot reload for config, cold sweat for deploys.",
	"I keep secrets like a vault... unless you print them in debug logs again.",
	"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.",
	"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.",
	"Your inbox, your infra, your rules.",
	"Turning \"I'll reply later\" into \"my agent replied instantly\".",
	"Chat automation for people who peaked at IRC.",
	"The UNIX philosophy meets your DMs.",
	"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.",
	"Chat APIs that don't require a Senate hearing.",
	"Your messages, your servers, your control.",
	"OpenAI-compatible, not OpenAI-dependent.",
	"Because the right answer is usually a script.",
	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 env = options.env ?? process.env;
	const override = env?.DENCHCLAW_TAGLINE_INDEX ?? env?.OPENCLAW_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 hasJsonFlag = (argv) => argv.some((arg) => arg === "--json" || arg.startsWith("--json="));
const hasVersionFlag = (argv) => argv.some((arg) => arg === "--version" || arg === "-V") || hasRootVersionAlias(argv);
const DENCHCLAW_ASCII = [
	"██████╗ ███████╗███╗   ██╗ ██████╗██╗  ██╗ ██████╗██╗      █████╗ ██╗    ██╗",
	"██╔══██╗██╔════╝████╗  ██║██╔════╝██║  ██║██╔════╝██║     ██╔══██╗██║    ██║",
	"██║  ██║█████╗  ██╔██╗ ██║██║     ███████║██║     ██║     ███████║██║ █╗ ██║",
	"██║  ██║██╔══╝  ██║╚██╗██║██║     ██╔══██║██║     ██║     ██╔══██║██║███╗██║",
	"██████╔╝███████╗██║ ╚████║╚██████╗██║  ██║╚██████╗███████╗██║  ██║╚███╔███╔╝",
	"╚═════╝ ╚══════╝╚═╝  ╚═══╝ ╚═════╝╚═╝  ╚═╝ ╚═════╝╚══════╝╚═╝  ╚═╝ ╚══╝╚══╝ "
];
const IRON_GRADIENT_COLORS = [
	"#374151",
	"#4B5563",
	"#6B7280",
	"#9CA3AF",
	"#D1D5DB",
	"#F3F4F6",
	"#D1D5DB",
	"#9CA3AF",
	"#6B7280",
	"#4B5563"
];
function rotateArray(arr, offset) {
	const n = arr.length;
	const o = (offset % n + n) % n;
	return [...arr.slice(o), ...arr.slice(0, o)];
}
function renderGradientFrame(lines, frame) {
	return gradient(rotateArray(IRON_GRADIENT_COLORS, frame)).multiline(lines.join("\n"));
}
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
/**
* Play the iron shimmer animation: a bright highlight sweeps across the
* ASCII art like light glinting off polished metal. Runs for ~2.5 seconds
* at 12 fps, completing 3 full gradient cycles.
*/
async function animateIronBanner() {
	const lineCount = DENCHCLAW_ASCII.length;
	const fps = 12;
	const totalFrames = IRON_GRADIENT_COLORS.length * 3;
	const frameMs = Math.round(1e3 / fps);
	process.stdout.write(renderGradientFrame(DENCHCLAW_ASCII, 0) + "\n");
	for (let frame = 1; frame < totalFrames; frame++) {
		await sleep(frameMs);
		process.stdout.write(`\x1b[${lineCount}A\r`);
		process.stdout.write(renderGradientFrame(DENCHCLAW_ASCII, frame) + "\n");
	}
}
function formatCliBannerLine(version, options = {}) {
	const commitLabel = options.commit ?? resolveCommitHash({ env: options.env }) ?? "unknown";
	const tagline = pickTagline(options);
	const rich = options.richTty ?? isRich();
	const title = "DENCHCLAW";
	const prefix = "  ";
	const columns = options.columns ?? process.stdout.columns ?? 120;
	const plainFullLine = `${prefix}${title} ${version} (${commitLabel}) — ${tagline}`;
	const fitsOnOneLine = visibleWidth(plainFullLine) <= columns;
	if (rich) {
		if (fitsOnOneLine) return `${prefix}${theme.heading(title)} ${theme.info(version)} ${theme.muted(`(${commitLabel})`)} ${theme.muted("—")} ${theme.accentDim(tagline)}`;
		return `${`${prefix}${theme.heading(title)} ${theme.info(version)} ${theme.muted(`(${commitLabel})`)}`}\n${`${prefix}${theme.accentDim(tagline)}`}`;
	}
	if (fitsOnOneLine) return plainFullLine;
	return `${`${prefix}${title} ${version} (${commitLabel})`}\n${`${prefix}${tagline}`}`;
}
async 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;
	bannerEmitted = true;
	const rich = options.richTty ?? isRich();
	process.stdout.write("\n");
	if (rich) await animateIronBanner();
	else process.stdout.write(DENCHCLAW_ASCII.join("\n") + "\n");
	const line = formatCliBannerLine(version, options);
	process.stdout.write(`${line}\n\n`);
}
function hasEmittedCliBanner() {
	return bannerEmitted;
}

//#endregion
//#region src/cli/cli-name.ts
const DEFAULT_CLI_NAME = "denchclaw";
const KNOWN_CLI_NAMES = new Set([DEFAULT_CLI_NAME, "openclaw"]);
const CLI_PREFIX_RE = /^(?:((?:pnpm|npm|bunx|npx)\s+))?(denchclaw|openclaw)\b/;
function resolveCliName(argv = process.argv) {
	const argv1 = argv[1];
	if (!argv1) return DEFAULT_CLI_NAME;
	const base = path.basename(argv1).trim();
	if (KNOWN_CLI_NAMES.has(base)) return base;
	return DEFAULT_CLI_NAME;
}
function replaceCliName(command, cliName = resolveCliName()) {
	if (!command.trim()) return command;
	if (!CLI_PREFIX_RE.test(command)) return command;
	return command.replace(CLI_PREFIX_RE, (_match, runner) => {
		return `${runner ?? ""}${cliName}`;
	});
}

//#endregion
export { hasEmittedCliBanner as a, formatCliBannerLine as i, resolveCliName as n, emitCliBanner as r, replaceCliName as t };