@openacp/cli 0.6.2 → 0.6.3

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 (63) hide show
  1. package/dist/{admin-IVQTC72V.js → admin-3ZHEO5VP.js} +8 -4
  2. package/dist/{chunk-FF4C3ZE4.js → chunk-6LSFRNHE.js} +2 -2
  3. package/dist/{chunk-2OFIWTYD.js → chunk-AVCHZESZ.js} +2 -2
  4. package/dist/{chunk-ONENT7JQ.js → chunk-FZ5BIWG5.js} +6 -6
  5. package/dist/chunk-FZ5BIWG5.js.map +1 -0
  6. package/dist/{chunk-7WQH4SOY.js → chunk-G3OHCXZG.js} +32 -22
  7. package/dist/chunk-G3OHCXZG.js.map +1 -0
  8. package/dist/{chunk-IFTYEG5J.js → chunk-HP2IJYCA.js} +27 -27
  9. package/dist/chunk-HP2IJYCA.js.map +1 -0
  10. package/dist/chunk-IER5UCY7.js +298 -0
  11. package/dist/chunk-IER5UCY7.js.map +1 -0
  12. package/dist/{chunk-IUIMBEBX.js → chunk-NXEQXRQR.js} +53 -9
  13. package/dist/chunk-NXEQXRQR.js.map +1 -0
  14. package/dist/{chunk-WQZ4RXH7.js → chunk-OHR6SBMC.js} +2 -2
  15. package/dist/chunk-PWFPTG5X.js +101 -0
  16. package/dist/chunk-PWFPTG5X.js.map +1 -0
  17. package/dist/cli.js +8 -8
  18. package/dist/{config-editor-TOZUBMO7.js → config-editor-F25HEMGL.js} +3 -3
  19. package/dist/{discord-7B5NWW5Z.js → discord-VHCBN3JJ.js} +85 -29
  20. package/dist/discord-VHCBN3JJ.js.map +1 -0
  21. package/dist/{doctor-FR5GASOQ.js → doctor-GPW5ECK6.js} +3 -3
  22. package/dist/{doctor-UOH7YCT2.js → doctor-Y3SCSVPI.js} +2 -2
  23. package/dist/index.js +6 -6
  24. package/dist/install-cloudflared-G2GUKCHA.js +32 -0
  25. package/dist/install-cloudflared-G2GUKCHA.js.map +1 -0
  26. package/dist/install-jq-7QTU7XYY.js +31 -0
  27. package/dist/install-jq-7QTU7XYY.js.map +1 -0
  28. package/dist/{integrate-QTK4PPYQ.js → integrate-O4OCR4SN.js} +9 -6
  29. package/dist/integrate-O4OCR4SN.js.map +1 -0
  30. package/dist/{main-46BVXFWI.js → main-P4X6SAPZ.js} +18 -8
  31. package/dist/main-P4X6SAPZ.js.map +1 -0
  32. package/dist/{new-session-BVNE6S3A.js → new-session-PUNUHGYP.js} +3 -3
  33. package/dist/post-upgrade-6N4JCV5S.js +79 -0
  34. package/dist/post-upgrade-6N4JCV5S.js.map +1 -0
  35. package/dist/{settings-LQ57CFY4.js → settings-OEQEZS5Y.js} +3 -2
  36. package/dist/{setup-DZXZTQRD.js → setup-7YBFKRG7.js} +4 -2
  37. package/dist/{tunnel-service-O5EKGFLO.js → tunnel-service-BMIBHUBK.js} +31 -31
  38. package/dist/tunnel-service-BMIBHUBK.js.map +1 -0
  39. package/package.json +1 -1
  40. package/dist/chunk-7WQH4SOY.js.map +0 -1
  41. package/dist/chunk-HSGUPJU5.js +0 -62
  42. package/dist/chunk-HSGUPJU5.js.map +0 -1
  43. package/dist/chunk-IFTYEG5J.js.map +0 -1
  44. package/dist/chunk-IUIMBEBX.js.map +0 -1
  45. package/dist/chunk-ONENT7JQ.js.map +0 -1
  46. package/dist/chunk-RF3DUYFO.js +0 -103
  47. package/dist/chunk-RF3DUYFO.js.map +0 -1
  48. package/dist/discord-7B5NWW5Z.js.map +0 -1
  49. package/dist/install-cloudflared-BTGUD7SW.js +0 -8
  50. package/dist/integrate-QTK4PPYQ.js.map +0 -1
  51. package/dist/main-46BVXFWI.js.map +0 -1
  52. package/dist/setup-DZXZTQRD.js.map +0 -1
  53. package/dist/tunnel-service-O5EKGFLO.js.map +0 -1
  54. /package/dist/{admin-IVQTC72V.js.map → admin-3ZHEO5VP.js.map} +0 -0
  55. /package/dist/{chunk-FF4C3ZE4.js.map → chunk-6LSFRNHE.js.map} +0 -0
  56. /package/dist/{chunk-2OFIWTYD.js.map → chunk-AVCHZESZ.js.map} +0 -0
  57. /package/dist/{chunk-WQZ4RXH7.js.map → chunk-OHR6SBMC.js.map} +0 -0
  58. /package/dist/{config-editor-TOZUBMO7.js.map → config-editor-F25HEMGL.js.map} +0 -0
  59. /package/dist/{doctor-FR5GASOQ.js.map → doctor-GPW5ECK6.js.map} +0 -0
  60. /package/dist/{doctor-UOH7YCT2.js.map → doctor-Y3SCSVPI.js.map} +0 -0
  61. /package/dist/{install-cloudflared-BTGUD7SW.js.map → new-session-PUNUHGYP.js.map} +0 -0
  62. /package/dist/{new-session-BVNE6S3A.js.map → settings-OEQEZS5Y.js.map} +0 -0
  63. /package/dist/{settings-LQ57CFY4.js.map → setup-7YBFKRG7.js.map} +0 -0
