import { handleRemote } from "../../../remote-questions/mod.js";
import { getAutoSession } from "../../auto/session.js";
import { dispatchDirectPhase } from "../../auto-direct-dispatch.js";
import { handleConfig } from "../../commands-config.js";
import { handleDebug } from "../../commands-debug.js";
import { handleEscalate } from "../../commands-escalate.js";
import {
	handleCapture,
	handleDoctor,
	handleKnowledge,
	handleRunHook,
	handleSkillHealth,
	handleSteer,
	handleTriage,
	handleUpdate,
} from "../../commands-handlers.js";
import { handleInspect } from "../../commands-inspect.js";
import { handleLogs } from "../../commands-logs.js";
import {
	handleCleanupBranches,
	handleCleanupProjects,
	handleCleanupSnapshots,
	handleCleanupWorktrees,
	handleRecover,
	handleSkip,
} from "../../commands-maintenance.js";
import { handlePrBranch } from "../../commands-pr-branch.js";
import { handleRate } from "../../commands-rate.js";
import { handleSessionReport } from "../../commands-session-report.js";
import { handleShip } from "../../commands-ship.js";
import { handleCost } from "../../cost-command.js";
import { getExperimentalFlag } from "../../experimental.js";
import { handleExport } from "../../export.js";
import { handleHistory } from "../../history.js";
import { handleUndo } from "../../undo.js";
import { projectRoot } from "../context.js";
export async function handleOpsCommand(trimmed, ctx, pi) {
	if (trimmed === "init") {
		const { detectProjectState } = await import("../../detection.js");
		const { handleReinit, showProjectInit } = await import(
			"../../init-wizard.js"
		);
		const basePath = projectRoot();
		const detection = detectProjectState(basePath);
		if (detection.state === "v2-sf" || detection.state === "v2-sf-empty") {
			await handleReinit(ctx, detection);
		} else {
			await showProjectInit(ctx, pi, basePath, detection);
		}
		return true;
	}
	if (trimmed === "keys" || trimmed.startsWith("keys ")) {
		const { handleKeys } = await import("../../key-manager.js");
		await handleKeys(trimmed.replace(/^keys\s*/, "").trim(), ctx);
		return true;
	}
	if (trimmed === "doctor" || trimmed.startsWith("doctor ")) {
		await handleDoctor(trimmed.replace(/^doctor\s*/, "").trim(), ctx, pi);
		return true;
	}
	if (trimmed === "repair" || trimmed.startsWith("repair ")) {
		const s = getAutoSession();
		const args = trimmed.replace(/^repair\s*/, "").trim();
		// Switch to repair work mode
		const transition = s.setMode({ workMode: "repair" });
		ctx.ui.notify(
			`Repair mode: ${transition.from.workMode} → ${transition.to.workMode}`,
			"info",
		);
		// If --autonomous flag, also set run control
		if (args.includes("--autonomous")) {
			s.setMode({ runControl: "autonomous" });
			ctx.ui.notify(
				"Repair will run autonomously until clean or blocked.",
				"info",
			);
		}
		// Run doctor diagnostics
		await handleDoctor("fix", ctx, pi);
		return true;
	}
	if (trimmed === "uok" || trimmed.startsWith("uok ")) {
		const { handleUok } = await import("../../commands-uok.js");
		await handleUok(trimmed.replace(/^uok\s*/, "").trim(), ctx);
		return true;
	}
	if (trimmed === "logs" || trimmed.startsWith("logs ")) {
		await handleLogs(trimmed.replace(/^logs\s*/, "").trim(), ctx);
		return true;
	}
	if (trimmed === "debug" || trimmed.startsWith("debug ")) {
		await handleDebug(trimmed.replace(/^debug\s*/, "").trim(), ctx, pi);
		return true;
	}
	if (trimmed === "escalate" || trimmed.startsWith("escalate ")) {
		await handleEscalate(trimmed.replace(/^escalate\s*/, "").trim(), ctx);
		return true;
	}
	if (trimmed === "forensics" || trimmed.startsWith("forensics ")) {
		const { handleForensics } = await import("../../forensics.js");
		await handleForensics(trimmed.replace(/^forensics\s*/, "").trim(), ctx, pi);
		return true;
	}
	if (trimmed === "scan" || trimmed.startsWith("scan ")) {
		const { handleScan } = await import("../../commands-scan.js");
		await handleScan(trimmed.replace(/^scan\s*/, "").trim(), ctx, pi);
		return true;
	}
	if (trimmed === "changelog" || trimmed.startsWith("changelog ")) {
		const { handleChangelog } = await import("../../changelog.js");
		await handleChangelog(trimmed.replace(/^changelog\s*/, "").trim(), ctx, pi);
		return true;
	}
	if (trimmed === "history" || trimmed.startsWith("history ")) {
		await handleHistory(
			trimmed.replace(/^history\s*/, "").trim(),
			ctx,
			projectRoot(),
		);
		return true;
	}
	if (trimmed === "cost" || trimmed.startsWith("cost ")) {
		await handleCost(
			trimmed.replace(/^cost\s*/, "").trim(),
			ctx,
			projectRoot(),
		);
		return true;
	}
	if (trimmed === "trajectory" || trimmed.startsWith("trajectory ")) {
		const { handleTrajectory } = await import("../../trajectory-command.js");
		await handleTrajectory(
			trimmed.replace(/^trajectory\s*/, "").trim(),
			ctx,
			projectRoot(),
		);
		return true;
	}
	if (trimmed === "undo-task" || trimmed.startsWith("undo-task ")) {
		const { handleUndoTask } = await import("../../undo.js");
		await handleUndoTask(
			trimmed.replace(/^undo-task\s*/, "").trim(),
			ctx,
			pi,
			projectRoot(),
		);
		return true;
	}
	if (trimmed === "reset-slice" || trimmed.startsWith("reset-slice ")) {
		const { handleResetSlice } = await import("../../undo.js");
		await handleResetSlice(
			trimmed.replace(/^reset-slice\s*/, "").trim(),
			ctx,
			pi,
			projectRoot(),
		);
		return true;
	}
	if (trimmed === "undo" || trimmed.startsWith("undo ")) {
		await handleUndo(
			trimmed.replace(/^undo\s*/, "").trim(),
			ctx,
			pi,
			projectRoot(),
		);
		return true;
	}
	if (trimmed === "skip") {
		ctx.ui.notify(
			"Usage: /skip <unit-id>  Example: /skip M001/S01/T03",
			"warning",
		);
		return true;
	}
	if (trimmed.startsWith("skip ")) {
		await handleSkip(
			trimmed.replace(/^skip\s*/, "").trim(),
			ctx,
			projectRoot(),
		);
		return true;
	}
	if (trimmed === "recover") {
		await handleRecover(ctx, projectRoot());
		return true;
	}
	if (trimmed === "rate" || trimmed.startsWith("rate ")) {
		await handleRate(
			trimmed.replace(/^rate\s*/, "").trim(),
			ctx,
			projectRoot(),
		);
		return true;
	}
	if (trimmed === "export" || trimmed.startsWith("export ")) {
		await handleExport(
			trimmed.replace(/^export\s*/, "").trim(),
			ctx,
			projectRoot(),
		);
		return true;
	}
	if (
		trimmed === "cleanup projects" ||
		trimmed.startsWith("cleanup projects ")
	) {
		await handleCleanupProjects(
			trimmed.replace(/^cleanup projects\s*/, "").trim(),
			ctx,
		);
		return true;
	}
	if (trimmed === "cleanup worktrees") {
		await handleCleanupWorktrees(ctx, projectRoot());
		return true;
	}
	if (trimmed === "cleanup") {
		await handleCleanupBranches(ctx, projectRoot());
		await handleCleanupSnapshots(ctx, projectRoot());
		return true;
	}
	if (trimmed === "cleanup branches") {
		await handleCleanupBranches(ctx, projectRoot());
		return true;
	}
	if (trimmed === "cleanup snapshots") {
		await handleCleanupSnapshots(ctx, projectRoot());
		return true;
	}
	if (trimmed.startsWith("capture ") || trimmed === "capture") {
		await handleCapture(trimmed.replace(/^capture\s*/, "").trim(), ctx);
		return true;
	}
	if (trimmed === "triage" || trimmed.startsWith("triage ")) {
		await handleTriage(
			trimmed.replace(/^triage\s*/, "").trim(),
			ctx,
			pi,
			process.cwd(),
		);
		return true;
	}
	if (trimmed === "todo" || trimmed.startsWith("todo ")) {
		const { handleTodo } = await import("../../commands-todo.js");
		await handleTodo(trimmed.replace(/^todo\s*/, "").trim(), ctx, pi);
		return true;
	}
	if (trimmed === "config") {
		await handleConfig(ctx);
		return true;
	}
	if (trimmed === "hooks") {
		const { formatHookStatus } = await import("../../post-unit-hooks.js");
		ctx.ui.notify(formatHookStatus(), "info");
		return true;
	}
	if (trimmed === "skill-health" || trimmed.startsWith("skill-health ")) {
		await handleSkillHealth(
			trimmed.replace(/^skill-health\s*/, "").trim(),
			ctx,
		);
		return true;
	}
	if (trimmed.startsWith("run-hook ")) {
		await handleRunHook(trimmed.replace(/^run-hook\s*/, "").trim(), ctx, pi);
		return true;
	}
	if (trimmed === "run-hook") {
		ctx.ui.notify(
			`Usage: /run-hook <hook-name> <unit-type> <unit-id>

Unit types:
  execute-task   - Task execution (unit-id: M001/S01/T01)
  plan-slice     - Slice planning (unit-id: M001/S01)
  research-milestone - Milestone research (unit-id: M001)
  complete-slice - Slice completion (unit-id: M001/S01)
  complete-milestone - Milestone completion (unit-id: M001)

Examples:
  /run-hook code-review execute-task M001/S01/T01
  /run-hook lint-check plan-slice M001/S01`,
			"warning",
		);
		return true;
	}
	if (trimmed.startsWith("steer ")) {
		await handleSteer(trimmed.replace(/^steer\s+/, "").trim(), ctx, pi);
		return true;
	}
	if (trimmed === "steer") {
		ctx.ui.notify(
			"Usage: /steer <description of change>. Example: /steer Use Postgres instead of SQLite",
			"warning",
		);
		return true;
	}
	if (trimmed.startsWith("knowledge ")) {
		await handleKnowledge(trimmed.replace(/^knowledge\s+/, "").trim(), ctx);
		return true;
	}
	if (trimmed === "knowledge") {
		ctx.ui.notify(
			"Usage: /knowledge <rule|pattern|lesson> <description>. Example: /knowledge rule Use real DB for integration tests",
			"warning",
		);
		return true;
	}
	if (trimmed === "harness" || trimmed.startsWith("harness ")) {
		const { handleHarness } = await import("../../commands-harness.js");
		await handleHarness(trimmed.replace(/^harness\s*/, "").trim(), ctx);
		return true;
	}
	if (trimmed === "solver-eval" || trimmed.startsWith("solver-eval ")) {
		const { handleAutonomousSolverEval } = await import(
			"../../autonomous-solver-eval.js"
		);
		await handleAutonomousSolverEval(
			trimmed.replace(/^solver-eval\s*/, "").trim(),
			ctx,
			projectRoot(),
		);
		return true;
	}
	if (trimmed === "migrate" || trimmed.startsWith("migrate ")) {
		const { handleMigrate } = await import("../../migrate/command.js");
		await handleMigrate(trimmed.replace(/^migrate\s*/, "").trim(), ctx, pi);
		return true;
	}
	if (trimmed === "remote" || trimmed.startsWith("remote ")) {
		await handleRemote(trimmed.replace(/^remote\s*/, "").trim(), ctx, pi);
		return true;
	}
	if (trimmed === "dispatch" || trimmed.startsWith("dispatch ")) {
		const phase = trimmed.replace(/^dispatch\s*/, "").trim();
		if (!phase) {
			ctx.ui.notify(
				"Usage: /dispatch <phase>  (research|plan|execute|complete|reassess|uat|replan)",
				"warning",
			);
			return true;
		}
		await dispatchDirectPhase(ctx, pi, phase, projectRoot());
		return true;
	}
	if (trimmed === "research") {
		const s = getAutoSession();
		s.setMode({ workMode: "research" });
		ctx.ui.notify("Stage: research — will research before planning", "info");
		await dispatchDirectPhase(ctx, pi, "research", projectRoot());
		return true;
	}
	if (trimmed === "plan") {
		const s = getAutoSession();
		s.setMode({ workMode: "plan" });
		ctx.ui.notify("Stage: plan — will plan before implementing", "info");
		await dispatchDirectPhase(ctx, pi, "plan", projectRoot());
		return true;
	}
	if (trimmed === "implement") {
		const s = getAutoSession();
		s.setMode({ workMode: "build" });
		ctx.ui.notify("Stage: implement — will execute tasks", "info");
		await dispatchDirectPhase(ctx, pi, "execute", projectRoot());
		return true;
	}
	if (trimmed === "notifications" || trimmed.startsWith("notifications ")) {
		const { handleNotificationsCommand } = await import(
			"./notifications-handler.js"
		);
		await handleNotificationsCommand(
			trimmed.replace(/^notifications\s*/, "").trim(),
			ctx,
			pi,
		);
		return true;
	}
	if (trimmed === "inspect") {
		await handleInspect(ctx);
		return true;
	}
	if (trimmed === "update") {
		await handleUpdate(ctx);
		return true;
	}
	if (trimmed === "fast" || trimmed.startsWith("fast ")) {
		const { handleFast } = await import("../../service-tier.js");
		await handleFast(trimmed.replace(/^fast\s*/, "").trim(), ctx);
		return true;
	}
	if (trimmed === "mcp" || trimmed.startsWith("mcp ")) {
		const { handleMcpStatus } = await import("../../commands-mcp-status.js");
		await handleMcpStatus(trimmed.replace(/^mcp\s*/, "").trim(), ctx);
		return true;
	}
	if (trimmed === "extensions" || trimmed.startsWith("extensions ")) {
		const { handleExtensions } = await import("../../commands-extensions.js");
		await handleExtensions(trimmed.replace(/^extensions\s*/, "").trim(), ctx);
		return true;
	}
	if (trimmed === "rethink") {
		const { handleRethink } = await import("../../rethink.js");
		await handleRethink(trimmed, ctx, pi);
		return true;
	}
	if (trimmed === "codebase" || trimmed.startsWith("codebase ")) {
		const { handleCodebase } = await import("../../commands-codebase.js");
		await handleCodebase(trimmed.replace(/^codebase\s*/, "").trim(), ctx, pi);
		return true;
	}
	if (trimmed === "ship" || trimmed.startsWith("ship ")) {
		await handleShip(trimmed.replace(/^ship\s*/, "").trim(), ctx, pi);
		return true;
	}
	if (trimmed === "session-report" || trimmed.startsWith("session-report ")) {
		await handleSessionReport(
			trimmed.replace(/^session-report\s*/, "").trim(),
			ctx,
		);
		return true;
	}
	if (trimmed === "pr-branch" || trimmed.startsWith("pr-branch ")) {
		await handlePrBranch(trimmed.replace(/^pr-branch\s*/, "").trim(), ctx);
		return true;
	}
	if (trimmed === "add-tests" || trimmed.startsWith("add-tests ")) {
		const { handleAddTests } = await import("../../commands-add-tests.js");
		await handleAddTests(trimmed.replace(/^add-tests\s*/, "").trim(), ctx, pi);
		return true;
	}
	if (trimmed === "scaffold sync" || trimmed.startsWith("scaffold sync ")) {
		const { handleScaffoldSync } = await import(
			"../../commands-scaffold-sync.js"
		);
		await handleScaffoldSync(
			trimmed.replace(/^scaffold sync\s*/, "").trim(),
			ctx,
		);
		return true;
	}
	if (
		trimmed === "scaffold migrate" ||
		trimmed.startsWith("scaffold migrate ")
	) {
		const { handleScaffoldMigrate } = await import(
			"../../commands-scaffold-migrate.js"
		);
		await handleScaffoldMigrate(
			trimmed.replace(/^scaffold migrate\s*/, "").trim(),
			ctx,
		);
		return true;
	}
	if (trimmed === "scaffold") {
		ctx.ui.notify(
			"Usage: /scaffold sync [--dry-run] [--include-editing] [--only=<glob>]\n       /scaffold migrate [--profile=<name>] [--dry-run] [--prune]",
			"warning",
		);
		return true;
	}
	if (
		trimmed === "extract-learnings" ||
		trimmed.startsWith("extract-learnings ")
	) {
		const { handleExtractLearnings } = await import(
			"../../commands-extract-learnings.js"
		);
		await handleExtractLearnings(
			trimmed.replace(/^extract-learnings\s*/, "").trim(),
			ctx,
			pi,
		);
		return true;
	}
	if (
		trimmed === "worktree" ||
		trimmed.startsWith("worktree ") ||
		trimmed === "wt" ||
		trimmed.startsWith("wt ")
	) {
		const { handleWorktree } = await import("../../commands-worktree.js");
		await handleWorktree(trimmed.replace(/^(worktree|wt)\s*/, "").trim(), ctx);
		return true;
	}
	if (trimmed === "eval-review" || trimmed.startsWith("eval-review ")) {
		const { handleEvalReview } = await import("../../commands-eval-review.js");
		await handleEvalReview(
			trimmed.replace(/^eval-review\s*/, "").trim(),
			ctx,
			pi,
		);
		return true;
	}
	if (trimmed === "plan" || trimmed.startsWith("plan ")) {
		const { handlePlan } = await import("../../commands-plan.js");
		const handled = await handlePlan(
			trimmed.replace(/^plan\s*/, "").trim(),
			ctx,
		);
		if (handled) return true;
		ctx.ui.notify("Usage: /plan promote|list|diff|specs ...", "info");
		return true;
	}
	if (trimmed === "agent" || trimmed.startsWith("agent ")) {
		const { handleAgent } = await import("../../commands-agent.js");
		await handleAgent(
			trimmed.replace(/^agent\s*/, "").trim(),
			ctx,
			projectRoot(),
		);
		return true;
	}
	if (trimmed === "keep-alive" || trimmed.startsWith("keep-alive ")) {
		await handleKeepAlive(trimmed.replace(/^keep-alive\s*/, "").trim(), ctx);
		return true;
	}
	if (trimmed === "delegate" || trimmed.startsWith("delegate ")) {
		await handleDelegateCommand(
			trimmed.replace(/^delegate\s*/, "").trim(),
			ctx,
		);
		return true;
	}
	if (trimmed === "share" || trimmed.startsWith("share ")) {
		await handleShareCommand(trimmed.replace(/^share\s*/, "").trim(), ctx);
		return true;
	}
	if (trimmed === "configure-agent" || trimmed.startsWith("configure-agent ")) {
		await handleConfigureAgentCommand(
			trimmed.replace(/^configure-agent\s*/, "").trim(),
			ctx,
		);
		return true;
	}
	return false;
}

