import "./paths-Cmq4jkLW.js";
import { B as theme } from "./utils-CcH8KYHm.js";
import "./pi-embedded-helpers-CUM4EVtq.js";
import "./registry-BvTskRju.js";
import "./subsystem-D5jeWpPI.js";
import "./exec-Drj_Y0q4.js";
import "./agent-scope-B830_s1e.js";
import "./model-selection-Cu-UzQaa.js";
import "./boolean-Wzu0-e0P.js";
import "./env-L9Bekcgw.js";
import { V as VERSION, l as writeConfigFile, o as readConfigFileSnapshot } from "./io-B0vHiKay.js";
import "./manifest-registry-CKXLdOam.js";
import "./config-CPJqIoc0.js";
import "./sandbox-l0BIS2AF.js";
import "./chrome-BHApvxyL.js";
import "./tailscale-C4Vg-KZ-.js";
import "./auth-DIeV2lKw.js";
import "./server-context-bg3lXzeH.js";
import "./frontmatter-CNh1FjpI.js";
import "./skills-CKZwNx6X.js";
import "./routes-CuHfLF5P.js";
import "./redact-D8ZUlwEM.js";
import "./errors-CaeqAr2b.js";
import "./paths-Bd5AWivy.js";
import "./ssrf-CqwYCyyw.js";
import "./image-ops-CgU_RtSG.js";
import "./store-vua1MTJe.js";
import "./ports-_-ibL5BF.js";
import "./trash-DyQphUG9.js";
import "./sessions-CUSpOb-h.js";
import "./message-channel-BZ3Pmru_.js";
import "./plugins-CK8s7WRs.js";
import "./accounts-CqvejUxk.js";
import "./accounts-DBps791j.js";
import "./accounts-D9-52N3f.js";
import "./bindings-Rfu8UC_f.js";
import "./logging-GKUQydLE.js";
import "./paths-DRmXMWHJ.js";
import "./tool-images-BLUAnHRr.js";
import "./tool-display-D_iFHKHp.js";
import "./commands-registry-BqlDWjuG.js";
import "./client-DHtTLXhO.js";
import "./call-D2SDoKJk.js";
import { a as loadProjectContext, n as isCoderClawProject, s as updateProjectContextFields, t as initializeCoderClawProject } from "./project-context-Cdlm0139.js";
import { _ as setOpenrouterApiKey, c as setAnthropicApiKey, u as setGeminiApiKey } from "./onboard-auth.credentials-CcUNd8i7.js";
import { n as upsertSharedEnvVar, t as readSharedEnvVar } from "./env-file-DUypwWSM.js";
import { t as runTui } from "./tui-CjW5gTVp.js";
import path from "node:path";
import fs from "node:fs/promises";
import { confirm, intro, note, outro, password, select, spinner, text } from "@clack/prompts";
import { Command } from "commander";

