import { existsSync, readdirSync, readFileSync } from "node:fs";
import { join } from "node:path";
import { sfHome } from "../sf-home.js";
import {
	loadRegistry,
	workflowTemplateCommandDefinitions,
} from "../workflow-templates.js";
import { resolveProjectRoot } from "../worktree.js";

/**
 * Comprehensive description of all available SF commands for help text.
 */
export const SF_COMMAND_DESCRIPTION =
	"SF — Singularity Forge workflow runtime: /next for assisted build, /discuss for plan/discovery, /autonomous for the full research-plan-execute loop.";

export const BASE_RUNTIME_COMMANDS = new Set([
	"settings",
	"model",
	"scoped-models",
	"export",
	"share",
	"copy",
	"name",
	"session",
	"changelog",
	"hotkeys",
	"fork",
	"tree",
	"provider",
	"login",
	"logout",
	"new",
	"compact",
	"resume",
	"reload",
	"thinking",
	"edit-mode",
	"terminal",
	"exit",
	"quit",
]);
/**
 * Top-level SF subcommands with descriptions.
 */
export const TOP_LEVEL_SUBCOMMANDS = [
	{ cmd: "help", desc: "Categorized command reference with descriptions" },
	{ cmd: "next", desc: "Assisted mode — execute one unit, then pause" },
	{
		cmd: "autonomous",
		desc: "Autonomous mode — continuous loop, never asks user (self-resolves or stops with blocker)",
	},
	{ cmd: "stop", desc: "Stop autonomous mode gracefully" },
	{
		cmd: "pause",
		desc: "Pause autonomous mode (preserves state, /autonomous to resume)",
	},
	{
		cmd: "reload",
		desc: "Reload extensions, skills, prompts, and themes in the TUI",
	},
	{ cmd: "status", desc: "Progress dashboard" },
	{ cmd: "widget", desc: "Cycle widget: full → small → min → off" },
	{
		cmd: "visualize",
		desc: "Open 10-tab workflow visualizer (progress, timeline, deps, metrics, health, agent, changes, knowledge, captures, export)",
	},
	{ cmd: "queue", desc: "Queue and reorder future milestones" },
	{ cmd: "quick", desc: "Execute a quick task without full planning overhead" },
	{ cmd: "discuss", desc: "Discuss architecture and decisions" },
	{ cmd: "capture", desc: "Fire-and-forget thought capture" },
	{ cmd: "debug", desc: "Create and inspect persistent /debug sessions" },
	{ cmd: "scan", desc: "Run source and project scans" },
	{
		cmd: "escalate",
		desc: "List, show, or resolve task escalations (SF ADR-011 P2)",
	},
	{ cmd: "changelog", desc: "Show categorized release notes" },
	{ cmd: "triage", desc: "Manually trigger triage of pending captures" },
	{ cmd: "todo", desc: "Triage root TODO.md dump into eval/backlog artifacts" },
	{ cmd: "dispatch", desc: "Dispatch a specific phase directly" },
	{ cmd: "research", desc: "Force research stage for current unit" },
	{
		cmd: "plan",
		desc: "Force planning stage; /plan promote|list|diff manages planning artifacts in docs/",
	},
	{ cmd: "implement", desc: "Force implementation stage for current unit" },
	{ cmd: "history", desc: "View execution history" },
	{
		cmd: "cost",
		desc: "Show cost summary from metrics-central or legacy ledger",
	},
	{
		cmd: "trajectory",
		desc: "View execution trajectory — step-by-step trace with costs and errors",
	},
	{ cmd: "undo", desc: "Revert last completed unit" },
	{
		cmd: "undo-task",
		desc: "Reset a specific task's completion state (DB + markdown)",
	},
	{
		cmd: "reset-slice",
		desc: "Reset a slice and all its tasks (DB + markdown)",
	},
	{
		cmd: "rate",
		desc: "Rate last unit's model tier (over/ok/under) — improves adaptive routing",
	},
	{ cmd: "skip", desc: "Prevent a unit from autonomous dispatch" },
	{ cmd: "export", desc: "Export milestone/slice results" },
	{ cmd: "cleanup", desc: "Remove merged branches or snapshots" },
	{
		cmd: "worktree",
		desc: "Manage worktrees from the TUI (list, merge, clean, remove)",
	},
	{ cmd: "model", desc: "Switch the active session model or open a picker" },
	{
		cmd: "mode",
		desc: "Internal mode compatibility; use /discuss, /next, or /autonomous for product workflows",
	},
	{
		cmd: "control",
		desc: "Override run control (manual/assisted/autonomous) — advanced",
	},
	{
		cmd: "permission-profile",
		desc: "Switch permission profile (restricted/normal/trusted/unrestricted)",
	},
	{
		cmd: "model-mode",
		desc: "Override model quality (fast/smart/deep) — advanced",
	},
	{
		cmd: "show-config",
		desc: "Show effective configuration (models, routing, toggles)",
	},
	{
		cmd: "prefs",
		desc: "Manage preferences (model selection, timeouts, etc.)",
	},
	{ cmd: "config", desc: "Set API keys for external tools" },
	{
		cmd: "keys",
		desc: "API key manager — list, add, remove, test, rotate, doctor",
	},
	{ cmd: "hooks", desc: "Show configured post-unit and pre-dispatch hooks" },
	{ cmd: "run-hook", desc: "Manually trigger a specific hook" },
	{ cmd: "skill-health", desc: "Skill lifecycle dashboard" },
	{
		cmd: "notifications",
		desc: "View, filter, and clear persistent notification history",
	},
	{ cmd: "doctor", desc: "Runtime health checks with auto-fix" },
	{
		cmd: "repair",
		desc: "Switch to repair work mode and run diagnostics [--autonomous]",
	},
	{ cmd: "tasks", desc: "Background work surface — units, workers, budget" },
	{
		cmd: "skills",
		desc: "List discovered skills from .agents/skills/ [reload|--eval|--auto-create]",
	},
	{
		cmd: "uok",
		desc: "UOK runtime health: ledger, last run, last error, startup gate, gate metrics",
	},
	{ cmd: "logs", desc: "Browse activity logs, debug logs, and metrics" },
	{ cmd: "forensics", desc: "Examine execution logs" },
	{
		cmd: "init",
		desc: "Project init wizard — detect, configure, bootstrap .sf/",
	},
	{ cmd: "setup", desc: "Global setup status and configuration" },
	{ cmd: "migrate", desc: "Migrate a v1 .planning directory to .sf format" },
	{ cmd: "remote", desc: "Configure remote question delivery" },
	{ cmd: "steer", desc: "Hard-steer plan documents during execution" },
	{
		cmd: "recover",
		desc: "Reconstruct DB hierarchy (milestones/slices/tasks) from rendered markdown on disk",
	},
	{ cmd: "inspect", desc: "Show SQLite DB diagnostics" },
	{
		cmd: "knowledge",
		desc: "Add persistent project knowledge (rule, pattern, or lesson)",
	},
	{
		cmd: "harness",
		desc: "Repo-native harness evolution (profile, status)",
	},
	{
		cmd: "solver-eval",
		desc: "Compare raw agent loops against SF autonomous solver control",
	},
	{
		cmd: "new-milestone",
		desc: "Create a milestone from a specification document (headless)",
	},
	{
		cmd: "parallel",
		desc: "Parallel milestone orchestration (start, status, stop, merge, watch)",
	},
	{
		cmd: "cmux",
		desc: "Manage cmux integration (status, sidebar, notifications, splits)",
	},
	{ cmd: "park", desc: "Park a milestone — skip without deleting" },
	{ cmd: "unpark", desc: "Reactivate a parked milestone" },
	{ cmd: "update", desc: "Update SF to the latest version" },
	{
		cmd: "start",
		desc: "Start a workflow template (bugfix, spike, feature, etc.)",
	},
	{ cmd: "templates", desc: "List available workflow templates" },
	{
		cmd: "extensions",
		desc: "Manage extensions (list, enable, disable, info)",
	},
	{ cmd: "fast", desc: "Toggle OpenAI service tier (on/off/flex/status)" },
	{
		cmd: "mcp",
		desc: "External MCP server status and connectivity (status, check)",
	},
	{
		cmd: "rethink",
		desc: "Conversational project reorganization — reorder, park, discard, add milestones",
	},
	{
		cmd: "workflow",
		desc: "Custom workflow lifecycle (new, run, list, validate, pause, resume)",
	},
	{
		cmd: "codebase",
		desc: "Generate, refresh, and inspect the codebase map cache (.sf/CODEBASE.md)",
	},
	{
		cmd: "ship",
		desc: "Create PR from milestone artifacts and open for review",
	},
	{ cmd: "do", desc: "Route freeform text to the right SF command" },
	{ cmd: "session-report", desc: "Session cost, tokens, and work summary" },
	{ cmd: "backlog", desc: "Manage backlog items (add, promote, remove, list)" },
	{
		cmd: "schedule",
		desc: "Manage scheduled items (add, list, done, cancel, snooze, run)",
	},
	{ cmd: "pr-branch", desc: "Create clean PR branch filtering .sf/ commits" },
	{ cmd: "add-tests", desc: "Generate tests for completed slices" },
	{
		cmd: "scaffold",
		desc: "Inspect or refresh ADR-021 versioned scaffold docs (sync, --dry-run, --include-editing, --only=<glob>)",
	},
	{
		cmd: "extract-learnings",
		desc: "Extract durable project learnings from session artifacts",
	},
	{
		cmd: "eval-review",
		desc: "Milestone-end evaluation review — audit slice coverage and infrastructure with scored EVAL-REVIEW.md",
	},
	{
		cmd: "experimental",
		desc: "Toggle experimental feature flags (show/on/off/on <flag>/off <flag>)",
	},
	{ cmd: "diff", desc: "Show git diff (HEAD by default, --staged for staged)" },
	{ cmd: "theme", desc: "Get or set the UI theme (dark/light/dim/auto)" },
	{ cmd: "rename", desc: "Rename the current session (sets terminal title)" },
	{
		cmd: "streamer-mode",
		desc: "Toggle streamer mode — masks model names and quota details",
	},
	{
		cmd: "statusline",
		desc: "Configure the status line script (script <path> | off)",
	},
	{ cmd: "search", desc: "Search the session timeline for a query" },
	{ cmd: "find", desc: "Alias for /search — search the session timeline" },
	{
		cmd: "chronicle",
		desc: "Show session chronicle (recent git log + session events)",
	},
	{
		cmd: "rewind",
		desc: "Rewind the last turn and revert its file changes",
	},
	{
		cmd: "instructions",
		desc: "List instruction files loaded into the agent context",
	},
	{
		cmd: "sidekicks",
		desc: "List background parallel worker jobs and their status",
	},
	{
		cmd: "keep-alive",
		desc: "Prevent system sleep during long runs (caffeinate / systemd-inhibit)",
	},
	{
		cmd: "delegate",
		desc: "Create a GitHub PR from the current branch via gh pr create",
	},
	{
		cmd: "share",
		desc: "Export session transcript to a Markdown file",
	},
	{
		cmd: "ask",
		desc: "Ask a side question without it entering the main conversation history",
	},
	{
		cmd: "resume",
		desc: "List or switch to another session (BACKGROUND_SESSIONS flag for live switching)",
	},
	{
		cmd: "configure-agent",
		desc: "Manage MCP servers and agent settings (CONFIGURE_COPILOT_AGENT flag)",
	},
];