// ─── /keep-alive ─────────────────────────────────────────────────────────────

let _keepAliveProcess = null;

async function handleKeepAlive(args, ctx) {
	const os = await import("node:os");
	const { spawn } = await import("node:child_process");
	if (args === "off" || args === "stop") {
		if (_keepAliveProcess) {
			_keepAliveProcess.kill();
			_keepAliveProcess = null;
			ctx.ui.notify("Keep-alive stopped.", "info");
		} else {
			ctx.ui.notify("Keep-alive is not running.", "info");
		}
		return;
	}
	if (_keepAliveProcess) {
		ctx.ui.notify(
			"Keep-alive is already running. Use /keep-alive off to stop it.",
			"info",
		);
		return;
	}
	const platform = os.platform();
	let cmd, cmdArgs;
	if (platform === "darwin") {
		cmd = "caffeinate";
		cmdArgs = ["-dims"];
	} else if (platform === "linux") {
		// systemd-inhibit keeps the session alive (no-op if unavailable)
		cmd = "systemd-inhibit";
		cmdArgs = [
			"--what=idle:sleep",
			"--who=SF",
			"--why=Active SF session",
			"sleep",
			"infinity",
		];
	} else {
		ctx.ui.notify(
			"Keep-alive is supported on macOS (caffeinate) and Linux (systemd-inhibit).",
			"info",
		);
		return;
	}
	try {
		_keepAliveProcess = spawn(cmd, cmdArgs, {
			stdio: "ignore",
			detached: false,
		});
		_keepAliveProcess.on("error", () => {
			_keepAliveProcess = null;
		});
		_keepAliveProcess.on("exit", () => {
			_keepAliveProcess = null;
		});
		ctx.ui.notify(
			`Keep-alive started (${cmd}). Run /keep-alive off to stop.`,
			"info",
		);
	} catch {
		ctx.ui.notify(
			`Could not start ${cmd}. Make sure it is installed.`,
			"warning",
		);
	}
}

