@openacp/cli 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +1 -1
  2. package/dist/{agent-catalog-4IAJ7HEG.js → agent-catalog-LAAVBVLY.js} +3 -3
  3. package/dist/agent-dependencies-FCLRGMZM.js +23 -0
  4. package/dist/{agent-registry-B5YAMA4T.js → agent-registry-KZANAFXQ.js} +2 -2
  5. package/dist/{chunk-S3DRLJPM.js → chunk-5MH66WUY.js} +6 -4
  6. package/dist/chunk-5MH66WUY.js.map +1 -0
  7. package/dist/{chunk-LAFKARV3.js → chunk-776VAU3T.js} +2 -2
  8. package/dist/chunk-GUHCS6X7.js +282 -0
  9. package/dist/chunk-GUHCS6X7.js.map +1 -0
  10. package/dist/{chunk-UG6X672R.js → chunk-IURZ4QHG.js} +3 -2
  11. package/dist/chunk-IURZ4QHG.js.map +1 -0
  12. package/dist/{chunk-FWN3UIRT.js → chunk-PHC67OP4.js} +114 -29
  13. package/dist/chunk-PHC67OP4.js.map +1 -0
  14. package/dist/{chunk-D73LCTPF.js → chunk-QODDJ4PH.js} +19 -10
  15. package/dist/chunk-QODDJ4PH.js.map +1 -0
  16. package/dist/cli.js +269 -65
  17. package/dist/cli.js.map +1 -1
  18. package/dist/{config-editor-5L7AJ5AF.js → config-editor-RGV6VKPZ.js} +4 -4
  19. package/dist/index.d.ts +1 -0
  20. package/dist/index.js +15 -15
  21. package/dist/integrate-X7LI6MUO.js +257 -0
  22. package/dist/integrate-X7LI6MUO.js.map +1 -0
  23. package/dist/{main-37GLOJ7G.js → main-DSQBCJHR.js} +10 -10
  24. package/dist/{menu-6RCPBVGQ.js → menu-J5YVH665.js} +2 -2
  25. package/dist/{setup-QAS3QW3M.js → setup-3A3XDGCM.js} +3 -3
  26. package/dist/setup-3A3XDGCM.js.map +1 -0
  27. package/dist/suggest-RST5VOHB.js +36 -0
  28. package/dist/suggest-RST5VOHB.js.map +1 -0
  29. package/package.json +2 -1
  30. package/dist/chunk-D73LCTPF.js.map +0 -1
  31. package/dist/chunk-FWN3UIRT.js.map +0 -1
  32. package/dist/chunk-S3DRLJPM.js.map +0 -1
  33. package/dist/chunk-UG6X672R.js.map +0 -1
  34. package/dist/chunk-XJJ7LPXP.js +0 -85
  35. package/dist/chunk-XJJ7LPXP.js.map +0 -1
  36. package/dist/integrate-WUPLRJD3.js +0 -145
  37. package/dist/integrate-WUPLRJD3.js.map +0 -1
  38. /package/dist/{agent-catalog-4IAJ7HEG.js.map → agent-catalog-LAAVBVLY.js.map} +0 -0
  39. /package/dist/{agent-registry-B5YAMA4T.js.map → agent-dependencies-FCLRGMZM.js.map} +0 -0
  40. /package/dist/{config-editor-5L7AJ5AF.js.map → agent-registry-KZANAFXQ.js.map} +0 -0
  41. /package/dist/{chunk-LAFKARV3.js.map → chunk-776VAU3T.js.map} +0 -0
  42. /package/dist/{menu-6RCPBVGQ.js.map → config-editor-RGV6VKPZ.js.map} +0 -0
  43. /package/dist/{main-37GLOJ7G.js.map → main-DSQBCJHR.js.map} +0 -0
  44. /package/dist/{setup-QAS3QW3M.js.map → menu-J5YVH665.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  commandExists
3
- } from "./chunk-XJJ7LPXP.js";
3
+ } from "./chunk-GUHCS6X7.js";
4
4
  import {
5
5
  expandHome
6
6
  } from "./chunk-JRF4G4X7.js";
@@ -309,7 +309,7 @@ async function setupTelegram() {
309
309
  };
310
310
  }