// Lean product surface (UOK control-plane convo 2026-05-14): operators
// pick workflows, not personas, and SF runs implementation machinery (agent
// picks, mode/work-mode shifts, orchestration internals) on its own. Commands
// not in this set stay callable for scripting/debug but don't show up in the
// slash catalog or help. Registration uses DIRECT_SF_COMMANDS below; visibility
// uses PUBLIC_DIRECT_COMMANDS.
//
// Hidden by category:
//   - /agent, /parallel, /cmux, /sidekicks — internal orchestration machinery
//   - /mode, /control, /permission-profile, /model-mode — Shift+Tab + advanced axes
//   - /hooks, /run-hook, /skill-health, /inspect, /recover — diagnostics
//   - /mcp, /extensions, /configure-agent, /experimental — platform plumbing
//   - /delegate, /pr-branch, /add-tests — lower-level conveniences reached
//     through /ship, /next, or autonomous workflow
export const PUBLIC_DIRECT_COMMANDS = new Set([
	"autonomous",
	"backlog",
	"capture",
	"config",
	"discuss",
	"doctor",
	"forensics",
	"help",
	"history",
	"init",
	"keys",
	"knowledge",
	"logs",
	"model",
	"next",
	"park",
	"pause",
	"prefs",
	"queue",
	"quick",
	"remote",
	"repair",
	"schedule",
	"ship",
	"skip",
	"setup",
	"start",
	"status",
	"stop",
	"templates",
	"triage",
	"undo",
	"unpark",
	"update",
	"visualize",
	"workflow",
]);