// ─── /delegate ───────────────────────────────────────────────────────────────

async function handleDelegateCommand(args, ctx) {
	const { execSync } = await import("node:child_process");
	const root = projectRoot();
	const title = args || undefined;
	try {
		// Check if gh is available
		execSync("gh --version", { stdio: "pipe" });
	} catch {
		ctx.ui.notify(
			"GitHub CLI (gh) is not installed. Install it from https://cli.github.com",
			"warning",
		);
		return;
	}
	try {
		const branch = execSync("git rev-parse --abbrev-ref HEAD", {
			cwd: root,
			encoding: "utf-8",
		}).trim();
		const summary = execSync(
			"git log --oneline -5 2>/dev/null || echo '(no commits)'",
			{ cwd: root, encoding: "utf-8" },
		).trim();
		ctx.ui.notify(
			[
				`Branch: ${branch}`,
				"",
				"Recent commits:",
				summary,
				"",
				title
					? `Creating PR with title: "${title}"`
					: 'Run: gh pr create --web  (or: /delegate "My PR title")',
			].join("\n"),
			"info",
		);
		if (title) {
			const prUrl = execSync(
				`gh pr create --title "${title.replace(/"/g, '\\"')}" --body "Created from SF session" --web 2>&1 || true`,
				{ cwd: root, encoding: "utf-8" },
			).trim();
			if (prUrl) ctx.ui.notify(`PR: ${prUrl}`, "info");
		}
	} catch (e) {
		ctx.ui.notify(`Delegate failed: ${e.message}`, "error");
	}
}