//#region src/commands/coderclaw.ts
/**
* CLI command for initializing coderClaw projects
*/
/**
* Launches the coderClaw interactive session — the Claude Code-style experience.
* Shows a project-aware banner then hands off to the full TUI REPL.
* The TUI stays open until the user presses Ctrl+C.
*/
async function runCoderClawSession(projectRoot, opts = {}) {
	const context = await loadProjectContext(projectRoot);
	const cwd = projectRoot === process.cwd() ? projectRoot : `${projectRoot} (${process.cwd()})`;
	const lines = [theme.heading("coderClaw") + " " + theme.muted(VERSION)];
	if (context?.llm) lines.push(theme.muted(`  ${context.llm.provider} \u00b7 ${context.llm.model}`));
	if (context?.clawLink) {
		const label = context.clawLink.instanceSlug ?? context.clawLink.instanceName ?? context.clawLink.instanceId;
		lines.push(theme.muted(`  \u{1F517} coderClawLink \u00b7 ${label}`));
	}
	lines.push(theme.muted(`  ${cwd}`));
	if (context?.projectName && context.projectName !== path.basename(projectRoot)) lines.push(theme.accentDim(`  ${context.projectName}`));
	lines.push(theme.muted("  type a message, /help for commands, Ctrl+C to exit"));
	process.stdout.write(lines.join("\n") + "\n\n");
	await runTui({ message: opts.message });
}
async function readJsonFile(filePath) {
	try {
		const content = await fs.readFile(filePath, "utf-8");
		return JSON.parse(content);
	} catch {
		return null;
	}
}
async function fileExists(filePath) {
	try {
		await fs.access(filePath);
		return true;
	} catch {
		return false;
	}
}
/** Walk one level of the project to count file extensions → infer languages */
async function detectLanguagesFromFiles(projectRoot) {
	const extLangMap = {
		".ts": "typescript",
		".tsx": "typescript",
		".js": "javascript",
		".jsx": "javascript",
		".mjs": "javascript",
		".cjs": "javascript",
		".py": "python",
		".go": "go",
		".rs": "rust",
		".java": "java",
		".kt": "kotlin",
		".swift": "swift",
		".rb": "ruby",
		".php": "php",
		".cs": "csharp",
		".cpp": "cpp",
		".c": "c",
		".dart": "dart",
		".ex": "elixir",
		".exs": "elixir",
		".hs": "haskell"
	};
	const counts = {};
	const ignoreDirs = new Set([
		"node_modules",
		".git",
		"dist",
		"build",
		".coderClaw",
		"__pycache__",
		".next",
		"out",
		"coverage",
		"vendor"
	]);
	async function walk(dir, depth) {
		if (depth > 3) return;
		let entries;
		try {
			entries = await fs.readdir(dir, { withFileTypes: true });
		} catch {
			return;
		}
		for (const entry of entries) if (entry.isDirectory()) {
			if (!ignoreDirs.has(entry.name) && !entry.name.startsWith(".")) await walk(path.join(dir, entry.name), depth + 1);
		} else {
			const lang = extLangMap[path.extname(entry.name).toLowerCase()];
			if (lang) counts[lang] = (counts[lang] ?? 0) + 1;
		}
	}
	await walk(projectRoot, 0);
	return Object.entries(counts).sort((a, b) => b[1] - a[1]).map(([lang]) => lang);
}
/** Infer frameworks from package.json deps or well-known config files */
async function detectFrameworks(projectRoot, pkgDeps) {
	const found = [];
	const all = Object.keys(pkgDeps);
	for (const [match, label] of [
		["next", "next.js"],
		["nuxt", "nuxt"],
		[/^@remix-run/, "remix"],
		["astro", "astro"],
		["@sveltejs/kit", "sveltekit"],
		["svelte", "svelte"],
		["react", "react"],
		["vue", "@vue"],
		["angular", "angular"],
		["express", "express"],
		["fastify", "fastify"],
		["hono", "hono"],
		["koa", "koa"],
		["nest", "nestjs"],
		[/^@nestjs/, "nestjs"],
		["trpc", "trpc"],
		[/^@trpc/, "trpc"],
		["drizzle-orm", "drizzle"],
		["prisma", "prisma"],
		[/^@prisma/, "prisma"],
		["mongoose", "mongoose"],
		["typeorm", "typeorm"],
		["django", "django"],
		["flask", "flask"],
		["fastapi", "fastapi"],
		["tailwindcss", "tailwind"]
	]) {
		if (found.includes(label)) continue;
		if (typeof match === "string") {
			if (all.some((k) => k === match || k.startsWith(`${match}/`) || k.startsWith(`@${match}/`))) found.push(label);
		} else if (all.some((k) => match.test(k))) found.push(label);
	}
	for (const [file, label] of [
		["next.config.js", "next.js"],
		["next.config.ts", "next.js"],
		["nuxt.config.ts", "nuxt"],
		["astro.config.mjs", "astro"],
		["astro.config.ts", "astro"],
		["svelte.config.js", "sveltekit"],
		["vite.config.ts", "vite"],
		["vite.config.js", "vite"],
		["angular.json", "angular"],
		["remix.config.js", "remix"],
		["tailwind.config.ts", "tailwind"],
		["tailwind.config.js", "tailwind"]
	]) if (!found.includes(label) && await fileExists(path.join(projectRoot, file))) found.push(label);
	return [...new Set(found)];
}
/** Infer test framework from deps / config files */
async function detectTestFramework(projectRoot, pkgDeps) {
	const all = Object.keys(pkgDeps);
	if (all.includes("vitest")) return "vitest";
	if (all.includes("jest") || all.some((k) => k.startsWith("@jest/"))) return "jest";
	if (all.includes("mocha")) return "mocha";
	if (all.includes("jasmine")) return "jasmine";
	if (all.includes("ava")) return "ava";
	if (all.includes("pytest") || await fileExists(path.join(projectRoot, "pytest.ini"))) return "pytest";
	if (await fileExists(path.join(projectRoot, "vitest.config.ts"))) return "vitest";
	if (await fileExists(path.join(projectRoot, "jest.config.js"))) return "jest";
	if (await fileExists(path.join(projectRoot, "jest.config.ts"))) return "jest";
}
/** Infer linting tools */
async function detectLintingTools(projectRoot, pkgDeps) {
	const tools = [];
	const all = Object.keys(pkgDeps);
	if (all.includes("eslint") || await fileExists(path.join(projectRoot, ".eslintrc.js"))) tools.push("eslint");
	if (all.includes("oxlint")) tools.push("oxlint");
	if (all.includes("prettier") || await fileExists(path.join(projectRoot, ".prettierrc"))) tools.push("prettier");
	if (all.includes("biome")) tools.push("biome");
	if (all.includes("ruff") || await fileExists(path.join(projectRoot, "ruff.toml"))) tools.push("ruff");
	if (all.includes("pylint")) tools.push("pylint");
	return tools;
}
/** Infer build system */
async function detectBuildSystem(projectRoot, pkgDeps) {
	const all = Object.keys(pkgDeps);
	if (all.includes("turbo")) return "turborepo";
	if (all.includes("nx")) return "nx";
	if (all.includes("tsdown") || all.includes("tsup")) return all.includes("tsdown") ? "tsdown" : "tsup";
	if (all.includes("vite")) return "vite";
	if (all.includes("webpack")) return "webpack";
	if (all.includes("rollup")) return "rollup";
	if (all.includes("esbuild")) return "esbuild";
	if (await fileExists(path.join(projectRoot, "Makefile"))) return "make";
	if (await fileExists(path.join(projectRoot, "CMakeLists.txt"))) return "cmake";
	if (await fileExists(path.join(projectRoot, "Cargo.toml"))) return "cargo";
	if (await fileExists(path.join(projectRoot, "pyproject.toml"))) return "poetry";
	if (await fileExists(path.join(projectRoot, "setup.py"))) return "setuptools";
	if (await fileExists(path.join(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
	if (await fileExists(path.join(projectRoot, "yarn.lock"))) return "yarn";
	if (await fileExists(path.join(projectRoot, "package-lock.json"))) return "npm";
}
/**
* Auto-detect project information from the filesystem.
* Returns sensible defaults even when no package.json is present.
*/
async function detectProjectInfo(projectRoot) {
	const pkg = await readJsonFile(path.join(projectRoot, "package.json"));
	const pkgName = typeof pkg?.name === "string" ? pkg.name : "";
	const pkgDesc = typeof pkg?.description === "string" ? pkg.description : "";
	const allDeps = {
		...pkg?.dependencies ?? {},
		...pkg?.devDependencies ?? {},
		...pkg?.peerDependencies ?? {}
	};
	const [langsByFile, frameworks, testFramework, lintingTools, buildSystem] = await Promise.all([
		detectLanguagesFromFiles(projectRoot),
		detectFrameworks(projectRoot, allDeps),
		detectTestFramework(projectRoot, allDeps),
		detectLintingTools(projectRoot, allDeps),
		detectBuildSystem(projectRoot, allDeps)
	]);
	const languages = await fileExists(path.join(projectRoot, "tsconfig.json")) ? ["typescript", ...langsByFile.filter((l) => l !== "typescript")] : langsByFile;
	return {
		projectName: pkgName || path.basename(projectRoot),
		description: pkgDesc,
		languages: [...new Set(languages)].slice(0, 6),
		frameworks,
		buildSystem,
		testFramework,
		lintingTools
	};
}
const PROVIDERS = [
	{
		id: "anthropic",
		label: "Anthropic (Claude)",
		envVar: "ANTHROPIC_API_KEY",
		defaultModel: "anthropic/claude-sonnet-4-6"
	},
	{
		id: "openai",
		label: "OpenAI (GPT-4o)",
		envVar: "OPENAI_API_KEY",
		defaultModel: "openai/gpt-4o"
	},
	{
		id: "openrouter",
		label: "OpenRouter",
		envVar: "OPENROUTER_API_KEY",
		defaultModel: "openrouter/auto"
	},
	{
		id: "gemini",
		label: "Google Gemini",
		envVar: "GEMINI_API_KEY",
		defaultModel: "google/gemini-2.0-flash"
	},
	{
		id: "ollama",
		label: "Ollama (local)",
		envVar: "OLLAMA_API_KEY",
		defaultModel: "ollama/llama3.3"
	},
	{
		id: "vllm",
		label: "vLLM / llama.cpp / LiteLLM (local)",
		defaultModel: "vllm/your-model-id"
	}
];
function isProviderConfigured(p) {
	if (!p.envVar) return false;
	const val = process.env[p.envVar];
	return typeof val === "string" && val.trim().length > 0;
}
async function applyLlmProviderModel(projectRoot, provider, modelRef) {
	try {
		await updateProjectContextFields(projectRoot, { llm: {
			provider,
			model: modelRef
		} });
	} catch {}
}
/**
* Interactive wizard step: choose and configure an LLM provider.
* Returns summary string of what was done (for the outro), or null if skipped.
*/
async function promptLlmProvider(projectRoot) {
	const chosen = await select({
		message: "LLM provider to use for AI agents:",
		options: [...PROVIDERS.map((p) => ({
			value: p.id,
			label: isProviderConfigured(p) ? `${p.label}  ✓ configured` : p.label,
			hint: isProviderConfigured(p) ? `${p.envVar} is set` : p.envVar ? `needs ${p.envVar}` : "enter server URL"
		})), {
			value: "skip",
			label: "Skip — configure later"
		}]
	});
	if (typeof chosen === "symbol" || chosen === "skip") return null;
	const meta = PROVIDERS.find((p) => p.id === chosen);
	if (chosen === "anthropic" || chosen === "openai" || chosen === "openrouter" || chosen === "gemini") {
		if (isProviderConfigured(meta)) {
			note(`${meta.envVar} is already set — keeping existing credential.`, meta.label);
			await applyLlmProviderModel(projectRoot, chosen, meta.defaultModel);
			return `${meta.label} (existing credential kept), model → ${meta.defaultModel}`;
		}
		const apiKey = await password({ message: `${meta.label} API key:` });
		if (typeof apiKey === "symbol" || !apiKey.trim()) return null;
		const keyValue = apiKey.trim();
		if (chosen === "anthropic") await setAnthropicApiKey(keyValue);
		else if (chosen === "openrouter") await setOpenrouterApiKey(keyValue);
		else if (chosen === "gemini") await setGeminiApiKey(keyValue);
		else upsertSharedEnvVar({
			key: "OPENAI_API_KEY",
			value: keyValue
		});
		await applyLlmProviderModel(projectRoot, chosen, meta.defaultModel);
		return `${meta.label} configured, model → ${meta.defaultModel}`;
	}
	if (chosen === "ollama") {
		const ollamaUrl = await text({
			message: "Ollama base URL:",
			initialValue: "http://127.0.0.1:11434"
		});
		if (typeof ollamaUrl === "symbol") return null;
		const ollamaModel = await text({
			message: "Ollama model to use as default:",
			initialValue: "llama3.3",
			placeholder: "llama3.3  or  qwen2.5-coder:32b  or  deepseek-r1:32b"
		});
		if (typeof ollamaModel === "symbol") return null;
		const modelRef = `ollama/${ollamaModel.trim() || "llama3.3"}`;
		upsertSharedEnvVar({
			key: "OLLAMA_API_KEY",
			value: "ollama-local"
		});
		const normalizedUrl = ollamaUrl.trim().replace(/\/+$/, "");
		if (normalizedUrl !== "http://127.0.0.1:11434") try {
			const existing = (await readConfigFileSnapshot())?.config ?? {};
			await writeConfigFile({
				...existing,
				models: {
					...existing.models,
					providers: {
						...existing.models?.providers ?? {},
						ollama: {
							baseUrl: normalizedUrl,
							api: "ollama",
							apiKey: "ollama-local"
						}
					}
				}
			});
		} catch {}
		await applyLlmProviderModel(projectRoot, "ollama", modelRef);
		return `Ollama configured (${normalizedUrl}), model → ${modelRef}`;
	}
	if (chosen === "vllm") {
		const vllmUrl = await text({
			message: "Server base URL (e.g. http://127.0.0.1:8000/v1):",
			initialValue: "http://127.0.0.1:8000/v1"
		});
		if (typeof vllmUrl === "symbol") return null;
		const vllmModelId = await text({
			message: "Model ID served at that endpoint:",
			placeholder: "meta-llama/Llama-3.1-8B-Instruct"
		});
		if (typeof vllmModelId === "symbol") return null;
		if (!vllmModelId.trim()) return null;
		const modelId = vllmModelId.trim();
		const modelRef = `vllm/${modelId}`;
		try {
			const existing = (await readConfigFileSnapshot())?.config ?? {};
			await writeConfigFile({
				...existing,
				models: {
					...existing.models,
					providers: {
						...existing.models?.providers ?? {},
						vllm: {
							baseUrl: vllmUrl.trim().replace(/\/+$/, ""),
							api: "openai-completions",
							apiKey: "VLLM_API_KEY",
							models: [{
								id: modelId,
								name: modelId,
								reasoning: false,
								input: ["text"],
								cost: {
									input: 0,
									output: 0,
									cacheRead: 0,
									cacheWrite: 0
								},
								contextWindow: 128e3,
								maxTokens: 8192
							}]
						}
					}
				}
			});
		} catch {}
		await applyLlmProviderModel(projectRoot, "vllm", modelRef);
		return `vLLM configured (${vllmUrl.trim()}), model → ${modelRef}`;
	}
	return null;
}
/** Thin fetch wrapper — throws a descriptive error on non-2xx. */
async function clawLinkFetch(url, opts = {}) {
	const { token, ...rest } = opts;
	const headers = {
		"Content-Type": "application/json",
		...token ? { Authorization: `Bearer ${token}` } : {}
	};
	const res = await fetch(url, {
		...rest,
		headers
	});
	const body = await res.json().catch(() => ({}));
	if (!res.ok) {
		const msg = body.error ?? body.message ?? res.statusText;
		throw new Error(`${res.status} ${msg}`);
	}
	return body;
}
/**
* Full API-driven coderClawLink onboarding wizard.
*
* Flow:
*   1. Offer to skip
*   2. Server URL
*   3. Login or create account → webToken
*   4. Pick or create tenant   → tenantId + tenantJwt
*   5. Register new claw       → claw.id, claw.slug, one-time apiKey
*   6. Persist everything globally + to project context.yaml
*/
async function promptClawLink(projectRoot, defaultInstanceName) {
	if (readSharedEnvVar("CODERCLAW_LINK_API_KEY")) {
		const existingUrl = readSharedEnvVar("CODERCLAW_LINK_URL") ?? "https://api.coderclaw.ai";
		const existingTenantId = readSharedEnvVar("CODERCLAW_LINK_TENANT_ID");
		const existingCtx = await loadProjectContext(projectRoot).catch(() => null);
		const clawLabel = existingCtx?.clawLink?.instanceSlug ?? existingCtx?.clawLink?.instanceName ?? existingCtx?.clawLink?.instanceId ?? "(registered)";
		note([
			`URL:    ${existingUrl}`,
			`Tenant: ${existingTenantId ?? "unknown"}`,
			`Claw:   ${clawLabel}`,
			``,
			`Run 'coderclaw init --reconnect' to link a different account.`
		].join("\n"), "Already connected to coderClawLink");
		return `coderClawLink: already connected (${existingUrl})`;
	}
	if (readSharedEnvVar("CODERCLAW_LINK_SKIPPED") === "1") return null;
	const connect = await confirm({
		message: "Connect to coderClawLink? (manage projects, tasks & agents across your mesh)",
		initialValue: true
	});
	if (typeof connect === "symbol" || !connect) {
		upsertSharedEnvVar({
			key: "CODERCLAW_LINK_SKIPPED",
			value: "1"
		});
		return null;
	}
	const urlInput = await text({
		message: "coderClawLink server URL:",
		initialValue: "https://api.coderclaw.ai"
	});
	if (typeof urlInput === "symbol") return null;
	const serverUrl = urlInput.trim().replace(/\/+$/, "") || "https://api.coderclaw.ai";
	const authMode = await select({
		message: "Do you have a coderClawLink account?",
		options: [{
			value: "login",
			label: "Yes — log in"
		}, {
			value: "register",
			label: "No  — create a free account"
		}]
	});
	if (typeof authMode === "symbol") return null;
	const emailInput = await text({ message: "Email:" });
	if (typeof emailInput === "symbol" || !emailInput.trim()) return null;
	const email = emailInput.trim();
	let usernameForReg = "";
	if (authMode === "register") {
		const unInput = await text({
			message: "Username:",
			initialValue: defaultInstanceName.toLowerCase().replace(/[^a-z0-9]+/g, "-")
		});
		if (typeof unInput === "symbol" || !unInput.trim()) return null;
		usernameForReg = unInput.trim();
	}
	const pwdInput = await password({ message: "Password:" });
	if (typeof pwdInput === "symbol" || !pwdInput.trim()) return null;
	const pwd = pwdInput.trim();
	let webToken = "";
	const authSpin = spinner();
	try {
		if (authMode === "register") {
			authSpin.start("Creating account…");
			webToken = (await clawLinkFetch(`${serverUrl}/api/auth/web/register`, {
				method: "POST",
				body: JSON.stringify({
					email,
					username: usernameForReg,
					password: pwd
				})
			})).token;
			authSpin.stop("Account created");
		} else {
			authSpin.start("Authenticating…");
			webToken = (await clawLinkFetch(`${serverUrl}/api/auth/web/login`, {
				method: "POST",
				body: JSON.stringify({
					email,
					password: pwd
				})
			})).token;
			authSpin.stop("Authenticated");
		}
	} catch (err) {
		authSpin.stop("Authentication failed");
		note(String(err instanceof Error ? err.message : err), "Error");
		return null;
	}
	let tenantId = 0;
	const tenantSpin = spinner();
	tenantSpin.start("Loading workspaces…");
	let tenants = [];
	try {
		tenants = (await clawLinkFetch(`${serverUrl}/api/auth/my-tenants`, { token: webToken })).tenants;
		tenantSpin.stop(`${tenants.length} workspace(s) found`);
	} catch (err) {
		tenantSpin.stop("Could not load workspaces");
		note(String(err instanceof Error ? err.message : err), "Error");
		return null;
	}
	if (tenants.length === 0) {
		const wsNameInput = await text({
			message: "Create your first workspace:",
			initialValue: defaultInstanceName
		});
		if (typeof wsNameInput === "symbol" || !wsNameInput.trim()) return null;
		const wsSpin = spinner();
		wsSpin.start("Creating workspace…");
		try {
			const created = await clawLinkFetch(`${serverUrl}/api/tenants/create`, {
				method: "POST",
				token: webToken,
				body: JSON.stringify({ name: wsNameInput.trim() })
			});
			tenantId = created.id;
			wsSpin.stop(`Workspace "${created.name}" created`);
		} catch (err) {
			wsSpin.stop("Could not create workspace");
			note(String(err instanceof Error ? err.message : err), "Error");
			return null;
		}
	} else if (tenants.length === 1) {
		tenantId = tenants[0].id;
		note(`Using workspace: ${tenants[0].name}`, "Workspace");
	} else {
		const picked = await select({
			message: "Select workspace:",
			options: tenants.map((t) => ({
				value: t.id,
				label: t.name,
				hint: t.slug
			}))
		});
		if (typeof picked === "symbol") return null;
		tenantId = picked;
	}
	let tenantJwt = "";
	try {
		tenantJwt = (await clawLinkFetch(`${serverUrl}/api/auth/tenant-token`, {
			method: "POST",
			token: webToken,
			body: JSON.stringify({ tenantId })
		})).token;
	} catch (err) {
		note(String(err instanceof Error ? err.message : err), "Could not get workspace token");
		return null;
	}
	const clawNameInput = await text({
		message: "Claw instance name (shown in dashboard):",
		initialValue: defaultInstanceName
	});
	if (typeof clawNameInput === "symbol") return null;
	const clawName = clawNameInput.trim() || defaultInstanceName;
	const clawSpin = spinner();
	clawSpin.start("Registering claw instance…");
	let clawId = "";
	let clawSlug = "";
	let apiKey = "";
	try {
		const res = await clawLinkFetch(`${serverUrl}/api/claws`, {
			method: "POST",
			token: tenantJwt,
			body: JSON.stringify({ name: clawName })
		});
		clawId = String(res.claw.id);
		clawSlug = res.claw.slug;
		apiKey = res.apiKey;
		clawSpin.stop(`Claw "${res.claw.name}" registered`);
	} catch (err) {
		clawSpin.stop("Claw registration failed");
		note(String(err instanceof Error ? err.message : err), "Error");
		return null;
	}
	upsertSharedEnvVar({
		key: "CODERCLAW_LINK_URL",
		value: serverUrl
	});
	upsertSharedEnvVar({
		key: "CODERCLAW_LINK_WEB_TOKEN",
		value: webToken
	});
	upsertSharedEnvVar({
		key: "CODERCLAW_LINK_TENANT_ID",
		value: String(tenantId)
	});
	upsertSharedEnvVar({
		key: "CODERCLAW_LINK_API_KEY",
		value: apiKey
	});
	try {
		await updateProjectContextFields(projectRoot, { clawLink: {
			instanceId: clawId,
			instanceSlug: clawSlug,
			instanceName: clawName,
			tenantId,
			url: serverUrl
		} });
	} catch {}
	note([
		`Claw API key saved to ~/.coderclaw/.env`,
		`This key was shown once — it is hashed on the server.`,
		`Instance slug: ${clawSlug}  ·  tenant: ${tenantId}`
	].join("\n"), "coderClawLink connected");
	return `coderClawLink: ${clawName} (${clawSlug}) on tenant ${tenantId}`;
}
function createCoderClawCommand() {
	const cmd = new Command("project");
	cmd.description("Manage coderClaw project context").addCommand(createStatusCommand());
	return cmd;
}
function createInitCommand() {
	return new Command("init").description("Initialize a project with coderClaw").argument("[path]", "Project directory path", ".").action(async (projectPath) => {
		const projectRoot = projectPath === "." ? process.cwd() : projectPath;
		if (await isCoderClawProject(projectRoot)) {
			await runCoderClawSession(projectRoot);
			return;
		}
		intro(theme.accent("coderClaw"));
		const detectSpin = spinner();
		detectSpin.start("Detecting project info...");
		const detected = await detectProjectInfo(projectRoot);
		detectSpin.stop("Project info detected");
		note([
			`name:        ${detected.projectName}`,
			`languages:   ${detected.languages.join(", ") || "(none detected)"}`,
			`frameworks:  ${detected.frameworks.join(", ") || "(none detected)"}`,
			`build:       ${detected.buildSystem ?? "(unknown)"}`,
			`test:        ${detected.testFramework ?? "(unknown)"}`,
			`lint:        ${detected.lintingTools.join(", ") || "(none detected)"}`
		].join("\n"), "Auto-detected");
		const projectNameInput = await text({
			message: "Project name:",
			initialValue: detected.projectName
		});
		if (typeof projectNameInput === "symbol") {
			outro(theme.muted("Cancelled"));
			return;
		}
		const descriptionInput = await text({
			message: "Project description:",
			initialValue: detected.description,
			placeholder: "A brief description of what this project does"
		});
		if (typeof descriptionInput === "symbol") {
			outro(theme.muted("Cancelled"));
			return;
		}
		const languagesInput = await text({
			message: "Primary languages (comma-separated):",
			initialValue: detected.languages.join(", "),
			placeholder: "typescript, javascript"
		});
		if (typeof languagesInput === "symbol") {
			outro(theme.muted("Cancelled"));
			return;
		}
		const frameworksInput = await text({
			message: "Frameworks used (comma-separated):",
			initialValue: detected.frameworks.join(", "),
			placeholder: "express, react"
		});
		if (typeof frameworksInput === "symbol") {
			outro(theme.muted("Cancelled"));
			return;
		}
		const spin = spinner();
		spin.start("Setting up .coderClaw/...");
		try {
			await initializeCoderClawProject(projectRoot, {
				projectName: projectNameInput || detected.projectName,
				description: descriptionInput || detected.description,
				languages: languagesInput.trim().length > 0 ? languagesInput.split(",").map((l) => l.trim()).filter(Boolean) : detected.languages,
				frameworks: frameworksInput.trim().length > 0 ? frameworksInput.split(",").map((f) => f.trim()).filter(Boolean) : detected.frameworks,
				buildSystem: detected.buildSystem,
				testFramework: detected.testFramework,
				lintingTools: detected.lintingTools
			});
			spin.stop(theme.success("coderClaw initialized!"));
			note([
				`  ${theme.muted("context.yaml")}      – project metadata (edit to tune AI understanding)`,
				`  ${theme.muted("architecture.md")} – high-level design docs`,
				`  ${theme.muted("rules.yaml")}       – coding standards & conventions`
			].join("\n"), `.coderClaw/ created`);
			await promptLlmProvider(projectRoot);
			await promptClawLink(projectRoot, projectNameInput || detected.projectName);
			const aiPopulate = await confirm({
				message: "Use an AI agent to populate context.yaml, architecture.md, and rules.yaml now?",
				initialValue: true
			});
			await runCoderClawSession(projectRoot, { message: typeof aiPopulate !== "symbol" && aiPopulate ? "Analyze this project and populate .coderClaw/context.yaml, architecture.md, and rules.yaml with accurate project context" : void 0 });
		} catch (error) {
			spin.stop(theme.error("Failed to initialize project"));
			outro(theme.error(error instanceof Error ? error.message : String(error)));
		}
	});
}
function createStatusCommand() {
	return new Command("status").description("Show coderClaw project status and context").argument("[path]", "Project directory path", ".").action(async (projectPath) => {
		const projectRoot = projectPath === "." ? process.cwd() : projectPath;
		if (!await isCoderClawProject(projectRoot)) {
			console.log(theme.warn("Project is not initialized with coderClaw"));
			console.log(theme.muted(`Run 'coderclaw init' to initialize`));
			return;
		}
		console.log(theme.success("✓ coderClaw project detected"));
		console.log(theme.muted(`  Location: ${projectRoot}/.coderClaw/`));
	});
}

//#endregion
export { createCoderClawCommand, createInitCommand, runCoderClawSession };