@@ -1,16 +1,20 @@
1
1
  import {
2
- buildDangerousModeKeyboard,
2
+ buildSessionControlKeyboard,
3
3
  handleDangerous,
4
4
  handleDangerousButton,
5
5
  handleRestart,
6
+ handleTTS,
7
+ handleTTSButton,
6
8
  handleUpdate
7
- } from "./chunk-IUIMBEBX.js";
9
+ } from "./chunk-NXEQXRQR.js";
8
10
  import "./chunk-ESOPMQAY.js";
9
11
  export {
10
- buildDangerousModeKeyboard,
12
+ buildSessionControlKeyboard,
11
13
  handleDangerous,
12
14
  handleDangerousButton,
13
15
  handleRestart,
16
+ handleTTS,
17
+ handleTTSButton,
14
18
  handleUpdate
15
19
  };
16
- //# sourceMappingURL=admin-IVQTC72V.js.map
20
+ //# sourceMappingURL=admin-3ZHEO5VP.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  DoctorEngine
3
- } from "./chunk-WQZ4RXH7.js";
3
+ } from "./chunk-OHR6SBMC.js";
4
4
  import {
5
5
  log
6
6
  } from "./chunk-ESOPMQAY.js";
@@ -131,4 +131,4 @@ export {
131
131
  runDoctorInline,
132
132
  handleDoctorButton
133
133
  };
134
- //# sourceMappingURL=chunk-FF4C3ZE4.js.map
134
+ //# sourceMappingURL=chunk-6LSFRNHE.js.map
@@ -8,7 +8,7 @@ import {
8
8
  validateBotToken,
9
9
  validateChatId,
10
10
  validateDiscordToken
11
- } from "./chunk-7WQH4SOY.js";
11
+ } from "./chunk-G3OHCXZG.js";
12
12
  import {
13
13
  expandHome
14
14
  } from "./chunk-EWYNCHUH.js";