// ─── /share ──────────────────────────────────────────────────────────────────

async function handleShareCommand(format, ctx) {
	const { writeFileSync } = await import("node:fs");
	const { join: pathJoin } = await import("node:path");
	const { homedir } = await import("node:os");
	const { execSync } = await import("node:child_process");

	const fmt = format || "md";
	const entries = ctx.sessionManager?.getEntries?.() ?? [];
	const ts = new Date().toISOString().replace(/[:.]/g, "-").slice(0, 19);
	const outPath = pathJoin(
		homedir(),
		`sf-session-${ts}.${fmt === "md" ? "md" : "txt"}`,
	);

	const lines = [`# SF Session — ${new Date().toLocaleString()}`, ""];
	for (const entry of entries) {
		const role =
			entry.type === "user"
				? "**User**"
				: entry.type === "assistant"
					? "**SF**"
					: `*${entry.type ?? "system"}*`;
		const content =
			typeof entry.content === "string"
				? entry.content
				: JSON.stringify(entry.content ?? "");
		lines.push(`${role}:\n${content}\n`);
	}
	const md = lines.join("\n");
	writeFileSync(outPath, md, "utf-8");
	ctx.ui.notify(`Session exported to: ${outPath}`, "info");
	// Try to copy to clipboard (non-fatal)
	try {
		const platform = process.platform;
		if (platform === "darwin") {
			execSync(`echo "${outPath}" | pbcopy`, { stdio: "pipe" });
		} else if (platform === "linux") {
			execSync(
				`echo "${outPath}" | xclip -selection clipboard 2>/dev/null || echo "${outPath}" | xsel --clipboard --input 2>/dev/null || true`,
				{ stdio: "pipe" },
			);
		}
	} catch {
		/* non-fatal */
	}
}

