import { o as normalizeOptionalLowercaseString, s as normalizeOptionalString } from "./string-coerce-CIT1-v_a.js";
import { r as getActivePluginRegistry } from "./runtime-DvDGh8U9.js";
import { r as listChannelPlugins } from "./registry-DAH3dnPp.js";
import "./plugins-g2B6w-qz.js";
import { r as listThinkingLevels } from "./thinking-3DdG218q.js";
//#region src/auto-reply/commands-args.ts
function normalizeArgValue(value) {
	if (value == null) return;
	let text;
	if (typeof value === "string") text = normalizeOptionalString(value) ?? "";
	else if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") text = normalizeOptionalString(String(value)) ?? "";
	else if (typeof value === "symbol") text = normalizeOptionalString(value.toString()) ?? "";
	else if (typeof value === "function") text = normalizeOptionalString(value.toString()) ?? "";
	else text = JSON.stringify(value);
	return text ? text : void 0;
}
function formatActionArgs(values, params) {
	const action = normalizeOptionalLowercaseString(normalizeArgValue(values.action));
	const path = normalizeArgValue(values.path);
	const value = normalizeArgValue(values.value);
	if (!action) return;
	const knownAction = params.formatKnownAction(action, path);
	if (knownAction) return knownAction;
	return formatSetUnsetArgAction(action, {
		path,
		value
	});
}
const formatConfigArgs = (values) => formatActionArgs(values, { formatKnownAction: (action, path) => {
	if (action === "show" || action === "get") return path ? `${action} ${path}` : action;
} });
const formatMcpArgs = (values) => formatActionArgs(values, { formatKnownAction: (action, path) => {
	if (action === "show" || action === "get") return path ? `${action} ${path}` : action;
} });
const formatPluginsArgs = (values) => formatActionArgs(values, { formatKnownAction: (action, path) => {
	if (action === "list") return "list";
	if (action === "show" || action === "get") return path ? `${action} ${path}` : action;
	if (action === "enable" || action === "disable") return path ? `${action} ${path}` : action;
} });
const formatDebugArgs = (values) => formatActionArgs(values, { formatKnownAction: (action) => {
	if (action === "show" || action === "reset") return action;
} });
function formatSetUnsetArgAction(action, params) {
	if (action === "unset") return params.path ? `${action} ${params.path}` : action;
	if (action === "set") {
		if (!params.path) return action;
		if (!params.value) return `${action} ${params.path}`;
		return `${action} ${params.path}=${params.value}`;
	}
	return action;
}
const formatQueueArgs = (values) => {
	const mode = normalizeArgValue(values.mode);
	const debounce = normalizeArgValue(values.debounce);
	const cap = normalizeArgValue(values.cap);
	const drop = normalizeArgValue(values.drop);
	const parts = [];
	if (mode) parts.push(mode);
	if (debounce) parts.push(`debounce:${debounce}`);
	if (cap) parts.push(`cap:${cap}`);
	if (drop) parts.push(`drop:${drop}`);
	return parts.length > 0 ? parts.join(" ") : void 0;
};
const formatExecArgs = (values) => {
	const host = normalizeArgValue(values.host);
	const security = normalizeArgValue(values.security);
	const ask = normalizeArgValue(values.ask);
	const node = normalizeArgValue(values.node);
	const parts = [];
	if (host) parts.push(`host=${host}`);
	if (security) parts.push(`security=${security}`);
	if (ask) parts.push(`ask=${ask}`);
	if (node) parts.push(`node=${node}`);
	return parts.length > 0 ? parts.join(" ") : void 0;
};
const COMMAND_ARG_FORMATTERS = {
	config: formatConfigArgs,
	mcp: formatMcpArgs,
	plugins: formatPluginsArgs,
	debug: formatDebugArgs,
	queue: formatQueueArgs,
	exec: formatExecArgs
};
//#endregion
//#region src/auto-reply/commands-registry.shared.ts
function defineChatCommand(command) {
	const aliases = (command.textAliases ?? (command.textAlias ? [command.textAlias] : [])).map((alias) => alias.trim()).filter(Boolean);
	const scope = command.scope ?? (command.nativeName ? aliases.length ? "both" : "native" : "text");
	const acceptsArgs = command.acceptsArgs ?? Boolean(command.args?.length);
	const argsParsing = command.argsParsing ?? (command.args?.length ? "positional" : "none");
	return {
		key: command.key,
		nativeName: command.nativeName,
		description: command.description,
		acceptsArgs,
		args: command.args,
		argsParsing,
		formatArgs: command.formatArgs,
		argsMenu: command.argsMenu,
		textAliases: aliases,
		scope,
		category: command.category
	};
}
function registerAlias(commands, key, ...aliases) {
	const command = commands.find((entry) => entry.key === key);
	if (!command) throw new Error(`registerAlias: unknown command key: ${key}`);
	const existing = new Set(command.textAliases.map((alias) => normalizeOptionalLowercaseString(alias)).filter((alias) => Boolean(alias)));
	for (const alias of aliases) {
		const trimmed = alias.trim();
		if (!trimmed) continue;
		const lowered = normalizeOptionalLowercaseString(trimmed);
		if (!lowered) continue;
		if (existing.has(lowered)) continue;
		existing.add(lowered);
		command.textAliases.push(trimmed);
	}
}
function assertCommandRegistry(commands) {
	const keys = /* @__PURE__ */ new Set();
	const nativeNames = /* @__PURE__ */ new Set();
	const textAliases = /* @__PURE__ */ new Set();
	for (const command of commands) {
		if (keys.has(command.key)) throw new Error(`Duplicate command key: ${command.key}`);
		keys.add(command.key);
		const nativeName = command.nativeName?.trim();
		if (command.scope === "text") {
			if (nativeName) throw new Error(`Text-only command has native name: ${command.key}`);
			if (command.textAliases.length === 0) throw new Error(`Text-only command missing text alias: ${command.key}`);
		} else if (!nativeName) throw new Error(`Native command missing native name: ${command.key}`);
		else {
			const nativeKey = normalizeOptionalLowercaseString(nativeName) ?? "";
			if (nativeNames.has(nativeKey)) throw new Error(`Duplicate native command: ${nativeName}`);
			nativeNames.add(nativeKey);
		}
		if (command.scope === "native" && command.textAliases.length > 0) throw new Error(`Native-only command has text aliases: ${command.key}`);
		for (const alias of command.textAliases) {
			if (!alias.startsWith("/")) throw new Error(`Command alias missing leading '/': ${alias}`);
			const aliasKey = normalizeOptionalLowercaseString(alias) ?? "";
			if (textAliases.has(aliasKey)) throw new Error(`Duplicate command alias: ${alias}`);
			textAliases.add(aliasKey);
		}
	}
}
function buildBuiltinChatCommands() {
	const commands = [
		defineChatCommand({
			key: "help",
			nativeName: "help",
			description: "Show available commands.",
			textAlias: "/help",
			category: "status"
		}),
		defineChatCommand({
			key: "commands",
			nativeName: "commands",
			description: "List all slash commands.",
			textAlias: "/commands",
			category: "status"
		}),
		defineChatCommand({
			key: "tools",
			nativeName: "tools",
			description: "List available runtime tools.",
			textAlias: "/tools",
			category: "status",
			args: [{
				name: "mode",
				description: "compact or verbose",
				type: "string",
				choices: ["compact", "verbose"]
			}],
			argsMenu: "auto"
		}),
		defineChatCommand({
			key: "skill",
			nativeName: "skill",
			description: "Run a skill by name.",
			textAlias: "/skill",
			category: "tools",
			args: [{
				name: "name",
				description: "Skill name",
				type: "string",
				required: true
			}, {
				name: "input",
				description: "Skill input",
				type: "string",
				captureRemaining: true
			}]
		}),
		defineChatCommand({
			key: "status",
			nativeName: "status",
			description: "Show current status.",
			textAlias: "/status",
			category: "status"
		}),
		defineChatCommand({
			key: "tasks",
			nativeName: "tasks",
			description: "List background tasks for this session.",
			textAlias: "/tasks",
			category: "status"
		}),
		defineChatCommand({
			key: "allowlist",
			description: "List/add/remove allowlist entries.",
			textAlias: "/allowlist",
			acceptsArgs: true,
			scope: "text",
			category: "management"
		}),
		defineChatCommand({
			key: "approve",
			nativeName: "approve",
			description: "Approve or deny exec requests.",
			textAlias: "/approve",
			acceptsArgs: true,
			category: "management"
		}),
		defineChatCommand({
			key: "context",
			nativeName: "context",
			description: "Explain how context is built and used.",
			textAlias: "/context",
			acceptsArgs: true,
			category: "status"
		}),
		defineChatCommand({
			key: "btw",
			nativeName: "btw",
			description: "Ask a side question without changing future session context.",
			textAlias: "/btw",
			acceptsArgs: true,
			category: "tools"
		}),
		defineChatCommand({
			key: "export-session",
			nativeName: "export-session",
			description: "Export current session to HTML file with full system prompt.",
			textAliases: ["/export-session", "/export"],
			acceptsArgs: true,
			category: "status",
			args: [{
				name: "path",
				description: "Output path (default: workspace)",
				type: "string",
				required: false
			}]
		}),
		defineChatCommand({
			key: "tts",
			nativeName: "tts",
			description: "Control text-to-speech (TTS).",
			textAlias: "/tts",
			category: "media",
			args: [{
				name: "action",
				description: "TTS action",
				type: "string",
				choices: [
					{
						value: "on",
						label: "On"
					},
					{
						value: "off",
						label: "Off"
					},
					{
						value: "status",
						label: "Status"
					},
					{
						value: "provider",
						label: "Provider"
					},
					{
						value: "limit",
						label: "Limit"
					},
					{
						value: "summary",
						label: "Summary"
					},
					{
						value: "audio",
						label: "Audio"
					},
					{
						value: "help",
						label: "Help"
					}
				]
			}, {
				name: "value",
				description: "Provider, limit, or text",
				type: "string",
				captureRemaining: true
			}],
			argsMenu: {
				arg: "action",
				title: "TTS Actions:\n• On – Enable TTS for responses\n• Off – Disable TTS\n• Status – Show current settings\n• Provider – Show or set the voice provider\n• Limit – Set max characters for TTS\n• Summary – Toggle AI summary for long texts\n• Audio – Generate TTS from custom text\n• Help – Show usage guide"
			}
		}),
		defineChatCommand({
			key: "whoami",
			nativeName: "whoami",
			description: "Show your sender id.",
			textAlias: "/whoami",
			category: "status"
		}),
		defineChatCommand({
			key: "session",
			nativeName: "session",
			description: "Manage session-level settings (for example /session idle).",
			textAlias: "/session",
			category: "session",
			args: [{
				name: "action",
				description: "idle | max-age",
				type: "string",
				choices: ["idle", "max-age"]
			}, {
				name: "value",
				description: "Duration (24h, 90m) or off",
				type: "string",
				captureRemaining: true
			}],
			argsMenu: "auto"
		}),
		defineChatCommand({
			key: "subagents",
			nativeName: "subagents",
			description: "List, kill, log, spawn, or steer subagent runs for this session.",
			textAlias: "/subagents",
			category: "management",
			args: [
				{
					name: "action",
					description: "list | kill | log | info | send | steer | spawn",
					type: "string",
					choices: [
						"list",
						"kill",
						"log",
						"info",
						"send",
						"steer",
						"spawn"
					]
				},
				{
					name: "target",
					description: "Run id, index, or session key",
					type: "string"
				},
				{
					name: "value",
					description: "Additional input (limit/message)",
					type: "string",
					captureRemaining: true
				}
			],
			argsMenu: "auto"
		}),
		defineChatCommand({
			key: "acp",
			nativeName: "acp",
			description: "Manage ACP sessions and runtime options.",
			textAlias: "/acp",
			category: "management",
			args: [{
				name: "action",
				description: "Action to run",
				type: "string",
				preferAutocomplete: true,
				choices: [
					"spawn",
					"cancel",
					"steer",
					"close",
					"sessions",
					"status",
					"set-mode",
					"set",
					"cwd",
					"permissions",
					"timeout",
					"model",
					"reset-options",
					"doctor",
					"install",
					"help"
				]
			}, {
				name: "value",
				description: "Action arguments",
				type: "string",
				captureRemaining: true
			}],
			argsMenu: "auto"
		}),
		defineChatCommand({
			key: "focus",
			nativeName: "focus",
			description: "Bind this thread or group chat to a session target.",
			textAlias: "/focus",
			category: "management",
			args: [{
				name: "target",
				description: "Subagent label/index or session key/id/label",
				type: "string",
				captureRemaining: true
			}]
		}),
		defineChatCommand({
			key: "unfocus",
			nativeName: "unfocus",
			description: "Remove the current thread or group chat session binding.",
			textAlias: "/unfocus",
			category: "management"
		}),
		defineChatCommand({
			key: "agents",
			nativeName: "agents",
			description: "List thread-bound agents for this session.",
			textAlias: "/agents",
			category: "management"
		}),
		defineChatCommand({
			key: "kill",
			nativeName: "kill",
			description: "Kill a running subagent (or all).",
			textAlias: "/kill",
			category: "management",
			args: [{
				name: "target",
				description: "Label, run id, index, or all",
				type: "string"
			}],
			argsMenu: "auto"
		}),
		defineChatCommand({
			key: "steer",
			nativeName: "steer",
			description: "Send guidance to a running subagent.",
			textAlias: "/steer",
			category: "management",
			args: [{
				name: "target",
				description: "Label, run id, or index",
				type: "string"
			}, {
				name: "message",
				description: "Steering message",
				type: "string",
				captureRemaining: true
			}]
		}),
		defineChatCommand({
			key: "config",
			nativeName: "config",
			description: "Show or set config values.",
			textAlias: "/config",
			category: "management",
			args: [
				{
					name: "action",
					description: "show | get | set | unset",
					type: "string",
					choices: [
						"show",
						"get",
						"set",
						"unset"
					]
				},
				{
					name: "path",
					description: "Config path",
					type: "string"
				},
				{
					name: "value",
					description: "Value for set",
					type: "string",
					captureRemaining: true
				}
			],
			argsParsing: "none",
			formatArgs: COMMAND_ARG_FORMATTERS.config
		}),
		defineChatCommand({
			key: "mcp",
			nativeName: "mcp",
			description: "Show or set KaijiBot MCP servers.",
			textAlias: "/mcp",
			category: "management",
			args: [
				{
					name: "action",
					description: "show | get | set | unset",
					type: "string",
					choices: [
						"show",
						"get",
						"set",
						"unset"
					]
				},
				{
					name: "path",
					description: "MCP server name",
					type: "string"
				},
				{
					name: "value",
					description: "JSON config for set",
					type: "string",
					captureRemaining: true
				}
			],
			argsParsing: "none",
			formatArgs: COMMAND_ARG_FORMATTERS.mcp
		}),
		defineChatCommand({
			key: "plugins",
			nativeName: "plugins",
			description: "List, show, enable, or disable plugins.",
			textAliases: ["/plugins", "/plugin"],
			category: "management",
			args: [{
				name: "action",
				description: "list | show | get | enable | disable",
				type: "string",
				choices: [
					"list",
					"show",
					"get",
					"enable",
					"disable"
				]
			}, {
				name: "path",
				description: "Plugin id or name",
				type: "string"
			}],
			argsParsing: "none",
			formatArgs: COMMAND_ARG_FORMATTERS.plugins
		}),
		defineChatCommand({
			key: "debug",
			nativeName: "debug",
			description: "Set runtime debug overrides.",
			textAlias: "/debug",
			category: "management",
			args: [
				{
					name: "action",
					description: "show | reset | set | unset",
					type: "string",
					choices: [
						"show",
						"reset",
						"set",
						"unset"
					]
				},
				{
					name: "path",
					description: "Debug path",
					type: "string"
				},
				{
					name: "value",
					description: "Value for set",
					type: "string",
					captureRemaining: true
				}
			],
			argsParsing: "none",
			formatArgs: COMMAND_ARG_FORMATTERS.debug
		}),
		defineChatCommand({
			key: "usage",
			nativeName: "usage",
			description: "Usage footer or cost summary.",
			textAlias: "/usage",
			category: "options",
			args: [{
				name: "mode",
				description: "off, tokens, full, or cost",
				type: "string",
				choices: [
					"off",
					"tokens",
					"full",
					"cost"
				]
			}],
			argsMenu: "auto"
		}),
		defineChatCommand({
			key: "stop",
			nativeName: "stop",
			description: "Stop the current run.",
			textAlias: "/stop",
			category: "session"
		}),
		defineChatCommand({
			key: "restart",
			nativeName: "restart",
			description: "Restart KaijiBot.",
			textAlias: "/restart",
			category: "tools"
		}),
		defineChatCommand({
			key: "activation",
			nativeName: "activation",
			description: "Set group activation mode.",
			textAlias: "/activation",
			category: "management",
			args: [{
				name: "mode",
				description: "mention or always",
				type: "string",
				choices: ["mention", "always"]
			}],
			argsMenu: "auto"
		}),
		defineChatCommand({
			key: "send",
			nativeName: "send",
			description: "Set send policy.",
			textAlias: "/send",
			category: "management",
			args: [{
				name: "mode",
				description: "on, off, or inherit",
				type: "string",
				choices: [
					"on",
					"off",
					"inherit"
				]
			}],
			argsMenu: "auto"
		}),
		defineChatCommand({
			key: "reset",
			nativeName: "reset",
			description: "Reset the current session.",
			textAlias: "/reset",
			acceptsArgs: true,
			category: "session"
		}),
		defineChatCommand({
			key: "new",
			nativeName: "new",
			description: "Start a new session.",
			textAlias: "/new",
			acceptsArgs: true,
			category: "session"
		}),
		defineChatCommand({
			key: "compact",
			nativeName: "compact",
			description: "Compact the session context.",
			textAlias: "/compact",
			category: "session",
			args: [{
				name: "instructions",
				description: "Extra compaction instructions",
				type: "string",
				captureRemaining: true
			}]
		}),
		defineChatCommand({
			key: "think",
			nativeName: "think",
			description: "Set thinking level.",
			textAlias: "/think",
			category: "options",
			args: [{
				name: "level",
				description: "off, minimal, low, medium, high, xhigh",
				type: "string",
				choices: ({ provider, model }) => listThinkingLevels(provider, model)
			}],
			argsMenu: "auto"
		}),
		defineChatCommand({
			key: "verbose",
			nativeName: "verbose",
			description: "Toggle verbose mode.",
			textAlias: "/verbose",
			category: "options",
			args: [{
				name: "mode",
				description: "on or off",
				type: "string",
				choices: ["on", "off"]
			}],
			argsMenu: "auto"
		}),
		defineChatCommand({
			key: "fast",
			nativeName: "fast",
			description: "Toggle fast mode.",
			textAlias: "/fast",
			category: "options",
			args: [{
				name: "mode",
				description: "status, on, or off",
				type: "string",
				choices: [
					"status",
					"on",
					"off"
				]
			}],
			argsMenu: "auto"
		}),
		defineChatCommand({
			key: "reasoning",
			nativeName: "reasoning",
			description: "Toggle reasoning visibility.",
			textAlias: "/reasoning",
			category: "options",
			args: [{
				name: "mode",
				description: "on, off, or stream",
				type: "string",
				choices: [
					"on",
					"off",
					"stream"
				]
			}],
			argsMenu: "auto"
		}),
		defineChatCommand({
			key: "elevated",
			nativeName: "elevated",
			description: "Toggle elevated mode.",
			textAlias: "/elevated",
			category: "options",
			args: [{
				name: "mode",
				description: "on, off, ask, or full",
				type: "string",
				choices: [
					"on",
					"off",
					"ask",
					"full"
				]
			}],
			argsMenu: "auto"
		}),
		defineChatCommand({
			key: "exec",
			nativeName: "exec",
			description: "Set exec defaults for this session.",
			textAlias: "/exec",
			category: "options",
			args: [
				{
					name: "host",
					description: "sandbox, gateway, or node",
					type: "string",
					choices: [
						"sandbox",
						"gateway",
						"node"
					]
				},
				{
					name: "security",
					description: "deny, allowlist, or full",
					type: "string",
					choices: [
						"deny",
						"allowlist",
						"full"
					]
				},
				{
					name: "ask",
					description: "off, on-miss, or always",
					type: "string",
					choices: [
						"off",
						"on-miss",
						"always"
					]
				},
				{
					name: "node",
					description: "Node id or name",
					type: "string"
				}
			],
			argsParsing: "none",
			formatArgs: COMMAND_ARG_FORMATTERS.exec
		}),
		defineChatCommand({
			key: "model",
			nativeName: "model",
			description: "Show or set the model.",
			textAlias: "/model",
			category: "options",
			args: [{
				name: "model",
				description: "Model id (provider/model or id)",
				type: "string"
			}]
		}),
		defineChatCommand({
			key: "models",
			nativeName: "models",
			description: "List model providers or provider models.",
			textAlias: "/models",
			argsParsing: "none",
			acceptsArgs: true,
			category: "options"
		}),
		defineChatCommand({
			key: "queue",
			nativeName: "queue",
			description: "Adjust queue settings.",
			textAlias: "/queue",
			category: "options",
			args: [
				{
					name: "mode",
					description: "queue mode",
					type: "string",
					choices: [
						"steer",
						"interrupt",
						"followup",
						"collect",
						"steer-backlog"
					]
				},
				{
					name: "debounce",
					description: "debounce duration (e.g. 500ms, 2s)",
					type: "string"
				},
				{
					name: "cap",
					description: "queue cap",
					type: "number"
				},
				{
					name: "drop",
					description: "drop policy",
					type: "string",
					choices: [
						"old",
						"new",
						"summarize"
					]
				}
			],
			argsParsing: "none",
			formatArgs: COMMAND_ARG_FORMATTERS.queue
		}),
		defineChatCommand({
			key: "bash",
			description: "Run host shell commands (host-only).",
			textAlias: "/bash",
			scope: "text",
			category: "tools",
			args: [{
				name: "command",
				description: "Shell command",
				type: "string",
				captureRemaining: true
			}]
		})
	];
	registerAlias(commands, "whoami", "/id");
	registerAlias(commands, "think", "/thinking", "/t");
	registerAlias(commands, "verbose", "/v");
	registerAlias(commands, "reasoning", "/reason");
	registerAlias(commands, "elevated", "/elev");
	registerAlias(commands, "steer", "/tell");
	assertCommandRegistry(commands);
	return commands;
}
//#endregion
//#region src/auto-reply/commands-registry.data.ts
function supportsNativeCommands(plugin) {
	return plugin.capabilities?.nativeCommands === true;
}
function defineDockCommand(plugin) {
	return defineChatCommand({
		key: `dock:${plugin.id}`,
		nativeName: `dock_${plugin.id}`,
		description: `Switch to ${plugin.id} for replies.`,
		textAliases: [`/dock-${plugin.id}`, `/dock_${plugin.id}`],
		category: "docks"
	});
}
let cachedCommands = null;
let cachedRegistry = null;
let cachedNativeCommandSurfaces = null;
let cachedNativeRegistry = null;
function buildChatCommands() {
	const commands = [...buildBuiltinChatCommands(), ...listChannelPlugins().filter(supportsNativeCommands).map((plugin) => defineDockCommand(plugin))];
	assertCommandRegistry(commands);
	return commands;
}
function getChatCommands() {
	const registry = getActivePluginRegistry();
	if (cachedCommands && registry === cachedRegistry) return cachedCommands;
	const commands = buildChatCommands();
	cachedCommands = commands;
	cachedRegistry = registry;
	cachedNativeCommandSurfaces = null;
	return commands;
}
function getNativeCommandSurfaces() {
	const registry = getActivePluginRegistry();
	if (cachedNativeCommandSurfaces && registry === cachedNativeRegistry) return cachedNativeCommandSurfaces;
	cachedNativeCommandSurfaces = new Set(listChannelPlugins().filter(supportsNativeCommands).map((plugin) => plugin.id));
	cachedNativeRegistry = registry;
	return cachedNativeCommandSurfaces;
}
//#endregion
export { getNativeCommandSurfaces as n, getChatCommands as t };
