@openacp/cli 0.2.17 → 0.2.19
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.
- package/dist/{chunk-E6BM7RUB.js → chunk-HTXK4NLG.js} +541 -80
- package/dist/chunk-HTXK4NLG.js.map +1 -0
- package/dist/{chunk-QY32F5S7.js → chunk-XOVJLTEC.js} +49 -7
- package/dist/chunk-XOVJLTEC.js.map +1 -0
- package/dist/cli.js +4 -2
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +73 -23
- package/dist/index.js +2 -2
- package/dist/{main-OAVE4LUW.js → main-WH6JJXBY.js} +5 -5
- package/dist/{setup-GIUUMBDH.js → setup-FB4DGR6R.js} +12 -3
- package/dist/setup-FB4DGR6R.js.map +1 -0
- package/dist/{tunnel-service-FPRPBPQ5.js → tunnel-service-I6NUMBT4.js} +263 -15
- package/dist/tunnel-service-I6NUMBT4.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-E6BM7RUB.js.map +0 -1
- package/dist/chunk-QY32F5S7.js.map +0 -1
- package/dist/setup-GIUUMBDH.js.map +0 -1
- package/dist/tunnel-service-FPRPBPQ5.js.map +0 -1
- /package/dist/{main-OAVE4LUW.js.map → main-WH6JJXBY.js.map} +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ interface IncomingMessage {
|
|
|
10
10
|
text: string;
|
|
11
11
|
}
|
|
12
12
|
interface OutgoingMessage {
|
|
13
|
-
type:
|
|
13
|
+
type: "text" | "thought" | "tool_call" | "tool_update" | "plan" | "usage" | "session_end" | "error";
|
|
14
14
|
text: string;
|
|
15
15
|
metadata?: Record<string, unknown>;
|
|
16
16
|
}
|
|
@@ -27,7 +27,7 @@ interface PermissionOption {
|
|
|
27
27
|
interface NotificationMessage {
|
|
28
28
|
sessionId: string;
|
|
29
29
|
sessionName?: string;
|
|
30
|
-
type:
|
|
30
|
+
type: "completed" | "error" | "permission" | "input_required";
|
|
31
31
|
summary: string;
|
|
32
32
|
deepLink?: string;
|
|
33
33
|
}
|
|
@@ -37,13 +37,13 @@ interface AgentCommand {
|
|
|
37
37
|
input?: unknown;
|
|
38
38
|
}
|
|
39
39
|
type AgentEvent = {
|
|
40
|
-
type:
|
|
40
|
+
type: "text";
|
|
41
41
|
content: string;
|
|
42
42
|
} | {
|
|
43
|
-
type:
|
|
43
|
+
type: "thought";
|
|
44
44
|
content: string;
|
|
45
45
|
} | {
|
|
46
|
-
type:
|
|
46
|
+
type: "tool_call";
|
|
47
47
|
id: string;
|
|
48
48
|
name: string;
|
|
49
49
|
kind?: string;
|
|
@@ -51,16 +51,16 @@ type AgentEvent = {
|
|
|
51
51
|
content?: unknown;
|
|
52
52
|
locations?: unknown;
|
|
53
53
|
} | {
|
|
54
|
-
type:
|
|
54
|
+
type: "tool_update";
|
|
55
55
|
id: string;
|
|
56
56
|
status: string;
|
|
57
57
|
content?: unknown;
|
|
58
58
|
locations?: unknown;
|
|
59
59
|
} | {
|
|
60
|
-
type:
|
|
60
|
+
type: "plan";
|
|
61
61
|
entries: PlanEntry[];
|
|
62
62
|
} | {
|
|
63
|
-
type:
|
|
63
|
+
type: "usage";
|
|
64
64
|
tokensUsed?: number;
|
|
65
65
|
contextSize?: number;
|
|
66
66
|
cost?: {
|
|
@@ -68,19 +68,19 @@ type AgentEvent = {
|
|
|
68
68
|
currency: string;
|
|
69
69
|
};
|
|
70
70
|
} | {
|
|
71
|
-
type:
|
|
71
|
+
type: "commands_update";
|
|
72
72
|
commands: AgentCommand[];
|
|
73
73
|
} | {
|
|
74
|
-
type:
|
|
74
|
+
type: "session_end";
|
|
75
75
|
reason: string;
|
|
76
76
|
} | {
|
|
77
|
-
type:
|
|
77
|
+
type: "error";
|
|
78
78
|
message: string;
|
|
79
79
|
};
|
|
80
80
|
interface PlanEntry {
|
|
81
81
|
content: string;
|
|
82
|
-
status:
|
|
83
|
-
priority:
|
|
82
|
+
status: "pending" | "in_progress" | "completed";
|
|
83
|
+
priority: "high" | "medium" | "low";
|
|
84
84
|
}
|
|
85
85
|
interface AgentDefinition {
|
|
86
86
|
name: string;
|
|
@@ -89,7 +89,22 @@ interface AgentDefinition {
|
|
|
89
89
|
workingDirectory?: string;
|
|
90
90
|
env?: Record<string, string>;
|
|
91
91
|
}
|
|
92
|
-
type SessionStatus =
|
|
92
|
+
type SessionStatus = "initializing" | "active" | "cancelled" | "finished" | "error";
|
|
93
|
+
interface SessionRecord<P = Record<string, unknown>> {
|
|
94
|
+
sessionId: string;
|
|
95
|
+
agentSessionId: string;
|
|
96
|
+
agentName: string;
|
|
97
|
+
workingDir: string;
|
|
98
|
+
channelId: string;
|
|
99
|
+
status: SessionStatus;
|
|
100
|
+
createdAt: string;
|
|
101
|
+
lastActiveAt: string;
|
|
102
|
+
name?: string;
|
|
103
|
+
platform: P;
|
|
104
|
+
}
|
|
105
|
+
interface TelegramPlatformData {
|
|
106
|
+
topicId: number;
|
|
107
|
+
}
|
|
93
108
|
|
|
94
109
|
declare const PLUGINS_DIR: string;
|
|
95
110
|
declare const LoggingSchema: z.ZodDefault<z.ZodObject<{
|
|
@@ -115,7 +130,7 @@ type LoggingConfig = z.infer<typeof LoggingSchema>;
|
|
|
115
130
|
declare const TunnelSchema: z.ZodDefault<z.ZodObject<{
|
|
116
131
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
117
132
|
port: z.ZodDefault<z.ZodNumber>;
|
|
118
|
-
provider: z.ZodDefault<z.ZodEnum<["cloudflare", "ngrok", "bore"]>>;
|
|
133
|
+
provider: z.ZodDefault<z.ZodEnum<["cloudflare", "ngrok", "bore", "tailscale"]>>;
|
|
119
134
|
options: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
120
135
|
storeTtlMinutes: z.ZodDefault<z.ZodNumber>;
|
|
121
136
|
auth: z.ZodDefault<z.ZodObject<{
|
|
@@ -132,7 +147,7 @@ declare const TunnelSchema: z.ZodDefault<z.ZodObject<{
|
|
|
132
147
|
options: Record<string, unknown>;
|
|
133
148
|
enabled: boolean;
|
|
134
149
|
port: number;
|
|
135
|
-
provider: "cloudflare" | "ngrok" | "bore";
|
|
150
|
+
provider: "cloudflare" | "ngrok" | "bore" | "tailscale";
|
|
136
151
|
storeTtlMinutes: number;
|
|
137
152
|
auth: {
|
|
138
153
|
enabled: boolean;
|
|
@@ -142,7 +157,7 @@ declare const TunnelSchema: z.ZodDefault<z.ZodObject<{
|
|
|
142
157
|
options?: Record<string, unknown> | undefined;
|
|
143
158
|
enabled?: boolean | undefined;
|
|
144
159
|
port?: number | undefined;
|
|
145
|
-
provider?: "cloudflare" | "ngrok" | "bore" | undefined;
|
|
160
|
+
provider?: "cloudflare" | "ngrok" | "bore" | "tailscale" | undefined;
|
|
146
161
|
storeTtlMinutes?: number | undefined;
|
|
147
162
|
auth?: {
|
|
148
163
|
enabled?: boolean | undefined;
|
|
@@ -217,10 +232,17 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
217
232
|
maxFiles?: number | undefined;
|
|
218
233
|
sessionLogRetentionDays?: number | undefined;
|
|
219
234
|
}>>;
|
|
235
|
+
sessionStore: z.ZodDefault<z.ZodObject<{
|
|
236
|
+
ttlDays: z.ZodDefault<z.ZodNumber>;
|
|
237
|
+
}, "strip", z.ZodTypeAny, {
|
|
238
|
+
ttlDays: number;
|
|
239
|
+
}, {
|
|
240
|
+
ttlDays?: number | undefined;
|
|
241
|
+
}>>;
|
|
220
242
|
tunnel: z.ZodDefault<z.ZodObject<{
|
|
221
243
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
222
244
|
port: z.ZodDefault<z.ZodNumber>;
|
|
223
|
-
provider: z.ZodDefault<z.ZodEnum<["cloudflare", "ngrok", "bore"]>>;
|
|
245
|
+
provider: z.ZodDefault<z.ZodEnum<["cloudflare", "ngrok", "bore", "tailscale"]>>;
|
|
224
246
|
options: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
225
247
|
storeTtlMinutes: z.ZodDefault<z.ZodNumber>;
|
|
226
248
|
auth: z.ZodDefault<z.ZodObject<{
|
|
@@ -237,7 +259,7 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
237
259
|
options: Record<string, unknown>;
|
|
238
260
|
enabled: boolean;
|
|
239
261
|
port: number;
|
|
240
|
-
provider: "cloudflare" | "ngrok" | "bore";
|
|
262
|
+
provider: "cloudflare" | "ngrok" | "bore" | "tailscale";
|
|
241
263
|
storeTtlMinutes: number;
|
|
242
264
|
auth: {
|
|
243
265
|
enabled: boolean;
|
|
@@ -247,7 +269,7 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
247
269
|
options?: Record<string, unknown> | undefined;
|
|
248
270
|
enabled?: boolean | undefined;
|
|
249
271
|
port?: number | undefined;
|
|
250
|
-
provider?: "cloudflare" | "ngrok" | "bore" | undefined;
|
|
272
|
+
provider?: "cloudflare" | "ngrok" | "bore" | "tailscale" | undefined;
|
|
251
273
|
storeTtlMinutes?: number | undefined;
|
|
252
274
|
auth?: {
|
|
253
275
|
enabled?: boolean | undefined;
|
|
@@ -281,11 +303,14 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
281
303
|
maxFiles: number;
|
|
282
304
|
sessionLogRetentionDays: number;
|
|
283
305
|
};
|
|
306
|
+
sessionStore: {
|
|
307
|
+
ttlDays: number;
|
|
308
|
+
};
|
|
284
309
|
tunnel: {
|
|
285
310
|
options: Record<string, unknown>;
|
|
286
311
|
enabled: boolean;
|
|
287
312
|
port: number;
|
|
288
|
-
provider: "cloudflare" | "ngrok" | "bore";
|
|
313
|
+
provider: "cloudflare" | "ngrok" | "bore" | "tailscale";
|
|
289
314
|
storeTtlMinutes: number;
|
|
290
315
|
auth: {
|
|
291
316
|
enabled: boolean;
|
|
@@ -319,11 +344,14 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
319
344
|
maxFiles?: number | undefined;
|
|
320
345
|
sessionLogRetentionDays?: number | undefined;
|
|
321
346
|
} | undefined;
|
|
347
|
+
sessionStore?: {
|
|
348
|
+
ttlDays?: number | undefined;
|
|
349
|
+
} | undefined;
|
|
322
350
|
tunnel?: {
|
|
323
351
|
options?: Record<string, unknown> | undefined;
|
|
324
352
|
enabled?: boolean | undefined;
|
|
325
353
|
port?: number | undefined;
|
|
326
|
-
provider?: "cloudflare" | "ngrok" | "bore" | undefined;
|
|
354
|
+
provider?: "cloudflare" | "ngrok" | "bore" | "tailscale" | undefined;
|
|
327
355
|
storeTtlMinutes?: number | undefined;
|
|
328
356
|
auth?: {
|
|
329
357
|
enabled?: boolean | undefined;
|
|
@@ -413,7 +441,10 @@ declare class AgentInstance {
|
|
|
413
441
|
onSessionUpdate: (event: AgentEvent) => void;
|
|
414
442
|
onPermissionRequest: (request: PermissionRequest) => Promise<string>;
|
|
415
443
|
private constructor();
|
|
444
|
+
private static spawnSubprocess;
|
|
445
|
+
private setupCrashDetection;
|
|
416
446
|
static spawn(agentDef: AgentDefinition, workingDirectory: string): Promise<AgentInstance>;
|
|
447
|
+
static resume(agentDef: AgentDefinition, workingDirectory: string, agentSessionId: string): Promise<AgentInstance>;
|
|
417
448
|
private createClient;
|
|
418
449
|
prompt(text: string): Promise<PromptResponse>;
|
|
419
450
|
cancel(): Promise<void>;
|
|
@@ -426,6 +457,7 @@ declare class AgentManager {
|
|
|
426
457
|
getAvailableAgents(): AgentDefinition[];
|
|
427
458
|
getAgent(name: string): AgentDefinition | undefined;
|
|
428
459
|
spawn(agentName: string, workingDirectory: string): Promise<AgentInstance>;
|
|
460
|
+
resume(agentName: string, workingDirectory: string, agentSessionId: string): Promise<AgentInstance>;
|
|
429
461
|
}
|
|
430
462
|
|
|
431
463
|
declare class Session {
|
|
@@ -435,6 +467,7 @@ declare class Session {
|
|
|
435
467
|
agentName: string;
|
|
436
468
|
workingDirectory: string;
|
|
437
469
|
agentInstance: AgentInstance;
|
|
470
|
+
agentSessionId: string;
|
|
438
471
|
status: SessionStatus;
|
|
439
472
|
name?: string;
|
|
440
473
|
promptQueue: string[];
|
|
@@ -462,11 +495,25 @@ declare class Session {
|
|
|
462
495
|
destroy(): Promise<void>;
|
|
463
496
|
}
|
|
464
497
|
|
|
498
|
+
interface SessionStore {
|
|
499
|
+
save(record: SessionRecord): Promise<void>;
|
|
500
|
+
get(sessionId: string): SessionRecord | undefined;
|
|
501
|
+
findByPlatform(channelId: string, predicate: (platform: Record<string, unknown>) => boolean): SessionRecord | undefined;
|
|
502
|
+
list(channelId?: string): SessionRecord[];
|
|
503
|
+
remove(sessionId: string): Promise<void>;
|
|
504
|
+
}
|
|
505
|
+
|
|
465
506
|
declare class SessionManager {
|
|
466
507
|
private sessions;
|
|
508
|
+
private store;
|
|
509
|
+
constructor(store?: SessionStore | null);
|
|
467
510
|
createSession(channelId: string, agentName: string, workingDirectory: string, agentManager: AgentManager): Promise<Session>;
|
|
468
511
|
getSession(sessionId: string): Session | undefined;
|
|
469
512
|
getSessionByThread(channelId: string, threadId: string): Session | undefined;
|
|
513
|
+
registerSession(session: Session): void;
|
|
514
|
+
updateSessionPlatform(sessionId: string, platform: Record<string, unknown>): Promise<void>;
|
|
515
|
+
updateSessionActivity(sessionId: string): Promise<void>;
|
|
516
|
+
updateSessionStatus(sessionId: string, status: SessionStatus): Promise<void>;
|
|
470
517
|
cancelSession(sessionId: string): Promise<void>;
|
|
471
518
|
listSessions(channelId?: string): Session[];
|
|
472
519
|
destroyAll(): Promise<void>;
|
|
@@ -521,6 +568,8 @@ declare class OpenACPCore {
|
|
|
521
568
|
notificationManager: NotificationManager;
|
|
522
569
|
adapters: Map<string, ChannelAdapter>;
|
|
523
570
|
tunnelService?: TunnelService;
|
|
571
|
+
private sessionStore;
|
|
572
|
+
private resumeLocks;
|
|
524
573
|
constructor(configManager: ConfigManager);
|
|
525
574
|
registerAdapter(name: string, adapter: ChannelAdapter): void;
|
|
526
575
|
start(): Promise<void>;
|
|
@@ -528,6 +577,7 @@ declare class OpenACPCore {
|
|
|
528
577
|
handleMessage(message: IncomingMessage): Promise<void>;
|
|
529
578
|
handleNewSession(channelId: string, agentName?: string, workspacePath?: string): Promise<Session>;
|
|
530
579
|
handleNewChat(channelId: string, currentThreadId: string): Promise<Session | null>;
|
|
580
|
+
private lazyResume;
|
|
531
581
|
private toOutgoingMessage;
|
|
532
582
|
private enrichWithViewerLinks;
|
|
533
583
|
wireSessionEvents(session: Session, adapter: ChannelAdapter): void;
|
|
@@ -575,4 +625,4 @@ declare class TelegramAdapter extends ChannelAdapter {
|
|
|
575
625
|
private finalizeDraft;
|
|
576
626
|
}
|
|
577
627
|
|
|
578
|
-
export { type AdapterFactory, type AgentCommand, type AgentDefinition, type AgentEvent, AgentInstance, AgentManager, ChannelAdapter, type ChannelConfig, type Config, ConfigManager, type IncomingMessage, type Logger, type LoggingConfig, NotificationManager, type NotificationMessage, OpenACPCore, type OutgoingMessage, PLUGINS_DIR, type PermissionOption, type PermissionRequest, type PlanEntry, Session, SessionManager, type SessionStatus, StderrCapture, TelegramAdapter, cleanupOldSessionLogs, createChildLogger, createSessionLogger, expandHome, initLogger, installPlugin, listPlugins, loadAdapterFactory, log, nodeToWebReadable, nodeToWebWritable, shutdownLogger, uninstallPlugin };
|
|
628
|
+
export { type AdapterFactory, type AgentCommand, type AgentDefinition, type AgentEvent, AgentInstance, AgentManager, ChannelAdapter, type ChannelConfig, type Config, ConfigManager, type IncomingMessage, type Logger, type LoggingConfig, NotificationManager, type NotificationMessage, OpenACPCore, type OutgoingMessage, PLUGINS_DIR, type PermissionOption, type PermissionRequest, type PlanEntry, Session, SessionManager, type SessionRecord, type SessionStatus, StderrCapture, TelegramAdapter, type TelegramPlatformData, cleanupOldSessionLogs, createChildLogger, createSessionLogger, expandHome, initLogger, installPlugin, listPlugins, loadAdapterFactory, log, nodeToWebReadable, nodeToWebWritable, shutdownLogger, uninstallPlugin };
|
package/dist/index.js
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
TelegramAdapter,
|
|
11
11
|
nodeToWebReadable,
|
|
12
12
|
nodeToWebWritable
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-HTXK4NLG.js";
|
|
14
14
|
import {
|
|
15
15
|
ConfigManager,
|
|
16
16
|
PLUGINS_DIR,
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
listPlugins,
|
|
20
20
|
loadAdapterFactory,
|
|
21
21
|
uninstallPlugin
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-XOVJLTEC.js";
|
|
23
23
|
import {
|
|
24
24
|
cleanupOldSessionLogs,
|
|
25
25
|
createChildLogger,
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
import {
|
|
3
3
|
OpenACPCore,
|
|
4
4
|
TelegramAdapter
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-HTXK4NLG.js";
|
|
6
6
|
import {
|
|
7
7
|
ConfigManager,
|
|
8
8
|
loadAdapterFactory
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-XOVJLTEC.js";
|
|
10
10
|
import {
|
|
11
11
|
cleanupOldSessionLogs,
|
|
12
12
|
initLogger,
|
|
@@ -20,7 +20,7 @@ async function startServer() {
|
|
|
20
20
|
const configManager = new ConfigManager();
|
|
21
21
|
const configExists = await configManager.exists();
|
|
22
22
|
if (!configExists) {
|
|
23
|
-
const { runSetup } = await import("./setup-
|
|
23
|
+
const { runSetup } = await import("./setup-FB4DGR6R.js");
|
|
24
24
|
const shouldStart = await runSetup(configManager);
|
|
25
25
|
if (!shouldStart) process.exit(0);
|
|
26
26
|
}
|
|
@@ -34,7 +34,7 @@ async function startServer() {
|
|
|
34
34
|
const core = new OpenACPCore(configManager);
|
|
35
35
|
let tunnelService;
|
|
36
36
|
if (config.tunnel.enabled) {
|
|
37
|
-
const { TunnelService } = await import("./tunnel-service-
|
|
37
|
+
const { TunnelService } = await import("./tunnel-service-I6NUMBT4.js");
|
|
38
38
|
tunnelService = new TunnelService(config.tunnel);
|
|
39
39
|
const publicUrl = await tunnelService.start();
|
|
40
40
|
core.tunnelService = tunnelService;
|
|
@@ -100,4 +100,4 @@ if (isDirectExecution) {
|
|
|
100
100
|
export {
|
|
101
101
|
startServer
|
|
102
102
|
};
|
|
103
|
-
//# sourceMappingURL=main-
|
|
103
|
+
//# sourceMappingURL=main-WH6JJXBY.js.map
|
|
@@ -174,7 +174,8 @@ async function detectChatId(token) {
|
|
|
174
174
|
}
|
|
175
175
|
}
|
|
176
176
|
var KNOWN_AGENTS = [
|
|
177
|
-
{ name: "claude", commands: ["claude-agent-acp"] }
|
|
177
|
+
{ name: "claude", commands: ["claude-agent-acp", "claude-code", "claude"] },
|
|
178
|
+
{ name: "codex", commands: ["codex"] }
|
|
178
179
|
];
|
|
179
180
|
function commandExists(cmd) {
|
|
180
181
|
try {
|
|
@@ -306,7 +307,15 @@ async function runSetup(configManager) {
|
|
|
306
307
|
maxFiles: 7,
|
|
307
308
|
sessionLogRetentionDays: 30
|
|
308
309
|
},
|
|
309
|
-
|
|
310
|
+
sessionStore: { ttlDays: 30 },
|
|
311
|
+
tunnel: {
|
|
312
|
+
enabled: false,
|
|
313
|
+
port: 3100,
|
|
314
|
+
provider: "cloudflare",
|
|
315
|
+
options: {},
|
|
316
|
+
storeTtlMinutes: 60,
|
|
317
|
+
auth: { enabled: false }
|
|
318
|
+
}
|
|
310
319
|
};
|
|
311
320
|
try {
|
|
312
321
|
await configManager.writeNew(config);
|
|
@@ -341,4 +350,4 @@ export {
|
|
|
341
350
|
validateBotToken,
|
|
342
351
|
validateChatId
|
|
343
352
|
};
|
|
344
|
-
//# sourceMappingURL=setup-
|
|
353
|
+
//# sourceMappingURL=setup-FB4DGR6R.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/setup.ts"],"sourcesContent":["import { execFileSync } from \"node:child_process\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { input, select } from \"@inquirer/prompts\";\nimport type { Config, ConfigManager } from \"./config.js\";\n\n// --- ANSI colors ---\n\nconst c = {\n reset: \"\\x1b[0m\",\n bold: \"\\x1b[1m\",\n dim: \"\\x1b[2m\",\n green: \"\\x1b[32m\",\n yellow: \"\\x1b[33m\",\n red: \"\\x1b[31m\",\n cyan: \"\\x1b[36m\",\n white: \"\\x1b[37m\",\n};\n\nconst ok = (msg: string) =>\n `${c.green}${c.bold}✓${c.reset} ${c.green}${msg}${c.reset}`;\nconst warn = (msg: string) => `${c.yellow}⚠ ${msg}${c.reset}`;\nconst fail = (msg: string) => `${c.red}✗ ${msg}${c.reset}`;\nconst step = (n: number, title: string) =>\n `\\n${c.cyan}${c.bold}[${n}/3]${c.reset} ${c.bold}${title}${c.reset}\\n`;\nconst dim = (msg: string) => `${c.dim}${msg}${c.reset}`;\n\n// --- Telegram validation ---\n\nexport async function validateBotToken(\n token: string,\n): Promise<\n | { ok: true; botName: string; botUsername: string }\n | { ok: false; error: string }\n> {\n try {\n const res = await fetch(`https://api.telegram.org/bot${token}/getMe`);\n const data = (await res.json()) as {\n ok: boolean;\n result?: { first_name: string; username: string };\n description?: string;\n };\n if (data.ok && data.result) {\n return {\n ok: true,\n botName: data.result.first_name,\n botUsername: data.result.username,\n };\n }\n return { ok: false, error: data.description || \"Invalid token\" };\n } catch (err) {\n return { ok: false, error: (err as Error).message };\n }\n}\n\nexport async function validateChatId(\n token: string,\n chatId: number,\n): Promise<\n { ok: true; title: string; isForum: boolean } | { ok: false; error: string }\n> {\n try {\n const res = await fetch(`https://api.telegram.org/bot${token}/getChat`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ chat_id: chatId }),\n });\n const data = (await res.json()) as {\n ok: boolean;\n result?: { title: string; type: string; is_forum?: boolean };\n description?: string;\n };\n if (!data.ok || !data.result) {\n return { ok: false, error: data.description || \"Invalid chat ID\" };\n }\n if (data.result.type !== \"supergroup\") {\n return {\n ok: false,\n error: `Chat is \"${data.result.type}\", must be a supergroup`,\n };\n }\n return {\n ok: true,\n title: data.result.title,\n isForum: data.result.is_forum === true,\n };\n } catch (err) {\n return { ok: false, error: (err as Error).message };\n }\n}\n\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 { name: \"claude\", commands: [\"claude-agent-acp\", \"claude-code\", \"claude\"] },\n { name: \"codex\", commands: [\"codex\"] },\n];\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 // Check node_modules/.bin (walks up from cwd)\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 async function detectAgents(): Promise<\n Array<{ name: string; command: string }>\n> {\n const found: Array<{ name: string; command: string }> = [];\n for (const agent of KNOWN_AGENTS) {\n // Find all available commands for this agent (PATH + node_modules/.bin)\n const available: string[] = [];\n for (const cmd of agent.commands) {\n if (commandExists(cmd)) {\n available.push(cmd);\n }\n }\n if (available.length > 0) {\n // Prefer claude-agent-acp over claude/claude-code (priority order)\n found.push({ name: agent.name, command: available[0] });\n }\n }\n return found;\n}\n\nexport async function validateAgentCommand(command: string): Promise<boolean> {\n try {\n execFileSync(\"which\", [command], { stdio: \"pipe\" });\n return true;\n } catch {\n return false;\n }\n}\n\n// --- Setup steps ---\n\nexport async function setupTelegram(): Promise<Config[\"channels\"][string]> {\n console.log(step(1, \"Telegram Bot\"));\n\n let botToken = \"\";\n\n while (true) {\n botToken = await input({\n message: \"Bot token (from @BotFather):\",\n validate: (val) => val.trim().length > 0 || \"Token cannot be empty\",\n });\n botToken = botToken.trim();\n\n const result = await validateBotToken(botToken);\n if (result.ok) {\n console.log(ok(`Connected to @${result.botUsername}`));\n break;\n }\n console.log(fail(result.error));\n const action = await select({\n message: \"What to do?\",\n choices: [\n { name: \"Re-enter token\", value: \"retry\" },\n { name: \"Use as-is (skip validation)\", value: \"skip\" },\n ],\n });\n if (action === \"skip\") break;\n }\n\n console.log(step(2, \"Group Chat\"));\n\n const chatId = await detectChatId(botToken);\n\n return {\n enabled: true,\n botToken,\n chatId,\n notificationTopicId: null,\n assistantTopicId: null,\n };\n}\n\nexport async function setupAgents(): Promise<{\n agents: Config[\"agents\"];\n defaultAgent: string;\n}> {\n const detected = await detectAgents();\n const agents: Config[\"agents\"] = {};\n\n if (detected.length > 0) {\n for (const agent of detected) {\n agents[agent.name] = { command: agent.command, args: [], env: {} };\n }\n } else {\n agents[\"claude\"] = { command: \"claude-agent-acp\", args: [], env: {} };\n }\n\n const defaultAgent = Object.keys(agents)[0];\n const agentCmd = agents[defaultAgent].command;\n console.log(\n ok(`Agent: ${c.bold}${defaultAgent}${c.reset}${c.green} (${agentCmd})`),\n );\n\n return { agents, defaultAgent };\n}\n\nexport async function setupWorkspace(): Promise<{ baseDir: string }> {\n console.log(step(3, \"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\n// --- Orchestrator ---\n\nfunction printWelcomeBanner(): void {\n console.log(`\n${c.cyan}${c.bold} ╔══════════════════════════════╗\n ║ Welcome to OpenACP ║\n ╚══════════════════════════════╝${c.reset}\n`);\n}\n\nexport async function runSetup(configManager: ConfigManager): Promise<boolean> {\n printWelcomeBanner();\n\n try {\n const telegram = await setupTelegram();\n const { agents, defaultAgent } = await setupAgents();\n const workspace = await setupWorkspace();\n const security = {\n allowedUserIds: [] as string[],\n maxConcurrentSessions: 5,\n sessionTimeoutMinutes: 60,\n };\n\n const config: Config = {\n channels: { telegram },\n agents,\n defaultAgent,\n workspace,\n security,\n logging: {\n level: \"info\",\n logDir: \"~/.openacp/logs\",\n maxFileSize: \"10m\",\n maxFiles: 7,\n sessionLogRetentionDays: 30,\n },\n sessionStore: { ttlDays: 30 },\n tunnel: {\n enabled: false,\n port: 3100,\n provider: \"cloudflare\",\n options: {},\n storeTtlMinutes: 60,\n auth: { enabled: false },\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 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":[]}
|