// ─── /configure-agent ────────────────────────────────────────────────────────

/**
 * Interactive wizard for MCP servers and agent settings.
 *
 * Purpose: CONFIGURE_COPILOT_AGENT parity — let the user view and toggle
 * MCP server entries without leaving SF.
 * Consumer: /configure-agent command dispatch.
 */
async function handleConfigureAgentCommand(args, ctx) {
	if (!getExperimentalFlag("configure_agent")) {
		ctx.ui.notify(
			"CONFIGURE_COPILOT_AGENT is not enabled.\nRun /experimental on configure_agent to enable.",
			"warning",
		);
		return;
	}

	const { existsSync, readFileSync, writeFileSync, mkdirSync } = await import(
		"node:fs"
	);
	const { join: pathJoin } = await import("node:path");

	const root = projectRoot();
	const mcpPath = pathJoin(root, ".mcp.json");
	const sfMcpPath = pathJoin(root, ".sf", "mcp.json");

	// Sub-command routing
	if (args === "mcp" || args === "servers" || !args) {
		// Show interactive MCP server list
		let config = {};
		const activePath = existsSync(mcpPath)
			? mcpPath
			: existsSync(sfMcpPath)
				? sfMcpPath
				: null;
		if (activePath) {
			try {
				config = JSON.parse(readFileSync(activePath, "utf-8"));
			} catch {
				/* malformed */
			}
		}
		const servers = Object.entries(config.mcpServers ?? config.servers ?? {});
		if (!servers.length) {
			const lines = [
				"No MCP servers configured.",
				"",
				"Add a server:",
				"  /configure-agent add-mcp <name> <command> [args...]",
				"",
				"Example:",
				"  /configure-agent add-mcp filesystem npx @modelcontextprotocol/server-filesystem /tmp",
				"",
				"Config file: .mcp.json (or .sf/mcp.json)",
			];
			ctx.ui.notify(lines.join("\n"), "info");
			return;
		}
		const lines = [`MCP Servers (${servers.length}) — config: ${activePath}\n`];
		for (const [name, cfg] of servers) {
			const endpoint = cfg.command ?? cfg.url ?? "(unknown)";
			lines.push(`  ● ${name.padEnd(18)} ${endpoint}`);
		}
		lines.push("\n/configure-agent add-mcp <name> <cmd> — add a server");
		lines.push("/configure-agent remove-mcp <name>  — remove a server");
		ctx.ui.notify(lines.join("\n"), "info");
		return;
	}

	// add-mcp <name> <command> [args...]
	if (args.startsWith("add-mcp ")) {
		const parts = args.slice(8).trim().split(/\s+/);
		const [name, command, ...cmdArgs] = parts;
		if (!name || !command) {
			ctx.ui.notify(
				"Usage: /configure-agent add-mcp <name> <command> [args...]\nExample: /configure-agent add-mcp fs npx @modelcontextprotocol/server-filesystem /tmp",
				"info",
			);
			return;
		}
		const targetPath = existsSync(mcpPath) ? mcpPath : mcpPath;
		let config = {};
		if (existsSync(targetPath)) {
			try {
				config = JSON.parse(readFileSync(targetPath, "utf-8"));
			} catch {
				/* malformed */
			}
		}
		config.mcpServers = config.mcpServers ?? {};
		config.mcpServers[name] = {
			command,
			...(cmdArgs.length ? { args: cmdArgs } : {}),
		};
		mkdirSync(projectRoot(), { recursive: true });
		writeFileSync(targetPath, JSON.stringify(config, null, 2), "utf-8");
		ctx.ui.notify(
			`MCP server "${name}" added to ${targetPath}.\nRestart SF to load the new server.`,
			"info",
		);
		return;
	}

	// remove-mcp <name>
	if (args.startsWith("remove-mcp ")) {
		const name = args.slice(11).trim();
		const activePath = existsSync(mcpPath)
			? mcpPath
			: existsSync(sfMcpPath)
				? sfMcpPath
				: null;
		if (!activePath || !existsSync(activePath)) {
			ctx.ui.notify("No MCP config file found.", "warning");
			return;
		}
		let config = {};
		try {
			config = JSON.parse(readFileSync(activePath, "utf-8"));
		} catch {
			ctx.ui.notify("Could not parse MCP config.", "error");
			return;
		}
		if (config.mcpServers?.[name]) {
			delete config.mcpServers[name];
			writeFileSync(activePath, JSON.stringify(config, null, 2), "utf-8");
			ctx.ui.notify(`MCP server "${name}" removed.`, "info");
		} else if (config.servers?.[name]) {
			delete config.servers[name];
			writeFileSync(activePath, JSON.stringify(config, null, 2), "utf-8");
			ctx.ui.notify(`MCP server "${name}" removed.`, "info");
		} else {
			ctx.ui.notify(`No server named "${name}" found.`, "warning");
		}
		return;
	}

	ctx.ui.notify(
		[
			"configure-agent subcommands:",
			"  /configure-agent                      — List MCP servers",
			"  /configure-agent mcp                  — Same as above",
			"  /configure-agent add-mcp <name> <cmd> — Add MCP server",
			"  /configure-agent remove-mcp <name>    — Remove MCP server",
		].join("\n"),
		"info",
	);
}
