@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,735 +0,0 @@
1
- import {
2
- commandExists
3
- } from "./chunk-JKBFUAJK.js";
4
- import {
5
- expandHome
6
- } from "./chunk-33RP6K2O.js";
7
-
8
- // src/core/setup.ts
9
- import { execFileSync } from "child_process";
10
- import * as clack from "@clack/prompts";
11
- function guardCancel(value) {
12
- if (clack.isCancel(value)) {
13
- clack.cancel("Setup cancelled.");
14
- process.exit(0);
15
- }
16
- return value;
17
- }
18
- var c = {
19
- reset: "\x1B[0m",
20
- bold: "\x1B[1m",
21
- dim: "\x1B[2m",
22
- green: "\x1B[32m",
23
- yellow: "\x1B[33m",
24
- red: "\x1B[31m",
25
- cyan: "\x1B[36m",
26
- white: "\x1B[37m"
27
- };
28
- var ok = (msg) => `${c.green}${c.bold}\u2713${c.reset} ${c.green}${msg}${c.reset}`;
29
- var warn = (msg) => `${c.yellow}\u26A0 ${msg}${c.reset}`;
30
- var fail = (msg) => `${c.red}\u2717 ${msg}${c.reset}`;
31
- var step = (n, total, title) => `
32
- ${c.cyan}${c.bold}[${n}/${total}]${c.reset} ${c.bold}${title}${c.reset}
33
- `;
34
- var dim = (msg) => `${c.dim}${msg}${c.reset}`;
35
- async function validateBotToken(token) {
36
- try {
37
- const res = await fetch(`https://api.telegram.org/bot${token}/getMe`);
38
- const data = await res.json();
39
- if (data.ok && data.result) {
40
- return {
41
- ok: true,
42
- botName: data.result.first_name,
43
- botUsername: data.result.username
44
- };
45
- }
46
- return { ok: false, error: data.description || "Invalid token" };
47
- } catch (err) {
48
- return { ok: false, error: err.message };
49
- }
50
- }
51
- async function validateChatId(token, chatId) {
52
- try {
53
- const res = await fetch(`https://api.telegram.org/bot${token}/getChat`, {
54
- method: "POST",
55
- headers: { "Content-Type": "application/json" },
56
- body: JSON.stringify({ chat_id: chatId })
57
- });
58
- const data = await res.json();
59
- if (!data.ok || !data.result) {
60
- return { ok: false, error: data.description || "Invalid chat ID" };
61
- }
62
- if (data.result.type !== "supergroup") {
63
- return {
64
- ok: false,
65
- error: `Chat is "${data.result.type}", must be a supergroup`
66
- };
67
- }
68
- return {
69
- ok: true,
70
- title: data.result.title,
71
- isForum: data.result.is_forum === true
72
- };
73
- } catch (err) {
74
- return { ok: false, error: err.message };
75
- }
76
- }
77
- async function validateBotAdmin(token, chatId) {
78
- try {
79
- const meRes = await fetch(`https://api.telegram.org/bot${token}/getMe`);
80
- const meData = await meRes.json();
81
- if (!meData.ok || !meData.result) {
82
- return { ok: false, error: "Could not retrieve bot info" };
83
- }
84
- const res = await fetch(
85
- `https://api.telegram.org/bot${token}/getChatMember`,
86
- {
87
- method: "POST",
88
- headers: { "Content-Type": "application/json" },
89
- body: JSON.stringify({ chat_id: chatId, user_id: meData.result.id })
90
- }
91
- );
92
- const data = await res.json();
93
- if (!data.ok || !data.result) {
94
- return {
95
- ok: false,
96
- error: data.description || "Could not check bot membership"
97
- };
98
- }
99
- const { status } = data.result;
100
- if (status === "administrator" || status === "creator") {
101
- return { ok: true };
102
- }
103
- return {
104
- ok: false,
105
- error: `Bot is "${status}" in this group. It must be an admin. Please promote the bot to admin in group settings.`
106
- };
107
- } catch (err) {
108
- return { ok: false, error: err.message };
109
- }
110
- }
111
- async function promptManualChatId() {
112
- const val = guardCancel(
113
- await clack.text({
114
- message: "Supergroup chat ID (e.g. -1001234567890):",
115
- validate: (val2) => {
116
- const n = Number((val2 ?? "").toString().trim());
117
- if (isNaN(n) || !Number.isInteger(n)) return "Chat ID must be an integer";
118
- return void 0;
119
- }
120
- })
121
- );
122
- return Number(val.trim());
123
- }
124
- async function detectChatId(token) {
125
- let lastUpdateId = 0;
126
- try {
127
- const clearRes = await fetch(
128
- `https://api.telegram.org/bot${token}/getUpdates?offset=-1`
129
- );
130
- const clearData = await clearRes.json();
131
- if (clearData.ok && clearData.result?.length) {
132
- lastUpdateId = clearData.result[clearData.result.length - 1].update_id;
133
- }
134
- } catch {
135
- }
136
- console.log("");
137
- console.log(` ${c.bold}If you don't have a supergroup yet:${c.reset}`);
138
- console.log(dim(" 1. Open Telegram \u2192 New Group \u2192 add your bot"));
139
- console.log(dim(" 2. Group Settings \u2192 convert to Supergroup"));
140
- console.log(dim(" 3. Enable Topics in group settings"));
141
- console.log("");
142
- console.log(` ${c.bold}Then send "hi" in the group.${c.reset}`);
143
- console.log(
144
- dim(
145
- ` Listening... press ${c.reset}${c.yellow}m${c.reset}${c.dim} to enter ID manually`
146
- )
147
- );
148
- console.log("");
149
- const MAX_ATTEMPTS = 120;
150
- const POLL_INTERVAL = 1e3;
151
- let cancelled = false;
152
- const onKeypress = (data) => {
153
- const key = data.toString();
154
- if (key === "m" || key === "M") {
155
- cancelled = true;
156
- }
157
- };
158
- if (process.stdin.isTTY) {
159
- process.stdin.setRawMode(true);
160
- process.stdin.resume();
161
- process.stdin.on("data", onKeypress);
162
- }
163
- const cleanup = () => {
164
- if (process.stdin.isTTY) {
165
- process.stdin.removeListener("data", onKeypress);
166
- process.stdin.setRawMode(false);
167
- process.stdin.pause();
168
- }
169
- };
170
- try {
171
- for (let i = 0; i < MAX_ATTEMPTS; i++) {
172
- if (cancelled) {
173
- cleanup();
174
- return promptManualChatId();
175
- }
176
- try {
177
- const offset = lastUpdateId ? lastUpdateId + 1 : 0;
178
- const res = await fetch(
179
- `https://api.telegram.org/bot${token}/getUpdates?offset=${offset}&timeout=1`
180
- );
181
- const data = await res.json();
182
- if (!data.ok || !data.result?.length) {
183
- await new Promise((r) => setTimeout(r, POLL_INTERVAL));
184
- continue;
185
- }
186
- const groups = /* @__PURE__ */ new Map();
187
- for (const update of data.result) {
188
- lastUpdateId = update.update_id;
189
- const chat = update.message?.chat ?? update.my_chat_member?.chat;
190
- if (chat && (chat.type === "supergroup" || chat.type === "group")) {
191
- groups.set(chat.id, chat.title ?? String(chat.id));
192
- }
193
- }
194
- if (groups.size === 1) {
195
- const [id, title] = [...groups.entries()][0];
196
- console.log(
197
- ok(`Group detected: ${c.bold}${title}${c.reset}${c.green} (${id})`)
198
- );
199
- cleanup();
200
- return id;
201
- }
202
- if (groups.size > 1) {
203
- cleanup();
204
- const options = [...groups.entries()].map(([id, title]) => ({
205
- label: `${title} (${id})`,
206
- value: id
207
- }));
208
- return guardCancel(
209
- await clack.select({
210
- message: "Multiple groups found. Pick one:",
211
- options
212
- })
213
- );
214
- }
215
- } catch {
216
- }
217
- await new Promise((r) => setTimeout(r, POLL_INTERVAL));
218
- }
219
- console.log(warn("Timed out waiting for messages."));
220
- cleanup();
221
- return promptManualChatId();
222
- } catch (err) {
223
- cleanup();
224
- throw err;
225
- }
226
- }
227
- var KNOWN_AGENTS = [
228
- // claude-agent-acp is bundled as a dependency — no detection needed, but
229
- // kept here so detectAgents() still returns it for display purposes.
230
- { name: "claude", commands: ["claude-agent-acp"] },
231
- { name: "codex", commands: ["codex"] }
232
- ];
233
- async function detectAgents() {
234
- const found = [];
235
- for (const agent of KNOWN_AGENTS) {
236
- const available = [];
237
- for (const cmd of agent.commands) {
238
- if (commandExists(cmd)) {
239
- available.push(cmd);
240
- }
241
- }
242
- if (available.length > 0) {
243
- found.push({ name: agent.name, command: available[0] });
244
- }
245
- }
246
- return found;
247
- }
248
- async function validateAgentCommand(command) {
249
- try {
250
- execFileSync("which", [command], { stdio: "pipe" });
251
- return true;
252
- } catch {
253
- return false;
254
- }
255
- }
256
- async function setupTelegram(stepNum = 1, totalSteps = 3) {
257
- console.log(step(stepNum, totalSteps, "Telegram Bot"));
258
- let botToken = "";
259
- while (true) {
260
- botToken = guardCancel(
261
- await clack.text({
262
- message: "Bot token (from @BotFather):",
263
- validate: (val) => (val ?? "").toString().trim().length > 0 ? void 0 : "Token cannot be empty"
264
- })
265
- );
266
- botToken = botToken.trim();
267
- const s = clack.spinner();
268
- s.start("Validating token...");
269
- const result = await validateBotToken(botToken);
270
- s.stop("Token validated");
271
- if (result.ok) {
272
- console.log(ok(`Connected to @${result.botUsername}`));
273
- break;
274
- }
275
- console.log(fail(result.error));
276
- const action = guardCancel(
277
- await clack.select({
278
- message: "What to do?",
279
- options: [
280
- { label: "Re-enter token", value: "retry" },
281
- { label: "Use as-is (skip validation)", value: "skip" }
282
- ]
283
- })
284
- );
285
- if (action === "skip") break;
286
- }
287
- let chatId;
288
- while (true) {
289
- chatId = await detectChatId(botToken);
290
- const chatResult = await validateChatId(botToken, chatId);
291
- if (!chatResult.ok) {
292
- console.log(fail(chatResult.error));
293
- console.log("");
294
- console.log(` ${c.bold}How to fix:${c.reset}`);
295
- console.log(dim(" 1. Make sure the bot is added to the group"));
296
- console.log(dim(" 2. The group must be a Supergroup (Group Settings \u2192 convert)"));
297
- console.log(dim(" 3. Send a message in the group after adding the bot"));
298
- console.log("");
299
- guardCancel(await clack.text({ message: "Press Enter to try again..." }));
300
- continue;
301
- }
302
- console.log(
303
- ok(
304
- `Group: ${c.bold}${chatResult.title}${c.reset}${c.green}${chatResult.isForum ? " (Topics enabled)" : ""}`
305
- )
306
- );
307
- const adminResult = await validateBotAdmin(botToken, chatId);
308
- if (!adminResult.ok) {
309
- console.log(fail(adminResult.error));
310
- console.log("");
311
- console.log(` ${c.bold}How to fix:${c.reset}`);
312
- console.log(dim(" 1. Open the group in Telegram"));
313
- console.log(dim(" 2. Go to Group Settings \u2192 Administrators"));
314
- console.log(dim(" 3. Add the bot as an administrator"));
315
- console.log("");
316
- guardCancel(await clack.text({ message: "Press Enter to check again..." }));
317
- continue;
318
- }
319
- console.log(ok("Bot has admin privileges"));
320
- break;
321
- }
322
- return {
323
- enabled: true,
324
- botToken,
325
- chatId,
326
- notificationTopicId: null,
327
- assistantTopicId: null
328
- };
329
- }
330
- async function validateDiscordToken(token) {
331
- try {
332
- const res = await fetch("https://discord.com/api/v10/users/@me", {
333
- headers: { Authorization: `Bot ${token}` }
334
- });
335
- if (res.status === 200) {
336
- const data = await res.json();
337
- return { ok: true, username: data.username, id: data.id };
338
- }
339
- if (res.status === 401) {
340
- return { ok: false, error: "Token rejected by Discord (401 Unauthorized)" };
341
- }
342
- return { ok: false, error: `Discord API returned ${res.status}` };
343
- } catch (err) {
344
- return { ok: false, error: err.message };
345
- }
346
- }
347
- async function setupDiscord() {
348
- console.log("\n\u{1F4F1} Discord Setup\n");
349
- console.log(` ${c.bold}Quick setup:${c.reset}`);
350
- console.log(dim(" 1. Create app at https://discord.com/developers/applications"));
351
- console.log(dim(" 2. Go to Bot \u2192 Reset Token \u2192 copy it"));
352
- console.log(dim(" 3. Enable Message Content Intent (Bot \u2192 Privileged Intents)"));
353
- console.log(dim(" 4. OAuth2 \u2192 URL Generator \u2192 scopes: bot + applications.commands"));
354
- console.log(dim(" 5. Bot Permissions: Manage Channels, Send Messages, Manage Threads, Attach Files"));
355
- console.log(dim(" 6. Open generated URL \u2192 invite bot to your server"));
356
- console.log("");
357
- console.log(dim(` \u{1F4D6} Detailed guide: https://github.com/Open-ACP/OpenACP/blob/main/docs/guide/discord-setup.md`));
358
- console.log("");
359
- let botToken = "";
360
- while (true) {
361
- botToken = guardCancel(
362
- await clack.text({
363
- message: "Bot token (from Discord Developer Portal):",
364
- validate: (val) => (val ?? "").toString().trim().length > 0 ? void 0 : "Token cannot be empty"
365
- })
366
- );
367
- botToken = botToken.trim();
368
- const s = clack.spinner();
369
- s.start("Validating token...");
370
- const result = await validateDiscordToken(botToken);
371
- s.stop("Token validated");
372
- if (result.ok) {
373
- console.log(ok(`Connected as @${result.username} (id: ${result.id})`));
374
- break;
375
- }
376
- console.log(fail(result.error));
377
- const action = guardCancel(
378
- await clack.select({
379
- message: "What to do?",
380
- options: [
381
- { label: "Re-enter token", value: "retry" },
382
- { label: "Use as-is (skip validation)", value: "skip" }
383
- ]
384
- })
385
- );
386
- if (action === "skip") break;
387
- }
388
- const guildId = guardCancel(
389
- await clack.text({
390
- message: "Guild (server) ID:",
391
- validate: (val) => {
392
- const trimmed = (val ?? "").toString().trim();
393
- if (!trimmed) return "Guild ID cannot be empty";
394
- if (!/^\d{17,20}$/.test(trimmed)) return "Guild ID must be a numeric Discord snowflake (17-20 digits)";
395
- return void 0;
396
- }
397
- })
398
- );
399
- return {
400
- enabled: true,
401
- botToken,
402
- guildId: guildId.trim(),
403
- forumChannelId: null,
404
- notificationChannelId: null,
405
- assistantThreadId: null
406
- };
407
- }
408
- async function setupAgents() {
409
- const { AgentCatalog } = await import("./agent-catalog-FC3HGDEQ.js");
410
- const { muteLogger, unmuteLogger } = await import("./log-NXABYJTT.js");
411
- muteLogger();
412
- const catalog = new AgentCatalog();
413
- catalog.load();
414
- const s = clack.spinner();
415
- s.start("Checking available agents...");
416
- await catalog.refreshRegistryIfStale();
417
- if (!catalog.getInstalledAgent("claude")) {
418
- const claudeRegistry = catalog.findRegistryAgent("claude-acp");
419
- if (claudeRegistry) {
420
- await catalog.install("claude-acp");
421
- } else {
422
- const { AgentStore } = await import("./agent-store-VZLFPTZU.js");
423
- const store = new AgentStore();
424
- store.load();
425
- store.addAgent("claude", {
426
- registryId: "claude-acp",
427
- name: "Claude Agent",
428
- version: "bundled",
429
- distribution: "npx",
430
- command: "npx",
431
- args: ["@zed-industries/claude-agent-acp"],
432
- env: {},
433
- installedAt: (/* @__PURE__ */ new Date()).toISOString(),
434
- binaryPath: null
435
- });
436
- }
437
- }
438
- s.stop(ok("Claude Agent ready"));
439
- unmuteLogger();
440
- const available = catalog.getAvailable();
441
- const installed = available.filter((a) => a.installed);
442
- const installable = available.filter((a) => !a.installed && a.available);
443
- if (installed.length > 0 || installable.length > 0) {
444
- const seen = /* @__PURE__ */ new Set();
445
- const options = [];
446
- for (const a of installed) {
447
- const dedupeKey = `${a.key}::${a.name}`;
448
- if (seen.has(dedupeKey)) continue;
449
- seen.add(dedupeKey);
450
- options.push({
451
- label: `${a.name} (installed)`,
452
- value: a.key
453
- });
454
- }
455
- for (const a of installable) {
456
- const dedupeKey = `${a.key}::${a.name}`;
457
- if (seen.has(dedupeKey)) continue;
458
- seen.add(dedupeKey);
459
- options.push({
460
- label: `${a.name} (${a.distribution})`,
461
- value: a.key
462
- });
463
- }
464
- const installedKeys = installed.map((a) => a.key);
465
- const selected = guardCancel(
466
- await clack.autocompleteMultiselect({
467
- message: "Install additional agents? (type to search, Space to select)",
468
- options,
469
- initialValues: installedKeys,
470
- required: false
471
- })
472
- );
473
- for (const key of selected) {
474
- const regAgent = catalog.findRegistryAgent(key);
475
- if (regAgent) {
476
- const installSpinner = clack.spinner();
477
- installSpinner.start(`Installing ${regAgent.name}...`);
478
- muteLogger();
479
- const result = await catalog.install(key);
480
- unmuteLogger();
481
- if (result.ok) {
482
- installSpinner.stop(ok("done"));
483
- } else {
484
- installSpinner.stop(warn(`skipped: ${result.error}`));
485
- }
486
- }
487
- }
488
- }
489
- const installedAgents = Object.keys(catalog.getInstalledEntries());
490
- let defaultAgent = "claude";
491
- if (installedAgents.length > 1) {
492
- defaultAgent = guardCancel(
493
- await clack.select({
494
- message: "Which agent should be the default?",
495
- options: installedAgents.map((key) => {
496
- const agent = catalog.getInstalledAgent(key);
497
- return { label: `${agent.name} (${key})`, value: key };
498
- }),
499
- initialValue: "claude"
500
- })
501
- );
502
- }
503
- console.log(ok(`Default agent: ${c.bold}${defaultAgent}${c.reset}`));
504
- return { defaultAgent };
505
- }
506
- async function setupWorkspace(stepNum = 2, totalSteps = 3) {
507
- console.log(step(stepNum, totalSteps, "Workspace"));
508
- const baseDir = guardCancel(
509
- await clack.text({
510
- message: "Base directory for workspaces:",
511
- initialValue: "~/openacp-workspace",
512
- validate: (val) => (val ?? "").toString().trim().length > 0 ? void 0 : "Path cannot be empty"
513
- })
514
- );
515
- return { baseDir: baseDir.trim().replace(/^['"]|['"]$/g, "") };
516
- }
517
- async function setupRunMode(stepNum = 3, totalSteps = 3) {
518
- console.log(step(stepNum, totalSteps, "Run Mode"));
519
- if (process.platform === "win32") {
520
- console.log(dim(" (Daemon mode not available on Windows)"));
521
- return { runMode: "foreground", autoStart: false };
522
- }
523
- const mode = guardCancel(
524
- await clack.select({
525
- message: "How would you like to run OpenACP?",
526
- options: [
527
- {
528
- label: "Background (daemon)",
529
- value: "daemon",
530
- hint: "Runs silently, auto-starts on boot. Manage with: openacp status | stop | logs"
531
- },
532
- {
533
- label: "Foreground (terminal)",
534
- value: "foreground",
535
- hint: "Runs in current terminal session. Start with: openacp"
536
- }
537
- ]
538
- })
539
- );
540
- if (mode === "daemon") {
541
- const { installAutoStart, isAutoStartSupported } = await import("./autostart-X33OGMX6.js");
542
- const autoStart = isAutoStartSupported();
543
- if (autoStart) {
544
- const result = installAutoStart(expandHome("~/.openacp/logs"));
545
- if (result.success) {
546
- console.log(ok("Auto-start on boot enabled"));
547
- } else {
548
- console.log(warn(`Auto-start failed: ${result.error}`));
549
- }
550
- }
551
- return { runMode: "daemon", autoStart };
552
- }
553
- return { runMode: "foreground", autoStart: false };
554
- }
555
- function applyGradient(text2) {
556
- const colors = [135, 99, 63, 33, 39, 44, 44];
557
- const lines = text2.split("\n");
558
- return lines.map((line, i) => {
559
- const colorIdx = Math.min(i, colors.length - 1);
560
- return `\x1B[38;5;${colors[colorIdx]}m${line}\x1B[0m`;
561
- }).join("\n");
562
- }
563
- var BANNER = `
564
- \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
565
- \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
566
- \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
567
- \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
568
- \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
569
- \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
570
- `;
571
- async function printStartBanner() {
572
- let version = "0.0.0";
573
- try {
574
- const { getCurrentVersion } = await import("./version-NQZBM5M7.js");
575
- version = getCurrentVersion();
576
- } catch {
577
- }
578
- console.log(applyGradient(BANNER));
579
- console.log(`${c.dim} AI coding agents, anywhere. v${version}${c.reset}
580
- `);
581
- }
582
- async function printWelcomeBanner() {
583
- await printStartBanner();
584
- }
585
- async function runSetup(configManager, opts) {
586
- await printWelcomeBanner();
587
- clack.intro("Let's set up OpenACP");
588
- try {
589
- const channelChoice = guardCancel(
590
- await clack.select({
591
- message: "Which messaging platform do you want to use?",
592
- options: [
593
- { label: "Telegram", value: "telegram" },
594
- { label: "Discord", value: "discord" },
595
- { label: "Both", value: "both" }
596
- ]
597
- })
598
- );
599
- let telegram;
600
- let discord;
601
- const channelSteps = channelChoice === "both" ? 2 : 1;
602
- const runModeSteps = opts?.skipRunMode ? 0 : 1;
603
- const totalSteps = channelSteps + 1 + runModeSteps;
604
- let currentStep = 0;
605
- if (channelChoice === "telegram" || channelChoice === "both") {
606
- currentStep++;
607
- telegram = await setupTelegram(currentStep, totalSteps);
608
- }
609
- if (channelChoice === "discord" || channelChoice === "both") {
610
- currentStep++;
611
- discord = await setupDiscord();
612
- }
613
- const { defaultAgent } = await setupAgents();
614
- {
615
- const installClaude = guardCancel(
616
- await clack.confirm({
617
- message: "Install session transfer for Claude? (enables /openacp:handoff in your terminal)",
618
- initialValue: true
619
- })
620
- );
621
- if (installClaude) {
622
- try {
623
- const { getIntegration } = await import("./integrate-PNEHRY2I.js");
624
- const integration = getIntegration("claude");
625
- if (integration) {
626
- for (const item of integration.items) {
627
- const result = await item.install();
628
- for (const log of result.logs) console.log(` ${log}`);
629
- }
630
- }
631
- console.log("Claude CLI integration installed.\n");
632
- } catch (err) {
633
- console.log(`Could not install Claude CLI integration: ${err instanceof Error ? err.message : err}`);
634
- console.log(" You can install it later with: openacp integrate claude\n");
635
- }
636
- }
637
- }
638
- currentStep++;
639
- const workspace = await setupWorkspace(currentStep, totalSteps);
640
- let runMode = "foreground";
641
- let autoStart = false;
642
- if (!opts?.skipRunMode) {
643
- currentStep++;
644
- const result = await setupRunMode(currentStep, totalSteps);
645
- runMode = result.runMode;
646
- autoStart = result.autoStart;
647
- }
648
- const security = {
649
- allowedUserIds: [],
650
- maxConcurrentSessions: 20,
651
- sessionTimeoutMinutes: 60
652
- };
653
- const channels = {};
654
- if (telegram) channels.telegram = telegram;
655
- if (discord) channels.discord = discord;
656
- const config = {
657
- channels,
658
- agents: {},
659
- defaultAgent,
660
- workspace,
661
- security,
662
- logging: {
663
- level: "info",
664
- logDir: "~/.openacp/logs",
665
- maxFileSize: "10m",
666
- maxFiles: 7,
667
- sessionLogRetentionDays: 30
668
- },
669
- runMode,
670
- autoStart,
671
- api: {
672
- port: 21420,
673
- host: "127.0.0.1"
674
- },
675
- sessionStore: { ttlDays: 30 },
676
- tunnel: {
677
- enabled: true,
678
- port: 3100,
679
- provider: "cloudflare",
680
- options: {},
681
- maxUserTunnels: 5,
682
- storeTtlMinutes: 60,
683
- auth: { enabled: false }
684
- },
685
- usage: {
686
- enabled: true,
687
- warningThreshold: 0.8,
688
- currency: "USD",
689
- retentionDays: 90
690
- },
691
- integrations: {},
692
- speech: {
693
- stt: { provider: null, providers: {} },
694
- tts: { provider: null, providers: {} }
695
- }
696
- };
697
- try {
698
- await configManager.writeNew(config);
699
- } catch (writeErr) {
700
- console.log(
701
- fail(`Could not save config: ${writeErr.message}`)
702
- );
703
- return false;
704
- }
705
- clack.outro(`Config saved to ${configManager.getConfigPath()}`);
706
- if (!opts?.skipRunMode) {
707
- console.log(ok("Starting OpenACP..."));
708
- console.log("");
709
- }
710
- return true;
711
- } catch (err) {
712
- if (err.name === "ExitPromptError") {
713
- clack.cancel("Setup cancelled.");
714
- return false;
715
- }
716
- throw err;
717
- }
718
- }
719
-
720
- export {
721
- validateBotToken,
722
- validateChatId,
723
- validateBotAdmin,
724
- detectAgents,
725
- validateAgentCommand,
726
- setupTelegram,
727
- validateDiscordToken,
728
- setupDiscord,
729
- setupAgents,
730
- setupWorkspace,
731
- setupRunMode,
732
- printStartBanner,
733
- runSetup
734
- };
735
- //# sourceMappingURL=chunk-BDYVCIBH.js.map