311
311
  async function setupAgents() {
312
- const { AgentCatalog } = await import("./agent-catalog-4IAJ7HEG.js");
312
+ const { AgentCatalog } = await import("./agent-catalog-LAAVBVLY.js");
313
313
  const { select: select2, checkbox } = await import("@inquirer/prompts");
314
314
  const catalog = new AgentCatalog();
315
315
  catalog.load();
@@ -338,13 +338,22 @@ async function setupAgents() {
338
338
  }
339
339
  console.log(ok("Claude Agent ready"));
340
340
  const available = catalog.getAvailable();
341
+ const installed = available.filter((a) => a.installed);
341
342
  const installable = available.filter((a) => !a.installed && a.available);
342
- if (installable.length > 0) {
343
- const choices = installable.slice(0, 10).map((a) => ({
344
- name: `${a.name} (${a.distribution})`,
345
- value: a.key,
346
- checked: false
347
- }));
343
+ if (installed.length > 0 || installable.length > 0) {
344
+ const choices = [
345
+ ...installed.map((a) => ({
346
+ name: `${a.name} (installed)`,
347
+ value: a.key,
348
+ checked: true,
349
+ disabled: "(already installed)"
350
+ })),
351
+ ...installable.slice(0, 10).map((a) => ({
352
+ name: `${a.name} (${a.distribution})`,
353
+ value: a.key,
354
+ checked: false
355
+ }))
356
+ ];
348
357
  const selected = await checkbox({
349
358
  message: "Install additional agents? (Space to select, Enter to continue)",
350
359
  choices
@@ -442,7 +451,7 @@ async function runSetup(configManager) {
442
451
  });
443
452
  if (installClaude) {
444
453
  try {
445
- const { getIntegration } = await import("./integrate-WUPLRJD3.js");
454
+ const { getIntegration } = await import("./integrate-X7LI6MUO.js");
446
455
  const integration = getIntegration("claude");
447
456
  if (integration) {
448
457
  for (const item of integration.items) {
@@ -544,4 +553,4 @@ export {
544
553
  setupRunMode,
545
554
  runSetup
546
555
  };
547
- //# sourceMappingURL=chunk-D73LCTPF.js.map
556
+ //# sourceMappingURL=chunk-QODDJ4PH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/setup.ts"],"sourcesContent":["import { execFileSync } from \"node:child_process\";\nimport { input, select } from \"@inquirer/prompts\";\nimport type { Config, ConfigManager } from \"./config.js\";\nimport { expandHome } from \"./config.js\";\nimport { commandExists } from \"./agent-dependencies.js\";\n\n// --- ANSI colors ---\n\nconst c = {\n reset: \"\\x1b[0m\",\n bold: \"\\x1b[1m\",\n dim: \"\\x1b[2m\",\n green: \"\\x1b[32m\",\n yellow: \"\\x1b[33m\",\n red: \"\\x1b[31m\",\n cyan: \"\\x1b[36m\",\n white: \"\\x1b[37m\",\n};\n\nconst ok = (msg: string) =>\n `${c.green}${c.bold}✓${c.reset} ${c.green}${msg}${c.reset}`;\nconst warn = (msg: string) => `${c.yellow}⚠ ${msg}${c.reset}`;\nconst fail = (msg: string) => `${c.red}✗ ${msg}${c.reset}`;\nconst step = (n: number, title: string) =>\n `\\n${c.cyan}${c.bold}[${n}/3]${c.reset} ${c.bold}${title}${c.reset}\\n`;\nconst dim = (msg: string) => `${c.dim}${msg}${c.reset}`;\n\n// --- Telegram validation ---\n\nexport async function validateBotToken(\n token: string,\n): Promise<\n | { ok: true; botName: string; botUsername: string }\n | { ok: false; error: string }\n> {\n try {\n const res = await fetch(`https://api.telegram.org/bot${token}/getMe`);\n const data = (await res.json()) as {\n ok: boolean;\n result?: { first_name: string; username: string };\n description?: string;\n };\n if (data.ok && data.result) {\n return {\n ok: true,\n botName: data.result.first_name,\n botUsername: data.result.username,\n };\n }\n return { ok: false, error: data.description || \"Invalid token\" };\n } catch (err) {\n return { ok: false, error: (err as Error).message };\n }\n}\n\nexport async function validateChatId(\n token: string,\n chatId: number,\n): Promise<\n { ok: true; title: string; isForum: boolean } | { ok: false; error: string }\n> {\n try {\n const res = await fetch(`https://api.telegram.org/bot${token}/getChat`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ chat_id: chatId }),\n });\n const data = (await res.json()) as {\n ok: boolean;\n result?: { title: string; type: string; is_forum?: boolean };\n description?: string;\n };\n if (!data.ok || !data.result) {\n return { ok: false, error: data.description || \"Invalid chat ID\" };\n }\n if (data.result.type !== \"supergroup\") {\n return {\n ok: false,\n error: `Chat is \"${data.result.type}\", must be a supergroup`,\n };\n }\n return {\n ok: true,\n title: data.result.title,\n isForum: data.result.is_forum === true,\n };\n } catch (err) {\n return { ok: false, error: (err as Error).message };\n }\n}\n\nexport async function validateBotAdmin(\n token: string,\n chatId: number,\n): Promise<{ ok: true } | { ok: false; error: string }> {\n try {\n // Get bot's own user ID\n const meRes = await fetch(`https://api.telegram.org/bot${token}/getMe`);\n const meData = (await meRes.json()) as {\n ok: boolean;\n result?: { id: number };\n };\n if (!meData.ok || !meData.result) {\n return { ok: false, error: \"Could not retrieve bot info\" };\n }\n\n const res = await fetch(\n `https://api.telegram.org/bot${token}/getChatMember`,\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ chat_id: chatId, user_id: meData.result.id }),\n },\n );\n const data = (await res.json()) as {\n ok: boolean;\n result?: { status: string };\n description?: string;\n };\n if (!data.ok || !data.result) {\n return {\n ok: false,\n error: data.description || \"Could not check bot membership\",\n };\n }\n\n const { status } = data.result;\n if (status === \"administrator\" || status === \"creator\") {\n return { ok: true };\n }\n return {\n ok: false,\n error: `Bot is \"${status}\" in this group. It must be an admin. Please promote the bot to admin in group settings.`,\n };\n } catch (err) {\n return { ok: false, error: (err as Error).message };\n }\n}\n\n// --- Chat ID auto-detection ---\n\nfunction promptManualChatId(): Promise<number> {\n return input({\n message: \"Supergroup chat ID (e.g. -1001234567890):\",\n validate: (val) => {\n const n = Number(val.trim());\n if (isNaN(n) || !Number.isInteger(n)) return \"Chat ID must be an integer\";\n return true;\n },\n }).then((val) => Number(val.trim()));\n}\n\nasync function detectChatId(token: string): Promise<number> {\n // Clear old updates\n let lastUpdateId = 0;\n try {\n const clearRes = await fetch(\n `https://api.telegram.org/bot${token}/getUpdates?offset=-1`,\n );\n const clearData = (await clearRes.json()) as {\n ok: boolean;\n result?: Array<{ update_id: number }>;\n };\n if (clearData.ok && clearData.result?.length) {\n lastUpdateId = clearData.result[clearData.result.length - 1].update_id;\n }\n } catch {\n // ignore\n }\n\n console.log(\"\");\n console.log(` ${c.bold}If you don't have a supergroup yet:${c.reset}`);\n console.log(dim(\" 1. Open Telegram → New Group → add your bot\"));\n console.log(dim(\" 2. Group Settings → convert to Supergroup\"));\n console.log(dim(\" 3. Enable Topics in group settings\"));\n console.log(\"\");\n console.log(` ${c.bold}Then send \"hi\" in the group.${c.reset}`);\n console.log(\n dim(\n ` Listening... press ${c.reset}${c.yellow}m${c.reset}${c.dim} to enter ID manually`,\n ),\n );\n console.log(\"\");\n\n const MAX_ATTEMPTS = 120;\n const POLL_INTERVAL = 1000;\n\n // Listen for 'm' keypress to switch to manual\n let cancelled = false;\n const onKeypress = (data: Buffer) => {\n const key = data.toString();\n if (key === \"m\" || key === \"M\") {\n cancelled = true;\n }\n };\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(true);\n process.stdin.resume();\n process.stdin.on(\"data\", onKeypress);\n }\n\n const cleanup = () => {\n if (process.stdin.isTTY) {\n process.stdin.removeListener(\"data\", onKeypress);\n process.stdin.setRawMode(false);\n process.stdin.pause();\n }\n };\n\n try {\n for (let i = 0; i < MAX_ATTEMPTS; i++) {\n if (cancelled) {\n cleanup();\n return promptManualChatId();\n }\n\n try {\n const offset = lastUpdateId ? lastUpdateId + 1 : 0;\n const res = await fetch(\n `https://api.telegram.org/bot${token}/getUpdates?offset=${offset}&timeout=1`,\n );\n const data = (await res.json()) as {\n ok: boolean;\n result?: Array<{\n update_id: number;\n message?: {\n chat: { id: number; title?: string; type: string };\n };\n my_chat_member?: {\n chat: { id: number; title?: string; type: string };\n };\n }>;\n };\n\n if (!data.ok || !data.result?.length) {\n await new Promise((r) => setTimeout(r, POLL_INTERVAL));\n continue;\n }\n\n const groups = new Map<number, string>();\n for (const update of data.result) {\n lastUpdateId = update.update_id;\n const chat = update.message?.chat ?? update.my_chat_member?.chat;\n if (chat && (chat.type === \"supergroup\" || chat.type === \"group\")) {\n groups.set(chat.id, chat.title ?? String(chat.id));\n }\n }\n\n if (groups.size === 1) {\n const [id, title] = [...groups.entries()][0];\n console.log(\n ok(`Group detected: ${c.bold}${title}${c.reset}${c.green} (${id})`),\n );\n cleanup();\n return id;\n }\n\n if (groups.size > 1) {\n cleanup();\n const choices = [...groups.entries()].map(([id, title]) => ({\n name: `${title} (${id})`,\n value: id,\n }));\n return select({\n message: \"Multiple groups found. Pick one:\",\n choices,\n });\n }\n } catch {\n // Network error, retry\n }\n await new Promise((r) => setTimeout(r, POLL_INTERVAL));\n }\n\n console.log(warn(\"Timed out waiting for messages.\"));\n cleanup();\n return promptManualChatId();\n } catch (err) {\n cleanup();\n throw err;\n }\n}\n\n// --- Agent detection ---\n\nconst KNOWN_AGENTS: Array<{ name: string; commands: string[] }> = [\n // claude-agent-acp is bundled as a dependency — no detection needed, but\n // kept here so detectAgents() still returns it for display purposes.\n { name: \"claude\", commands: [\"claude-agent-acp\"] },\n { name: \"codex\", commands: [\"codex\"] },\n];\n\nexport async function detectAgents(): Promise<\n Array<{ name: string; command: string }>\n> {\n const found: Array<{ name: string; command: string }> = [];\n for (const agent of KNOWN_AGENTS) {\n // Find all available commands for this agent (PATH + node_modules/.bin)\n const available: string[] = [];\n for (const cmd of agent.commands) {\n if (commandExists(cmd)) {\n available.push(cmd);\n }\n }\n if (available.length > 0) {\n // Prefer claude-agent-acp over claude/claude-code (priority order)\n found.push({ name: agent.name, command: available[0] });\n }\n }\n return found;\n}\n\nexport async function validateAgentCommand(command: string): Promise<boolean> {\n try {\n execFileSync(\"which\", [command], { stdio: \"pipe\" });\n return true;\n } catch {\n return false;\n }\n}\n\n// --- Setup steps ---\n\nexport async function setupTelegram(): Promise<Config[\"channels\"][string]> {\n console.log(step(1, \"Telegram Bot\"));\n\n let botToken = \"\";\n\n while (true) {\n botToken = await input({\n message: \"Bot token (from @BotFather):\",\n validate: (val) => val.trim().length > 0 || \"Token cannot be empty\",\n });\n botToken = botToken.trim();\n\n const result = await validateBotToken(botToken);\n if (result.ok) {\n console.log(ok(`Connected to @${result.botUsername}`));\n break;\n }\n console.log(fail(result.error));\n const action = await select({\n message: \"What to do?\",\n choices: [\n { name: \"Re-enter token\", value: \"retry\" },\n { name: \"Use as-is (skip validation)\", value: \"skip\" },\n ],\n });\n if (action === \"skip\") break;\n }\n\n let chatId: number;\n\n while (true) {\n chatId = await detectChatId(botToken);\n\n // Validate bot can access this chat and it's a supergroup\n const chatResult = await validateChatId(botToken, chatId);\n if (!chatResult.ok) {\n console.log(fail(chatResult.error));\n console.log(\"\");\n console.log(` ${c.bold}How to fix:${c.reset}`);\n console.log(dim(\" 1. Make sure the bot is added to the group\"));\n console.log(dim(\" 2. The group must be a Supergroup (Group Settings → convert)\"));\n console.log(dim(\" 3. Send a message in the group after adding the bot\"));\n console.log(\"\");\n await input({ message: \"Press Enter to try again...\" });\n continue;\n }\n console.log(\n ok(\n `Group: ${c.bold}${chatResult.title}${c.reset}${c.green}${chatResult.isForum ? \" (Topics enabled)\" : \"\"}`,\n ),\n );\n\n // Check bot has admin privileges\n const adminResult = await validateBotAdmin(botToken, chatId);\n if (!adminResult.ok) {\n console.log(fail(adminResult.error));\n console.log(\"\");\n console.log(` ${c.bold}How to fix:${c.reset}`);\n console.log(dim(\" 1. Open the group in Telegram\"));\n console.log(dim(\" 2. Go to Group Settings → Administrators\"));\n console.log(dim(\" 3. Add the bot as an administrator\"));\n console.log(\"\");\n await input({ message: \"Press Enter to check again...\" });\n continue;\n }\n console.log(ok(\"Bot has admin privileges\"));\n break;\n }\n\n return {\n enabled: true,\n botToken,\n chatId,\n notificationTopicId: null,\n assistantTopicId: null,\n };\n}\n\nexport async function setupAgents(): Promise<{\n defaultAgent: string;\n}> {\n const { AgentCatalog } = await import(\"./agent-catalog.js\");\n const { select, checkbox } = await import(\"@inquirer/prompts\");\n\n const catalog = new AgentCatalog();\n catalog.load();\n\n console.log(dim(\" Checking available agents...\"));\n await catalog.refreshRegistryIfStale();\n\n // Claude is always pre-installed (bundled dependency)\n if (!catalog.getInstalledAgent(\"claude\")) {\n const claudeRegistry = catalog.findRegistryAgent(\"claude-acp\");\n if (claudeRegistry) {\n await catalog.install(\"claude-acp\");\n } else {\n // Fallback: register bundled claude-agent-acp directly\n const { AgentStore } = await import(\"./agent-store.js\");\n const store = new AgentStore();\n store.load();\n store.addAgent(\"claude\", {\n registryId: \"claude-acp\",\n name: \"Claude Agent\",\n version: \"bundled\",\n distribution: \"npx\",\n command: \"npx\",\n args: [\"@zed-industries/claude-agent-acp\"],\n env: {},\n installedAt: new Date().toISOString(),\n binaryPath: null,\n });\n }\n }\n console.log(ok(\"Claude Agent ready\"));\n\n const available = catalog.getAvailable();\n const installed = available.filter((a) => a.installed);\n const installable = available.filter((a) => !a.installed && a.available);\n\n // Offer agent selection — show installed agents as pre-checked + disabled\n if (installed.length > 0 || installable.length > 0) {\n const choices = [\n ...installed.map((a) => ({\n name: `${a.name} (installed)`,\n value: a.key,\n checked: true,\n disabled: \"(already installed)\",\n })),\n ...installable.slice(0, 10).map((a) => ({\n name: `${a.name} (${a.distribution})`,\n value: a.key,\n checked: false,\n })),\n ];\n\n const selected = await checkbox({\n message: \"Install additional agents? (Space to select, Enter to continue)\",\n choices,\n });\n\n for (const key of selected) {\n const regAgent = catalog.findRegistryAgent(key);\n if (regAgent) {\n process.stdout.write(` Installing ${regAgent.name}... `);\n const result = await catalog.install(key);\n if (result.ok) {\n console.log(ok(\"done\"));\n } else {\n console.log(warn(`skipped: ${result.error}`));\n }\n }\n }\n }\n\n // Choose default agent\n const installedAgents = Object.keys(catalog.getInstalledEntries());\n let defaultAgent = \"claude\";\n\n if (installedAgents.length > 1) {\n defaultAgent = await select({\n message: \"Which agent should be the default?\",\n choices: installedAgents.map((key) => {\n const agent = catalog.getInstalledAgent(key)!;\n return { name: `${agent.name} (${key})`, value: key };\n }),\n default: \"claude\",\n });\n }\n\n console.log(ok(`Default agent: ${c.bold}${defaultAgent}${c.reset}`));\n return { defaultAgent };\n}\n\nexport async function setupWorkspace(): Promise<{ baseDir: string }> {\n console.log(step(2, \"Workspace\"));\n\n const baseDir = await input({\n message: \"Base directory for workspaces:\",\n default: \"~/openacp-workspace\",\n validate: (val) => val.trim().length > 0 || \"Path cannot be empty\",\n });\n\n return { baseDir: baseDir.trim().replace(/^['\"]|['\"]$/g, \"\") };\n}\n\nexport async function setupRunMode(): Promise<{ runMode: 'foreground' | 'daemon'; autoStart: boolean }> {\n console.log(step(3, 'Run Mode'))\n\n // Don't show daemon option on Windows\n if (process.platform === 'win32') {\n console.log(dim(' (Daemon mode not available on Windows)'))\n return { runMode: 'foreground', autoStart: false }\n }\n\n const mode = await select({\n message: 'How would you like to run OpenACP?',\n choices: [\n {\n name: 'Background (daemon)',\n value: 'daemon' as const,\n description: 'Runs silently, auto-starts on boot. Manage with: openacp status | stop | logs',\n },\n {\n name: 'Foreground (terminal)',\n value: 'foreground' as const,\n description: 'Runs in current terminal session. Start with: openacp',\n },\n ],\n })\n\n if (mode === 'daemon') {\n const { installAutoStart, isAutoStartSupported } = await import('./autostart.js')\n const autoStart = isAutoStartSupported()\n if (autoStart) {\n const result = installAutoStart(expandHome('~/.openacp/logs'))\n if (result.success) {\n console.log(ok('Auto-start on boot enabled'))\n } else {\n console.log(warn(`Auto-start failed: ${result.error}`))\n }\n }\n return { runMode: 'daemon', autoStart }\n }\n\n return { runMode: 'foreground', autoStart: false }\n}\n\n// --- Orchestrator ---\n\nfunction printWelcomeBanner(): void {\n console.log(`\n${c.cyan}${c.bold} ╔══════════════════════════════╗\n ║ Welcome to OpenACP ║\n ╚══════════════════════════════╝${c.reset}\n`);\n}\n\nexport async function runSetup(configManager: ConfigManager): Promise<boolean> {\n printWelcomeBanner();\n\n try {\n const telegram = await setupTelegram();\n const { defaultAgent } = await setupAgents();\n\n // Offer Claude CLI integration\n {\n const { confirm } = await import(\"@inquirer/prompts\");\n const installClaude = await confirm({\n message: \"Install session transfer for Claude? (enables /openacp:handoff in your terminal)\",\n default: true,\n });\n\n if (installClaude) {\n try {\n const { getIntegration } = await import(\"../cli/integrate.js\");\n const integration = getIntegration(\"claude\");\n if (integration) {\n for (const item of integration.items) {\n const result = await item.install();\n for (const log of result.logs) console.log(` ${log}`);\n }\n }\n console.log(\"Claude CLI integration installed.\\n\");\n } catch (err) {\n console.log(`Could not install Claude CLI integration: ${err instanceof Error ? err.message : err}`);\n console.log(\" You can install it later with: openacp integrate claude\\n\");\n }\n }\n }\n\n const workspace = await setupWorkspace();\n const { runMode, autoStart } = await setupRunMode();\n const security = {\n allowedUserIds: [] as string[],\n maxConcurrentSessions: 20,\n sessionTimeoutMinutes: 60,\n };\n\n const config: Config = {\n channels: { telegram },\n agents: {},\n defaultAgent,\n workspace,\n security,\n logging: {\n level: \"info\",\n logDir: \"~/.openacp/logs\",\n maxFileSize: \"10m\",\n maxFiles: 7,\n sessionLogRetentionDays: 30,\n },\n runMode,\n autoStart,\n api: {\n port: 21420,\n host: '127.0.0.1',\n },\n sessionStore: { ttlDays: 30 },\n tunnel: {\n enabled: true,\n port: 3100,\n provider: \"cloudflare\",\n options: {},\n storeTtlMinutes: 60,\n auth: { enabled: false },\n },\n integrations: {},\n };\n\n try {\n await configManager.writeNew(config);\n } catch (writeErr) {\n console.log(\n fail(`Could not save config: ${(writeErr as Error).message}`),\n );\n return false;\n }\n\n console.log(\"\");\n console.log(\n ok(`Config saved to ${c.bold}${configManager.getConfigPath()}`),\n );\n\n // Pre-download cloudflared if tunnel enabled\n if (config.tunnel.enabled && config.tunnel.provider === \"cloudflare\") {\n console.log(dim(\" Ensuring cloudflared is installed...\"));\n try {\n const { ensureCloudflared } = await import(\n \"../tunnel/providers/install-cloudflared.js\"\n );\n const binPath = await ensureCloudflared();\n console.log(ok(`cloudflared ready at ${dim(binPath)}`));\n } catch (err) {\n console.log(\n warn(\n `Could not install cloudflared: ${(err as Error).message}. Tunnel may not work.`,\n ),\n );\n }\n }\n\n console.log(ok(\"Starting OpenACP...\"));\n console.log(\"\");\n\n return true;\n } catch (err) {\n if ((err as Error).name === \"ExitPromptError\") {\n console.log(dim(\"\\nSetup cancelled.\"));\n return false;\n }\n throw err;\n }\n}\n"],"mappings":"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","names":["select"]}
package/dist/cli.js CHANGED
@@ -4,6 +4,8 @@ import {
4
4
  listPlugins,
5
5
  uninstallPlugin
6
6
  } from "./chunk-NDR5JCS7.js";
7
+ import "./chunk-JRF4G4X7.js";
8
+ import "./chunk-ESOPMQAY.js";
7
9
  import {
8
10
  apiCall,
9
11
  readApiPort,
@@ -16,8 +18,6 @@ import {
16
18
  getLatestVersion,
17
19
  runUpdate
18
20
  } from "./chunk-KSIQZC3J.js";
19
- import "./chunk-JRF4G4X7.js";
20
- import "./chunk-ESOPMQAY.js";
21
21
 
22
22
  // src/cli.ts
23
23
  import { setDefaultAutoSelectFamily } from "net";
@@ -25,66 +25,66 @@ import { setDefaultAutoSelectFamily } from "net";
25
25
  // src/cli/commands.ts
26
26
  function printHelp() {
27
27
  console.log(`
28
- OpenACP - Self-hosted bridge for AI coding agents
28
+ \x1B[1mOpenACP\x1B[0m \u2014 Self-hosted bridge for AI coding agents
29
+ Connect Telegram (and more) to 28+ AI coding agents via ACP protocol.
29
30
 
30
- Usage:
31
+ \x1B[1mGetting Started:\x1B[0m
32
+ openacp First run launches setup wizard
33
+ openacp After setup, starts the server
34
+
35
+ \x1B[1mServer:\x1B[0m
31
36
  openacp Start (mode from config)
32
37
  openacp start Start as background daemon
33
38
  openacp stop Stop background daemon
34
39
  openacp status Show daemon status
35
40
  openacp logs Tail daemon log file
36
- openacp config Edit configuration
41
+ openacp --foreground Force foreground mode
42
+
43
+ \x1B[1mAgent Management:\x1B[0m
44
+ openacp agents Browse all agents (installed + available)
45
+ openacp agents install <name> Install an agent from the ACP Registry
46
+ openacp agents uninstall <name> Remove an installed agent
47
+ openacp agents info <name> Show details, dependencies & setup guide
48
+ openacp agents run <name> [-- args] Run agent CLI directly (login, config...)
49
+ openacp agents refresh Force-refresh agent list from registry
50
+
51
+ \x1B[2mExamples:\x1B[0m
52
+ openacp agents install gemini Install Gemini CLI
53
+ openacp agents run gemini -- auth login Login to Google
54
+ openacp agents run claude -- login Login to Anthropic
55
+ openacp agents info cursor See setup instructions
56
+
57
+ \x1B[1mConfiguration:\x1B[0m
58
+ openacp config Interactive config editor
37
59
  openacp config set <key> <value> Set a config value
38
- openacp reset Delete all data and start fresh
60
+ openacp reset Re-run setup wizard
39
61
  openacp update Update to latest version
40
- openacp doctor Run system diagnostics
41
- openacp doctor --dry-run Check only, don't fix
42
- openacp agents List available agents
43
- openacp agents install <name> Install an agent
44
- openacp agents uninstall <name> Remove an agent
45
- openacp agents refresh Update agent list
46
- openacp agents info <name> Show agent details
47
- openacp install <package> Install a plugin adapter
48
- openacp uninstall <package> Uninstall a plugin adapter
49
- openacp plugins List installed plugins
50
- openacp --foreground Force foreground mode
51
- openacp --version Show version
52
- openacp --help Show this help
53
- adopt <agent> <id> Adopt an external agent session into OpenACP
54
- integrate <agent> Install/uninstall agent integration for session transfer
62
+ openacp doctor Run system diagnostics
63
+ openacp doctor --dry-run Check only, don't fix
55
64
 
56
- API (requires running daemon):
57
- openacp api status Show active sessions
58
- openacp api session <id> Show session details
59
- openacp api new [agent] [workspace] Create a new session
60
- openacp api send <id> <prompt> Send prompt to session
61
- openacp api cancel <id> Cancel a session
62
- openacp api dangerous <id> [on|off] Toggle dangerous mode
63
- openacp api agents List available agents
64
- openacp api topics [--status s1,s2] List topics
65
- openacp api delete-topic <id> [--force] Delete a topic
66
- openacp api cleanup [--status s1,s2] Cleanup finished topics
67
- openacp api health Show system health
68
- openacp api adapters List registered adapters
69
- openacp api tunnel Show tunnel status
70
- openacp api config Show runtime config (deprecated)
71
- openacp api config set <key> <value> Update config value (deprecated)
72
- openacp api restart Restart daemon
73
- openacp api notify <message> Send notification to all channels
74
- openacp api version Show daemon version
65
+ \x1B[1mPlugins:\x1B[0m
66
+ openacp install <package> Install adapter (e.g. @openacp/adapter-discord)
67
+ openacp uninstall <package> Remove adapter
68
+ openacp plugins List installed plugins
75
69
 
76
- Note: "openacp status" shows daemon process health.
77
- "openacp api status" shows active agent sessions.
78
- "openacp --version" shows CLI version.
79
- "openacp api version" shows running daemon version.
70
+ \x1B[1mSession Transfer:\x1B[0m
71
+ openacp integrate <agent> Install handoff integration
72
+ openacp integrate <agent> --uninstall
73
+ openacp adopt <agent> <id> Adopt an external session
80
74
 
81
- Install:
82
- npm install -g @openacp/cli
75
+ \x1B[1mDaemon API:\x1B[0m \x1B[2m(requires running daemon)\x1B[0m
76
+ openacp api status Active sessions
77
+ openacp api session <id> Session details
78
+ openacp api new [agent] [workspace] Create session
79
+ openacp api send <id> <prompt> Send prompt
80
+ openacp api cancel <id> Cancel session
81
+ openacp api dangerous <id> on|off Toggle dangerous mode
82
+ openacp api topics [--status ...] List topics
83
+ openacp api cleanup [--status ...] Cleanup old topics
84
+ openacp api health System health check
85
+ openacp api restart Restart daemon
83
86
 
84
- Examples:
85
- openacp
86
- openacp install @openacp/adapter-discord
87
- openacp uninstall @openacp/adapter-discord
87
+ \x1B[2mMore info: https://github.com/Open-ACP/OpenACP\x1B[0m
88
88
  `);
89
89
  }
90
90
  async function cmdVersion() {
@@ -431,7 +431,30 @@ async function cmdApi(args2) {
431
431
  }
432
432
  console.log(`Daemon version: ${data.version}`);
433
433
  } else {
434
+ const { suggestMatch } = await import("./suggest-RST5VOHB.js");
435
+ const apiSubcommands = [
436
+ "new",
437
+ "cancel",
438
+ "status",
439
+ "agents",
440
+ "topics",
441
+ "delete-topic",
442
+ "cleanup",
443
+ "send",
444
+ "session",
445
+ "dangerous",
446
+ "health",
447
+ "restart",
448
+ "config",
449
+ "adapters",
450
+ "tunnel",
451
+ "notify",
452
+ "version"
453
+ ];
454
+ const suggestion = suggestMatch(subCmd ?? "", apiSubcommands);
434
455
  console.error(`Unknown api command: ${subCmd || "(none)"}
456
+ `);
457
+ if (suggestion) console.error(`Did you mean: ${suggestion}?
435
458
  `);
436
459
  console.log("Usage:");
437
460
  console.log(" openacp api status Show active sessions");
@@ -527,6 +550,16 @@ async function cmdConfig(args2 = []) {
527
550
  console.error("Usage: openacp config set <path> <value>");
528
551
  process.exit(1);
529
552
  }
553
+ const { ConfigSchema } = await import("./config-PCPIBPUA.js");
554
+ const topLevelKey = configPath.split(".")[0];
555
+ const validConfigKeys = Object.keys(ConfigSchema.shape);
556
+ if (!validConfigKeys.includes(topLevelKey)) {
557
+ const { suggestMatch } = await import("./suggest-RST5VOHB.js");
558
+ const suggestion = suggestMatch(topLevelKey, validConfigKeys);
559
+ console.error(`Unknown config key: ${topLevelKey}`);
560
+ if (suggestion) console.error(`Did you mean: ${suggestion}?`);
561
+ process.exit(1);
562
+ }
530
563
  let value = configValue;
531
564
  try {
532
565
  value = JSON.parse(configValue);
@@ -562,7 +595,7 @@ async function cmdConfig(args2 = []) {
562
595
  }
563
596
  return;
564
597
  }
565
- const { runConfigEditor } = await import("./config-editor-5L7AJ5AF.js");
598
+ const { runConfigEditor } = await import("./config-editor-RGV6VKPZ.js");
566
599
  const { ConfigManager } = await import("./config-PCPIBPUA.js");
567
600
  const cm = new ConfigManager();
568
601
  if (!await cm.exists()) {
@@ -672,7 +705,7 @@ async function cmdAdopt(args2) {
672
705
  }
673
706
  }
674
707
  async function cmdIntegrate(args2) {
675
- const { getIntegration, listIntegrations } = await import("./integrate-WUPLRJD3.js");
708
+ const { getIntegration, listIntegrations } = await import("./integrate-X7LI6MUO.js");
676
709
  const agent = args2[1];
677
710
  const uninstall = args2.includes("--uninstall");
678
711
  if (!agent) {
@@ -682,8 +715,12 @@ async function cmdIntegrate(args2) {
682
715
  }
683
716
  const integration = getIntegration(agent);
684
717
  if (!integration) {
718
+ const { suggestMatch } = await import("./suggest-RST5VOHB.js");
719
+ const available = listIntegrations();
720
+ const suggestion = suggestMatch(agent, available);
685
721
  console.log(`No integration available for '${agent}'.`);
686
- console.log(`Available: ${listIntegrations().join(", ")}`);
722
+ if (suggestion) console.log(`Did you mean: ${suggestion}?`);
723
+ console.log(`Available: ${available.join(", ")}`);
687
724
  process.exit(1);
688
725
  }
689
726
  for (const item of integration.items) {
@@ -711,6 +748,19 @@ async function cmdIntegrate(args2) {
711
748
  }
712
749
  }
713
750
  async function cmdDoctor(args2) {
751
+ const knownFlags = ["--dry-run"];
752
+ const unknownFlags = args2.slice(1).filter(
753
+ (a) => a.startsWith("--") && !knownFlags.includes(a)
754
+ );
755
+ if (unknownFlags.length > 0) {
756
+ const { suggestMatch } = await import("./suggest-RST5VOHB.js");
757
+ for (const flag of unknownFlags) {
758
+ const suggestion = suggestMatch(flag, knownFlags);
759
+ console.error(`Unknown flag: ${flag}`);
760
+ if (suggestion) console.error(`Did you mean: ${suggestion}?`);
761
+ }
762
+ process.exit(1);
763
+ }
714
764
  const dryRun = args2.includes("--dry-run");
715
765
  const { DoctorEngine } = await import("./doctor-N2HKKUUQ.js");
716
766
  const engine = new DoctorEngine({ dryRun });
@@ -765,12 +815,25 @@ async function cmdAgents(args2) {
765
815
  return agentsRefresh();
766
816
  case "info":
767
817
  return agentsInfo(args2[2]);
768
- default:
818
+ case "run":
819
+ return agentsRun(args2[2], args2.slice(3));
820
+ case "list":
821
+ case void 0:
769
822
  return agentsList();
823
+ default: {
824
+ const { suggestMatch } = await import("./suggest-RST5VOHB.js");
825
+ const agentSubcommands = ["install", "uninstall", "refresh", "info", "run", "list"];
826
+ const suggestion = suggestMatch(subcommand, agentSubcommands);
827
+ console.error(`Unknown agents command: ${subcommand}`);
828
+ if (suggestion) console.error(`Did you mean: ${suggestion}?`);
829
+ console.error(`
830
+ Run 'openacp agents' to see available agents.`);
831
+ process.exit(1);
832
+ }
770
833
  }
771
834
  }
772
835
  async function agentsList() {
773
- const { AgentCatalog } = await import("./agent-catalog-4IAJ7HEG.js");
836
+ const { AgentCatalog } = await import("./agent-catalog-LAAVBVLY.js");
774
837
  const catalog = new AgentCatalog();
775
838
  catalog.load();
776
839
  await catalog.refreshRegistryIfStale();
@@ -816,7 +879,7 @@ async function agentsInstall(nameOrId, force) {
816
879
  console.log(" Run 'openacp agents' to see available agents.\n");
817
880
  return;
818
881
  }
819
- const { AgentCatalog } = await import("./agent-catalog-4IAJ7HEG.js");
882
+ const { AgentCatalog } = await import("./agent-catalog-LAAVBVLY.js");
820
883
  const catalog = new AgentCatalog();
821
884
  catalog.load();
822
885
  await catalog.refreshRegistryIfStale();
@@ -850,30 +913,69 @@ async function agentsInstall(nameOrId, force) {
850
913
  };
851
914
  const result = await catalog.install(nameOrId, progress, force);
852
915
  if (!result.ok) {
916
+ if (result.error?.includes("not found")) {
917
+ const { suggestMatch } = await import("./suggest-RST5VOHB.js");
918
+ const allKeys = catalog.getAvailable().map((a) => a.key);
919
+ const suggestion = suggestMatch(nameOrId, allKeys);
920
+ if (suggestion) console.log(` Did you mean: ${suggestion}?`);
921
+ }
853
922
  process.exit(1);
854
923
  }
924
+ const { getAgentCapabilities } = await import("./agent-dependencies-FCLRGMZM.js");
925
+ const caps = getAgentCapabilities(result.agentKey);
926
+ if (caps.integration) {
927
+ const { installIntegration } = await import("./integrate-X7LI6MUO.js");
928
+ const intResult = await installIntegration(result.agentKey, caps.integration);
929
+ if (intResult.success) {
930
+ console.log(` \x1B[32m\u2713\x1B[0m Handoff integration installed for ${result.agentKey}`);
931
+ } else {
932
+ console.log(` \x1B[33m\u26A0 Handoff integration failed: ${intResult.logs[intResult.logs.length - 1] ?? "unknown error"}\x1B[0m`);
933
+ }
934
+ }
935
+ if (result.setupSteps?.length) {
936
+ console.log(" \x1B[1mNext steps to get started:\x1B[0m\n");
937
+ for (const step of result.setupSteps) {
938
+ console.log(` \u2192 ${step}`);
939
+ }
940
+ console.log(`
941
+ \x1B[2mRun 'openacp agents info ${result.agentKey}' for more details.\x1B[0m
942
+ `);
943
+ }
855
944
  }
856
945
  async function agentsUninstall(name) {
857
946
  if (!name) {
858
947
  console.log("\n Usage: openacp agents uninstall <name>\n");
859
948
  return;
860
949
  }
861
- const { AgentCatalog } = await import("./agent-catalog-4IAJ7HEG.js");
950
+ const { AgentCatalog } = await import("./agent-catalog-LAAVBVLY.js");
862
951
  const catalog = new AgentCatalog();
863
952
  catalog.load();
864
953
  const result = await catalog.uninstall(name);
865
954
  if (result.ok) {
955
+ const { getAgentCapabilities } = await import("./agent-dependencies-FCLRGMZM.js");
956
+ const caps = getAgentCapabilities(name);
957
+ if (caps.integration) {
958
+ const { uninstallIntegration } = await import("./integrate-X7LI6MUO.js");
959
+ await uninstallIntegration(name, caps.integration);
960
+ console.log(` \x1B[32m\u2713\x1B[0m Handoff integration removed for ${name}`);
961
+ }
866
962
  console.log(`
867
963
  \x1B[32m\u2713 ${name} removed.\x1B[0m
868
964
  `);
869
965
  } else {
870
966
  console.log(`
871
- \x1B[31m\u2717 ${result.error}\x1B[0m
872
- `);
967
+ \x1B[31m\u2717 ${result.error}\x1B[0m`);
968
+ if (result.error?.includes("not installed")) {
969
+ const { suggestMatch } = await import("./suggest-RST5VOHB.js");
970
+ const installedKeys = Object.keys(catalog.getInstalledEntries());
971
+ const suggestion = suggestMatch(name, installedKeys);
972
+ if (suggestion) console.log(` Did you mean: ${suggestion}?`);
973
+ }
974
+ console.log();
873
975
  }
874
976
  }
875
977
  async function agentsRefresh() {
876
- const { AgentCatalog } = await import("./agent-catalog-4IAJ7HEG.js");
978
+ const { AgentCatalog } = await import("./agent-catalog-LAAVBVLY.js");
877
979
  const catalog = new AgentCatalog();
878
980
  catalog.load();
879
981
  console.log("\n Updating agent list...");
@@ -885,9 +987,10 @@ async function agentsInfo(nameOrId) {
885
987
  console.log("\n Usage: openacp agents info <name>\n");
886
988
  return;
887
989
  }
888
- const { AgentCatalog } = await import("./agent-catalog-4IAJ7HEG.js");
990
+ const { AgentCatalog } = await import("./agent-catalog-LAAVBVLY.js");
889
991
  const catalog = new AgentCatalog();
890
992
  catalog.load();
993
+ const { getAgentSetup } = await import("./agent-dependencies-FCLRGMZM.js");
891
994
  const installed = catalog.getInstalledAgent(nameOrId);
892
995
  if (installed) {
893
996
  console.log(`
@@ -897,6 +1000,16 @@ async function agentsInfo(nameOrId) {
897
1000
  console.log(` Command: ${installed.command} ${installed.args.join(" ")}`);
898
1001
  console.log(` Installed: ${new Date(installed.installedAt).toLocaleDateString()}`);
899
1002
  if (installed.binaryPath) console.log(` Binary path: ${installed.binaryPath}`);
1003
+ const setup = installed.registryId ? getAgentSetup(installed.registryId) : void 0;
1004
+ if (setup) {
1005
+ console.log(`
1006
+ \x1B[1mSetup:\x1B[0m`);
1007
+ for (const step of setup.setupSteps) {
1008
+ console.log(` \u2192 ${step}`);
1009
+ }
1010
+ }
1011
+ console.log(`
1012
+ Run agent CLI: openacp agents run ${nameOrId} -- <args>`);
900
1013
  console.log("");
901
1014
  return;
902
1015
  }
@@ -911,19 +1024,110 @@ async function agentsInfo(nameOrId) {
911
1024
  if (regAgent.website) console.log(` Website: ${regAgent.website}`);
912
1025
  if (regAgent.repository) console.log(` Source: ${regAgent.repository}`);
913
1026
  console.log(` Available: ${availability.available ? "\x1B[32mYes\x1B[0m" : `\x1B[33mNo\x1B[0m \u2014 ${availability.reason}`}`);
1027
+ const setup = getAgentSetup(regAgent.id);
1028
+ if (setup) {
1029
+ console.log(`
1030
+ \x1B[1mSetup after install:\x1B[0m`);
1031
+ for (const step of setup.setupSteps) {
1032
+ console.log(` \u2192 ${step}`);
1033
+ }
1034
+ }
914
1035
  console.log(`
915
1036
  Install: openacp agents install ${nameOrId}
916
1037
  `);
917
1038
  return;
918
1039
  }
1040
+ const { suggestMatch } = await import("./suggest-RST5VOHB.js");
1041
+ const allKeys = catalog.getAvailable().map((a) => a.key);
1042
+ const suggestion = suggestMatch(nameOrId, allKeys);
1043
+ console.log(`
1044
+ \x1B[31m"${nameOrId}" not found.\x1B[0m`);
1045
+ if (suggestion) console.log(` Did you mean: ${suggestion}?`);
1046
+ console.log(` Run 'openacp agents' to see available agents.
1047
+ `);
1048
+ }
1049
+ async function agentsRun(nameOrId, extraArgs) {
1050
+ if (!nameOrId) {
1051
+ console.log("\n Usage: openacp agents run <name> [-- <args>]");
1052
+ console.log(" Run the agent's CLI directly (e.g., for login or config).\n");
1053
+ console.log(" Examples:");
1054
+ console.log(" openacp agents run gemini -- auth login");
1055
+ console.log(" openacp agents run copilot -- auth login");
1056
+ console.log(" openacp agents run claude -- login\n");
1057
+ return;
1058
+ }
1059
+ const { AgentCatalog } = await import("./agent-catalog-LAAVBVLY.js");
1060
+ const catalog = new AgentCatalog();
1061
+ catalog.load();
1062
+ const installed = catalog.getInstalledAgent(nameOrId);
1063
+ if (!installed) {
1064
+ const { suggestMatch } = await import("./suggest-RST5VOHB.js");
1065
+ const installedKeys = Object.keys(catalog.getInstalledEntries());
1066
+ const suggestion = suggestMatch(nameOrId, installedKeys);
1067
+ console.log(`
1068
+ \x1B[31m"${nameOrId}" is not installed.\x1B[0m`);
1069
+ if (suggestion) {
1070
+ console.log(` Did you mean: ${suggestion}?`);
1071
+ console.log(` Install first: openacp agents install ${suggestion}
1072
+ `);
1073
+ } else {
1074
+ console.log(` Install first: openacp agents install ${nameOrId}
1075
+ `);
1076
+ }
1077
+ return;
1078
+ }
1079
+ const userArgs = extraArgs[0] === "--" ? extraArgs.slice(1) : extraArgs;
1080
+ const { spawnSync } = await import("child_process");
1081
+ const command2 = installed.command;
1082
+ const acpFlags = /* @__PURE__ */ new Set(["--acp", "acp", "--acp=true", "--experimental-skills"]);
1083
+ const baseArgs = [];
1084
+ for (let i = 0; i < installed.args.length; i++) {
1085
+ const arg = installed.args[i];
1086
+ if (acpFlags.has(arg)) continue;
1087
+ if (arg === "--output-format" && installed.args[i + 1] === "acp") {
1088
+ i++;
1089
+ continue;
1090
+ }
1091
+ if (arg === "exec" && installed.args[i + 1] === "--output-format") continue;
1092
+ baseArgs.push(arg);
1093
+ }
1094
+ const fullArgs = [...baseArgs, ...userArgs];
919
1095
  console.log(`
920
- \x1B[31m"${nameOrId}" not found.\x1B[0m Run 'openacp agents' to see available agents.
1096
+ Running: ${command2} ${fullArgs.join(" ")}
921
1097
  `);
1098
+ const result = spawnSync(command2, fullArgs, {
1099
+ stdio: "inherit",
1100
+ env: { ...process.env, ...installed.env },
1101
+ cwd: process.cwd()
1102
+ });
1103
+ if (result.status !== null && result.status !== 0) {
1104
+ process.exit(result.status);
1105
+ }
922
1106
  }
923
1107
  async function cmdDefault(command2) {
924
1108
  const forceForeground = command2 === "--foreground";
925
1109
  if (command2 && !command2.startsWith("-")) {
1110
+ const { suggestMatch } = await import("./suggest-RST5VOHB.js");
1111
+ const topLevelCommands = [
1112
+ "start",
1113
+ "stop",
1114
+ "status",
1115
+ "logs",
1116
+ "config",
1117
+ "reset",
1118
+ "update",
1119
+ "install",
1120
+ "uninstall",
1121
+ "plugins",
1122
+ "api",
1123
+ "adopt",
1124
+ "integrate",
1125
+ "doctor",
1126
+ "agents"
1127
+ ];
1128
+ const suggestion = suggestMatch(command2, topLevelCommands);
926
1129
  console.error(`Unknown command: ${command2}`);
1130
+ if (suggestion) console.error(`Did you mean: ${suggestion}?`);
927
1131
  printHelp();
928
1132
  process.exit(1);
929
1133
  }
@@ -931,7 +1135,7 @@ async function cmdDefault(command2) {
931
1135
  const { ConfigManager } = await import("./config-PCPIBPUA.js");
932
1136
  const cm = new ConfigManager();
933
1137
  if (!await cm.exists()) {
934
- const { runSetup } = await import("./setup-QAS3QW3M.js");
1138
+ const { runSetup } = await import("./setup-3A3XDGCM.js");
935
1139
  const shouldStart = await runSetup(cm);
936
1140
  if (!shouldStart) process.exit(0);
937
1141
  }
@@ -949,7 +1153,7 @@ async function cmdDefault(command2) {
949
1153
  }
950
1154
  const { markRunning } = await import("./daemon-JZLFRUW6.js");
951
1155
  markRunning();
952
- const { startServer } = await import("./main-37GLOJ7G.js");
1156
+ const { startServer } = await import("./main-DSQBCJHR.js");
953
1157
  await startServer();
954
1158
  }
955
1159
 
@@ -978,7 +1182,7 @@ var commands = {
978
1182
  "doctor": () => cmdDoctor(args),
979
1183
  "agents": () => cmdAgents(args),
980
1184
  "--daemon-child": async () => {
981
- const { startServer } = await import("./main-37GLOJ7G.js");
1185
+ const { startServer } = await import("./main-DSQBCJHR.js");
982
1186
  await startServer();
983
1187
  }
984
1188
  };