@openacp/cli 0.6.9 → 2026.41.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 (133) hide show
  1. package/README.md +116 -152
  2. package/dist/cli.d.ts +11 -0
  3. package/dist/cli.js +27740 -415
  4. package/dist/cli.js.map +1 -1
  5. package/dist/data/registry-snapshot.json +1 -1
  6. package/dist/index.d.ts +1944 -463
  7. package/dist/index.js +17365 -102
  8. package/dist/index.js.map +1 -1
  9. package/package.json +13 -7
  10. package/dist/action-detect-P7ZE4NEM.js +0 -16
  11. package/dist/action-detect-P7ZE4NEM.js.map +0 -1
  12. package/dist/adapter-LNEGLMOE.js +0 -799
  13. package/dist/adapter-LNEGLMOE.js.map +0 -1
  14. package/dist/admin-6SYB6XCZ.js +0 -23
  15. package/dist/admin-6SYB6XCZ.js.map +0 -1
  16. package/dist/agent-catalog-FC3HGDEQ.js +0 -11
  17. package/dist/agent-catalog-FC3HGDEQ.js.map +0 -1
  18. package/dist/agent-dependencies-4OWBMZWZ.js +0 -24
  19. package/dist/agent-dependencies-4OWBMZWZ.js.map +0 -1
  20. package/dist/agent-registry-WT4NXPYG.js +0 -9
  21. package/dist/agent-registry-WT4NXPYG.js.map +0 -1
  22. package/dist/agent-store-VZLFPTZU.js +0 -9
  23. package/dist/agent-store-VZLFPTZU.js.map +0 -1
  24. package/dist/agents-QO7DKARJ.js +0 -15
  25. package/dist/agents-QO7DKARJ.js.map +0 -1
  26. package/dist/api-client-CFQT5U7D.js +0 -14
  27. package/dist/api-client-CFQT5U7D.js.map +0 -1
  28. package/dist/autostart-X33OGMX6.js +0 -23
  29. package/dist/autostart-X33OGMX6.js.map +0 -1
  30. package/dist/chunk-2CJ46J3C.js +0 -154
  31. package/dist/chunk-2CJ46J3C.js.map +0 -1
  32. package/dist/chunk-2HMQOC7N.js +0 -134
  33. package/dist/chunk-2HMQOC7N.js.map +0 -1
  34. package/dist/chunk-33RP6K2O.js +0 -435
  35. package/dist/chunk-33RP6K2O.js.map +0 -1
  36. package/dist/chunk-34M4OS5P.js +0 -83
  37. package/dist/chunk-34M4OS5P.js.map +0 -1
  38. package/dist/chunk-4CTX774K.js +0 -265
  39. package/dist/chunk-4CTX774K.js.map +0 -1
  40. package/dist/chunk-7QJS2XBD.js +0 -92
  41. package/dist/chunk-7QJS2XBD.js.map +0 -1
  42. package/dist/chunk-BDYVCIBH.js +0 -735
  43. package/dist/chunk-BDYVCIBH.js.map +0 -1
  44. package/dist/chunk-BN3X7UXB.js +0 -738
  45. package/dist/chunk-BN3X7UXB.js.map +0 -1
  46. package/dist/chunk-BNLGTZ34.js +0 -122
  47. package/dist/chunk-BNLGTZ34.js.map +0 -1
  48. package/dist/chunk-GAK6PIBW.js +0 -224
  49. package/dist/chunk-GAK6PIBW.js.map +0 -1
  50. package/dist/chunk-H5P2C6H4.js +0 -4740
  51. package/dist/chunk-H5P2C6H4.js.map +0 -1
  52. package/dist/chunk-I7WC6E5S.js +0 -71
  53. package/dist/chunk-I7WC6E5S.js.map +0 -1
  54. package/dist/chunk-J4SJTKIK.js +0 -203
  55. package/dist/chunk-J4SJTKIK.js.map +0 -1
  56. package/dist/chunk-JHYXKVV2.js +0 -183
  57. package/dist/chunk-JHYXKVV2.js.map +0 -1
  58. package/dist/chunk-JKBFUAJK.js +0 -282
  59. package/dist/chunk-JKBFUAJK.js.map +0 -1
  60. package/dist/chunk-JUYDFUSN.js +0 -673
  61. package/dist/chunk-JUYDFUSN.js.map +0 -1
  62. package/dist/chunk-KIRH7TUJ.js +0 -219
  63. package/dist/chunk-KIRH7TUJ.js.map +0 -1
  64. package/dist/chunk-LBIKITQT.js +0 -22
  65. package/dist/chunk-LBIKITQT.js.map +0 -1
  66. package/dist/chunk-LGP2YGRL.js +0 -4880
  67. package/dist/chunk-LGP2YGRL.js.map +0 -1
  68. package/dist/chunk-NAMYZIS5.js +0 -1
  69. package/dist/chunk-NAMYZIS5.js.map +0 -1
  70. package/dist/chunk-NVPG6JCL.js +0 -724
  71. package/dist/chunk-NVPG6JCL.js.map +0 -1
  72. package/dist/chunk-O7CPGUAI.js +0 -298
  73. package/dist/chunk-O7CPGUAI.js.map +0 -1
  74. package/dist/chunk-S64CB6J3.js +0 -98
  75. package/dist/chunk-S64CB6J3.js.map +0 -1
  76. package/dist/chunk-UKT3G5IA.js +0 -484
  77. package/dist/chunk-UKT3G5IA.js.map +0 -1
  78. package/dist/chunk-V5GZQEIY.js +0 -101
  79. package/dist/chunk-V5GZQEIY.js.map +0 -1
  80. package/dist/chunk-VOIJ6OY4.js +0 -63
  81. package/dist/chunk-VOIJ6OY4.js.map +0 -1
  82. package/dist/chunk-VUNV25KB.js +0 -16
  83. package/dist/chunk-VUNV25KB.js.map +0 -1
  84. package/dist/chunk-W3EYKZNQ.js +0 -45
  85. package/dist/chunk-W3EYKZNQ.js.map +0 -1
  86. package/dist/chunk-WTZDAYZX.js +0 -172
  87. package/dist/chunk-WTZDAYZX.js.map +0 -1
  88. package/dist/chunk-XANPHG7W.js +0 -145
  89. package/dist/chunk-XANPHG7W.js.map +0 -1
  90. package/dist/config-6S355X75.js +0 -15
  91. package/dist/config-6S355X75.js.map +0 -1
  92. package/dist/config-editor-RVLWZLVB.js +0 -13
  93. package/dist/config-editor-RVLWZLVB.js.map +0 -1
  94. package/dist/config-registry-AHYI4MYL.js +0 -18
  95. package/dist/config-registry-AHYI4MYL.js.map +0 -1
  96. package/dist/daemon-4CS6HMB5.js +0 -30
  97. package/dist/daemon-4CS6HMB5.js.map +0 -1
  98. package/dist/discord-7IVQKB2H.js +0 -2083
  99. package/dist/discord-7IVQKB2H.js.map +0 -1
  100. package/dist/dist-UHQK5CXN.js +0 -21151
  101. package/dist/dist-UHQK5CXN.js.map +0 -1
  102. package/dist/doctor-HZZ5BSHB.js +0 -10
  103. package/dist/doctor-HZZ5BSHB.js.map +0 -1
  104. package/dist/doctor-OLYBO3V3.js +0 -15
  105. package/dist/doctor-OLYBO3V3.js.map +0 -1
  106. package/dist/install-cloudflared-Z7VCGOVG.js +0 -33
  107. package/dist/install-cloudflared-Z7VCGOVG.js.map +0 -1
  108. package/dist/install-jq-HUYSQWKR.js +0 -32
  109. package/dist/install-jq-HUYSQWKR.js.map +0 -1
  110. package/dist/integrate-PNEHRY2I.js +0 -373
  111. package/dist/integrate-PNEHRY2I.js.map +0 -1
  112. package/dist/log-NXABYJTT.js +0 -24
  113. package/dist/log-NXABYJTT.js.map +0 -1
  114. package/dist/main-ZK4MPMBG.js +0 -238
  115. package/dist/main-ZK4MPMBG.js.map +0 -1
  116. package/dist/menu-YY5MKHEK.js +0 -16
  117. package/dist/menu-YY5MKHEK.js.map +0 -1
  118. package/dist/new-session-FEO4J4VU.js +0 -17
  119. package/dist/new-session-FEO4J4VU.js.map +0 -1
  120. package/dist/post-upgrade-CJG5I7M2.js +0 -80
  121. package/dist/post-upgrade-CJG5I7M2.js.map +0 -1
  122. package/dist/session-IUSI7P5S.js +0 -20
  123. package/dist/session-IUSI7P5S.js.map +0 -1
  124. package/dist/settings-RQPAM4KC.js +0 -14
  125. package/dist/settings-RQPAM4KC.js.map +0 -1
  126. package/dist/setup-3GQSYBE4.js +0 -35
  127. package/dist/setup-3GQSYBE4.js.map +0 -1
  128. package/dist/suggest-7D6B542M.js +0 -38
  129. package/dist/suggest-7D6B542M.js.map +0 -1
  130. package/dist/tunnel-service-CJLUH6SZ.js +0 -1174
  131. package/dist/tunnel-service-CJLUH6SZ.js.map +0 -1
  132. package/dist/version-NQZBM5M7.js +0 -16
  133. package/dist/version-NQZBM5M7.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/core/doctor/index.ts","../../src/core/doctor/checks/config.ts","../../src/core/doctor/checks/agents.ts","../../src/core/doctor/checks/telegram.ts","../../src/core/doctor/checks/discord.ts","../../src/core/doctor/checks/storage.ts","../../src/core/doctor/checks/workspace.ts","../../src/core/doctor/checks/plugins.ts","../../src/core/doctor/checks/daemon.ts","../../src/core/doctor/checks/tunnel.ts"],"sourcesContent":["import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\nimport type { DoctorCheck, DoctorContext, DoctorReport, CategoryResult, PendingFix, CheckResult } from \"./types.js\";\nimport { ConfigManager, expandHome } from \"../config.js\";\n\nimport { configCheck } from \"./checks/config.js\";\nimport { agentsCheck } from \"./checks/agents.js\";\nimport { telegramCheck } from \"./checks/telegram.js\";\nimport { discordCheck } from \"./checks/discord.js\";\nimport { storageCheck } from \"./checks/storage.js\";\nimport { workspaceCheck } from \"./checks/workspace.js\";\nimport { pluginsCheck } from \"./checks/plugins.js\";\nimport { daemonCheck } from \"./checks/daemon.js\";\nimport { tunnelCheck } from \"./checks/tunnel.js\";\n\nconst ALL_CHECKS: DoctorCheck[] = [\n configCheck,\n agentsCheck,\n telegramCheck,\n discordCheck,\n storageCheck,\n workspaceCheck,\n pluginsCheck,\n daemonCheck,\n tunnelCheck,\n];\n\nconst CHECK_TIMEOUT_MS = 10_000;\n\nexport class DoctorEngine {\n private dryRun: boolean;\n\n constructor(options?: { dryRun?: boolean }) {\n this.dryRun = options?.dryRun ?? false;\n }\n\n async runAll(): Promise<DoctorReport> {\n const ctx = await this.buildContext();\n const checks = [...ALL_CHECKS].sort((a, b) => a.order - b.order);\n\n const categories: CategoryResult[] = [];\n const pendingFixes: PendingFix[] = [];\n const summary = { passed: 0, warnings: 0, failed: 0, fixed: 0 };\n\n for (const check of checks) {\n let results: CheckResult[];\n try {\n results = await Promise.race([\n check.run(ctx),\n new Promise<CheckResult[]>((_, reject) =>\n setTimeout(() => reject(new Error(\"timeout\")), CHECK_TIMEOUT_MS),\n ),\n ]);\n } catch {\n results = [{ status: \"fail\", message: `${check.name} check timed out` }];\n }\n\n for (const result of results) {\n if (result.fixable && result.fix) {\n if (result.fixRisk === \"safe\" && !this.dryRun) {\n try {\n const fixResult = await result.fix();\n if (fixResult.success) {\n result.message += ` → Fixed (${fixResult.message})`;\n result.status = \"warn\";\n delete result.fix;\n summary.fixed++;\n }\n } catch {\n // Fix failed, leave as-is\n }\n } else if (result.fixRisk === \"risky\") {\n pendingFixes.push({\n category: check.name,\n message: result.message,\n fix: result.fix,\n });\n }\n }\n\n if (result.status === \"pass\") summary.passed++;\n else if (result.status === \"warn\") summary.warnings++;\n else if (result.status === \"fail\") summary.failed++;\n }\n\n categories.push({ name: check.name, results });\n }\n\n return { categories, summary, pendingFixes };\n }\n\n private async buildContext(): Promise<DoctorContext> {\n const dataDir = path.join(os.homedir(), \".openacp\");\n const configPath = process.env.OPENACP_CONFIG_PATH || path.join(dataDir, \"config.json\");\n\n let config = null;\n let rawConfig: unknown = null;\n\n try {\n const content = fs.readFileSync(configPath, \"utf-8\");\n rawConfig = JSON.parse(content);\n const cm = new ConfigManager();\n await cm.load();\n config = cm.get();\n } catch {\n // Config may not exist or may be invalid — checks will handle this\n }\n\n const logsDir = config\n ? expandHome(config.logging.logDir)\n : path.join(dataDir, \"logs\");\n\n return {\n config,\n rawConfig,\n configPath,\n dataDir,\n sessionsPath: path.join(dataDir, \"sessions.json\"),\n pidPath: path.join(dataDir, \"openacp.pid\"),\n portFilePath: path.join(dataDir, \"api.port\"),\n pluginsDir: path.join(dataDir, \"plugins\"),\n logsDir,\n };\n }\n}\n\nexport type { DoctorReport, CategoryResult, PendingFix, CheckResult, DoctorContext } from \"./types.js\";\n","import * as fs from \"node:fs\";\nimport { ConfigSchema } from \"../../config.js\";\nimport { applyMigrations } from \"../../config-migrations.js\";\nimport type { DoctorCheck, CheckResult } from \"../types.js\";\n\nexport const configCheck: DoctorCheck = {\n name: \"Config\",\n order: 1,\n async run(ctx) {\n const results: CheckResult[] = [];\n\n if (!fs.existsSync(ctx.configPath)) {\n results.push({ status: \"fail\", message: \"Config file not found\" });\n return results;\n }\n results.push({ status: \"pass\", message: \"Config file exists\" });\n\n let raw: Record<string, unknown>;\n try {\n raw = JSON.parse(fs.readFileSync(ctx.configPath, \"utf-8\"));\n } catch (err) {\n results.push({\n status: \"fail\",\n message: `Config JSON invalid: ${err instanceof Error ? err.message : String(err)}`,\n });\n return results;\n }\n results.push({ status: \"pass\", message: \"JSON valid\" });\n\n const testRaw = structuredClone(raw);\n const { changed } = applyMigrations(testRaw);\n if (changed) {\n results.push({\n status: \"warn\",\n message: \"Pending config migrations\",\n fixable: true,\n fixRisk: \"safe\",\n fix: async () => {\n applyMigrations(raw);\n fs.writeFileSync(ctx.configPath, JSON.stringify(raw, null, 2));\n return { success: true, message: \"applied migrations\" };\n },\n });\n }\n\n const result = ConfigSchema.safeParse(raw);\n if (!result.success) {\n for (const issue of result.error.issues) {\n results.push({\n status: \"fail\",\n message: `Validation: ${issue.path.join(\".\")} — ${issue.message}`,\n });\n }\n } else {\n results.push({ status: \"pass\", message: \"Schema valid\" });\n }\n\n return results;\n },\n};\n","import { execFileSync } from \"node:child_process\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { DoctorCheck, CheckResult } from \"../types.js\";\n\nfunction commandExists(cmd: string): boolean {\n try {\n execFileSync(\"which\", [cmd], { stdio: \"pipe\" });\n return true;\n } catch {\n // not in PATH\n }\n let dir = process.cwd();\n while (true) {\n const binPath = path.join(dir, \"node_modules\", \".bin\", cmd);\n if (fs.existsSync(binPath)) return true;\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return false;\n}\n\nexport const agentsCheck: DoctorCheck = {\n name: \"Agents\",\n order: 2,\n async run(ctx) {\n const results: CheckResult[] = [];\n if (!ctx.config) {\n results.push({ status: \"fail\", message: \"Cannot check agents — config not loaded\" });\n return results;\n }\n\n const agents = ctx.config.agents;\n const defaultAgent = ctx.config.defaultAgent;\n\n if (!agents[defaultAgent]) {\n results.push({\n status: \"fail\",\n message: `Default agent \"${defaultAgent}\" not found in agents config`,\n });\n }\n\n for (const [name, agent] of Object.entries(agents)) {\n const isDefault = name === defaultAgent;\n if (commandExists(agent.command)) {\n results.push({\n status: \"pass\",\n message: `${agent.command} found${isDefault ? \" (default)\" : \"\"}`,\n });\n } else {\n results.push({\n status: isDefault ? \"fail\" : \"warn\",\n message: `${agent.command} not found in PATH${isDefault ? \" (default agent!)\" : \"\"}`,\n });\n }\n }\n\n return results;\n },\n};\n","import type { DoctorCheck, CheckResult } from \"../types.js\";\n\nconst BOT_TOKEN_REGEX = /^\\d+:[A-Za-z0-9_-]{35,}$/;\n\nexport const telegramCheck: DoctorCheck = {\n name: \"Telegram\",\n order: 3,\n async run(ctx) {\n const results: CheckResult[] = [];\n\n if (!ctx.config) {\n results.push({ status: \"fail\", message: \"Cannot check Telegram — config not loaded\" });\n return results;\n }\n\n const tgConfig = ctx.config.channels.telegram as Record<string, unknown> | undefined;\n if (!tgConfig || !tgConfig.enabled) {\n results.push({ status: \"pass\", message: \"Telegram not enabled (skipped)\" });\n return results;\n }\n\n const botToken = tgConfig.botToken as string | undefined;\n const chatId = tgConfig.chatId as number | undefined;\n\n if (!botToken || !BOT_TOKEN_REGEX.test(botToken)) {\n results.push({ status: \"fail\", message: \"Bot token format invalid\" });\n return results;\n }\n results.push({ status: \"pass\", message: \"Bot token format valid\" });\n\n let botId: number | undefined;\n try {\n const res = await fetch(`https://api.telegram.org/bot${botToken}/getMe`);\n const data = (await res.json()) as { ok: boolean; result?: { id: number; username: string }; description?: string };\n if (data.ok && data.result) {\n botId = data.result.id;\n results.push({ status: \"pass\", message: `Bot token valid (@${data.result.username})` });\n } else {\n results.push({ status: \"fail\", message: `Bot token rejected: ${data.description || \"unknown error\"}` });\n return results;\n }\n } catch (err) {\n results.push({ status: \"fail\", message: `Cannot reach Telegram API: ${err instanceof Error ? err.message : String(err)}` });\n return results;\n }\n\n if (!chatId || chatId === 0) {\n results.push({ status: \"fail\", message: \"Chat ID not configured\" });\n return results;\n }\n\n try {\n const res = await fetch(`https://api.telegram.org/bot${botToken}/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?: { type: string; is_forum?: boolean; title: string };\n description?: string;\n };\n if (!data.ok || !data.result) {\n results.push({ status: \"fail\", message: `Chat ID invalid: ${data.description || \"unknown error\"}` });\n return results;\n }\n if (data.result.type !== \"supergroup\") {\n results.push({ status: \"fail\", message: `Chat is \"${data.result.type}\", must be a supergroup` });\n return results;\n }\n if (!data.result.is_forum) {\n results.push({ status: \"warn\", message: \"Chat does not have topics enabled\" });\n } else {\n results.push({ status: \"pass\", message: `Chat is supergroup with topics (\"${data.result.title}\")` });\n }\n } catch (err) {\n results.push({ status: \"fail\", message: `Cannot validate chat: ${err instanceof Error ? err.message : String(err)}` });\n return results;\n }\n\n try {\n const res = await fetch(`https://api.telegram.org/bot${botToken}/getChatMember`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ chat_id: chatId, user_id: botId }),\n });\n const data = (await res.json()) as { ok: boolean; result?: { status: string }; description?: string };\n if (!data.ok || !data.result) {\n results.push({ status: \"fail\", message: `Cannot check bot membership: ${data.description || \"unknown\"}` });\n } else if (data.result.status === \"administrator\" || data.result.status === \"creator\") {\n results.push({ status: \"pass\", message: \"Bot is admin in group\" });\n } else {\n results.push({\n status: \"fail\",\n message: `Bot is \"${data.result.status}\" — must be admin. Promote bot in group settings.`,\n });\n }\n } catch (err) {\n results.push({ status: \"fail\", message: `Admin check failed: ${err instanceof Error ? err.message : String(err)}` });\n }\n\n return results;\n },\n};\n","import type { DoctorCheck, CheckResult } from \"../types.js\";\n\n// Discord bot tokens are base64-encoded and follow a recognizable pattern:\n// <user_id>.<timestamp>.<hmac> — the user_id part is a base64-encoded snowflake\nconst BOT_TOKEN_REGEX = /^[A-Za-z0-9_-]{24,28}\\.[A-Za-z0-9_-]{6,7}\\.[A-Za-z0-9_-]{27,}$/;\n\nexport const discordCheck: DoctorCheck = {\n name: \"Discord\",\n order: 3.5,\n async run(ctx) {\n const results: CheckResult[] = [];\n\n if (!ctx.config) {\n results.push({ status: \"fail\", message: \"Cannot check Discord — config not loaded\" });\n return results;\n }\n\n const discordConfig = (ctx.config.channels as Record<string, unknown>).discord as Record<string, unknown> | undefined;\n if (!discordConfig || !discordConfig.enabled) {\n results.push({ status: \"pass\", message: \"Discord not enabled (skipped)\" });\n return results;\n }\n\n // Check 1: Bot token format/presence\n const botToken = discordConfig.botToken as string | undefined;\n if (!botToken || !BOT_TOKEN_REGEX.test(botToken)) {\n results.push({ status: \"fail\", message: \"Discord bot token format invalid or missing\" });\n return results;\n }\n results.push({ status: \"pass\", message: \"Discord bot token format valid\" });\n\n // Check 2: Token validity via GET https://discord.com/api/v10/users/@me\n let botUsername: string | undefined;\n try {\n const res = await fetch(\"https://discord.com/api/v10/users/@me\", {\n headers: { Authorization: `Bot ${botToken}` },\n });\n if (res.status === 200) {\n const data = (await res.json()) as { username: string; id: string };\n botUsername = data.username;\n results.push({ status: \"pass\", message: `Bot token valid (@${data.username}, id: ${data.id})` });\n } else if (res.status === 401) {\n results.push({ status: \"fail\", message: \"Bot token rejected by Discord (401 Unauthorized)\" });\n return results;\n } else {\n const text = await res.text();\n results.push({ status: \"fail\", message: `Discord API error ${res.status}: ${text.slice(0, 100)}` });\n return results;\n }\n } catch (err) {\n results.push({ status: \"fail\", message: `Cannot reach Discord API: ${err instanceof Error ? err.message : String(err)}` });\n return results;\n }\n\n // Check 3: Guild access via GET https://discord.com/api/v10/guilds/{guildId}\n const guildId = discordConfig.guildId as string | undefined;\n if (!guildId) {\n results.push({ status: \"fail\", message: \"Guild ID not configured\" });\n return results;\n }\n\n try {\n const res = await fetch(`https://discord.com/api/v10/guilds/${guildId}`, {\n headers: { Authorization: `Bot ${botToken}` },\n });\n if (res.status === 200) {\n const data = (await res.json()) as { name: string; id: string };\n results.push({ status: \"pass\", message: `Bot has access to guild \"${data.name}\" (id: ${data.id})` });\n } else if (res.status === 403) {\n results.push({\n status: \"fail\",\n message: `Bot (${botUsername ?? \"unknown\"}) is not a member of guild ${guildId} or lacks access. Invite the bot to your server.`,\n });\n } else if (res.status === 404) {\n results.push({ status: \"fail\", message: `Guild ${guildId} not found — check the guild ID` });\n } else {\n const text = await res.text();\n results.push({ status: \"fail\", message: `Guild check error ${res.status}: ${text.slice(0, 100)}` });\n }\n } catch (err) {\n results.push({ status: \"fail\", message: `Cannot validate guild: ${err instanceof Error ? err.message : String(err)}` });\n }\n\n return results;\n },\n};\n","import * as fs from \"node:fs\";\nimport type { DoctorCheck, CheckResult } from \"../types.js\";\n\nexport const storageCheck: DoctorCheck = {\n name: \"Storage\",\n order: 4,\n async run(ctx) {\n const results: CheckResult[] = [];\n\n if (!fs.existsSync(ctx.dataDir)) {\n results.push({\n status: \"fail\",\n message: \"Data directory ~/.openacp does not exist\",\n fixable: true,\n fixRisk: \"safe\",\n fix: async () => {\n fs.mkdirSync(ctx.dataDir, { recursive: true });\n return { success: true, message: \"created directory\" };\n },\n });\n } else {\n try {\n fs.accessSync(ctx.dataDir, fs.constants.W_OK);\n results.push({ status: \"pass\", message: \"Data directory exists and writable\" });\n } catch {\n results.push({ status: \"fail\", message: \"Data directory not writable\" });\n }\n }\n\n if (fs.existsSync(ctx.sessionsPath)) {\n try {\n const content = fs.readFileSync(ctx.sessionsPath, \"utf-8\");\n const data = JSON.parse(content);\n if (typeof data === \"object\" && data !== null && \"sessions\" in data) {\n results.push({ status: \"pass\", message: \"Sessions file valid\" });\n } else {\n results.push({\n status: \"fail\",\n message: \"Sessions file has invalid structure\",\n fixable: true,\n fixRisk: \"risky\",\n fix: async () => {\n fs.writeFileSync(ctx.sessionsPath, JSON.stringify({ version: 1, sessions: {} }, null, 2));\n return { success: true, message: \"reset sessions file\" };\n },\n });\n }\n } catch {\n results.push({\n status: \"fail\",\n message: \"Sessions file corrupt (invalid JSON)\",\n fixable: true,\n fixRisk: \"risky\",\n fix: async () => {\n fs.writeFileSync(ctx.sessionsPath, JSON.stringify({ version: 1, sessions: {} }, null, 2));\n return { success: true, message: \"reset sessions file\" };\n },\n });\n }\n } else {\n results.push({ status: \"pass\", message: \"Sessions file not present yet (created on first session)\" });\n }\n\n if (!fs.existsSync(ctx.logsDir)) {\n results.push({\n status: \"warn\",\n message: \"Log directory does not exist\",\n fixable: true,\n fixRisk: \"safe\",\n fix: async () => {\n fs.mkdirSync(ctx.logsDir, { recursive: true });\n return { success: true, message: \"created log directory\" };\n },\n });\n } else {\n try {\n fs.accessSync(ctx.logsDir, fs.constants.W_OK);\n results.push({ status: \"pass\", message: \"Log directory exists and writable\" });\n } catch {\n results.push({ status: \"fail\", message: \"Log directory not writable\" });\n }\n }\n\n return results;\n },\n};\n","import * as fs from \"node:fs\";\nimport { expandHome } from \"../../config.js\";\nimport type { DoctorCheck, CheckResult } from \"../types.js\";\n\nexport const workspaceCheck: DoctorCheck = {\n name: \"Workspace\",\n order: 5,\n async run(ctx) {\n const results: CheckResult[] = [];\n\n if (!ctx.config) {\n results.push({ status: \"fail\", message: \"Cannot check workspace — config not loaded\" });\n return results;\n }\n\n const baseDir = expandHome(ctx.config.workspace.baseDir);\n\n if (!fs.existsSync(baseDir)) {\n results.push({\n status: \"warn\",\n message: `Workspace directory does not exist: ${baseDir}`,\n fixable: true,\n fixRisk: \"safe\",\n fix: async () => {\n fs.mkdirSync(baseDir, { recursive: true });\n return { success: true, message: \"created directory\" };\n },\n });\n } else {\n try {\n fs.accessSync(baseDir, fs.constants.W_OK);\n results.push({ status: \"pass\", message: `Workspace directory exists: ${baseDir}` });\n } catch {\n results.push({ status: \"fail\", message: `Workspace directory not writable: ${baseDir}` });\n }\n }\n\n return results;\n },\n};\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { DoctorCheck, CheckResult } from \"../types.js\";\n\nexport const pluginsCheck: DoctorCheck = {\n name: \"Plugins\",\n order: 6,\n async run(ctx) {\n const results: CheckResult[] = [];\n\n if (!fs.existsSync(ctx.pluginsDir)) {\n results.push({\n status: \"warn\",\n message: \"Plugins directory does not exist\",\n fixable: true,\n fixRisk: \"safe\",\n fix: async () => {\n fs.mkdirSync(ctx.pluginsDir, { recursive: true });\n fs.writeFileSync(\n path.join(ctx.pluginsDir, \"package.json\"),\n JSON.stringify({ name: \"openacp-plugins\", private: true, dependencies: {} }, null, 2),\n );\n return { success: true, message: \"initialized plugins directory\" };\n },\n });\n return results;\n }\n results.push({ status: \"pass\", message: \"Plugins directory exists\" });\n\n const pkgPath = path.join(ctx.pluginsDir, \"package.json\");\n if (!fs.existsSync(pkgPath)) {\n results.push({\n status: \"warn\",\n message: \"Plugins package.json missing\",\n fixable: true,\n fixRisk: \"safe\",\n fix: async () => {\n fs.writeFileSync(\n pkgPath,\n JSON.stringify({ name: \"openacp-plugins\", private: true, dependencies: {} }, null, 2),\n );\n return { success: true, message: \"created package.json\" };\n },\n });\n return results;\n }\n\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\"));\n const deps = pkg.dependencies || {};\n const count = Object.keys(deps).length;\n results.push({ status: \"pass\", message: `Plugins package.json valid (${count} plugins)` });\n } catch {\n results.push({\n status: \"fail\",\n message: \"Plugins package.json is invalid JSON\",\n fixable: true,\n fixRisk: \"risky\",\n fix: async () => {\n fs.writeFileSync(\n pkgPath,\n JSON.stringify({ name: \"openacp-plugins\", private: true, dependencies: {} }, null, 2),\n );\n return { success: true, message: \"reset package.json\" };\n },\n });\n }\n\n return results;\n },\n};\n","import * as fs from \"node:fs\";\nimport * as net from \"node:net\";\nimport type { DoctorCheck, CheckResult } from \"../types.js\";\n\nfunction isProcessAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction checkPortInUse(port: number): Promise<boolean> {\n return new Promise((resolve) => {\n const server = net.createServer();\n server.once(\"error\", () => resolve(true));\n server.once(\"listening\", () => {\n server.close();\n resolve(false);\n });\n server.listen(port, \"127.0.0.1\");\n });\n}\n\nexport const daemonCheck: DoctorCheck = {\n name: \"Daemon\",\n order: 7,\n async run(ctx) {\n const results: CheckResult[] = [];\n\n if (fs.existsSync(ctx.pidPath)) {\n const content = fs.readFileSync(ctx.pidPath, \"utf-8\").trim();\n const pid = parseInt(content, 10);\n if (isNaN(pid)) {\n results.push({\n status: \"warn\",\n message: \"PID file contains invalid data\",\n fixable: true,\n fixRisk: \"safe\",\n fix: async () => {\n fs.unlinkSync(ctx.pidPath);\n return { success: true, message: \"removed invalid PID file\" };\n },\n });\n } else if (!isProcessAlive(pid)) {\n results.push({\n status: \"warn\",\n message: `Stale PID file (PID ${pid} not running)`,\n fixable: true,\n fixRisk: \"safe\",\n fix: async () => {\n fs.unlinkSync(ctx.pidPath);\n return { success: true, message: \"removed stale PID file\" };\n },\n });\n } else {\n results.push({ status: \"pass\", message: `Daemon running (PID ${pid})` });\n }\n }\n\n if (fs.existsSync(ctx.portFilePath)) {\n const content = fs.readFileSync(ctx.portFilePath, \"utf-8\").trim();\n const port = parseInt(content, 10);\n if (isNaN(port)) {\n results.push({\n status: \"warn\",\n message: \"Port file contains invalid data\",\n fixable: true,\n fixRisk: \"safe\",\n fix: async () => {\n fs.unlinkSync(ctx.portFilePath);\n return { success: true, message: \"removed invalid port file\" };\n },\n });\n } else {\n results.push({ status: \"pass\", message: `Port file valid (port ${port})` });\n }\n }\n\n if (ctx.config) {\n const apiPort = ctx.config.api.port;\n const inUse = await checkPortInUse(apiPort);\n if (inUse) {\n if (fs.existsSync(ctx.pidPath)) {\n const pid = parseInt(fs.readFileSync(ctx.pidPath, \"utf-8\").trim(), 10);\n if (!isNaN(pid) && isProcessAlive(pid)) {\n results.push({ status: \"pass\", message: `API port ${apiPort} in use by OpenACP daemon` });\n } else {\n results.push({ status: \"warn\", message: `API port ${apiPort} in use by another process` });\n }\n } else {\n results.push({ status: \"warn\", message: `API port ${apiPort} in use by another process` });\n }\n } else {\n results.push({ status: \"pass\", message: `API port ${apiPort} available` });\n }\n }\n\n return results;\n },\n};\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\nimport { execFileSync } from \"node:child_process\";\nimport type { DoctorCheck, CheckResult } from \"../types.js\";\n\nconst BIN_DIR = path.join(os.homedir(), \".openacp\", \"bin\");\nconst BIN_NAME = os.platform() === \"win32\" ? \"cloudflared.exe\" : \"cloudflared\";\nconst BIN_PATH = path.join(BIN_DIR, BIN_NAME);\n\nexport const tunnelCheck: DoctorCheck = {\n name: \"Tunnel\",\n order: 8,\n async run(ctx) {\n const results: CheckResult[] = [];\n\n if (!ctx.config) {\n results.push({ status: \"fail\", message: \"Cannot check tunnel — config not loaded\" });\n return results;\n }\n\n if (!ctx.config.tunnel.enabled) {\n results.push({ status: \"pass\", message: \"Tunnel not enabled (skipped)\" });\n return results;\n }\n\n const provider = ctx.config.tunnel.provider;\n results.push({ status: \"pass\", message: `Tunnel provider: ${provider}` });\n\n if (provider === \"cloudflare\") {\n let found = false;\n if (fs.existsSync(BIN_PATH)) {\n found = true;\n } else {\n try {\n execFileSync(\"which\", [\"cloudflared\"], { stdio: \"pipe\" });\n found = true;\n } catch {\n // not found\n }\n }\n\n if (found) {\n results.push({ status: \"pass\", message: \"cloudflared binary found\" });\n } else {\n results.push({\n status: \"warn\",\n message: \"cloudflared binary not found\",\n fixable: true,\n fixRisk: \"safe\",\n fix: async () => {\n try {\n const { ensureCloudflared } = await import(\"../../../tunnel/providers/install-cloudflared.js\");\n await ensureCloudflared();\n return { success: true, message: \"installed cloudflared\" };\n } catch (err) {\n return { success: false, message: err instanceof Error ? err.message : String(err) };\n }\n },\n });\n }\n }\n\n const tunnelPort = ctx.config.tunnel.port;\n if (tunnelPort < 1 || tunnelPort > 65535) {\n results.push({ status: \"fail\", message: `Invalid tunnel port: ${tunnelPort}` });\n } else {\n results.push({ status: \"pass\", message: `Tunnel port: ${tunnelPort}` });\n }\n\n return results;\n },\n};\n"],"mappings":"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","names":["fs","path","os","fs","BOT_TOKEN_REGEX","fs","fs","fs","path","fs","fs","path","execFileSync"]}
