@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.
- package/README.md +116 -152
- package/dist/cli.d.ts +11 -0
- package/dist/cli.js +27740 -415
- package/dist/cli.js.map +1 -1
- package/dist/data/registry-snapshot.json +1 -1
- package/dist/index.d.ts +1944 -463
- package/dist/index.js +17365 -102
- package/dist/index.js.map +1 -1
- package/package.json +13 -7
- package/dist/action-detect-P7ZE4NEM.js +0 -16
- package/dist/action-detect-P7ZE4NEM.js.map +0 -1
- package/dist/adapter-LNEGLMOE.js +0 -799
- package/dist/adapter-LNEGLMOE.js.map +0 -1
- package/dist/admin-6SYB6XCZ.js +0 -23
- package/dist/admin-6SYB6XCZ.js.map +0 -1
- package/dist/agent-catalog-FC3HGDEQ.js +0 -11
- package/dist/agent-catalog-FC3HGDEQ.js.map +0 -1
- package/dist/agent-dependencies-4OWBMZWZ.js +0 -24
- package/dist/agent-dependencies-4OWBMZWZ.js.map +0 -1
- package/dist/agent-registry-WT4NXPYG.js +0 -9
- package/dist/agent-registry-WT4NXPYG.js.map +0 -1
- package/dist/agent-store-VZLFPTZU.js +0 -9
- package/dist/agent-store-VZLFPTZU.js.map +0 -1
- package/dist/agents-QO7DKARJ.js +0 -15
- package/dist/agents-QO7DKARJ.js.map +0 -1
- package/dist/api-client-CFQT5U7D.js +0 -14
- package/dist/api-client-CFQT5U7D.js.map +0 -1
- package/dist/autostart-X33OGMX6.js +0 -23
- package/dist/autostart-X33OGMX6.js.map +0 -1
- package/dist/chunk-2CJ46J3C.js +0 -154
- package/dist/chunk-2CJ46J3C.js.map +0 -1
- package/dist/chunk-2HMQOC7N.js +0 -134
- package/dist/chunk-2HMQOC7N.js.map +0 -1
- package/dist/chunk-33RP6K2O.js +0 -435
- package/dist/chunk-33RP6K2O.js.map +0 -1
- package/dist/chunk-34M4OS5P.js +0 -83
- package/dist/chunk-34M4OS5P.js.map +0 -1
- package/dist/chunk-4CTX774K.js +0 -265
- package/dist/chunk-4CTX774K.js.map +0 -1
- package/dist/chunk-7QJS2XBD.js +0 -92
- package/dist/chunk-7QJS2XBD.js.map +0 -1
- package/dist/chunk-BDYVCIBH.js +0 -735
- package/dist/chunk-BDYVCIBH.js.map +0 -1
- package/dist/chunk-BN3X7UXB.js +0 -738
- package/dist/chunk-BN3X7UXB.js.map +0 -1
- package/dist/chunk-BNLGTZ34.js +0 -122
- package/dist/chunk-BNLGTZ34.js.map +0 -1
- package/dist/chunk-GAK6PIBW.js +0 -224
- package/dist/chunk-GAK6PIBW.js.map +0 -1
- package/dist/chunk-H5P2C6H4.js +0 -4740
- package/dist/chunk-H5P2C6H4.js.map +0 -1
- package/dist/chunk-I7WC6E5S.js +0 -71
- package/dist/chunk-I7WC6E5S.js.map +0 -1
- package/dist/chunk-J4SJTKIK.js +0 -203
- package/dist/chunk-J4SJTKIK.js.map +0 -1
- package/dist/chunk-JHYXKVV2.js +0 -183
- package/dist/chunk-JHYXKVV2.js.map +0 -1
- package/dist/chunk-JKBFUAJK.js +0 -282
- package/dist/chunk-JKBFUAJK.js.map +0 -1
- package/dist/chunk-JUYDFUSN.js +0 -673
- package/dist/chunk-JUYDFUSN.js.map +0 -1
- package/dist/chunk-KIRH7TUJ.js +0 -219
- package/dist/chunk-KIRH7TUJ.js.map +0 -1
- package/dist/chunk-LBIKITQT.js +0 -22
- package/dist/chunk-LBIKITQT.js.map +0 -1
- package/dist/chunk-LGP2YGRL.js +0 -4880
- package/dist/chunk-LGP2YGRL.js.map +0 -1
- package/dist/chunk-NAMYZIS5.js +0 -1
- package/dist/chunk-NAMYZIS5.js.map +0 -1
- package/dist/chunk-NVPG6JCL.js +0 -724
- package/dist/chunk-NVPG6JCL.js.map +0 -1
- package/dist/chunk-O7CPGUAI.js +0 -298
- package/dist/chunk-O7CPGUAI.js.map +0 -1
- package/dist/chunk-S64CB6J3.js +0 -98
- package/dist/chunk-S64CB6J3.js.map +0 -1
- package/dist/chunk-UKT3G5IA.js +0 -484
- package/dist/chunk-UKT3G5IA.js.map +0 -1
- package/dist/chunk-V5GZQEIY.js +0 -101
- package/dist/chunk-V5GZQEIY.js.map +0 -1
- package/dist/chunk-VOIJ6OY4.js +0 -63
- package/dist/chunk-VOIJ6OY4.js.map +0 -1
- package/dist/chunk-VUNV25KB.js +0 -16
- package/dist/chunk-VUNV25KB.js.map +0 -1
- package/dist/chunk-W3EYKZNQ.js +0 -45
- package/dist/chunk-W3EYKZNQ.js.map +0 -1
- package/dist/chunk-WTZDAYZX.js +0 -172
- package/dist/chunk-WTZDAYZX.js.map +0 -1
- package/dist/chunk-XANPHG7W.js +0 -145
- package/dist/chunk-XANPHG7W.js.map +0 -1
- package/dist/config-6S355X75.js +0 -15
- package/dist/config-6S355X75.js.map +0 -1
- package/dist/config-editor-RVLWZLVB.js +0 -13
- package/dist/config-editor-RVLWZLVB.js.map +0 -1
- package/dist/config-registry-AHYI4MYL.js +0 -18
- package/dist/config-registry-AHYI4MYL.js.map +0 -1
- package/dist/daemon-4CS6HMB5.js +0 -30
- package/dist/daemon-4CS6HMB5.js.map +0 -1
- package/dist/discord-7IVQKB2H.js +0 -2083
- package/dist/discord-7IVQKB2H.js.map +0 -1
- package/dist/dist-UHQK5CXN.js +0 -21151
- package/dist/dist-UHQK5CXN.js.map +0 -1
- package/dist/doctor-HZZ5BSHB.js +0 -10
- package/dist/doctor-HZZ5BSHB.js.map +0 -1
- package/dist/doctor-OLYBO3V3.js +0 -15
- package/dist/doctor-OLYBO3V3.js.map +0 -1
- package/dist/install-cloudflared-Z7VCGOVG.js +0 -33
- package/dist/install-cloudflared-Z7VCGOVG.js.map +0 -1
- package/dist/install-jq-HUYSQWKR.js +0 -32
- package/dist/install-jq-HUYSQWKR.js.map +0 -1
- package/dist/integrate-PNEHRY2I.js +0 -373
- package/dist/integrate-PNEHRY2I.js.map +0 -1
- package/dist/log-NXABYJTT.js +0 -24
- package/dist/log-NXABYJTT.js.map +0 -1
- package/dist/main-ZK4MPMBG.js +0 -238
- package/dist/main-ZK4MPMBG.js.map +0 -1
- package/dist/menu-YY5MKHEK.js +0 -16
- package/dist/menu-YY5MKHEK.js.map +0 -1
- package/dist/new-session-FEO4J4VU.js +0 -17
- package/dist/new-session-FEO4J4VU.js.map +0 -1
- package/dist/post-upgrade-CJG5I7M2.js +0 -80
- package/dist/post-upgrade-CJG5I7M2.js.map +0 -1
- package/dist/session-IUSI7P5S.js +0 -20
- package/dist/session-IUSI7P5S.js.map +0 -1
- package/dist/settings-RQPAM4KC.js +0 -14
- package/dist/settings-RQPAM4KC.js.map +0 -1
- package/dist/setup-3GQSYBE4.js +0 -35
- package/dist/setup-3GQSYBE4.js.map +0 -1
- package/dist/suggest-7D6B542M.js +0 -38
- package/dist/suggest-7D6B542M.js.map +0 -1
- package/dist/tunnel-service-CJLUH6SZ.js +0 -1174
- package/dist/tunnel-service-CJLUH6SZ.js.map +0 -1
- package/dist/version-NQZBM5M7.js +0 -16
- package/dist/version-NQZBM5M7.js.map +0 -1
package/dist/chunk-4CTX774K.js
DELETED
|
@@ -1,265 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
deleteSessionThread
|
|
3
|
-
} from "./chunk-BNLGTZ34.js";
|
|
4
|
-
import {
|
|
5
|
-
log
|
|
6
|
-
} from "./chunk-GAK6PIBW.js";
|
|
7
|
-
|
|
8
|
-
// src/adapters/discord/commands/session.ts
|
|
9
|
-
import {
|
|
10
|
-
ActionRowBuilder,
|
|
11
|
-
ButtonBuilder,
|
|
12
|
-
ButtonStyle
|
|
13
|
-
} from "discord.js";
|
|
14
|
-
var STATUS_EMOJI = {
|
|
15
|
-
active: "\u{1F7E2}",
|
|
16
|
-
initializing: "\u{1F7E1}",
|
|
17
|
-
finished: "\u2705",
|
|
18
|
-
error: "\u274C",
|
|
19
|
-
cancelled: "\u26D4"
|
|
20
|
-
};
|
|
21
|
-
var STATUS_ORDER = {
|
|
22
|
-
active: 0,
|
|
23
|
-
initializing: 1,
|
|
24
|
-
error: 2,
|
|
25
|
-
finished: 3,
|
|
26
|
-
cancelled: 4
|
|
27
|
-
};
|
|
28
|
-
async function handleCancel(interaction, adapter) {
|
|
29
|
-
await interaction.deferReply({ ephemeral: true });
|
|
30
|
-
const channelId = interaction.channelId;
|
|
31
|
-
const session = adapter.core.sessionManager.getSessionByThread("discord", channelId);
|
|
32
|
-
if (session) {
|
|
33
|
-
log.info({ sessionId: session.id }, "[discord-session] Cancel command");
|
|
34
|
-
await session.abortPrompt();
|
|
35
|
-
await interaction.editReply("\u26D4 Session cancelled.");
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
const record = adapter.core.sessionManager.getRecordByThread("discord", channelId);
|
|
39
|
-
if (record && record.status !== "cancelled" && record.status !== "error") {
|
|
40
|
-
log.info({ sessionId: record.sessionId }, "[discord-session] Cancel command (from store)");
|
|
41
|
-
await adapter.core.sessionManager.cancelSession(record.sessionId);
|
|
42
|
-
await interaction.editReply("\u26D4 Session cancelled.");
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
await interaction.editReply("No active session in this channel.");
|
|
46
|
-
}
|
|
47
|
-
async function handleStatus(interaction, adapter) {
|
|
48
|
-
await interaction.deferReply({ ephemeral: true });
|
|
49
|
-
const channelId = interaction.channelId;
|
|
50
|
-
const session = adapter.core.sessionManager.getSessionByThread("discord", channelId);
|
|
51
|
-
if (session) {
|
|
52
|
-
await interaction.editReply(
|
|
53
|
-
`**Session:** ${session.name || session.id}
|
|
54
|
-
**Agent:** ${session.agentName}
|
|
55
|
-
**Status:** ${session.status}
|
|
56
|
-
**Workspace:** \`${session.workingDirectory}\`
|
|
57
|
-
**Queue:** ${session.queueDepth} pending`
|
|
58
|
-
);
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
const record = adapter.core.sessionManager.getRecordByThread("discord", channelId);
|
|
62
|
-
if (record) {
|
|
63
|
-
await interaction.editReply(
|
|
64
|
-
`**Session:** ${record.name || record.sessionId}
|
|
65
|
-
**Agent:** ${record.agentName}
|
|
66
|
-
**Status:** ${record.status} (not loaded)
|
|
67
|
-
**Workspace:** \`${record.workingDir}\``
|
|
68
|
-
);
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
const sessions = adapter.core.sessionManager.listSessions("discord");
|
|
72
|
-
const active = sessions.filter(
|
|
73
|
-
(s) => s.status === "active" || s.status === "initializing"
|
|
74
|
-
);
|
|
75
|
-
await interaction.editReply(
|
|
76
|
-
`**OpenACP Status**
|
|
77
|
-
Active sessions: ${active.length}
|
|
78
|
-
Total sessions: ${sessions.length}`
|
|
79
|
-
);
|
|
80
|
-
}
|
|
81
|
-
async function handleSessions(interaction, adapter) {
|
|
82
|
-
await interaction.deferReply({ ephemeral: true });
|
|
83
|
-
try {
|
|
84
|
-
const allRecords = adapter.core.sessionManager.listRecords();
|
|
85
|
-
const records = allRecords.filter((r) => {
|
|
86
|
-
const platform = r.platform;
|
|
87
|
-
return !!platform?.topicId;
|
|
88
|
-
});
|
|
89
|
-
const headlessCount = allRecords.length - records.length;
|
|
90
|
-
if (records.length === 0) {
|
|
91
|
-
const extra = headlessCount > 0 ? ` (${headlessCount} headless hidden)` : "";
|
|
92
|
-
await interaction.editReply(`No sessions found.${extra}`);
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
records.sort(
|
|
96
|
-
(a, b) => (STATUS_ORDER[a.status] ?? 5) - (STATUS_ORDER[b.status] ?? 5)
|
|
97
|
-
);
|
|
98
|
-
const MAX_DISPLAY = 25;
|
|
99
|
-
const displayed = records.slice(0, MAX_DISPLAY);
|
|
100
|
-
const lines = displayed.map((r) => {
|
|
101
|
-
const emoji = STATUS_EMOJI[r.status] || "\u26AA";
|
|
102
|
-
const name = r.name?.trim() || `${r.agentName} session`;
|
|
103
|
-
return `${emoji} **${name}** \`[${r.status}]\``;
|
|
104
|
-
});
|
|
105
|
-
const header = `**Sessions: ${records.length}**` + (headlessCount > 0 ? ` (${headlessCount} headless hidden)` : "");
|
|
106
|
-
const truncated = records.length > MAX_DISPLAY ? `
|
|
107
|
-
|
|
108
|
-
*...and ${records.length - MAX_DISPLAY} more*` : "";
|
|
109
|
-
const finishedCount = allRecords.filter((r) => r.status === "finished").length;
|
|
110
|
-
const errorCount = allRecords.filter(
|
|
111
|
-
(r) => r.status === "error" || r.status === "cancelled"
|
|
112
|
-
).length;
|
|
113
|
-
const rows = [];
|
|
114
|
-
if (finishedCount + errorCount > 0) {
|
|
115
|
-
const cleanupRow = new ActionRowBuilder();
|
|
116
|
-
if (finishedCount > 0) {
|
|
117
|
-
cleanupRow.addComponents(
|
|
118
|
-
new ButtonBuilder().setCustomId("m:cleanup:finished").setLabel(`Cleanup finished (${finishedCount})`).setStyle(ButtonStyle.Secondary)
|
|
119
|
-
);
|
|
120
|
-
}
|
|
121
|
-
if (errorCount > 0) {
|
|
122
|
-
cleanupRow.addComponents(
|
|
123
|
-
new ButtonBuilder().setCustomId("m:cleanup:errors").setLabel(`Cleanup errors (${errorCount})`).setStyle(ButtonStyle.Secondary)
|
|
124
|
-
);
|
|
125
|
-
}
|
|
126
|
-
rows.push(cleanupRow);
|
|
127
|
-
const cleanupAllRow = new ActionRowBuilder();
|
|
128
|
-
cleanupAllRow.addComponents(
|
|
129
|
-
new ButtonBuilder().setCustomId("m:cleanup:all").setLabel(`Cleanup all non-active (${finishedCount + errorCount})`).setStyle(ButtonStyle.Secondary)
|
|
130
|
-
);
|
|
131
|
-
rows.push(cleanupAllRow);
|
|
132
|
-
}
|
|
133
|
-
await interaction.editReply({
|
|
134
|
-
content: `${header}
|
|
135
|
-
|
|
136
|
-
${lines.join("\n")}${truncated}`,
|
|
137
|
-
components: rows
|
|
138
|
-
});
|
|
139
|
-
} catch (err) {
|
|
140
|
-
log.error({ err }, "[discord-session] handleSessions error");
|
|
141
|
-
await interaction.editReply("\u274C Failed to list sessions.").catch(() => {
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
async function handleHandoff(interaction, adapter) {
|
|
146
|
-
await interaction.deferReply({ ephemeral: true });
|
|
147
|
-
const channelId = interaction.channelId;
|
|
148
|
-
const session = adapter.core.sessionManager.getSessionByThread("discord", channelId);
|
|
149
|
-
if (!session) {
|
|
150
|
-
const record = adapter.core.sessionManager.getRecordByThread("discord", channelId);
|
|
151
|
-
if (!record) {
|
|
152
|
-
await interaction.editReply("No session found in this channel.");
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
const cmd2 = `openacp agents run ${record.agentName} --resume ${record.agentSessionId} -- --continue`;
|
|
156
|
-
await interaction.editReply(
|
|
157
|
-
`**Resume in terminal:**
|
|
158
|
-
\`\`\`
|
|
159
|
-
${cmd2}
|
|
160
|
-
\`\`\`
|
|
161
|
-
|
|
162
|
-
*Run this from your project directory:* \`${record.workingDir}\``
|
|
163
|
-
);
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
const cmd = `openacp agents run ${session.agentName} --resume ${session.agentSessionId} -- --continue`;
|
|
167
|
-
await interaction.editReply(
|
|
168
|
-
`**Resume in terminal:**
|
|
169
|
-
\`\`\`
|
|
170
|
-
${cmd}
|
|
171
|
-
\`\`\`
|
|
172
|
-
|
|
173
|
-
*Run this from your project directory:* \`${session.workingDirectory}\``
|
|
174
|
-
);
|
|
175
|
-
}
|
|
176
|
-
async function executeCancelSession(interaction, adapter) {
|
|
177
|
-
const sessions = adapter.core.sessionManager.listSessions("discord").filter((s) => s.status === "active").sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
178
|
-
const session = sessions[0];
|
|
179
|
-
if (!session) {
|
|
180
|
-
await interaction.reply({ content: "No active sessions to cancel.", ephemeral: true });
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
await session.abortPrompt();
|
|
184
|
-
await interaction.reply({ content: `\u26D4 Cancelled session: **${session.name || session.id}**`, ephemeral: true });
|
|
185
|
-
}
|
|
186
|
-
async function handleCleanupButton(interaction, adapter) {
|
|
187
|
-
const { customId } = interaction;
|
|
188
|
-
switch (customId) {
|
|
189
|
-
case "m:cleanup:all":
|
|
190
|
-
await interaction.deferReply({ ephemeral: true });
|
|
191
|
-
await runCleanup(interaction, adapter, ["finished", "error", "cancelled"]);
|
|
192
|
-
break;
|
|
193
|
-
case "m:cleanup:finished":
|
|
194
|
-
await interaction.deferReply({ ephemeral: true });
|
|
195
|
-
await runCleanup(interaction, adapter, ["finished"]);
|
|
196
|
-
break;
|
|
197
|
-
case "m:cleanup:errors":
|
|
198
|
-
await interaction.deferReply({ ephemeral: true });
|
|
199
|
-
await runCleanup(interaction, adapter, ["error", "cancelled"]);
|
|
200
|
-
break;
|
|
201
|
-
case "m:cleanup:confirm":
|
|
202
|
-
await interaction.deferReply({ ephemeral: true });
|
|
203
|
-
await runCleanup(interaction, adapter, ["finished", "error", "cancelled", "active", "initializing"]);
|
|
204
|
-
break;
|
|
205
|
-
case "m:cleanup:cancel":
|
|
206
|
-
try {
|
|
207
|
-
await interaction.update({ components: [] });
|
|
208
|
-
} catch {
|
|
209
|
-
}
|
|
210
|
-
break;
|
|
211
|
-
default:
|
|
212
|
-
try {
|
|
213
|
-
await interaction.reply({ content: "Unknown cleanup action.", ephemeral: true });
|
|
214
|
-
} catch {
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
async function runCleanup(interaction, adapter, statuses) {
|
|
219
|
-
const allRecords = adapter.core.sessionManager.listRecords();
|
|
220
|
-
const cleanable = allRecords.filter((r) => statuses.includes(r.status));
|
|
221
|
-
if (cleanable.length === 0) {
|
|
222
|
-
await interaction.editReply("Nothing to clean up.");
|
|
223
|
-
return;
|
|
224
|
-
}
|
|
225
|
-
let deleted = 0;
|
|
226
|
-
let failed = 0;
|
|
227
|
-
for (const record of cleanable) {
|
|
228
|
-
try {
|
|
229
|
-
if (record.status === "active" || record.status === "initializing") {
|
|
230
|
-
try {
|
|
231
|
-
await adapter.core.sessionManager.cancelSession(record.sessionId);
|
|
232
|
-
} catch (err) {
|
|
233
|
-
log.warn({ err, sessionId: record.sessionId }, "[discord-session] Failed to cancel session during cleanup");
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
const platform = record.platform;
|
|
237
|
-
const threadId = platform?.threadId ?? (platform?.topicId != null ? String(platform.topicId) : void 0);
|
|
238
|
-
if (threadId) {
|
|
239
|
-
try {
|
|
240
|
-
await deleteSessionThread(adapter.getGuild(), threadId);
|
|
241
|
-
} catch (err) {
|
|
242
|
-
log.warn({ err, sessionId: record.sessionId, threadId }, "[discord-session] Failed to delete thread during cleanup");
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
await adapter.core.sessionManager.removeRecord(record.sessionId);
|
|
246
|
-
deleted++;
|
|
247
|
-
} catch (err) {
|
|
248
|
-
log.error({ err, sessionId: record.sessionId }, "[discord-session] Failed to cleanup session");
|
|
249
|
-
failed++;
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
await interaction.editReply(
|
|
253
|
-
`\u{1F5D1} Cleaned up **${deleted}** sessions${failed > 0 ? ` (${failed} failed)` : ""}.`
|
|
254
|
-
);
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
export {
|
|
258
|
-
handleCancel,
|
|
259
|
-
handleStatus,
|
|
260
|
-
handleSessions,
|
|
261
|
-
handleHandoff,
|
|
262
|
-
executeCancelSession,
|
|
263
|
-
handleCleanupButton
|
|
264
|
-
};
|
|
265
|
-
//# sourceMappingURL=chunk-4CTX774K.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/adapters/discord/commands/session.ts"],"sourcesContent":["import {\n ActionRowBuilder,\n ButtonBuilder,\n ButtonStyle,\n} from 'discord.js'\nimport type { ChatInputCommandInteraction, ButtonInteraction } from 'discord.js'\nimport type { Session } from '../../../core/session.js'\nimport { log } from '../../../core/log.js'\nimport { deleteSessionThread } from '../forums.js'\nimport type { DiscordAdapter } from '../adapter.js'\n\nconst STATUS_EMOJI: Record<string, string> = {\n active: '🟢',\n initializing: '🟡',\n finished: '✅',\n error: '❌',\n cancelled: '⛔',\n}\n\nconst STATUS_ORDER: Record<string, number> = {\n active: 0,\n initializing: 1,\n error: 2,\n finished: 3,\n cancelled: 4,\n}\n\nexport async function handleCancel(\n interaction: ChatInputCommandInteraction,\n adapter: DiscordAdapter,\n): Promise<void> {\n await interaction.deferReply({ ephemeral: true })\n\n const channelId = interaction.channelId\n const session = adapter.core.sessionManager.getSessionByThread('discord', channelId)\n\n if (session) {\n log.info({ sessionId: session.id }, '[discord-session] Cancel command')\n await session.abortPrompt()\n await interaction.editReply('⛔ Session cancelled.')\n return\n }\n\n // Fallback: cancel from store when session not in memory\n const record = adapter.core.sessionManager.getRecordByThread('discord', channelId)\n if (record && record.status !== 'cancelled' && record.status !== 'error') {\n log.info({ sessionId: record.sessionId }, '[discord-session] Cancel command (from store)')\n await adapter.core.sessionManager.cancelSession(record.sessionId)\n await interaction.editReply('⛔ Session cancelled.')\n return\n }\n\n await interaction.editReply('No active session in this channel.')\n}\n\nexport async function handleStatus(\n interaction: ChatInputCommandInteraction,\n adapter: DiscordAdapter,\n): Promise<void> {\n await interaction.deferReply({ ephemeral: true })\n\n const channelId = interaction.channelId\n const session = adapter.core.sessionManager.getSessionByThread('discord', channelId)\n\n if (session) {\n await interaction.editReply(\n `**Session:** ${session.name || session.id}\\n` +\n `**Agent:** ${session.agentName}\\n` +\n `**Status:** ${session.status}\\n` +\n `**Workspace:** \\`${session.workingDirectory}\\`\\n` +\n `**Queue:** ${session.queueDepth} pending`,\n )\n return\n }\n\n // Try stored record\n const record = adapter.core.sessionManager.getRecordByThread('discord', channelId)\n if (record) {\n await interaction.editReply(\n `**Session:** ${record.name || record.sessionId}\\n` +\n `**Agent:** ${record.agentName}\\n` +\n `**Status:** ${record.status} (not loaded)\\n` +\n `**Workspace:** \\`${record.workingDir}\\``,\n )\n return\n }\n\n // Global status\n const sessions = adapter.core.sessionManager.listSessions('discord')\n const active = sessions.filter(\n (s: Session) => s.status === 'active' || s.status === 'initializing',\n )\n await interaction.editReply(\n `**OpenACP Status**\\n` +\n `Active sessions: ${active.length}\\n` +\n `Total sessions: ${sessions.length}`,\n )\n}\n\nexport async function handleSessions(\n interaction: ChatInputCommandInteraction,\n adapter: DiscordAdapter,\n): Promise<void> {\n await interaction.deferReply({ ephemeral: true })\n\n try {\n const allRecords = adapter.core.sessionManager.listRecords()\n\n // Only show sessions that have a Discord thread\n const records = allRecords.filter((r: any) => {\n const platform = r.platform as { topicId?: string | number }\n return !!platform?.topicId\n })\n const headlessCount = allRecords.length - records.length\n\n if (records.length === 0) {\n const extra = headlessCount > 0 ? ` (${headlessCount} headless hidden)` : ''\n await interaction.editReply(`No sessions found.${extra}`)\n return\n }\n\n records.sort(\n (a: any, b: any) => (STATUS_ORDER[a.status] ?? 5) - (STATUS_ORDER[b.status] ?? 5),\n )\n\n const MAX_DISPLAY = 25\n const displayed = records.slice(0, MAX_DISPLAY)\n\n const lines = displayed.map((r: any) => {\n const emoji = STATUS_EMOJI[r.status] || '⚪'\n const name = r.name?.trim() || `${r.agentName} session`\n return `${emoji} **${name}** \\`[${r.status}]\\``\n })\n\n const header =\n `**Sessions: ${records.length}**` +\n (headlessCount > 0 ? ` (${headlessCount} headless hidden)` : '')\n const truncated =\n records.length > MAX_DISPLAY\n ? `\\n\\n*...and ${records.length - MAX_DISPLAY} more*`\n : ''\n\n // Cleanup buttons\n const finishedCount = allRecords.filter((r: any) => r.status === 'finished').length\n const errorCount = allRecords.filter(\n (r: any) => r.status === 'error' || r.status === 'cancelled',\n ).length\n\n const rows: ActionRowBuilder<ButtonBuilder>[] = []\n\n if (finishedCount + errorCount > 0) {\n const cleanupRow = new ActionRowBuilder<ButtonBuilder>()\n if (finishedCount > 0) {\n cleanupRow.addComponents(\n new ButtonBuilder()\n .setCustomId('m:cleanup:finished')\n .setLabel(`Cleanup finished (${finishedCount})`)\n .setStyle(ButtonStyle.Secondary),\n )\n }\n if (errorCount > 0) {\n cleanupRow.addComponents(\n new ButtonBuilder()\n .setCustomId('m:cleanup:errors')\n .setLabel(`Cleanup errors (${errorCount})`)\n .setStyle(ButtonStyle.Secondary),\n )\n }\n rows.push(cleanupRow)\n\n const cleanupAllRow = new ActionRowBuilder<ButtonBuilder>()\n cleanupAllRow.addComponents(\n new ButtonBuilder()\n .setCustomId('m:cleanup:all')\n .setLabel(`Cleanup all non-active (${finishedCount + errorCount})`)\n .setStyle(ButtonStyle.Secondary),\n )\n rows.push(cleanupAllRow)\n }\n\n await interaction.editReply({\n content: `${header}\\n\\n${lines.join('\\n')}${truncated}`,\n components: rows,\n })\n } catch (err) {\n log.error({ err }, '[discord-session] handleSessions error')\n await interaction.editReply('❌ Failed to list sessions.').catch(() => {})\n }\n}\n\nexport async function handleHandoff(\n interaction: ChatInputCommandInteraction,\n adapter: DiscordAdapter,\n): Promise<void> {\n await interaction.deferReply({ ephemeral: true })\n\n const channelId = interaction.channelId\n const session = adapter.core.sessionManager.getSessionByThread('discord', channelId)\n\n if (!session) {\n const record = adapter.core.sessionManager.getRecordByThread('discord', channelId)\n if (!record) {\n await interaction.editReply('No session found in this channel.')\n return\n }\n const cmd = `openacp agents run ${record.agentName} --resume ${record.agentSessionId} -- --continue`\n await interaction.editReply(\n `**Resume in terminal:**\\n\\`\\`\\`\\n${cmd}\\n\\`\\`\\`\\n\\n*Run this from your project directory:* \\`${record.workingDir}\\``,\n )\n return\n }\n\n const cmd = `openacp agents run ${session.agentName} --resume ${session.agentSessionId} -- --continue`\n await interaction.editReply(\n `**Resume in terminal:**\\n\\`\\`\\`\\n${cmd}\\n\\`\\`\\`\\n\\n*Run this from your project directory:* \\`${session.workingDirectory}\\``,\n )\n}\n\nexport async function executeCancelSession(\n interaction: ButtonInteraction,\n adapter: DiscordAdapter,\n): Promise<void> {\n const sessions: Session[] = adapter.core.sessionManager\n .listSessions('discord')\n .filter((s: Session) => s.status === 'active')\n .sort((a: Session, b: Session) => b.createdAt.getTime() - a.createdAt.getTime())\n\n const session = sessions[0]\n if (!session) {\n await interaction.reply({ content: 'No active sessions to cancel.', ephemeral: true })\n return\n }\n\n await session.abortPrompt()\n await interaction.reply({ content: `⛔ Cancelled session: **${session.name || session.id}**`, ephemeral: true })\n}\n\nexport async function handleCleanupButton(\n interaction: ButtonInteraction,\n adapter: DiscordAdapter,\n): Promise<void> {\n const { customId } = interaction\n\n switch (customId) {\n case 'm:cleanup:all':\n await interaction.deferReply({ ephemeral: true })\n await runCleanup(interaction, adapter, ['finished', 'error', 'cancelled'])\n break\n\n case 'm:cleanup:finished':\n await interaction.deferReply({ ephemeral: true })\n await runCleanup(interaction, adapter, ['finished'])\n break\n\n case 'm:cleanup:errors':\n await interaction.deferReply({ ephemeral: true })\n await runCleanup(interaction, adapter, ['error', 'cancelled'])\n break\n\n case 'm:cleanup:confirm':\n await interaction.deferReply({ ephemeral: true })\n await runCleanup(interaction, adapter, ['finished', 'error', 'cancelled', 'active', 'initializing'])\n break\n\n case 'm:cleanup:cancel':\n try { await interaction.update({ components: [] }) } catch { /* ignore */ }\n break\n\n default:\n // Unknown cleanup variant — ignore\n try { await interaction.reply({ content: 'Unknown cleanup action.', ephemeral: true }) } catch { /* ignore */ }\n }\n}\n\nasync function runCleanup(\n interaction: ButtonInteraction,\n adapter: DiscordAdapter,\n statuses: string[],\n): Promise<void> {\n const allRecords = adapter.core.sessionManager.listRecords()\n const cleanable = allRecords.filter((r: any) => statuses.includes(r.status))\n\n if (cleanable.length === 0) {\n await interaction.editReply('Nothing to clean up.')\n return\n }\n\n let deleted = 0\n let failed = 0\n\n for (const record of cleanable) {\n try {\n // Cancel active sessions first\n if (record.status === 'active' || record.status === 'initializing') {\n try {\n await adapter.core.sessionManager.cancelSession(record.sessionId)\n } catch (err) {\n log.warn({ err, sessionId: record.sessionId }, '[discord-session] Failed to cancel session during cleanup')\n }\n }\n\n const platform = record.platform as { topicId?: string | number; threadId?: string } | undefined\n const threadId = platform?.threadId ?? (platform?.topicId != null ? String(platform.topicId) : undefined)\n if (threadId) {\n try {\n await deleteSessionThread(adapter.getGuild(), threadId)\n } catch (err) {\n log.warn({ err, sessionId: record.sessionId, threadId }, '[discord-session] Failed to delete thread during cleanup')\n }\n }\n await adapter.core.sessionManager.removeRecord(record.sessionId)\n deleted++\n } catch (err) {\n log.error({ err, sessionId: record.sessionId }, '[discord-session] Failed to cleanup session')\n failed++\n }\n }\n\n await interaction.editReply(\n `🗑 Cleaned up **${deleted}** sessions${failed > 0 ? ` (${failed} failed)` : ''}.`,\n )\n}\n"],"mappings":"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","names":["cmd"]}
|
package/dist/chunk-7QJS2XBD.js
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
// src/adapters/telegram/commands/menu.ts
|
|
2
|
-
import { InlineKeyboard } from "grammy";
|
|
3
|
-
function buildMenuKeyboard() {
|
|
4
|
-
return new InlineKeyboard().text("\u{1F195} New Session", "m:new").text("\u{1F4CB} Sessions", "m:topics").row().text("\u{1F4CA} Status", "m:status").text("\u{1F916} Agents", "m:agents").row().text("\u2699\uFE0F Settings", "m:settings").text("\u{1F517} Integrate", "m:integrate").row().text("\u{1F504} Restart", "m:restart").text("\u2B06\uFE0F Update", "m:update").row().text("\u2753 Help", "m:help").text("\u{1FA7A} Doctor", "m:doctor");
|
|
5
|
-
}
|
|
6
|
-
async function handleMenu(ctx) {
|
|
7
|
-
await ctx.reply(`<b>OpenACP Menu</b>
|
|
8
|
-
Choose an action:`, {
|
|
9
|
-
parse_mode: "HTML",
|
|
10
|
-
reply_markup: buildMenuKeyboard()
|
|
11
|
-
});
|
|
12
|
-
}
|
|
13
|
-
async function handleHelp(ctx) {
|
|
14
|
-
await ctx.reply(
|
|
15
|
-
`\u{1F4D6} <b>OpenACP Help</b>
|
|
16
|
-
|
|
17
|
-
\u{1F680} <b>Getting Started</b>
|
|
18
|
-
Tap \u{1F195} New Session to start coding with AI.
|
|
19
|
-
Each session gets its own topic \u2014 chat there to work with the agent.
|
|
20
|
-
|
|
21
|
-
\u{1F4A1} <b>Common Tasks</b>
|
|
22
|
-
/new [agent] [workspace] \u2014 Create new session
|
|
23
|
-
/cancel \u2014 Cancel session (in session topic)
|
|
24
|
-
/status \u2014 Show session or system status
|
|
25
|
-
/sessions \u2014 List all sessions
|
|
26
|
-
/agents \u2014 Browse & install agents
|
|
27
|
-
/install <name> \u2014 Install an agent
|
|
28
|
-
|
|
29
|
-
\u2699\uFE0F <b>System</b>
|
|
30
|
-
/restart \u2014 Restart OpenACP
|
|
31
|
-
/update \u2014 Update to latest version
|
|
32
|
-
/integrate \u2014 Manage agent integrations
|
|
33
|
-
/menu \u2014 Show action menu
|
|
34
|
-
|
|
35
|
-
\u{1F512} <b>Session Options</b>
|
|
36
|
-
/enable_dangerous \u2014 Auto-approve permissions
|
|
37
|
-
/disable_dangerous \u2014 Restore permission prompts
|
|
38
|
-
/handoff \u2014 Continue session in terminal
|
|
39
|
-
/archive \u2014 Archive session topic
|
|
40
|
-
/clear \u2014 Clear assistant history
|
|
41
|
-
|
|
42
|
-
\u{1F4AC} Need help? Just ask me in this topic!`,
|
|
43
|
-
{ parse_mode: "HTML" }
|
|
44
|
-
);
|
|
45
|
-
}
|
|
46
|
-
async function handleClear(ctx, assistant) {
|
|
47
|
-
if (!assistant) {
|
|
48
|
-
await ctx.reply("\u26A0\uFE0F Assistant is not available.", { parse_mode: "HTML" });
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
const threadId = ctx.message?.message_thread_id;
|
|
52
|
-
if (threadId !== assistant.topicId) {
|
|
53
|
-
await ctx.reply("\u2139\uFE0F /clear only works in the Assistant topic.", { parse_mode: "HTML" });
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
await ctx.reply("\u{1F504} Clearing assistant history...", { parse_mode: "HTML" });
|
|
57
|
-
try {
|
|
58
|
-
await assistant.respawn();
|
|
59
|
-
await ctx.reply("\u2705 Assistant history cleared.", { parse_mode: "HTML" });
|
|
60
|
-
} catch (err) {
|
|
61
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
62
|
-
await ctx.reply(`\u274C Failed to clear: <code>${message}</code>`, { parse_mode: "HTML" });
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
var TELEGRAM_MSG_LIMIT = 4096;
|
|
66
|
-
function buildSkillMessages(commands) {
|
|
67
|
-
const sorted = [...commands].sort((a, b) => a.name.localeCompare(b.name));
|
|
68
|
-
const header = "\u{1F6E0} <b>Available Skills</b>\n";
|
|
69
|
-
const lines = sorted.map((c) => `<code>/${c.name}</code>`);
|
|
70
|
-
const messages = [];
|
|
71
|
-
let current = header;
|
|
72
|
-
for (const line of lines) {
|
|
73
|
-
const candidate = current + "\n" + line;
|
|
74
|
-
if (candidate.length > TELEGRAM_MSG_LIMIT) {
|
|
75
|
-
messages.push(current);
|
|
76
|
-
current = line;
|
|
77
|
-
} else {
|
|
78
|
-
current = candidate;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
if (current) messages.push(current);
|
|
82
|
-
return messages;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export {
|
|
86
|
-
buildMenuKeyboard,
|
|
87
|
-
handleMenu,
|
|
88
|
-
handleHelp,
|
|
89
|
-
handleClear,
|
|
90
|
-
buildSkillMessages
|
|
91
|
-
};
|
|
92
|
-
//# sourceMappingURL=chunk-7QJS2XBD.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/adapters/telegram/commands/menu.ts"],"sourcesContent":["import type { Context } from \"grammy\";\nimport { InlineKeyboard } from \"grammy\";\nimport type { AgentCommand } from \"../../../core/index.js\";\nimport type { CommandsAssistantContext } from \"../types.js\";\n\nexport function buildMenuKeyboard(): InlineKeyboard {\n return new InlineKeyboard()\n .text(\"🆕 New Session\", \"m:new\")\n .text(\"📋 Sessions\", \"m:topics\")\n .row()\n .text(\"📊 Status\", \"m:status\")\n .text(\"🤖 Agents\", \"m:agents\")\n .row()\n .text(\"⚙️ Settings\", \"m:settings\")\n .text(\"🔗 Integrate\", \"m:integrate\")\n .row()\n .text(\"🔄 Restart\", \"m:restart\")\n .text(\"⬆️ Update\", \"m:update\")\n .row()\n .text(\"❓ Help\", \"m:help\")\n .text(\"🩺 Doctor\", \"m:doctor\");\n}\n\nexport async function handleMenu(ctx: Context): Promise<void> {\n await ctx.reply(`<b>OpenACP Menu</b>\\nChoose an action:`, {\n parse_mode: \"HTML\",\n reply_markup: buildMenuKeyboard(),\n });\n}\n\nexport async function handleHelp(ctx: Context): Promise<void> {\n await ctx.reply(\n `📖 <b>OpenACP Help</b>\\n\\n` +\n `🚀 <b>Getting Started</b>\\n` +\n `Tap 🆕 New Session to start coding with AI.\\n` +\n `Each session gets its own topic — chat there to work with the agent.\\n\\n` +\n `💡 <b>Common Tasks</b>\\n` +\n `/new [agent] [workspace] — Create new session\\n` +\n `/cancel — Cancel session (in session topic)\\n` +\n `/status — Show session or system status\\n` +\n `/sessions — List all sessions\\n` +\n `/agents — Browse & install agents\\n` +\n `/install <name> — Install an agent\\n\\n` +\n `⚙️ <b>System</b>\\n` +\n `/restart — Restart OpenACP\\n` +\n `/update — Update to latest version\\n` +\n `/integrate — Manage agent integrations\\n` +\n `/menu — Show action menu\\n\\n` +\n `🔒 <b>Session Options</b>\\n` +\n `/enable_dangerous — Auto-approve permissions\\n` +\n `/disable_dangerous — Restore permission prompts\\n` +\n `/handoff — Continue session in terminal\\n` +\n `/archive — Archive session topic\\n` +\n `/clear — Clear assistant history\\n\\n` +\n `💬 Need help? Just ask me in this topic!`,\n { parse_mode: \"HTML\" },\n );\n}\n\nexport async function handleClear(ctx: Context, assistant?: CommandsAssistantContext): Promise<void> {\n if (!assistant) {\n await ctx.reply(\"⚠️ Assistant is not available.\", { parse_mode: \"HTML\" });\n return;\n }\n\n const threadId = ctx.message?.message_thread_id;\n if (threadId !== assistant.topicId) {\n await ctx.reply(\"ℹ️ /clear only works in the Assistant topic.\", { parse_mode: \"HTML\" });\n return;\n }\n\n await ctx.reply(\"🔄 Clearing assistant history...\", { parse_mode: \"HTML\" });\n\n try {\n await assistant.respawn();\n await ctx.reply(\"✅ Assistant history cleared.\", { parse_mode: \"HTML\" });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n await ctx.reply(`❌ Failed to clear: <code>${message}</code>`, { parse_mode: \"HTML\" });\n }\n}\n\nconst TELEGRAM_MSG_LIMIT = 4096;\n\n/**\n * Build plain-text skill command messages. Each command is on its own line\n * wrapped in <code> for tap-to-copy. If the list exceeds Telegram's message\n * limit, it is split into multiple messages (cut at line boundaries).\n */\nexport function buildSkillMessages(commands: AgentCommand[]): string[] {\n const sorted = [...commands].sort((a, b) => a.name.localeCompare(b.name));\n const header = \"🛠 <b>Available Skills</b>\\n\";\n const lines = sorted.map((c) => `<code>/${c.name}</code>`);\n\n const messages: string[] = [];\n let current = header;\n\n for (const line of lines) {\n const candidate = current + \"\\n\" + line;\n if (candidate.length > TELEGRAM_MSG_LIMIT) {\n messages.push(current);\n current = line;\n } else {\n current = candidate;\n }\n }\n if (current) messages.push(current);\n return messages;\n}\n"],"mappings":";AACA,SAAS,sBAAsB;AAIxB,SAAS,oBAAoC;AAClD,SAAO,IAAI,eAAe,EACvB,KAAK,yBAAkB,OAAO,EAC9B,KAAK,sBAAe,UAAU,EAC9B,IAAI,EACJ,KAAK,oBAAa,UAAU,EAC5B,KAAK,oBAAa,UAAU,EAC5B,IAAI,EACJ,KAAK,yBAAe,YAAY,EAChC,KAAK,uBAAgB,aAAa,EAClC,IAAI,EACJ,KAAK,qBAAc,WAAW,EAC9B,KAAK,uBAAa,UAAU,EAC5B,IAAI,EACJ,KAAK,eAAU,QAAQ,EACvB,KAAK,oBAAa,UAAU;AACjC;AAEA,eAAsB,WAAW,KAA6B;AAC5D,QAAM,IAAI,MAAM;AAAA,oBAA0C;AAAA,IACxD,YAAY;AAAA,IACZ,cAAc,kBAAkB;AAAA,EAClC,CAAC;AACH;AAEA,eAAsB,WAAW,KAA6B;AAC5D,QAAM,IAAI;AAAA,IACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAuBA,EAAE,YAAY,OAAO;AAAA,EACvB;AACF;AAEA,eAAsB,YAAY,KAAc,WAAqD;AACnG,MAAI,CAAC,WAAW;AACd,UAAM,IAAI,MAAM,4CAAkC,EAAE,YAAY,OAAO,CAAC;AACxE;AAAA,EACF;AAEA,QAAM,WAAW,IAAI,SAAS;AAC9B,MAAI,aAAa,UAAU,SAAS;AAClC,UAAM,IAAI,MAAM,0DAAgD,EAAE,YAAY,OAAO,CAAC;AACtF;AAAA,EACF;AAEA,QAAM,IAAI,MAAM,2CAAoC,EAAE,YAAY,OAAO,CAAC;AAE1E,MAAI;AACF,UAAM,UAAU,QAAQ;AACxB,UAAM,IAAI,MAAM,qCAAgC,EAAE,YAAY,OAAO,CAAC;AAAA,EACxE,SAAS,KAAK;AACZ,UAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,UAAM,IAAI,MAAM,iCAA4B,OAAO,WAAW,EAAE,YAAY,OAAO,CAAC;AAAA,EACtF;AACF;AAEA,IAAM,qBAAqB;AAOpB,SAAS,mBAAmB,UAAoC;AACrE,QAAM,SAAS,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AACxE,QAAM,SAAS;AACf,QAAM,QAAQ,OAAO,IAAI,CAAC,MAAM,UAAU,EAAE,IAAI,SAAS;AAEzD,QAAM,WAAqB,CAAC;AAC5B,MAAI,UAAU;AAEd,aAAW,QAAQ,OAAO;AACxB,UAAM,YAAY,UAAU,OAAO;AACnC,QAAI,UAAU,SAAS,oBAAoB;AACzC,eAAS,KAAK,OAAO;AACrB,gBAAU;AAAA,IACZ,OAAO;AACL,gBAAU;AAAA,IACZ;AAAA,EACF;AACA,MAAI,QAAS,UAAS,KAAK,OAAO;AAClC,SAAO;AACT;","names":[]}
|