/**
 * Primary command tier — the 5 things an operator should memorize. Four
 * product modes plus /help. Everything else is reachable via autocomplete
 * (PUBLIC_DIRECT_COMMANDS) or operator-driven discovery (`/help all`).
 *
 * Rationale (2026-05-14 product-surface convo): a 34-command menu defeats
 * the product-mode framing. Operators interact with modes (`/next`,
 * `/discuss`, `/autonomous`) plus the non-workflow lane (`/quick`); SF
 * surfaces relevant secondary commands inline when context warrants.
 */
export const PRIMARY_COMMANDS = new Set([
	"next",
	"autonomous",
	"discuss",
	"quick",
	"help",
]);

export const PRIMARY_TOP_LEVEL_SUBCOMMANDS = TOP_LEVEL_SUBCOMMANDS.filter(
	(command) => PRIMARY_COMMANDS.has(command.cmd),
);

export const PUBLIC_TOP_LEVEL_SUBCOMMANDS = TOP_LEVEL_SUBCOMMANDS.filter(
	(command) => PUBLIC_DIRECT_COMMANDS.has(command.cmd),
);

export const DIRECT_SF_COMMANDS = TOP_LEVEL_SUBCOMMANDS.filter(
	(command) => !BASE_RUNTIME_COMMANDS.has(command.cmd),
);