@@ -1,298 +0,0 @@
1
- import {
2
- getConfigValue,
3
- getSafeFields,
4
- isHotReloadable,
5
- resolveOptions
6
- } from "./chunk-JHYXKVV2.js";
7
- import {
8
- log
9
- } from "./chunk-GAK6PIBW.js";
10
-
11
- // src/adapters/discord/commands/settings.ts
12
- import {
13
- ActionRowBuilder,
14
- ButtonBuilder,
15
- ButtonStyle
16
- } from "discord.js";
17
- function formatFieldLabel(field, value) {
18
- const icons = {
19
- agent: "\u{1F916}",
20
- logging: "\u{1F4DD}",
21
- tunnel: "\u{1F517}",
22
- security: "\u{1F512}",
23
- workspace: "\u{1F4C1}",
24
- storage: "\u{1F4BE}",
25
- speech: "\u{1F3A4}"
26
- };
27
- const icon = icons[field.group] ?? "\u2699\uFE0F";
28
- if (field.type === "toggle") {
29
- return `${icon} ${field.displayName}: ${value ? "ON" : "OFF"}`;
30
- }
31
- const displayValue = value === null || value === void 0 ? "Not set" : String(value);
32
- return `${icon} ${field.displayName}: ${displayValue}`;
33
- }
34
- var SETTINGS_PAGE_SIZE = 4;
35
- function buildSettingsRows(adapter, page = 0) {
36
- const config = adapter.core.configManager.get();
37
- const fields = getSafeFields();
38
- const totalPages = Math.ceil(fields.length / SETTINGS_PAGE_SIZE);
39
- const start = page * SETTINGS_PAGE_SIZE;
40
- const pageFields = fields.slice(start, start + SETTINGS_PAGE_SIZE);
41
- const rows = [];
42
- for (const field of pageFields) {
43
- const value = getConfigValue(config, field.path);
44
- const label = formatFieldLabel(field, value);
45
- let customId;
46
- if (field.type === "toggle") {
47
- customId = `s:toggle:${field.path}`;
48
- } else if (field.type === "select") {
49
- customId = `s:select:${field.path}`;
50
- } else {
51
- customId = `s:input:${field.path}`;
52
- }
53
- rows.push(
54
- new ActionRowBuilder().addComponents(
55
- new ButtonBuilder().setCustomId(customId).setLabel(label.slice(0, 80)).setStyle(ButtonStyle.Secondary)
56
- )
57
- );
58
- }
59
- if (totalPages > 1) {
60
- const navRow = new ActionRowBuilder();
61
- if (page > 0) {
62
- navRow.addComponents(
63
- new ButtonBuilder().setCustomId(`s:page:${page - 1}`).setLabel("\u25C0\uFE0F Previous").setStyle(ButtonStyle.Primary)
64
- );
65
- }
66
- navRow.addComponents(
67
- new ButtonBuilder().setCustomId("s:pageinfo").setLabel(`Page ${page + 1}/${totalPages}`).setStyle(ButtonStyle.Secondary).setDisabled(true)
68
- );
69
- if (page < totalPages - 1) {
70
- navRow.addComponents(
71
- new ButtonBuilder().setCustomId(`s:page:${page + 1}`).setLabel("Next \u25B6\uFE0F").setStyle(ButtonStyle.Primary)
72
- );
73
- }
74
- rows.push(navRow);
75
- }
76
- return rows;
77
- }
78
- async function handleSettings(interaction, adapter) {
79
- await interaction.deferReply({ ephemeral: true });
80
- const rows = buildSettingsRows(adapter);
81
- await interaction.editReply({
82
- content: "**\u2699\uFE0F Settings**\nTap to change:",
83
- components: rows
84
- });
85
- }
86
- async function showSettingsInfo(interaction, adapter) {
87
- const rows = buildSettingsRows(adapter);
88
- await interaction.followUp({
89
- content: "**\u2699\uFE0F Settings**\nTap to change:",
90
- components: rows,
91
- ephemeral: true
92
- });
93
- }
94
- async function handleSettingsButton(interaction, adapter) {
95
- const { customId } = interaction;
96
- try {
97
- if (customId.startsWith("s:toggle:")) {
98
- const fieldPath = customId.replace("s:toggle:", "");
99
- const config = adapter.core.configManager.get();
100
- const currentValue = getConfigValue(config, fieldPath);
101
- const newValue = !currentValue;
102
- const updates = buildNestedUpdate(fieldPath, newValue);
103
- await adapter.core.configManager.save(updates, fieldPath);
104
- const toast = isHotReloadable(fieldPath) ? `\u2705 ${fieldPath} = ${newValue}` : `\u2705 ${fieldPath} = ${newValue} (restart needed)`;
105
- try {
106
- await interaction.update({
107
- content: "**\u2699\uFE0F Settings**\nTap to change:",
108
- components: buildSettingsRows(adapter)
109
- });
110
- } catch {
111
- }
112
- try {
113
- await interaction.followUp({ content: toast, ephemeral: true });
114
- } catch {
115
- }
116
- return;
117
- }
118
- if (customId.startsWith("s:select:")) {
119
- const fieldPath = customId.replace("s:select:", "");
120
- const config = adapter.core.configManager.get();
121
- const fieldDef = getSafeFields().find((f) => f.path === fieldPath);
122
- if (!fieldDef) return;
123
- const options = resolveOptions(fieldDef, config) ?? [];
124
- const currentValue = getConfigValue(config, fieldPath);
125
- const rows = [];
126
- let currentRow = new ActionRowBuilder();
127
- let count = 0;
128
- for (const opt of options) {
129
- const marker = opt === String(currentValue) ? " \u2713" : "";
130
- currentRow.addComponents(
131
- new ButtonBuilder().setCustomId(`s:pick:${fieldPath}:${opt}`).setLabel(`${opt}${marker}`.slice(0, 80)).setStyle(opt === String(currentValue) ? ButtonStyle.Success : ButtonStyle.Secondary)
132
- );
133
- count++;
134
- if (count % 3 === 0) {
135
- rows.push(currentRow);
136
- currentRow = new ActionRowBuilder();
137
- }
138
- }
139
- if (currentRow.components.length > 0) {
140
- rows.push(currentRow);
141
- }
142
- const backRow = new ActionRowBuilder().addComponents(
143
- new ButtonBuilder().setCustomId("s:back").setLabel("\u25C0\uFE0F Back").setStyle(ButtonStyle.Primary)
144
- );
145
- rows.push(backRow);
146
- try {
147
- await interaction.update({
148
- content: `**\u2699\uFE0F ${fieldDef.displayName}**
149
- Select a value:`,
150
- components: rows.slice(0, 5)
151
- });
152
- } catch {
153
- }
154
- return;
155
- }
156
- if (customId.startsWith("s:pick:")) {
157
- const parts = customId.replace("s:pick:", "").split(":");
158
- const fieldPath = parts.slice(0, -1).join(":");
159
- const newValue = parts[parts.length - 1];
160
- if (fieldPath === "speech.stt.provider") {
161
- const config = adapter.core.configManager.get();
162
- const providerConfig = config.speech?.stt?.providers?.[newValue];
163
- if (!providerConfig?.apiKey) {
164
- const assistantSessionId = adapter.getAssistantSessionId();
165
- if (assistantSessionId) {
166
- const assistantSession = adapter.core.sessionManager.getSession(assistantSessionId);
167
- if (assistantSession) {
168
- const prompt = `User wants to enable ${newValue} as Speech-to-Text provider, but no API key is configured yet. Guide them to get a ${newValue} API key and set it up. After they provide the key, run both commands: \`openacp config set speech.stt.providers.${newValue}.apiKey <key>\` and \`openacp config set speech.stt.provider ${newValue}\``;
169
- await assistantSession.enqueuePrompt(prompt);
170
- try {
171
- await interaction.update({
172
- content: "**\u2699\uFE0F Settings**\nTap to change:",
173
- components: buildSettingsRows(adapter)
174
- });
175
- } catch {
176
- }
177
- try {
178
- await interaction.followUp({ content: "\u{1F511} API key needed \u2014 check the Assistant thread.", ephemeral: true });
179
- } catch {
180
- }
181
- return;
182
- }
183
- }
184
- try {
185
- await interaction.update({
186
- content: "**\u2699\uFE0F Settings**\nTap to change:",
187
- components: buildSettingsRows(adapter)
188
- });
189
- } catch {
190
- }
191
- try {
192
- await interaction.followUp({ content: `\u26A0\uFE0F Set API key first: \`openacp config set speech.stt.providers.${newValue}.apiKey <key>\``, ephemeral: true });
193
- } catch {
194
- }
195
- return;
196
- }
197
- }
198
- const updates = buildNestedUpdate(fieldPath, newValue);
199
- await adapter.core.configManager.save(updates, fieldPath);
200
- try {
201
- await interaction.update({
202
- content: "**\u2699\uFE0F Settings**\nTap to change:",
203
- components: buildSettingsRows(adapter)
204
- });
205
- } catch {
206
- }
207
- try {
208
- await interaction.followUp({ content: `\u2705 ${fieldPath} = ${newValue}`, ephemeral: true });
209
- } catch {
210
- }
211
- return;
212
- }
213
- if (customId.startsWith("s:input:")) {
214
- const fieldPath = customId.replace("s:input:", "");
215
- const config = adapter.core.configManager.get();
216
- const fieldDef = getSafeFields().find((f) => f.path === fieldPath);
217
- if (!fieldDef) return;
218
- const currentValue = getConfigValue(config, fieldPath);
219
- const assistantSessionId = adapter.getAssistantSessionId();
220
- if (!assistantSessionId) {
221
- try {
222
- await interaction.reply({ content: "\u26A0\uFE0F Assistant is not available.", ephemeral: true });
223
- } catch {
224
- }
225
- return;
226
- }
227
- const assistantSession = adapter.core.sessionManager.getSession(assistantSessionId);
228
- if (!assistantSession) {
229
- try {
230
- await interaction.reply({ content: "\u26A0\uFE0F Assistant session not found.", ephemeral: true });
231
- } catch {
232
- }
233
- return;
234
- }
235
- try {
236
- await interaction.deferUpdate();
237
- } catch {
238
- }
239
- const prompt = `User wants to change ${fieldDef.displayName} (config path: ${fieldPath}). Current value: ${JSON.stringify(currentValue)}. Ask them for the new value and apply it using: openacp config set ${fieldPath} <value>`;
240
- await assistantSession.enqueuePrompt(prompt);
241
- try {
242
- await interaction.followUp({ content: `Delegating to assistant \u2014 check the Assistant thread.`, ephemeral: true });
243
- } catch {
244
- }
245
- return;
246
- }
247
- if (customId.startsWith("s:page:")) {
248
- const page = parseInt(customId.replace("s:page:", ""), 10);
249
- try {
250
- await interaction.update({
251
- content: "**\u2699\uFE0F Settings**\nTap to change:",
252
- components: buildSettingsRows(adapter, page)
253
- });
254
- } catch {
255
- }
256
- return;
257
- }
258
- if (customId === "s:back") {
259
- try {
260
- await interaction.update({
261
- content: "**\u2699\uFE0F Settings**\nTap to change:",
262
- components: buildSettingsRows(adapter)
263
- });
264
- } catch {
265
- }
266
- return;
267
- }
268
- log.warn({ customId }, "[discord-settings] Unhandled settings button");
269
- } catch (err) {
270
- log.error({ err, customId }, "[discord-settings] Settings button handler failed");
271
- try {
272
- if (!interaction.replied && !interaction.deferred) {
273
- await interaction.reply({ content: "\u274C Settings action failed.", ephemeral: true });
274
- } else {
275
- await interaction.followUp({ content: "\u274C Settings action failed.", ephemeral: true });
276
- }
277
- } catch {
278
- }
279
- }
280
- }
281
- function buildNestedUpdate(dotPath, value) {
282
- const parts = dotPath.split(".");
283
- const result = {};
284
- let target = result;
285
- for (let i = 0; i < parts.length - 1; i++) {
286
- target[parts[i]] = {};
287
- target = target[parts[i]];
288
- }
289
- target[parts[parts.length - 1]] = value;
290
- return result;
291
- }
292
-
293
- export {
294
- handleSettings,
295
- showSettingsInfo,
296
- handleSettingsButton
297
- };
298
- //# sourceMappingURL=chunk-O7CPGUAI.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/adapters/discord/commands/settings.ts"],"sourcesContent":["import {\n ActionRowBuilder,\n ButtonBuilder,\n ButtonStyle,\n} from 'discord.js'\nimport type { ChatInputCommandInteraction, ButtonInteraction } from 'discord.js'\nimport { log } from '../../../core/log.js'\nimport { getSafeFields, resolveOptions, getConfigValue, isHotReloadable, type ConfigFieldDef } from '../../../core/config-registry.js'\nimport type { DiscordAdapter } from '../adapter.js'\n\nfunction formatFieldLabel(field: ConfigFieldDef, value: unknown): string {\n const icons: Record<string, string> = {\n agent: '🤖', logging: '📝', tunnel: '🔗',\n security: '🔒', workspace: '📁', storage: '💾', speech: '🎤',\n }\n const icon = icons[field.group] ?? '⚙️'\n\n if (field.type === 'toggle') {\n return `${icon} ${field.displayName}: ${value ? 'ON' : 'OFF'}`\n }\n const displayValue = value === null || value === undefined ? 'Not set' : String(value)\n return `${icon} ${field.displayName}: ${displayValue}`\n}\n\nconst SETTINGS_PAGE_SIZE = 4 // 4 field rows + 1 navigation row = 5 max\n\nfunction buildSettingsRows(adapter: DiscordAdapter, page = 0): ActionRowBuilder<ButtonBuilder>[] {\n const config = adapter.core.configManager.get()\n const fields = getSafeFields()\n const totalPages = Math.ceil(fields.length / SETTINGS_PAGE_SIZE)\n const start = page * SETTINGS_PAGE_SIZE\n const pageFields = fields.slice(start, start + SETTINGS_PAGE_SIZE)\n\n const rows: ActionRowBuilder<ButtonBuilder>[] = []\n\n for (const field of pageFields) {\n const value = getConfigValue(config, field.path)\n const label = formatFieldLabel(field, value)\n\n let customId: string\n if (field.type === 'toggle') {\n customId = `s:toggle:${field.path}`\n } else if (field.type === 'select') {\n customId = `s:select:${field.path}`\n } else {\n customId = `s:input:${field.path}`\n }\n\n rows.push(\n new ActionRowBuilder<ButtonBuilder>().addComponents(\n new ButtonBuilder()\n .setCustomId(customId)\n .setLabel(label.slice(0, 80))\n .setStyle(ButtonStyle.Secondary),\n ),\n )\n }\n\n // Navigation row (if more than 1 page)\n if (totalPages > 1) {\n const navRow = new ActionRowBuilder<ButtonBuilder>()\n if (page > 0) {\n navRow.addComponents(\n new ButtonBuilder()\n .setCustomId(`s:page:${page - 1}`)\n .setLabel('◀️ Previous')\n .setStyle(ButtonStyle.Primary),\n )\n }\n navRow.addComponents(\n new ButtonBuilder()\n .setCustomId('s:pageinfo')\n .setLabel(`Page ${page + 1}/${totalPages}`)\n .setStyle(ButtonStyle.Secondary)\n .setDisabled(true),\n )\n if (page < totalPages - 1) {\n navRow.addComponents(\n new ButtonBuilder()\n .setCustomId(`s:page:${page + 1}`)\n .setLabel('Next ▶️')\n .setStyle(ButtonStyle.Primary),\n )\n }\n rows.push(navRow)\n }\n\n return rows\n}\n\nexport async function handleSettings(\n interaction: ChatInputCommandInteraction,\n adapter: DiscordAdapter,\n): Promise<void> {\n await interaction.deferReply({ ephemeral: true })\n\n const rows = buildSettingsRows(adapter)\n await interaction.editReply({\n content: '**⚙️ Settings**\\nTap to change:',\n components: rows,\n })\n}\n\nexport async function showSettingsInfo(\n interaction: ButtonInteraction,\n adapter: DiscordAdapter,\n): Promise<void> {\n const rows = buildSettingsRows(adapter)\n await interaction.followUp({\n content: '**⚙️ Settings**\\nTap to change:',\n components: rows,\n ephemeral: true,\n })\n}\n\nexport async function handleSettingsButton(\n interaction: ButtonInteraction,\n adapter: DiscordAdapter,\n): Promise<void> {\n const { customId } = interaction\n\n try {\n // Toggle buttons\n if (customId.startsWith('s:toggle:')) {\n const fieldPath = customId.replace('s:toggle:', '')\n const config = adapter.core.configManager.get()\n const currentValue = getConfigValue(config, fieldPath)\n const newValue = !currentValue\n\n const updates = buildNestedUpdate(fieldPath, newValue)\n await adapter.core.configManager.save(updates, fieldPath)\n\n const toast = isHotReloadable(fieldPath)\n ? `✅ ${fieldPath} = ${newValue}`\n : `✅ ${fieldPath} = ${newValue} (restart needed)`\n\n try {\n await interaction.update({\n content: '**⚙️ Settings**\\nTap to change:',\n components: buildSettingsRows(adapter),\n })\n } catch { /* ignore */ }\n\n try { await interaction.followUp({ content: toast, ephemeral: true }) } catch { /* ignore */ }\n return\n }\n\n // Select buttons — show options\n if (customId.startsWith('s:select:')) {\n const fieldPath = customId.replace('s:select:', '')\n const config = adapter.core.configManager.get()\n const fieldDef = getSafeFields().find((f) => f.path === fieldPath)\n if (!fieldDef) return\n\n const options = resolveOptions(fieldDef, config) ?? []\n const currentValue = getConfigValue(config, fieldPath)\n\n const rows: ActionRowBuilder<ButtonBuilder>[] = []\n let currentRow = new ActionRowBuilder<ButtonBuilder>()\n let count = 0\n\n for (const opt of options) {\n const marker = opt === String(currentValue) ? ' ✓' : ''\n currentRow.addComponents(\n new ButtonBuilder()\n .setCustomId(`s:pick:${fieldPath}:${opt}`)\n .setLabel(`${opt}${marker}`.slice(0, 80))\n .setStyle(opt === String(currentValue) ? ButtonStyle.Success : ButtonStyle.Secondary),\n )\n count++\n if (count % 3 === 0) {\n rows.push(currentRow)\n currentRow = new ActionRowBuilder<ButtonBuilder>()\n }\n }\n\n if (currentRow.components.length > 0) {\n rows.push(currentRow)\n }\n\n // Add back button\n const backRow = new ActionRowBuilder<ButtonBuilder>().addComponents(\n new ButtonBuilder()\n .setCustomId('s:back')\n .setLabel('◀️ Back')\n .setStyle(ButtonStyle.Primary),\n )\n rows.push(backRow)\n\n try {\n await interaction.update({\n content: `**⚙️ ${fieldDef.displayName}**\\nSelect a value:`,\n components: rows.slice(0, 5),\n })\n } catch { /* ignore */ }\n return\n }\n\n // Pick buttons — apply selected value\n if (customId.startsWith('s:pick:')) {\n const parts = customId.replace('s:pick:', '').split(':')\n const fieldPath = parts.slice(0, -1).join(':')\n const newValue = parts[parts.length - 1]\n\n // For speech.stt.provider: check if API key is configured\n if (fieldPath === 'speech.stt.provider') {\n const config = adapter.core.configManager.get()\n const providerConfig = config.speech?.stt?.providers?.[newValue]\n if (!providerConfig?.apiKey) {\n // No API key — delegate to assistant\n const assistantSessionId = adapter.getAssistantSessionId()\n if (assistantSessionId) {\n const assistantSession = adapter.core.sessionManager.getSession(assistantSessionId)\n if (assistantSession) {\n const prompt = `User wants to enable ${newValue} as Speech-to-Text provider, but no API key is configured yet. Guide them to get a ${newValue} API key and set it up. After they provide the key, run both commands: \\`openacp config set speech.stt.providers.${newValue}.apiKey <key>\\` and \\`openacp config set speech.stt.provider ${newValue}\\``\n await assistantSession.enqueuePrompt(prompt)\n\n try {\n await interaction.update({\n content: '**⚙️ Settings**\\nTap to change:',\n components: buildSettingsRows(adapter),\n })\n } catch { /* ignore */ }\n try { await interaction.followUp({ content: '🔑 API key needed — check the Assistant thread.', ephemeral: true }) } catch { /* ignore */ }\n return\n }\n }\n\n // No assistant — just warn\n try {\n await interaction.update({\n content: '**⚙️ Settings**\\nTap to change:',\n components: buildSettingsRows(adapter),\n })\n } catch { /* ignore */ }\n try { await interaction.followUp({ content: `⚠️ Set API key first: \\`openacp config set speech.stt.providers.${newValue}.apiKey <key>\\``, ephemeral: true }) } catch { /* ignore */ }\n return\n }\n }\n\n const updates = buildNestedUpdate(fieldPath, newValue)\n await adapter.core.configManager.save(updates, fieldPath)\n\n try {\n await interaction.update({\n content: '**⚙️ Settings**\\nTap to change:',\n components: buildSettingsRows(adapter),\n })\n } catch { /* ignore */ }\n try { await interaction.followUp({ content: `✅ ${fieldPath} = ${newValue}`, ephemeral: true }) } catch { /* ignore */ }\n return\n }\n\n // Input buttons — delegate to assistant\n if (customId.startsWith('s:input:')) {\n const fieldPath = customId.replace('s:input:', '')\n const config = adapter.core.configManager.get()\n const fieldDef = getSafeFields().find((f) => f.path === fieldPath)\n if (!fieldDef) return\n\n const currentValue = getConfigValue(config, fieldPath)\n const assistantSessionId = adapter.getAssistantSessionId()\n\n if (!assistantSessionId) {\n try { await interaction.reply({ content: '⚠️ Assistant is not available.', ephemeral: true }) } catch { /* ignore */ }\n return\n }\n\n const assistantSession = adapter.core.sessionManager.getSession(assistantSessionId)\n if (!assistantSession) {\n try { await interaction.reply({ content: '⚠️ Assistant session not found.', ephemeral: true }) } catch { /* ignore */ }\n return\n }\n\n try { await interaction.deferUpdate() } catch { /* ignore */ }\n\n const prompt = `User wants to change ${fieldDef.displayName} (config path: ${fieldPath}). Current value: ${JSON.stringify(currentValue)}. Ask them for the new value and apply it using: openacp config set ${fieldPath} <value>`\n await assistantSession.enqueuePrompt(prompt)\n\n try { await interaction.followUp({ content: `Delegating to assistant — check the Assistant thread.`, ephemeral: true }) } catch { /* ignore */ }\n return\n }\n\n // Page navigation\n if (customId.startsWith('s:page:')) {\n const page = parseInt(customId.replace('s:page:', ''), 10)\n try {\n await interaction.update({\n content: '**⚙️ Settings**\\nTap to change:',\n components: buildSettingsRows(adapter, page),\n })\n } catch { /* ignore */ }\n return\n }\n\n // Back button — return to page 0\n if (customId === 's:back') {\n try {\n await interaction.update({\n content: '**⚙️ Settings**\\nTap to change:',\n components: buildSettingsRows(adapter),\n })\n } catch { /* ignore */ }\n return\n }\n\n log.warn({ customId }, '[discord-settings] Unhandled settings button')\n } catch (err) {\n log.error({ err, customId }, '[discord-settings] Settings button handler failed')\n try {\n if (!interaction.replied && !interaction.deferred) {\n await interaction.reply({ content: '❌ Settings action failed.', ephemeral: true })\n } else {\n await interaction.followUp({ content: '❌ Settings action failed.', ephemeral: true })\n }\n } catch { /* ignore */ }\n }\n}\n\nfunction buildNestedUpdate(dotPath: string, value: unknown): Record<string, unknown> {\n const parts = dotPath.split('.')\n const result: Record<string, unknown> = {}\n let target = result\n for (let i = 0; i < parts.length - 1; i++) {\n target[parts[i]] = {}\n target = target[parts[i]] as Record<string, unknown>\n }\n target[parts[parts.length - 1]] = value\n return result\n}\n"],"mappings":"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","names":[]}
@@ -1,98 +0,0 @@
1
- // src/cli/version.ts
2
- import { fileURLToPath } from "url";
3
- import { dirname, join, resolve } from "path";
4
- import { existsSync, readFileSync } from "fs";
5
- var NPM_PACKAGE = "@openacp/cli";
6
- function findPackageJson() {
7
- let dir = dirname(fileURLToPath(import.meta.url));
8
- for (let i = 0; i < 5; i++) {
9
- const candidate = join(dir, "package.json");
10
- if (existsSync(candidate)) return candidate;
11
- const parent = resolve(dir, "..");
12
- if (parent === dir) break;
13
- dir = parent;
14
- }
15
- return null;
16
- }
17
- function getCurrentVersion() {
18
- try {
19
- const pkgPath = findPackageJson();
20
- if (!pkgPath) return "0.0.0-dev";
21
- const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
22
- return pkg.version;
23
- } catch {
24
- return "0.0.0-dev";
25
- }
26
- }
27
- async function getLatestVersion() {
28
- try {
29
- const res = await fetch(`https://registry.npmjs.org/${NPM_PACKAGE}/latest`, {
30
- signal: AbortSignal.timeout(5e3)
31
- });
32
- if (!res.ok) return null;
33
- const data = await res.json();
34
- return data.version ?? null;
35
- } catch {
36
- return null;
37
- }
38
- }
39
- function compareVersions(current, latest) {
40
- const a = current.split(".").map(Number);
41
- const b = latest.split(".").map(Number);
42
- for (let i = 0; i < 3; i++) {
43
- if ((a[i] ?? 0) < (b[i] ?? 0)) return -1;
44
- if ((a[i] ?? 0) > (b[i] ?? 0)) return 1;
45
- }
46
- return 0;
47
- }
48
- async function runUpdate() {
49
- const { spawn } = await import("child_process");
50
- return new Promise((resolve2) => {
51
- const child = spawn("npm", ["install", "-g", `${NPM_PACKAGE}@latest`], {
52
- stdio: "inherit",
53
- shell: true
54
- });
55
- const onSignal = () => {
56
- child.kill("SIGTERM");
57
- resolve2(false);
58
- };
59
- process.on("SIGINT", onSignal);
60
- process.on("SIGTERM", onSignal);
61
- child.on("close", (code) => {
62
- process.off("SIGINT", onSignal);
63
- process.off("SIGTERM", onSignal);
64
- resolve2(code === 0);
65
- });
66
- });
67
- }
68
- async function checkAndPromptUpdate() {
69
- if (process.env.OPENACP_DEV_LOOP || process.env.OPENACP_SKIP_UPDATE_CHECK) return;
70
- const current = getCurrentVersion();
71
- if (current === "0.0.0-dev") return;
72
- const latest = await getLatestVersion();
73
- if (!latest || compareVersions(current, latest) >= 0) return;
74
- console.log(`\x1B[33mUpdate available: v${current} \u2192 v${latest}\x1B[0m`);
75
- const clack = await import("@clack/prompts");
76
- const yes = await clack.confirm({
77
- message: "Update now before starting?"
78
- });
79
- if (clack.isCancel(yes) || !yes) {
80
- return;
81
- }
82
- const ok = await runUpdate();
83
- if (ok) {
84
- console.log(`\x1B[32m\u2713 Updated to v${latest}. Please re-run your command.\x1B[0m`);
85
- process.exit(0);
86
- } else {
87
- console.error("\x1B[31mUpdate failed. Continuing with current version.\x1B[0m");
88
- }
89
- }
90
-
91
- export {
92
- getCurrentVersion,
93
- getLatestVersion,
94
- compareVersions,
95
- runUpdate,
96
- checkAndPromptUpdate
97
- };
98
- //# sourceMappingURL=chunk-S64CB6J3.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/cli/version.ts"],"sourcesContent":["import { fileURLToPath } from 'node:url'\nimport { dirname, join, resolve } from 'node:path'\nimport { existsSync, readFileSync } from 'node:fs'\n\nconst NPM_PACKAGE = '@openacp/cli'\n\nfunction findPackageJson(): string | null {\n let dir = dirname(fileURLToPath(import.meta.url))\n for (let i = 0; i < 5; i++) {\n const candidate = join(dir, 'package.json')\n if (existsSync(candidate)) return candidate\n const parent = resolve(dir, '..')\n if (parent === dir) break\n dir = parent\n }\n return null\n}\n\nexport function getCurrentVersion(): string {\n try {\n const pkgPath = findPackageJson()\n if (!pkgPath) return '0.0.0-dev'\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'))\n return pkg.version as string\n } catch {\n return '0.0.0-dev'\n }\n}\n\nexport async function getLatestVersion(): Promise<string | null> {\n try {\n const res = await fetch(`https://registry.npmjs.org/${NPM_PACKAGE}/latest`, {\n signal: AbortSignal.timeout(5000),\n })\n if (!res.ok) return null\n const data = (await res.json()) as { version?: string }\n return data.version ?? null\n } catch {\n return null\n }\n}\n\nexport function compareVersions(current: string, latest: string): -1 | 0 | 1 {\n const a = current.split('.').map(Number)\n const b = latest.split('.').map(Number)\n for (let i = 0; i < 3; i++) {\n if ((a[i] ?? 0) < (b[i] ?? 0)) return -1\n if ((a[i] ?? 0) > (b[i] ?? 0)) return 1\n }\n return 0\n}\n\nexport async function runUpdate(): Promise<boolean> {\n const { spawn } = await import('node:child_process')\n return new Promise((resolve) => {\n const child = spawn('npm', ['install', '-g', `${NPM_PACKAGE}@latest`], {\n stdio: 'inherit',\n shell: true,\n })\n const onSignal = () => {\n child.kill('SIGTERM')\n resolve(false)\n }\n process.on('SIGINT', onSignal)\n process.on('SIGTERM', onSignal)\n child.on('close', (code) => {\n process.off('SIGINT', onSignal)\n process.off('SIGTERM', onSignal)\n resolve(code === 0)\n })\n })\n}\n\nexport async function checkAndPromptUpdate(): Promise<void> {\n if (process.env.OPENACP_DEV_LOOP || process.env.OPENACP_SKIP_UPDATE_CHECK) return\n\n const current = getCurrentVersion()\n if (current === '0.0.0-dev') return\n\n const latest = await getLatestVersion()\n if (!latest || compareVersions(current, latest) >= 0) return\n\n console.log(`\\x1b[33mUpdate available: v${current} → v${latest}\\x1b[0m`)\n const clack = await import('@clack/prompts')\n const yes = await clack.confirm({\n message: 'Update now before starting?',\n })\n if (clack.isCancel(yes) || !yes) {\n return\n }\n const ok = await runUpdate()\n if (ok) {\n console.log(`\\x1b[32m✓ Updated to v${latest}. Please re-run your command.\\x1b[0m`)\n process.exit(0)\n } else {\n console.error('\\x1b[31mUpdate failed. Continuing with current version.\\x1b[0m')\n }\n}\n"],"mappings":"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","names":["resolve"]}