@@ -706,4 +706,4 @@ function flattenToPaths(obj, prefix = "") {
706
706
  export {
707
707
  runConfigEditor
708
708
  };
709
- //# sourceMappingURL=chunk-2OFIWTYD.js.map
709
+ //# sourceMappingURL=chunk-AVCHZESZ.js.map
@@ -1,10 +1,10 @@
1
+ import {
2
+ buildSessionControlKeyboard
3
+ } from "./chunk-NXEQXRQR.js";
1
4
  import {
2
5
  createSessionThread,
3
6
  deleteSessionThread
4
7
  } from "./chunk-SM3G6UAX.js";
5
- import {
6
- buildDangerousModeKeyboard
7
- } from "./chunk-IUIMBEBX.js";
8
8
  import {
9
9
  log
10
10
  } from "./chunk-ESOPMQAY.js";
@@ -89,14 +89,14 @@ async function executeNewSession(interaction, adapter, agentName, workspace) {
89
89
  await adapter.core.sessionManager.patchRecord(session.id, {
90
90
  platform: { threadId: thread.id }
91
91
  });
92
- const dangerousRow = buildDangerousModeKeyboard(session.id, false);
92
+ const controlRow = buildSessionControlKeyboard(session.id, false, false);
93
93
  await thread.send({
94
94
  content: `\u2705 **Session started**
95
95
  **Agent:** ${session.agentName}
96
96
  **Workspace:** \`${session.workingDirectory}\`
97
97
 
98
98
  This is your coding session \u2014 chat here to work with the agent.`,
99
- components: [dangerousRow]
99
+ components: [controlRow]
100
100
  });
101
101
  const replyMsg = `\u2705 Session created \u2192 [Open thread](https://discord.com/channels/${adapter.getGuildId()}/${thread.id})`;
102
102
  if (interaction.deferred || interaction.replied) {
@@ -142,4 +142,4 @@ export {
142
142
  executeNewSession,
143
143
  handleNewSessionButton
144
144
  };
145
- //# sourceMappingURL=chunk-ONENT7JQ.js.map
145
+ //# sourceMappingURL=chunk-FZ5BIWG5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/adapters/discord/commands/new-session.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 { buildSessionControlKeyboard } from './admin.js'\nimport { createSessionThread, deleteSessionThread } from '../forums.js'\nimport type { DiscordAdapter } from '../adapter.js'\n\nexport async function handleNew(\n interaction: ChatInputCommandInteraction,\n adapter: DiscordAdapter,\n): Promise<void> {\n await interaction.deferReply({ ephemeral: true })\n\n const agentName = interaction.options.getString('agent') ?? undefined\n const workspace = interaction.options.getString('workspace') ?? undefined\n\n if (agentName) {\n await executeNewSession(interaction, adapter, agentName, workspace)\n return\n }\n\n // No agent specified — show agent picker\n const installedEntries = adapter.core.agentCatalog.getInstalledEntries()\n const agentKeys = Object.keys(installedEntries)\n const config = adapter.core.configManager.get()\n\n if (agentKeys.length === 0) {\n await interaction.editReply('❌ No agents installed. Use `/install` to install an agent first.')\n return\n }\n\n if (agentKeys.length === 1) {\n await executeNewSession(interaction, adapter, config.defaultAgent, workspace)\n return\n }\n\n // Multiple agents — show picker buttons\n const row = new ActionRowBuilder<ButtonBuilder>()\n for (const key of agentKeys) {\n const agent = installedEntries[key]!\n const label = key === config.defaultAgent ? `${agent.name} (default)` : agent.name\n row.addComponents(\n new ButtonBuilder()\n .setCustomId(`m:new:agent:${key}`)\n .setLabel(label)\n .setStyle(ButtonStyle.Primary),\n )\n }\n\n await interaction.editReply({\n content: '🤖 **Choose an agent:**',\n components: [row],\n })\n}\n\nexport async function handleNewChat(\n interaction: ChatInputCommandInteraction,\n adapter: DiscordAdapter,\n): Promise<void> {\n await interaction.deferReply({ ephemeral: true })\n\n // Get current thread to inherit config from\n const channelId = interaction.channelId\n const currentSession = adapter.core.sessionManager.getSessionByThread('discord', channelId)\n\n let agentName: string | undefined\n let workspace: string | undefined\n\n if (currentSession) {\n agentName = currentSession.agentName\n workspace = currentSession.workingDirectory\n } else {\n const record = adapter.core.sessionManager.getRecordByThread('discord', channelId)\n if (!record || record.status === 'cancelled' || record.status === 'error') {\n await interaction.editReply('No active session in this channel. Use `/new` to start one.')\n return\n }\n agentName = record.agentName\n workspace = record.workingDir\n }\n\n await executeNewSession(interaction, adapter, agentName, workspace)\n}\n\nexport async function executeNewSession(\n interaction: ChatInputCommandInteraction | ButtonInteraction,\n adapter: DiscordAdapter,\n agentName?: string,\n workspace?: string,\n): Promise<void> {\n const config = adapter.core.configManager.get()\n const resolvedAgent = agentName || config.defaultAgent\n\n log.info({ agentName: resolvedAgent, workspace }, '[discord-new-session] Creating session')\n\n const forumChannel = adapter.getForumChannel()\n if (!forumChannel) {\n const msg = '❌ Forum channel not configured. Please run setup first.'\n if (interaction.deferred || interaction.replied) {\n await interaction.editReply(msg)\n } else {\n await (interaction as ChatInputCommandInteraction).reply({ content: msg, ephemeral: true })\n }\n return\n }\n\n let thread: import('discord.js').ThreadChannel | undefined\n\n try {\n // Create forum thread BEFORE creating session to avoid race condition\n thread = await createSessionThread(forumChannel, `🔄 ${resolvedAgent} — New Session`)\n\n // Create session via core\n const session = await adapter.core.handleNewSession('discord', resolvedAgent, workspace)\n session.threadId = thread.id\n\n // Patch platform record with Discord thread ID\n await adapter.core.sessionManager.patchRecord(session.id, {\n platform: { threadId: thread.id },\n })\n\n // Send welcome message in the new thread\n const controlRow = buildSessionControlKeyboard(session.id, false, false)\n await thread.send({\n content:\n `✅ **Session started**\\n` +\n `**Agent:** ${session.agentName}\\n` +\n `**Workspace:** \\`${session.workingDirectory}\\`\\n\\n` +\n `This is your coding session — chat here to work with the agent.`,\n components: [controlRow],\n })\n\n // Reply to the interaction with a link to the thread\n const replyMsg = `✅ Session created → [Open thread](https://discord.com/channels/${adapter.getGuildId()}/${thread.id})`\n if (interaction.deferred || interaction.replied) {\n await interaction.editReply(replyMsg)\n } else {\n await (interaction as ChatInputCommandInteraction).reply({ content: replyMsg, ephemeral: true })\n }\n\n // Warm up model cache in background\n session.warmup().catch((err: unknown) => log.error({ err }, '[discord-new-session] Warm-up error'))\n } catch (err) {\n log.error({ err }, '[discord-new-session] Session creation failed')\n\n // Clean up orphaned thread on failure (archive+lock instead of permanent delete)\n if (thread) {\n try { await deleteSessionThread(adapter.getGuild(), thread.id) } catch { /* ignore */ }\n }\n\n const errMsg = `❌ ${err instanceof Error ? err.message : String(err)}`\n try {\n if (interaction.deferred || interaction.replied) {\n await interaction.editReply(errMsg)\n } else {\n await (interaction as ChatInputCommandInteraction).reply({ content: errMsg, ephemeral: true })\n }\n } catch { /* ignore */ }\n }\n}\n\nexport async function handleNewSessionButton(\n interaction: ButtonInteraction,\n adapter: DiscordAdapter,\n): Promise<void> {\n const { customId } = interaction\n\n if (customId.startsWith('m:new:agent:')) {\n const agentKey = customId.replace('m:new:agent:', '')\n try { await interaction.deferUpdate() } catch { /* ignore */ }\n await executeNewSession(interaction, adapter, agentKey, undefined)\n }\n}\n"],"mappings":"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","names":[]}
@@ -500,15 +500,38 @@ async function setupRunMode(stepNum = 3, totalSteps = 3) {
500
500
  }
501
501
  return { runMode: "foreground", autoStart: false };
502
502
  }
503
- function printWelcomeBanner() {
504
- console.log(`
505
- ${c.cyan}${c.bold} \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
506
- \u2551 Welcome to OpenACP \u2551
507
- \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D${c.reset}
503
+ function applyGradient(text) {
504
+ const colors = [135, 99, 63, 33, 39, 44, 44];
505
+ const lines = text.split("\n");
506
+ return lines.map((line, i) => {
507
+ const colorIdx = Math.min(i, colors.length - 1);
508
+ return `\x1B[38;5;${colors[colorIdx]}m${line}\x1B[0m`;
509
+ }).join("\n");
510
+ }
511
+ var BANNER = `
512
+ \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557
513
+ \u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557
514
+ \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D
515
+ \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2550\u255D
516
+ \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551
517
+ \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D
518
+ `;
519
+ async function printStartBanner() {
520
+ let version = "0.0.0";
521
+ try {
522
+ const { getCurrentVersion } = await import("./version-ALWGGVKM.js");
523
+ version = getCurrentVersion();
524
+ } catch {
525
+ }
526
+ console.log(applyGradient(BANNER));
527
+ console.log(`${c.dim} AI coding agents, anywhere. v${version}${c.reset}
508
528
  `);
509
529
  }
530
+ async function printWelcomeBanner() {
531
+ await printStartBanner();
532
+ }
510
533
  async function runSetup(configManager) {
511
- printWelcomeBanner();
534
+ await printWelcomeBanner();
512
535
  try {
513
536
  const { select: selectChannel } = await import("@inquirer/prompts");
514
537
  const channelChoice = await selectChannel({
@@ -541,7 +564,7 @@ async function runSetup(configManager) {
541
564
  });
542
565
  if (installClaude) {
543
566
  try {
544
- const { getIntegration } = await import("./integrate-QTK4PPYQ.js");
567
+ const { getIntegration } = await import("./integrate-O4OCR4SN.js");
545
568
  const integration = getIntegration("claude");
546
569
  if (integration) {
547
570
  for (const item of integration.items) {
@@ -621,20 +644,6 @@ async function runSetup(configManager) {
621
644
  console.log(
622
645
  ok(`Config saved to ${c.bold}${configManager.getConfigPath()}`)
623
646
  );
624
- if (config.tunnel.enabled && config.tunnel.provider === "cloudflare") {
625
- console.log(dim(" Ensuring cloudflared is installed..."));
626
- try {
627
- const { ensureCloudflared } = await import("./install-cloudflared-BTGUD7SW.js");
628
- const binPath = await ensureCloudflared();
629
- console.log(ok(`cloudflared ready at ${dim(binPath)}`));
630
- } catch (err) {
631
- console.log(
632
- warn(
633
- `Could not install cloudflared: ${err.message}. Tunnel may not work.`
634
- )
635
- );
636
- }
637
- }
638
647
  console.log(ok("Starting OpenACP..."));
639
648
  console.log("");
640
649
  return true;
@@ -659,6 +668,7 @@ export {
659
668
  setupAgents,
660
669
  setupWorkspace,
661
670
  setupRunMode,
671
+ printStartBanner,
662
672
  runSetup
663
673
  };
664
- //# sourceMappingURL=chunk-7WQH4SOY.js.map
674
+ //# sourceMappingURL=chunk-G3OHCXZG.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\";\nimport type { DiscordChannelConfig } from \"../adapters/discord/types.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, total: number, title: string) =>\n `\\n${c.cyan}${c.bold}[${n}/${total}]${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(stepNum = 1, totalSteps = 3): Promise<Config[\"channels\"][string]> {\n console.log(step(stepNum, totalSteps, \"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\n// --- Discord validation ---\n\nexport async function validateDiscordToken(token: string): Promise<\n | { ok: true; username: string; id: string }\n | { ok: false; error: string }\n> {\n try {\n const res = await fetch(\"https://discord.com/api/v10/users/@me\", {\n headers: { Authorization: `Bot ${token}` },\n });\n if (res.status === 200) {\n const data = (await res.json()) as { username: string; id: string };\n return { ok: true, username: data.username, id: data.id };\n }\n if (res.status === 401) {\n return { ok: false, error: \"Token rejected by Discord (401 Unauthorized)\" };\n }\n return { ok: false, error: `Discord API returned ${res.status}` };\n } catch (err) {\n return { ok: false, error: (err as Error).message };\n }\n}\n\nexport async function setupDiscord(): Promise<DiscordChannelConfig> {\n console.log('\\n📱 Discord Setup\\n');\n\n console.log(` ${c.bold}Quick setup:${c.reset}`);\n console.log(dim(' 1. Create app at https://discord.com/developers/applications'));\n console.log(dim(' 2. Go to Bot → Reset Token → copy it'));\n console.log(dim(' 3. Enable Message Content Intent (Bot → Privileged Intents)'));\n console.log(dim(' 4. OAuth2 → URL Generator → scopes: bot + applications.commands'));\n console.log(dim(' 5. Bot Permissions: Manage Channels, Send Messages, Manage Threads, Attach Files'));\n console.log(dim(' 6. Open generated URL → invite bot to your server'));\n console.log('');\n console.log(dim(` 📖 Detailed guide: https://github.com/Open-ACP/OpenACP/blob/main/docs/guide/discord-setup.md`));\n console.log('');\n\n let botToken = '';\n\n while (true) {\n botToken = await input({\n message: 'Bot token (from Discord Developer Portal):',\n validate: (val) => val.trim().length > 0 || 'Token cannot be empty',\n });\n botToken = botToken.trim();\n\n const result = await validateDiscordToken(botToken);\n if (result.ok) {\n console.log(ok(`Connected as @${result.username} (id: ${result.id})`));\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 const guildId = await input({\n message: 'Guild (server) ID:',\n validate: (val) => {\n const trimmed = val.trim();\n if (!trimmed) return 'Guild ID cannot be empty';\n if (!/^\\d{17,20}$/.test(trimmed)) return 'Guild ID must be a numeric Discord snowflake (17-20 digits)';\n return true;\n },\n });\n\n return {\n enabled: true,\n botToken,\n guildId: guildId.trim(),\n forumChannelId: null,\n notificationChannelId: null,\n assistantThreadId: 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(stepNum = 2, totalSteps = 3): Promise<{ baseDir: string }> {\n console.log(step(stepNum, totalSteps, \"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(stepNum = 3, totalSteps = 3): Promise<{ runMode: 'foreground' | 'daemon'; autoStart: boolean }> {\n console.log(step(stepNum, totalSteps, '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 applyGradient(text: string): string {\n // Purple → indigo → blue → cyan gradient using ANSI 256 colors\n const colors = [135, 99, 63, 33, 39, 44, 44];\n const lines = text.split(\"\\n\");\n return lines\n .map((line, i) => {\n const colorIdx = Math.min(i, colors.length - 1);\n return `\\x1b[38;5;${colors[colorIdx]}m${line}\\x1b[0m`;\n })\n .join(\"\\n\");\n}\n\nconst BANNER = `\n ██████╗ ██████╗ ███████╗███╗ ██╗ █████╗ ██████╗██████╗\n ██╔═══██╗██╔══██╗██╔════╝████╗ ██║██╔══██╗██╔════╝██╔══██╗\n ██║ ██║██████╔╝█████╗ ██╔██╗ ██║███████║██║ ██████╔╝\n ██║ ██║██╔═══╝ ██╔══╝ ██║╚██╗██║██╔══██║██║ ██╔═══╝\n ╚██████╔╝██║ ███████╗██║ ╚████║██║ ██║╚██████╗██║\n ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝╚═╝ ╚═╝ ╚═════╝╚═╝\n`;\n\n/** Compact banner for normal startup (foreground mode) */\nexport async function printStartBanner(): Promise<void> {\n let version = \"0.0.0\";\n try {\n const { getCurrentVersion } = await import(\"../cli/version.js\");\n version = getCurrentVersion();\n } catch {\n // ignore\n }\n console.log(applyGradient(BANNER));\n console.log(`${c.dim} AI coding agents, anywhere. v${version}${c.reset}\\n`);\n}\n\nasync function printWelcomeBanner(): Promise<void> {\n await printStartBanner();\n}\n\nexport async function runSetup(configManager: ConfigManager): Promise<boolean> {\n await printWelcomeBanner();\n\n try {\n const { select: selectChannel } = await import(\"@inquirer/prompts\");\n const channelChoice = await selectChannel({\n message: 'Which messaging platform do you want to use?',\n choices: [\n { name: 'Telegram', value: 'telegram' },\n { name: 'Discord', value: 'discord' },\n { name: 'Both', value: 'both' },\n ],\n });\n\n let telegram: Config[\"channels\"][string] | undefined;\n let discord: DiscordChannelConfig | undefined;\n\n // Calculate total steps dynamically: channel(s) + workspace + run mode\n const channelSteps = channelChoice === 'both' ? 2 : 1;\n const totalSteps = channelSteps + 2; // + workspace + run mode\n\n let currentStep = 0;\n\n if (channelChoice === 'telegram' || channelChoice === 'both') {\n currentStep++;\n telegram = await setupTelegram(currentStep, totalSteps);\n }\n if (channelChoice === 'discord' || channelChoice === 'both') {\n currentStep++;\n discord = await setupDiscord();\n }\n\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 currentStep++;\n const workspace = await setupWorkspace(currentStep, totalSteps);\n currentStep++;\n const { runMode, autoStart } = await setupRunMode(currentStep, totalSteps);\n const security = {\n allowedUserIds: [] as string[],\n maxConcurrentSessions: 20,\n sessionTimeoutMinutes: 60,\n };\n\n const channels: Config[\"channels\"] = {};\n if (telegram) channels.telegram = telegram;\n // DiscordChannelConfig is structurally compatible with the base channel schema\n if (discord) channels.discord = discord as Config[\"channels\"][string];\n\n const config: Config = {\n channels,\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 maxUserTunnels: 5,\n storeTtlMinutes: 60,\n auth: { enabled: false },\n },\n usage: {\n enabled: true,\n warningThreshold: 0.8,\n currency: \"USD\",\n retentionDays: 90,\n },\n integrations: {},\n speech: {\n stt: { provider: null, providers: {} },\n tts: { provider: null, providers: {} },\n },\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 // Dependencies (cloudflared, etc.) will be installed by post-upgrade check on first start\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"]}
@@ -5,7 +5,7 @@ import {
5
5
  } from "./chunk-FMWSVLRM.js";
6
6
  import {
7
7
  DoctorEngine
8
- } from "./chunk-WQZ4RXH7.js";
8
+ } from "./chunk-OHR6SBMC.js";
9
9
  import {
10
10
  buildMenuKeyboard,
11
11
  buildSkillMessages,
@@ -2328,8 +2328,11 @@ var OpenACPCore = class {
2328
2328
  );
2329
2329
  const speechConfig = config.speech ?? {
2330
2330
  stt: { provider: null, providers: {} },
2331
- tts: { provider: null, providers: {} }
2331
+ tts: { provider: "edge-tts", providers: {} }
2332
2332
  };
2333
+ if (speechConfig.tts.provider == null) {
2334
+ speechConfig.tts.provider = "edge-tts";
2335
+ }
2333
2336
  this.speechService = new SpeechService(speechConfig);
2334
2337
  const groqConfig = speechConfig.stt?.providers?.groq;
2335
2338
  if (groqConfig?.apiKey) {
@@ -2338,8 +2341,8 @@ var OpenACPCore = class {
2338
2341
  new GroqSTT(groqConfig.apiKey, groqConfig.model)
2339
2342
  );
2340
2343
  }
2341
- if (speechConfig.tts?.provider === "edge-tts") {
2342
- const edgeConfig = speechConfig.tts.providers?.["edge-tts"];
2344
+ {
2345
+ const edgeConfig = speechConfig.tts?.providers?.["edge-tts"];
2343
2346
  const voice = edgeConfig?.voice;
2344
2347
  this.speechService.registerTTSProvider("edge-tts", new EdgeTTS(voice));
2345
2348
  }
@@ -2371,9 +2374,8 @@ var OpenACPCore = class {
2371
2374
  new GroqSTT(groqCfg.apiKey, groqCfg.model)
2372
2375
  );
2373
2376
  }
2374
- const ttsCfg = newSpeechConfig.tts;
2375
- if (ttsCfg?.provider === "edge-tts") {
2376
- const edgeConfig = ttsCfg.providers?.["edge-tts"];
2377
+ {
2378
+ const edgeConfig = newSpeechConfig.tts?.providers?.["edge-tts"];
2377
2379
  const voice = edgeConfig?.voice;
2378
2380
  this.speechService.registerTTSProvider("edge-tts", new EdgeTTS(voice));
2379
2381
  }
@@ -3968,9 +3970,12 @@ async function renameSessionTopic(bot, chatId, threadId, name) {
3968
3970
  async function deleteSessionTopic(bot, chatId, threadId) {
3969
3971
  await bot.api.deleteForumTopic(chatId, threadId);
3970
3972
  }
3971
- function buildDeepLink(chatId, messageId) {
3973
+ function buildDeepLink(chatId, threadId, messageId) {
3972
3974
  const cleanId = String(chatId).replace("-100", "");
3973
- return `https://t.me/c/${cleanId}/${messageId}`;
3975
+ if (messageId && messageId !== threadId) {
3976
+ return `https://t.me/c/${cleanId}/${threadId}/${messageId}`;
3977
+ }
3978
+ return `https://t.me/c/${cleanId}/${threadId}`;
3974
3979
  }
3975
3980
 
3976
3981
  // src/adapters/telegram/commands/new-session.ts
@@ -4169,12 +4174,6 @@ function splitMessage(text, maxLength = 3800) {
4169
4174
  // src/adapters/telegram/commands/admin.ts
4170
4175
  import { InlineKeyboard } from "grammy";
4171
4176
  var log12 = createChildLogger({ module: "telegram-cmd-admin" });
4172
- function buildDangerousModeKeyboard(sessionId, enabled) {
4173
- return new InlineKeyboard().text(
4174
- enabled ? "\u{1F510} Disable Dangerous Mode" : "\u2620\uFE0F Enable Dangerous Mode",
4175
- `d:${sessionId}`
4176
- );
4177
- }
4178
4177
  function setupDangerousModeCallbacks(bot, core) {
4179
4178
  bot.callbackQuery(/^d:/, async (ctx) => {
4180
4179
  const sessionId = ctx.callbackQuery.data.slice(2);
@@ -4191,7 +4190,7 @@ function setupDangerousModeCallbacks(bot, core) {
4191
4190
  }
4192
4191
  try {
4193
4192
  await ctx.editMessageReplyMarkup({
4194
- reply_markup: buildDangerousModeKeyboard(sessionId, session.dangerousMode)
4193
+ reply_markup: buildSessionControlKeyboard(sessionId, session.dangerousMode, session.voiceMode === "on")
4195
4194
  });
4196
4195
  } catch {
4197
4196
  }
@@ -4216,7 +4215,7 @@ function setupDangerousModeCallbacks(bot, core) {
4216
4215
  }
4217
4216
  try {
4218
4217
  await ctx.editMessageReplyMarkup({
4219
- reply_markup: buildDangerousModeKeyboard(sessionId, newDangerousMode)
4218
+ reply_markup: buildSessionControlKeyboard(sessionId, newDangerousMode, false)
4220
4219
  });
4221
4220
  } catch {
4222
4221
  }
@@ -4293,7 +4292,7 @@ function buildSessionControlKeyboard(sessionId, dangerousMode, voiceMode) {
4293
4292
  return new InlineKeyboard().text(
4294
4293
  dangerousMode ? "\u{1F510} Disable Dangerous Mode" : "\u2620\uFE0F Enable Dangerous Mode",
4295
4294
  `d:${sessionId}`
4296
- ).text(
4295
+ ).row().text(
4297
4296
  voiceMode ? "\u{1F50A} Text to Speech" : "\u{1F507} Text to Speech",
4298
4297
  `v:${sessionId}`
4299
4298
  );
@@ -5351,7 +5350,7 @@ Downloading... ${bar} ${percent}%`, { parse_mode: "HTML" });
5351
5350
  const { getAgentCapabilities: getAgentCapabilities2 } = await import("./agent-dependencies-QY5QSULV.js");
5352
5351
  const caps = getAgentCapabilities2(result.agentKey);
5353
5352
  if (caps.integration) {
5354
- const { installIntegration } = await import("./integrate-QTK4PPYQ.js");
5353
+ const { installIntegration } = await import("./integrate-O4OCR4SN.js");
5355
5354
  const intResult = await installIntegration(result.agentKey, caps.integration);
5356
5355
  if (intResult.success) {
5357
5356
  try {
@@ -5421,7 +5420,7 @@ function buildProgressBar(percent) {
5421
5420
  // src/adapters/telegram/commands/integrate.ts
5422
5421
  import { InlineKeyboard as InlineKeyboard5 } from "grammy";
5423
5422
  async function handleIntegrate(ctx, _core) {
5424
- const { listIntegrations } = await import("./integrate-QTK4PPYQ.js");
5423
+ const { listIntegrations } = await import("./integrate-O4OCR4SN.js");
5425
5424
  const agents = listIntegrations();
5426
5425
  const keyboard = new InlineKeyboard5();
5427
5426
  for (const agent of agents) {
@@ -5454,7 +5453,7 @@ function setupIntegrateCallbacks(bot, core) {
5454
5453
  } catch {
5455
5454
  }
5456
5455
  if (data === "i:back") {
5457
- const { listIntegrations } = await import("./integrate-QTK4PPYQ.js");
5456
+ const { listIntegrations } = await import("./integrate-O4OCR4SN.js");
5458
5457
  const agents = listIntegrations();
5459
5458
  const keyboard2 = new InlineKeyboard5();
5460
5459
  for (const agent of agents) {
@@ -5474,7 +5473,7 @@ Select an agent to manage its integrations.`,
5474
5473
  const agentMatch = data.match(/^i:agent:(.+)$/);
5475
5474
  if (agentMatch) {
5476
5475
  const agentName2 = agentMatch[1];
5477
- const { getIntegration: getIntegration2 } = await import("./integrate-QTK4PPYQ.js");
5476
+ const { getIntegration: getIntegration2 } = await import("./integrate-O4OCR4SN.js");
5478
5477
  const integration2 = getIntegration2(agentName2);
5479
5478
  if (!integration2) {
5480
5479
  await ctx.reply(`\u274C No integration available for '${escapeHtml(agentName2)}'.`, { parse_mode: "HTML" });
@@ -5501,7 +5500,7 @@ ${integration2.items.map((i) => `\u2022 <b>${escapeHtml(i.name)}</b> \u2014 ${es
5501
5500
  const action = actionMatch[1];
5502
5501
  const agentName = actionMatch[2];
5503
5502
  const itemId = actionMatch[3];
5504
- const { getIntegration } = await import("./integrate-QTK4PPYQ.js");
5503
+ const { getIntegration } = await import("./integrate-O4OCR4SN.js");
5505
5504
  const integration = getIntegration(agentName);
5506
5505
  if (!integration) return;
5507
5506
  const item = integration.items.find((i) => i.id === itemId);
@@ -6143,7 +6142,7 @@ ${escapeHtml(request.description)}`,
6143
6142
  disable_notification: false
6144
6143
  }
6145
6144
  );
6146
- const deepLink = buildDeepLink(this.chatId, msg.message_id);
6145
+ const deepLink = buildDeepLink(this.chatId, threadId, msg.message_id);
6147
6146
  void this.sendNotification({
6148
6147
  sessionId: session.id,
6149
6148
  sessionName: session.name,
@@ -6826,7 +6825,8 @@ function setupActionCallbacks(bot, core, chatId, getAssistantSessionId) {
6826
6825
  action.agent,
6827
6826
  action.workspace
6828
6827
  );
6829
- const topicLink = `https://t.me/c/${String(chatId).replace("-100", "")}/${firstMsgId ?? threadId}`;
6828
+ const cleanId = String(chatId).replace("-100", "");
6829
+ const topicLink = firstMsgId ? `https://t.me/c/${cleanId}/${threadId}/${firstMsgId}` : `https://t.me/c/${cleanId}/${threadId}`;
6830
6830
  const originalText = ctx.callbackQuery.message?.text ?? "";
6831
6831
  try {
6832
6832
  await ctx.editMessageText(
@@ -7774,7 +7774,7 @@ var TelegramAdapter = class extends ChannelAdapter {
7774
7774
  const chatIdStr = String(this.telegramConfig.chatId);
7775
7775
  const numericId = chatIdStr.startsWith("-100") ? chatIdStr.slice(4) : chatIdStr.replace("-", "");
7776
7776
  const usageMsgId = tracker.getUsageMsgId();
7777
- const deepLink = `https://t.me/c/${numericId}/${usageMsgId ?? ctx.threadId}`;
7777
+ const deepLink = usageMsgId ? `https://t.me/c/${numericId}/${ctx.threadId}/${usageMsgId}` : `https://t.me/c/${numericId}/${ctx.threadId}`;
7778
7778
  const text = `\u2705 <b>${escapeHtml(sessionName)}</b>
7779
7779
  Task completed.
7780
7780
 
@@ -8117,4 +8117,4 @@ export {
8117
8117
  TopicManager,
8118
8118
  TelegramAdapter
8119
8119
  };
8120
- //# sourceMappingURL=chunk-IFTYEG5J.js.map
8120
+ //# sourceMappingURL=chunk-HP2IJYCA.js.map