export const DIRECT_SF_COMMAND_NAMES = DIRECT_SF_COMMANDS.map(
	(command) => command.cmd,
);
/**
 * Nested subcommand definitions for multi-level completion.
 */
const NESTED_COMPLETIONS = {
	autonomous: [
		{ cmd: "--verbose", desc: "Show detailed execution output" },
		{ cmd: "--debug", desc: "Enable debug logging" },
	],
	next: [
		{ cmd: "--verbose", desc: "Show detailed step output" },
		{ cmd: "--dry-run", desc: "Preview next step without executing" },
		{ cmd: "--debug", desc: "Enable debug logging" },
	],
	widget: [
		{ cmd: "full", desc: "Full widget display" },
		{ cmd: "small", desc: "Compact widget display" },
		{ cmd: "min", desc: "Minimal widget display" },
		{ cmd: "off", desc: "Hide widget" },
	],
	mode: [
		{ cmd: "global", desc: "Edit global workflow mode" },
		{ cmd: "project", desc: "Edit project-specific workflow mode" },
	],
	parallel: [
		{ cmd: "start", desc: "Start parallel milestone orchestration" },
		{ cmd: "status", desc: "Show parallel worker statuses" },
		{ cmd: "stop", desc: "Stop all parallel workers" },
		{ cmd: "pause", desc: "Pause a specific worker" },
		{ cmd: "resume", desc: "Resume a paused worker" },
		{ cmd: "merge", desc: "Merge completed milestone branches" },
		{ cmd: "watch", desc: "Live TUI dashboard monitoring all workers" },
	],
	setup: [
		{ cmd: "llm", desc: "Configure LLM provider settings" },
		{ cmd: "search", desc: "Configure web search provider" },
		{ cmd: "remote", desc: "Configure remote integrations" },
		{ cmd: "keys", desc: "Manage API keys" },
		{ cmd: "prefs", desc: "Configure global preferences" },
	],
	notifications: [
		{ cmd: "clear", desc: "Clear all notifications" },
		{ cmd: "tail", desc: "Show last N notifications (default: 20)" },
		{ cmd: "filter", desc: "Filter by severity (error|warning|info|success)" },
	],
	logs: [
		{ cmd: "debug", desc: "List or view debug log files" },
		{ cmd: "tail", desc: "Show last N activity log summaries" },
		{ cmd: "clear", desc: "Remove old activity and debug logs" },
	],
	keys: [
		{ cmd: "list", desc: "Show key status dashboard" },
		{ cmd: "add", desc: "Add a key for a provider" },
		{ cmd: "remove", desc: "Remove a key" },
		{ cmd: "test", desc: "Validate key(s) with API call" },
		{ cmd: "rotate", desc: "Replace an existing key" },
		{ cmd: "doctor", desc: "Health check all keys" },
	],
	prefs: [
		{ cmd: "global", desc: "Edit global preferences file" },
		{ cmd: "project", desc: "Edit project preferences file" },
		{ cmd: "status", desc: "Show effective preferences" },
		{ cmd: "wizard", desc: "Interactive preferences wizard" },
		{ cmd: "setup", desc: "First-time preferences setup" },
		{ cmd: "import-claude", desc: "Import settings from Claude Code" },
	],
	remote: [
		{ cmd: "slack", desc: "Configure Slack integration" },
		{ cmd: "discord", desc: "Configure Discord integration" },
		{ cmd: "status", desc: "Show remote connection status" },
		{ cmd: "disconnect", desc: "Disconnect remote integrations" },
	],
	history: [
		{ cmd: "--cost", desc: "Show cost breakdown per entry" },
		{ cmd: "--phase", desc: "Filter by phase type" },
		{ cmd: "--model", desc: "Filter by model used" },
		{ cmd: "10", desc: "Show last 10 entries" },
		{ cmd: "20", desc: "Show last 20 entries" },
		{ cmd: "50", desc: "Show last 50 entries" },
	],
	export: [
		{ cmd: "--json", desc: "Export as JSON" },
		{ cmd: "--markdown", desc: "Export as Markdown" },
		{ cmd: "--html", desc: "Export as HTML" },
		{ cmd: "--html --all", desc: "Export all milestones as HTML" },
	],
	cleanup: [
		{ cmd: "branches", desc: "Remove merged milestone and legacy branches" },
		{ cmd: "snapshots", desc: "Remove old execution snapshots" },
		{ cmd: "worktrees", desc: "Remove merged/safe-to-delete worktrees" },
		{
			cmd: "projects",
			desc: "Audit orphaned ~/.sf/projects/ state directories",
		},
		{
			cmd: "projects --fix",
			desc: "Delete orphaned project state directories (cannot be undone)",
		},
	],
	worktree: [
		{ cmd: "list", desc: "Show all worktrees with status" },
		{ cmd: "merge", desc: "Merge a worktree into main, then remove it" },
		{ cmd: "clean", desc: "Remove all merged/empty worktrees" },
		{
			cmd: "remove",
			desc: "Remove a worktree (use --force to skip safety checks)",
		},
	],
	knowledge: [
		{ cmd: "rule", desc: "Add a project rule (always/never do X)" },
		{ cmd: "pattern", desc: "Add a code pattern to follow" },
		{ cmd: "lesson", desc: "Record a lesson learned" },
	],
	harness: [
		{
			cmd: "profile",
			desc: "Record a read-only repo profile for harness evolution",
		},
		{ cmd: "status", desc: "Alias for profile in the first implementation" },
	],
	start: [
		...workflowTemplateCommandDefinitions(),
		{ cmd: "resume", desc: "Resume an in-progress workflow" },
		{ cmd: "--list", desc: "List all available templates" },
		{ cmd: "--dry-run", desc: "Preview workflow without executing" },
	],
	templates: [{ cmd: "info", desc: "Show detailed template info" }],
	extensions: [
		{ cmd: "list", desc: "List all extensions and their status" },
		{ cmd: "enable", desc: "Enable a disabled extension" },
		{ cmd: "disable", desc: "Disable an extension" },
		{ cmd: "info", desc: "Show extension details" },
	],
	fast: [
		{ cmd: "on", desc: "Priority tier (2x cost, faster)" },
		{ cmd: "off", desc: "Disable service tier" },
		{ cmd: "flex", desc: "Flex tier (0.5x cost, slower)" },
		{ cmd: "status", desc: "Show current service tier setting" },
	],
	mcp: [
		{ cmd: "status", desc: "Show all MCP server statuses (default)" },
		{ cmd: "check", desc: "Detailed status for a specific server" },
		{
			cmd: "reload",
			desc: "Disconnect all MCP servers and re-read config — no restart needed",
		},
	],
	doctor: [
		{ cmd: "fix", desc: "Auto-fix detected issues" },
		{ cmd: "heal", desc: "AI-driven deep healing" },
		{ cmd: "audit", desc: "Run health audit without fixing" },
		{ cmd: "--dry-run", desc: "Show what --fix would change without applying" },
		{ cmd: "--json", desc: "Output report as JSON (CI/tooling friendly)" },
		{ cmd: "--build", desc: "Include slow build health check (npm run build)" },
		{ cmd: "--test", desc: "Include slow test health check (npm test)" },
	],
	dispatch: [
		{ cmd: "research", desc: "Run research phase" },
		{ cmd: "plan", desc: "Run planning phase" },
		{ cmd: "execute", desc: "Run execution phase" },
		{ cmd: "complete", desc: "Run completion phase" },
		{ cmd: "reassess", desc: "Reassess current progress" },
		{ cmd: "uat", desc: "Run user acceptance testing" },
		{ cmd: "replan", desc: "Replan the current slice" },
	],
	rate: [
		{ cmd: "over", desc: "Model was overqualified for this task" },
		{ cmd: "ok", desc: "Model was appropriate for this task" },
		{ cmd: "under", desc: "Model was underqualified for this task" },
	],
	workflow: [
		{ cmd: "new", desc: "Create a new workflow definition (via skill)" },
		{ cmd: "run", desc: "Create a run and start autonomous mode" },
		{ cmd: "list", desc: "List workflow runs" },
		{ cmd: "validate", desc: "Validate a workflow definition YAML" },
		{ cmd: "pause", desc: "Pause custom workflow autonomous mode" },
		{ cmd: "resume", desc: "Resume paused custom workflow autonomous mode" },
	],
	codebase: [
		{ cmd: "generate", desc: "Generate or regenerate CODEBASE.md" },
		{
			cmd: "generate --max-files",
			desc: "Generate with custom file limit (default: 500)",
		},
		{
			cmd: "generate --collapse-threshold",
			desc: "Generate with custom collapse threshold (default: 20)",
		},
		{
			cmd: "update",
			desc: "Refresh the CODEBASE.md cache immediately (preserves descriptions)",
		},
		{ cmd: "update --max-files", desc: "Update with custom file limit" },
		{
			cmd: "update --collapse-threshold",
			desc: "Update with custom collapse threshold",
		},
		{
			cmd: "stats",
			desc: "Show file count, description coverage, and generation time",
		},
		{ cmd: "indexer status", desc: "Show Sift codebase-indexer status" },
		{ cmd: "help", desc: "Show usage and available subcommands" },
	],
	ship: [
		{ cmd: "--dry-run", desc: "Preview PR without creating" },
		{ cmd: "--draft", desc: "Open as draft PR" },
		{ cmd: "--base", desc: "Override target branch (default: main)" },
		{ cmd: "--force", desc: "Ship even with pending tasks" },
	],
	"session-report": [
		{ cmd: "--json", desc: "Machine-readable JSON output" },
		{ cmd: "--save", desc: "Save report to .sf/reports/" },
	],
	backlog: [
		{ cmd: "add", desc: "Add item to backlog" },
		{ cmd: "promote", desc: "Promote backlog item to active slice" },
		{ cmd: "remove", desc: "Remove backlog item" },
	],
	schedule: [
		{ cmd: "add", desc: "Add a scheduled item" },
		{ cmd: "list", desc: "List scheduled items" },
		{ cmd: "done", desc: "Mark item as done" },
		{ cmd: "cancel", desc: "Cancel a scheduled item" },
		{ cmd: "snooze", desc: "Snooze an item by duration" },
		{ cmd: "run", desc: "Run a scheduled item now" },
	],
	todo: [
		{ cmd: "triage", desc: "Triage root TODO.md into .sf/triage artifacts" },
		{ cmd: "triage --no-clear", desc: "Triage TODO.md without resetting it" },
		{
			cmd: "triage --backlog",
			desc: "Also add implementation tasks to the SF backlog",
		},
	],
	"pr-branch": [
		{ cmd: "--dry-run", desc: "Preview what would be filtered" },
		{ cmd: "--name", desc: "Custom branch name" },
	],
	scaffold: [
		{
			cmd: "sync",
			desc: "Refresh ADR-021 scaffold docs (drift report + apply pending upgrades)",
		},
		{
			cmd: "sync --dry-run",
			desc: "Print drift report without modifying files",
		},
		{
			cmd: "sync --include-editing",
			desc: "Run scaffold-keeper synchronously for editing-drift items",
		},
		{
			cmd: "sync --only=",
			desc: "Restrict the operation to a path glob (e.g. --only=harness/**)",
		},
		{
			cmd: "migrate",
			desc: "Auto-detect repo profile and show what would change",
		},
		{
			cmd: "migrate --profile=",
			desc: "Switch active profile (app/library/infra/docs/minimal); disables out-of-profile files",
		},
		{
			cmd: "migrate --profile= --dry-run",
			desc: "Preview what migrate would change without modifying files",
		},
		{
			cmd: "migrate --profile= --prune",
			desc: "Delete (not just disable) pending out-of-profile files with clean hash",
		},
	],
	plan: [
		{ cmd: "promote", desc: "Copy a planning artifact from ~/.sf/ into docs/" },
		{
			cmd: "list",
			desc: "List ~/.sf/ planning artifacts with promoted status",
		},
		{ cmd: "diff", desc: "Show diff between ~/.sf/ and promoted version" },
	],
};
/**
 * Filter and format completion options by prefix.
 */
