import { c as normalizeOptionalString } from "./string-coerce-mnp54Vah.js";
import { P as timestampMsToIsoString } from "./number-coercion-CJQ8TR--.js";
import { t as formatCliCommand } from "./command-format-CKGmlpAQ.js";
import { n as isRich, r as theme } from "./theme-vjDs9tao.js";
import { r as writeRuntimeJson } from "./runtime-B4lgFmsS.js";
import { n as info } from "./globals-DXby5AAE.js";
import { t as sanitizeTerminalText } from "./safe-text-Crz8bz-e.js";
import { i as getRuntimeConfig } from "./io-CVFQolkW.js";
import "./config-BzUsatE2.js";
import { I as listTaskFlowRecords, P as getTaskFlowById, m as listTasksForFlowId, z as resolveTaskFlowForLookupToken } from "./task-registry-DoudS_z3.js";
import "./runtime-internal-BBrkqqKJ.js";
import { l as getFlowTaskSummary, n as cancelFlowById } from "./task-executor-CFm_Onrq.js";
//#region src/commands/flows.ts
/** CLI commands for listing, inspecting, and cancelling TaskFlow records. */
const ID_PAD = 10;
const STATUS_PAD = 10;
const MODE_PAD = 14;
const REV_PAD = 6;
const CTRL_PAD = 20;
function formatFlowLookupMiss(lookup) {
	return `TaskFlow not found: ${lookup}. Run ${formatCliCommand("openclaw tasks flow list")} to see recent flow ids.`;
}
function truncate(value, maxChars) {
	if (value.length <= maxChars) return value;
	if (maxChars <= 1) return value.slice(0, maxChars);
	return `${value.slice(0, maxChars - 1)}…`;
}
function safeFlowDisplayText(value, maxChars) {
	const sanitized = sanitizeTerminalText(value ?? "").trim();
	if (!sanitized) return "n/a";
	return typeof maxChars === "number" ? truncate(sanitized, maxChars) : sanitized;
}
function shortToken(value, maxChars = ID_PAD) {
	const trimmed = normalizeOptionalString(value);
	if (!trimmed) return "n/a";
	return truncate(trimmed, maxChars);
}
function formatFlowTimestamp(value) {
	return timestampMsToIsoString(value) ?? "n/a";
}
function formatFlowStatusCell(status, rich) {
	const padded = status.padEnd(STATUS_PAD);
	if (!rich) return padded;
	if (status === "succeeded") return theme.success(padded);
	if (status === "failed" || status === "lost") return theme.error(padded);
	if (status === "running") return theme.accentBright(padded);
	if (status === "blocked") return theme.warn(padded);
	return theme.muted(padded);
}
function formatFlowRows(flows, rich) {
	const header = [
		"TaskFlow".padEnd(ID_PAD),
		"Mode".padEnd(MODE_PAD),
		"Status".padEnd(STATUS_PAD),
		"Rev".padEnd(REV_PAD),
		"Controller".padEnd(CTRL_PAD),
		"Tasks".padEnd(14),
		"Goal"
	].join(" ");
	const lines = [rich ? theme.heading(header) : header];
	for (const flow of flows) {
		const taskSummary = getFlowTaskSummary(flow.flowId);
		const counts = `${taskSummary.active} active/${taskSummary.total} total`;
		lines.push([
			shortToken(flow.flowId).padEnd(ID_PAD),
			flow.syncMode.padEnd(MODE_PAD),
			formatFlowStatusCell(flow.status, rich),
			String(flow.revision).padEnd(REV_PAD),
			safeFlowDisplayText(flow.controllerId, CTRL_PAD).padEnd(CTRL_PAD),
			counts.padEnd(14),
			safeFlowDisplayText(flow.goal, 80)
		].join(" "));
	}
	return lines;
}
function formatFlowListSummary(flows) {
	return `${flows.filter((flow) => flow.status === "queued" || flow.status === "running").length} active · ${flows.filter((flow) => flow.status === "blocked").length} blocked · ${flows.filter((flow) => flow.cancelRequestedAt != null).length} cancel-requested · ${flows.length} total`;
}
function summarizeWait(flow) {
	if (flow.waitJson == null) return "n/a";
	if (typeof flow.waitJson === "string" || typeof flow.waitJson === "number" || typeof flow.waitJson === "boolean") return String(flow.waitJson);
	if (Array.isArray(flow.waitJson)) return `array(${flow.waitJson.length})`;
	return Object.keys(flow.waitJson).toSorted().join(", ") || "object";
}
function summarizeFlowState(flow) {
	if (flow.status === "blocked") {
		if (flow.blockedSummary) return flow.blockedSummary;
		if (flow.blockedTaskId) return `blocked by ${flow.blockedTaskId}`;
		return "blocked";
	}
	if (flow.status === "waiting" && flow.waitJson != null) return summarizeWait(flow);
	return null;
}
/** Lists TaskFlows with optional status filtering and JSON output. */
async function flowsListCommand(opts, runtime) {
	const statusFilter = opts.status?.trim();
	const flows = listTaskFlowRecords().filter((flow) => {
		if (statusFilter && flow.status !== statusFilter) return false;
		return true;
	});
	if (opts.json) {
		writeRuntimeJson(runtime, {
			count: flows.length,
			status: statusFilter ?? null,
			flows: flows.map((flow) => ({
				...flow,
				tasks: listTasksForFlowId(flow.flowId),
				taskSummary: getFlowTaskSummary(flow.flowId)
			}))
		});
		return;
	}
	runtime.log(info(`TaskFlows: ${flows.length}`));
	runtime.log(info(`TaskFlow pressure: ${formatFlowListSummary(flows)}`));
	if (statusFilter) runtime.log(info(`Status filter: ${statusFilter}`));
	if (flows.length === 0) {
		runtime.log(`No TaskFlows found. Run ${formatCliCommand("openclaw tasks list")} to inspect standalone background tasks.`);
		return;
	}
	const rich = isRich();
	for (const line of formatFlowRows(flows, rich)) runtime.log(line);
}
/** Shows one TaskFlow and its linked task summary. */
async function flowsShowCommand(opts, runtime) {
	const flow = resolveTaskFlowForLookupToken(opts.lookup);
	if (!flow) {
		runtime.error(formatFlowLookupMiss(opts.lookup));
		runtime.exit(1);
		return;
	}
	const tasks = listTasksForFlowId(flow.flowId);
	const taskSummary = getFlowTaskSummary(flow.flowId);
	const stateSummary = summarizeFlowState(flow);
	if (opts.json) {
		writeRuntimeJson(runtime, {
			...flow,
			tasks,
			taskSummary
		});
		return;
	}
	const lines = [
		"TaskFlow:",
		`flowId: ${flow.flowId}`,
		`status: ${flow.status}`,
		`goal: ${safeFlowDisplayText(flow.goal)}`,
		`currentStep: ${safeFlowDisplayText(flow.currentStep)}`,
		`owner: ${safeFlowDisplayText(flow.ownerKey)}`,
		`notify: ${flow.notifyPolicy}`,
		...stateSummary ? [`state: ${safeFlowDisplayText(stateSummary)}`] : [],
		...flow.cancelRequestedAt ? [`cancelRequestedAt: ${formatFlowTimestamp(flow.cancelRequestedAt)}`] : [],
		`createdAt: ${formatFlowTimestamp(flow.createdAt)}`,
		`updatedAt: ${formatFlowTimestamp(flow.updatedAt)}`,
		`endedAt: ${formatFlowTimestamp(flow.endedAt)}`,
		`tasks: ${taskSummary.total} total · ${taskSummary.active} active · ${taskSummary.failures} issues`
	];
	for (const line of lines) runtime.log(line);
	if (tasks.length === 0) {
		runtime.log("Linked tasks: none");
		return;
	}
	runtime.log("Linked tasks:");
	for (const task of tasks) {
		const safeLabel = safeFlowDisplayText(task.label ?? task.task);
		runtime.log(`- ${task.taskId} ${task.status} ${task.runId ?? "n/a"} ${safeLabel}`);
	}
}
/** Requests cancellation for one TaskFlow selected by id or lookup token. */
async function flowsCancelCommand(opts, runtime) {
	const flow = resolveTaskFlowForLookupToken(opts.lookup);
	if (!flow) {
		runtime.error(formatFlowLookupMiss(opts.lookup));
		runtime.exit(1);
		return;
	}
	const result = await cancelFlowById({
		cfg: getRuntimeConfig(),
		flowId: flow.flowId
	});
	if (!result.found) {
		runtime.error(result.reason ?? formatFlowLookupMiss(opts.lookup));
		runtime.exit(1);
		return;
	}
	if (!result.cancelled) {
		runtime.error(result.reason ?? `Could not cancel TaskFlow: ${opts.lookup}`);
		runtime.exit(1);
		return;
	}
	const updated = getTaskFlowById(flow.flowId) ?? result.flow ?? flow;
	runtime.log(`Cancelled ${updated.flowId} (${updated.syncMode}) with status ${updated.status}.`);
}
//#endregion
export { flowsCancelCommand, flowsListCommand, flowsShowCommand };