function filterOptions(partial, options, prefix = "") {
	const normalizedPrefix = prefix ? `${prefix} ` : "";
	return options
		.filter((option) => option.cmd.startsWith(partial))
		.map((option) => ({
			value: `${normalizedPrefix}${option.cmd}`,
			label: option.cmd,
			description: option.desc,
		}));
}
function getExtensionCompletions(prefix, action) {
	try {
		const extDir = join(sfHome(), "agent", "extensions");
		const ids = [];
		for (const entry of readdirSync(extDir, { withFileTypes: true })) {
			if (!entry.isDirectory()) continue;
			const manifestPath = join(extDir, entry.name, "extension-manifest.json");
			if (!existsSync(manifestPath)) continue;
			try {
				const manifest = JSON.parse(readFileSync(manifestPath, "utf-8"));
				if (typeof manifest?.id === "string") {
					ids.push({ id: manifest.id, name: manifest.name ?? manifest.id });
				}
			} catch {
				// ignore malformed manifests
			}
		}
		return ids
			.filter((entry) => entry.id.startsWith(prefix))
			.map((entry) => ({
				value: `extensions ${action} ${entry.id}`,
				label: entry.id,
				description: entry.name,
			}));
	} catch {
		return [];
	}
}
export function getSfArgumentCompletions(prefix) {
	const hasTrailingSpace = prefix.endsWith(" ");
	const parts = prefix.trim().split(/\s+/);
	if (hasTrailingSpace && parts.length >= 1) {
		parts.push("");
	}
	if (parts.length <= 1) {
		return filterOptions(parts[0] ?? "", PUBLIC_TOP_LEVEL_SUBCOMMANDS);
	}
	const [command, subcommand = "", third = ""] = parts;
	if (command === "cmux") {
		if (parts.length <= 2) {
			return filterOptions(
				subcommand,
				[
					{
						cmd: "status",
						desc: "Show cmux detection, prefs, and capabilities",
					},
					{ cmd: "on", desc: "Enable cmux integration" },
					{ cmd: "off", desc: "Disable cmux integration" },
					{ cmd: "notifications", desc: "Toggle cmux desktop notifications" },
					{ cmd: "sidebar", desc: "Toggle cmux sidebar metadata" },
					{ cmd: "splits", desc: "Toggle cmux visual subagent splits" },
					{ cmd: "browser", desc: "Toggle future browser integration flag" },
				],
				"cmux",
			);
		}
		if (
			parts.length <= 3 &&
			["notifications", "sidebar", "splits", "browser"].includes(subcommand)
		) {
			return filterOptions(
				third,
				[
					{ cmd: "on", desc: "Enable this cmux area" },
					{ cmd: "off", desc: "Disable this cmux area" },
				],
				`cmux ${subcommand}`,
			);
		}
		return [];
	}
	if (command === "templates" && subcommand === "info" && parts.length <= 3) {
		try {
			const registry = loadRegistry();
			return Object.entries(registry.templates)
				.filter(([id]) => id.startsWith(third))
				.map(([id, entry]) => ({
					value: `templates info ${id}`,
					label: id,
					description: entry.description,
				}));
		} catch {
			return [];
		}
	}
	if (
		command === "extensions" &&
		parts.length === 3 &&
		["enable", "disable", "info"].includes(subcommand)
	) {
		return getExtensionCompletions(third, subcommand);
	}
	if (command === "undo" && parts.length <= 2) {
		return [
			{
				value: "undo --force",
				label: "--force",
				description: "Skip confirmation prompt",
			},
		];
	}
	// Workflow definition-name completion for `workflow run <name>` and `workflow validate <name>`
	if (
		command === "workflow" &&
		(subcommand === "run" || subcommand === "validate") &&
		parts.length <= 3
	) {
		try {
			const defsDir = join(
				resolveProjectRoot(process.cwd()),
				".sf",
				"workflow-defs",
			);
			if (existsSync(defsDir)) {
				return readdirSync(defsDir)
					.filter((f) => f.endsWith(".yaml") && f.startsWith(third))
					.map((f) => {
						const name = f.replace(/\.yaml$/, "");
						return {
							value: `workflow ${subcommand} ${name}`,
							label: name,
							description: `Workflow definition: ${name}`,
						};
					});
			}
		} catch {
			// ignore filesystem errors during completion
		}
		return [];
	}
	const nested = NESTED_COMPLETIONS[command];
	if (nested && parts.length <= 2) {
		return filterOptions(subcommand, nested, command);
	}
	return [];
}

export function getSfTopLevelCommandCompletions(command, prefix) {
	const suffix = typeof prefix === "string" ? prefix : "";
	const fullPrefix = suffix.length > 0 ? `${command} ${suffix}` : `${command} `;
	const completions = getSfArgumentCompletions(fullPrefix) ?? [];
	const commandPrefix = `${command} `;
	return completions.map((completion) => ({
		...completion,
		value:
			typeof completion.value === "string" &&
			completion.value.startsWith(commandPrefix)
				? completion.value.slice(commandPrefix.length)
				: completion.value,
	}));
}
