agent4discord 0.1.0
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.ko.md +134 -0
- package/README.md +170 -0
- package/dist/bot.d.ts +1 -0
- package/dist/bot.js +114 -0
- package/dist/bot.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +27 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/index.d.ts +9 -0
- package/dist/commands/index.js +44 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/init.d.ts +5 -0
- package/dist/commands/init.js +152 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/model.d.ts +5 -0
- package/dist/commands/model.js +65 -0
- package/dist/commands/model.js.map +1 -0
- package/dist/commands/resume.d.ts +6 -0
- package/dist/commands/resume.js +113 -0
- package/dist/commands/resume.js.map +1 -0
- package/dist/config.d.ts +12 -0
- package/dist/config.js +49 -0
- package/dist/config.js.map +1 -0
- package/dist/formatters/chunker.d.ts +5 -0
- package/dist/formatters/chunker.js +46 -0
- package/dist/formatters/chunker.js.map +1 -0
- package/dist/formatters/embedBuilder.d.ts +28 -0
- package/dist/formatters/embedBuilder.js +32 -0
- package/dist/formatters/embedBuilder.js.map +1 -0
- package/dist/formatters/toolFormatter.d.ts +4 -0
- package/dist/formatters/toolFormatter.js +90 -0
- package/dist/formatters/toolFormatter.js.map +1 -0
- package/dist/guild.d.ts +22 -0
- package/dist/guild.js +41 -0
- package/dist/guild.js.map +1 -0
- package/dist/interactions/directoryBrowser.d.ts +61 -0
- package/dist/interactions/directoryBrowser.js +611 -0
- package/dist/interactions/directoryBrowser.js.map +1 -0
- package/dist/interactions/index.d.ts +5 -0
- package/dist/interactions/index.js +92 -0
- package/dist/interactions/index.js.map +1 -0
- package/dist/interactions/permissionHandler.d.ts +11 -0
- package/dist/interactions/permissionHandler.js +107 -0
- package/dist/interactions/permissionHandler.js.map +1 -0
- package/dist/interactions/sessionControls.d.ts +9 -0
- package/dist/interactions/sessionControls.js +95 -0
- package/dist/interactions/sessionControls.js.map +1 -0
- package/dist/sessions/eventHandler.d.ts +3 -0
- package/dist/sessions/eventHandler.js +209 -0
- package/dist/sessions/eventHandler.js.map +1 -0
- package/dist/sessions/sessionManager.d.ts +29 -0
- package/dist/sessions/sessionManager.js +203 -0
- package/dist/sessions/sessionManager.js.map +1 -0
- package/dist/sessions/sessionStore.d.ts +4 -0
- package/dist/sessions/sessionStore.js +29 -0
- package/dist/sessions/sessionStore.js.map +1 -0
- package/dist/sessions/streamHandler.d.ts +18 -0
- package/dist/sessions/streamHandler.js +119 -0
- package/dist/sessions/streamHandler.js.map +1 -0
- package/dist/sessions/toolProgress.d.ts +14 -0
- package/dist/sessions/toolProgress.js +65 -0
- package/dist/sessions/toolProgress.js.map +1 -0
- package/dist/sessions/usageTracker.d.ts +12 -0
- package/dist/sessions/usageTracker.js +222 -0
- package/dist/sessions/usageTracker.js.map +1 -0
- package/dist/setup.d.ts +1 -0
- package/dist/setup.js +101 -0
- package/dist/setup.js.map +1 -0
- package/dist/utils/filesystem.d.ts +11 -0
- package/dist/utils/filesystem.js +26 -0
- package/dist/utils/filesystem.js.map +1 -0
- package/dist/utils/logger.d.ts +1 -0
- package/dist/utils/logger.js +3 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/plugins.d.ts +6 -0
- package/dist/utils/plugins.js +66 -0
- package/dist/utils/plugins.js.map +1 -0
- package/package.json +45 -0
|
@@ -0,0 +1,611 @@
|
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, ChannelType, EmbedBuilder, StringSelectMenuBuilder, } from 'discord.js';
|
|
4
|
+
import { listSessions, getSessionMessages } from '@anthropic-ai/claude-agent-sdk';
|
|
5
|
+
import { isPathSafe, listDirectories } from '../utils/filesystem.js';
|
|
6
|
+
import { chunkMessage } from '../formatters/chunker.js';
|
|
7
|
+
import { loadGuildConfig } from '../guild.js';
|
|
8
|
+
import { sessionManager } from '../sessions/sessionManager.js';
|
|
9
|
+
import { saveSessionToGuild } from '../sessions/sessionStore.js';
|
|
10
|
+
import { buildStatusEmbed, COLORS } from '../formatters/embedBuilder.js';
|
|
11
|
+
import { requestPermission } from './permissionHandler.js';
|
|
12
|
+
const HOMEDIR = os.homedir();
|
|
13
|
+
const MAX_SELECT_OPTIONS = 25;
|
|
14
|
+
const MAX_LABEL_LENGTH = 95;
|
|
15
|
+
const MAX_VALUE_LENGTH = 100;
|
|
16
|
+
function parseFooterState(interaction) {
|
|
17
|
+
const text = interaction.message.embeds[0]?.footer?.text ?? '';
|
|
18
|
+
// New format: "path | pN" or "path | pN | mode:resume | sid:xxx"
|
|
19
|
+
const pipeIdx = text.lastIndexOf(' | p');
|
|
20
|
+
if (pipeIdx !== -1) {
|
|
21
|
+
const pathPart = text.slice(0, pipeIdx);
|
|
22
|
+
const rest = text.slice(pipeIdx + 4); // after " | p"
|
|
23
|
+
const segments = rest.split(' | ');
|
|
24
|
+
const page = parseInt(segments[0], 10) || 0;
|
|
25
|
+
let mode;
|
|
26
|
+
let selectedSessionId;
|
|
27
|
+
for (const seg of segments) {
|
|
28
|
+
if (seg.startsWith('mode:'))
|
|
29
|
+
mode = seg.slice(5);
|
|
30
|
+
if (seg.startsWith('sid:'))
|
|
31
|
+
selectedSessionId = seg.slice(4);
|
|
32
|
+
}
|
|
33
|
+
return { path: pathPart, page, mode, selectedSessionId };
|
|
34
|
+
}
|
|
35
|
+
// Legacy JSON format
|
|
36
|
+
try {
|
|
37
|
+
const parsed = JSON.parse(text);
|
|
38
|
+
if (typeof parsed.path === 'string') {
|
|
39
|
+
return {
|
|
40
|
+
path: parsed.path,
|
|
41
|
+
page: typeof parsed.page === 'number' ? parsed.page : 0,
|
|
42
|
+
mode: parsed.mode,
|
|
43
|
+
selectedSessionId: parsed.selectedSessionId,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// ignore
|
|
49
|
+
}
|
|
50
|
+
return { path: HOMEDIR, page: 0 };
|
|
51
|
+
}
|
|
52
|
+
export function displayPath(fullPath) {
|
|
53
|
+
if (fullPath === HOMEDIR)
|
|
54
|
+
return '~';
|
|
55
|
+
if (fullPath.startsWith(HOMEDIR + path.sep)) {
|
|
56
|
+
return '~' + fullPath.slice(HOMEDIR.length).replaceAll('\\', '/');
|
|
57
|
+
}
|
|
58
|
+
return fullPath;
|
|
59
|
+
}
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
// Build browser message
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
/**
|
|
64
|
+
* Build the directory browser message with embed, select menu, and buttons.
|
|
65
|
+
*/
|
|
66
|
+
export async function buildBrowserMessage(dirPath, page = 0) {
|
|
67
|
+
const resolvedPath = path.resolve(dirPath);
|
|
68
|
+
// Embed -- footer encodes state as "path | pN"
|
|
69
|
+
const embed = new EmbedBuilder()
|
|
70
|
+
.setTitle('Select Working Directory')
|
|
71
|
+
.setDescription(resolvedPath)
|
|
72
|
+
.setFooter({ text: `${resolvedPath} | p${page}` })
|
|
73
|
+
.setColor(0x5865f2);
|
|
74
|
+
// Fetch subdirectories
|
|
75
|
+
let dirs;
|
|
76
|
+
try {
|
|
77
|
+
dirs = await listDirectories(resolvedPath);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
dirs = [];
|
|
81
|
+
}
|
|
82
|
+
// Build select menu
|
|
83
|
+
const selectMenu = new StringSelectMenuBuilder()
|
|
84
|
+
.setCustomId('a4d:dir:browse')
|
|
85
|
+
.setPlaceholder('Select a directory...');
|
|
86
|
+
if (dirs.length === 0) {
|
|
87
|
+
selectMenu.addOptions({
|
|
88
|
+
label: 'No subdirectories',
|
|
89
|
+
value: '_none',
|
|
90
|
+
default: true,
|
|
91
|
+
});
|
|
92
|
+
selectMenu.setDisabled(true);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
const pagedDirs = dirs.slice(page * MAX_SELECT_OPTIONS, (page + 1) * MAX_SELECT_OPTIONS);
|
|
96
|
+
for (const dir of pagedDirs) {
|
|
97
|
+
const fullPath = path.join(resolvedPath, dir);
|
|
98
|
+
const label = dir.length > MAX_LABEL_LENGTH ? dir.slice(0, MAX_LABEL_LENGTH) : dir;
|
|
99
|
+
const value = fullPath.length > MAX_VALUE_LENGTH ? fullPath.slice(0, MAX_VALUE_LENGTH) : fullPath;
|
|
100
|
+
selectMenu.addOptions({ label, value });
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const selectRow = new ActionRowBuilder().addComponents(selectMenu);
|
|
104
|
+
// Buttons
|
|
105
|
+
const atRoot = path.dirname(resolvedPath) === resolvedPath;
|
|
106
|
+
const parentButton = new ButtonBuilder()
|
|
107
|
+
.setCustomId('a4d:dir:parent')
|
|
108
|
+
.setLabel('Parent')
|
|
109
|
+
.setStyle(ButtonStyle.Secondary)
|
|
110
|
+
.setDisabled(atRoot);
|
|
111
|
+
const startButton = new ButtonBuilder()
|
|
112
|
+
.setCustomId('a4d:dir:start')
|
|
113
|
+
.setLabel('Session Start')
|
|
114
|
+
.setStyle(ButtonStyle.Success);
|
|
115
|
+
const resumeButton = new ButtonBuilder()
|
|
116
|
+
.setCustomId('a4d:dir:resume')
|
|
117
|
+
.setLabel('Resume Session')
|
|
118
|
+
.setStyle(ButtonStyle.Primary);
|
|
119
|
+
const cancelButton = new ButtonBuilder()
|
|
120
|
+
.setCustomId('a4d:dir:cancel')
|
|
121
|
+
.setLabel('Cancel')
|
|
122
|
+
.setStyle(ButtonStyle.Danger);
|
|
123
|
+
const buttonRow = new ActionRowBuilder().addComponents(parentButton, startButton, resumeButton, cancelButton);
|
|
124
|
+
const components = [selectRow, buttonRow];
|
|
125
|
+
// Pagination row (only when >25 directories)
|
|
126
|
+
const totalPages = Math.max(1, Math.ceil(dirs.length / MAX_SELECT_OPTIONS));
|
|
127
|
+
if (totalPages > 1) {
|
|
128
|
+
const prevButton = new ButtonBuilder()
|
|
129
|
+
.setCustomId('a4d:dir:prev')
|
|
130
|
+
.setLabel('Previous')
|
|
131
|
+
.setStyle(ButtonStyle.Secondary)
|
|
132
|
+
.setDisabled(page <= 0);
|
|
133
|
+
const pageInfo = new ButtonBuilder()
|
|
134
|
+
.setCustomId('a4d:dir:pageinfo')
|
|
135
|
+
.setLabel(`Page ${page + 1}/${totalPages}`)
|
|
136
|
+
.setStyle(ButtonStyle.Secondary)
|
|
137
|
+
.setDisabled(true);
|
|
138
|
+
const nextButton = new ButtonBuilder()
|
|
139
|
+
.setCustomId('a4d:dir:next')
|
|
140
|
+
.setLabel('Next')
|
|
141
|
+
.setStyle(ButtonStyle.Secondary)
|
|
142
|
+
.setDisabled(page >= totalPages - 1);
|
|
143
|
+
const paginationRow = new ActionRowBuilder().addComponents(prevButton, pageInfo, nextButton);
|
|
144
|
+
components.push(paginationRow);
|
|
145
|
+
}
|
|
146
|
+
return { embeds: [embed], components };
|
|
147
|
+
}
|
|
148
|
+
// ---------------------------------------------------------------------------
|
|
149
|
+
// Interaction handlers
|
|
150
|
+
// ---------------------------------------------------------------------------
|
|
151
|
+
/**
|
|
152
|
+
* Handle directory selection from the StringSelectMenu.
|
|
153
|
+
*/
|
|
154
|
+
export async function handleDirectoryBrowse(interaction) {
|
|
155
|
+
const selected = interaction.values[0];
|
|
156
|
+
if (!selected || selected === '_none')
|
|
157
|
+
return;
|
|
158
|
+
if (!isPathSafe(selected)) {
|
|
159
|
+
await interaction.reply({ content: 'Invalid directory path.', ephemeral: true });
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const message = await buildBrowserMessage(selected);
|
|
163
|
+
await interaction.update(message);
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Handle the "Parent" button -- navigate to the parent directory.
|
|
167
|
+
*/
|
|
168
|
+
export async function handleDirectoryParent(interaction) {
|
|
169
|
+
const state = parseFooterState(interaction);
|
|
170
|
+
const parent = path.dirname(state.path);
|
|
171
|
+
if (parent === state.path) {
|
|
172
|
+
// Already at filesystem root
|
|
173
|
+
await interaction.deferUpdate();
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
const message = await buildBrowserMessage(parent);
|
|
177
|
+
await interaction.update(message);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Handle the "Cancel" button -- reset to home directory.
|
|
181
|
+
*/
|
|
182
|
+
export async function handleDirectoryCancel(interaction) {
|
|
183
|
+
const message = await buildBrowserMessage(HOMEDIR);
|
|
184
|
+
await interaction.update(message);
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Handle the "Previous" pagination button.
|
|
188
|
+
*/
|
|
189
|
+
export async function handleDirectoryPrev(interaction) {
|
|
190
|
+
const state = parseFooterState(interaction);
|
|
191
|
+
const newPage = Math.max(0, state.page - 1);
|
|
192
|
+
const message = await buildBrowserMessage(state.path, newPage);
|
|
193
|
+
await interaction.update(message);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Handle the "Next" pagination button.
|
|
197
|
+
*/
|
|
198
|
+
export async function handleDirectoryNext(interaction) {
|
|
199
|
+
const state = parseFooterState(interaction);
|
|
200
|
+
const message = await buildBrowserMessage(state.path, state.page + 1);
|
|
201
|
+
await interaction.update(message);
|
|
202
|
+
}
|
|
203
|
+
const MAX_SESSIONS_PER_USER = 3;
|
|
204
|
+
/**
|
|
205
|
+
* Handle the "Session Start" button -- show ephemeral model selection message.
|
|
206
|
+
*/
|
|
207
|
+
export async function handleSessionStart(interaction) {
|
|
208
|
+
const state = parseFooterState(interaction);
|
|
209
|
+
const guild = interaction.guild;
|
|
210
|
+
if (!guild) {
|
|
211
|
+
await interaction.reply({ content: 'This can only be used in a server.', ephemeral: true });
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
const guildConfig = loadGuildConfig(guild.id);
|
|
215
|
+
if (!guildConfig) {
|
|
216
|
+
await interaction.reply({ content: 'A4D is not set up in this server. Run `/a4d init` first.', ephemeral: true });
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
// Enforce concurrent session limit
|
|
220
|
+
const userSessions = sessionManager.getAllSessions().filter((s) => s.userId === interaction.user.id && s.guildId === guild.id);
|
|
221
|
+
if (userSessions.length >= MAX_SESSIONS_PER_USER) {
|
|
222
|
+
await interaction.reply({
|
|
223
|
+
content: `You already have ${MAX_SESSIONS_PER_USER} active sessions. Stop one before starting a new one.`,
|
|
224
|
+
ephemeral: true,
|
|
225
|
+
});
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
// Show ephemeral model picker instead of immediately creating the session
|
|
229
|
+
const modelSelect = new StringSelectMenuBuilder()
|
|
230
|
+
.setCustomId('a4d:model:select')
|
|
231
|
+
.setPlaceholder('Select a model...')
|
|
232
|
+
.addOptions({ label: 'Opus 4.6 (most capable)', value: 'opus', default: true }, { label: 'Sonnet 4.6 (fast)', value: 'sonnet' }, { label: 'Haiku 4.5 (fastest)', value: 'haiku' });
|
|
233
|
+
const selectRow = new ActionRowBuilder().addComponents(modelSelect);
|
|
234
|
+
const buttonRow = new ActionRowBuilder().addComponents(new ButtonBuilder().setCustomId('a4d:model:confirm').setLabel('Start Session').setStyle(ButtonStyle.Success), new ButtonBuilder().setCustomId('a4d:model:cancel').setLabel('Cancel').setStyle(ButtonStyle.Secondary));
|
|
235
|
+
const embed = new EmbedBuilder()
|
|
236
|
+
.setTitle('Select Model')
|
|
237
|
+
.setDescription('Choose the Claude model for this session.')
|
|
238
|
+
.setFooter({ text: `${state.path} | model:opus` })
|
|
239
|
+
.setColor(0x5865f2);
|
|
240
|
+
await interaction.reply({
|
|
241
|
+
embeds: [embed],
|
|
242
|
+
components: [selectRow, buttonRow],
|
|
243
|
+
ephemeral: true,
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
// ---------------------------------------------------------------------------
|
|
247
|
+
// Model footer parser
|
|
248
|
+
// ---------------------------------------------------------------------------
|
|
249
|
+
function parseModelFooter(interaction) {
|
|
250
|
+
const text = interaction.message.embeds[0]?.footer?.text ?? '';
|
|
251
|
+
const parts = text.split(' | ');
|
|
252
|
+
const pathValue = parts[0] || os.homedir();
|
|
253
|
+
let model = 'opus';
|
|
254
|
+
for (const part of parts) {
|
|
255
|
+
if (part.startsWith('model:'))
|
|
256
|
+
model = part.slice(6);
|
|
257
|
+
}
|
|
258
|
+
return { path: pathValue, model };
|
|
259
|
+
}
|
|
260
|
+
// ---------------------------------------------------------------------------
|
|
261
|
+
// Model selection handlers
|
|
262
|
+
// ---------------------------------------------------------------------------
|
|
263
|
+
/**
|
|
264
|
+
* Handle model select menu -- update the embed footer with the chosen model.
|
|
265
|
+
*/
|
|
266
|
+
export async function handleModelSelect(interaction) {
|
|
267
|
+
const selected = interaction.values[0];
|
|
268
|
+
if (!selected)
|
|
269
|
+
return;
|
|
270
|
+
const { path: cwdPath } = parseModelFooter(interaction);
|
|
271
|
+
const modelLabels = {
|
|
272
|
+
opus: 'Opus 4.6 (most capable)',
|
|
273
|
+
sonnet: 'Sonnet 4.6 (fast)',
|
|
274
|
+
haiku: 'Haiku 4.5 (fastest)',
|
|
275
|
+
};
|
|
276
|
+
const modelSelect = new StringSelectMenuBuilder()
|
|
277
|
+
.setCustomId('a4d:model:select')
|
|
278
|
+
.setPlaceholder('Select a model...')
|
|
279
|
+
.addOptions({ label: 'Opus 4.6 (most capable)', value: 'opus', default: selected === 'opus' }, { label: 'Sonnet 4.6 (fast)', value: 'sonnet', default: selected === 'sonnet' }, { label: 'Haiku 4.5 (fastest)', value: 'haiku', default: selected === 'haiku' });
|
|
280
|
+
const selectRow = new ActionRowBuilder().addComponents(modelSelect);
|
|
281
|
+
const buttonRow = new ActionRowBuilder().addComponents(new ButtonBuilder().setCustomId('a4d:model:confirm').setLabel('Start Session').setStyle(ButtonStyle.Success), new ButtonBuilder().setCustomId('a4d:model:cancel').setLabel('Cancel').setStyle(ButtonStyle.Secondary));
|
|
282
|
+
const embed = new EmbedBuilder()
|
|
283
|
+
.setTitle('Select Model')
|
|
284
|
+
.setDescription(`Choose the Claude model for this session.\nSelected: **${modelLabels[selected] ?? selected}**`)
|
|
285
|
+
.setFooter({ text: `${cwdPath} | model:${selected}` })
|
|
286
|
+
.setColor(0x5865f2);
|
|
287
|
+
await interaction.update({
|
|
288
|
+
embeds: [embed],
|
|
289
|
+
components: [selectRow, buttonRow],
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Handle model confirm button -- create session channel and start a Claude Code session.
|
|
294
|
+
*/
|
|
295
|
+
export async function handleModelConfirm(interaction) {
|
|
296
|
+
const { path: cwdPath, model } = parseModelFooter(interaction);
|
|
297
|
+
const guild = interaction.guild;
|
|
298
|
+
if (!guild) {
|
|
299
|
+
await interaction.reply({ content: 'This can only be used in a server.', ephemeral: true });
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
const guildConfig = loadGuildConfig(guild.id);
|
|
303
|
+
if (!guildConfig) {
|
|
304
|
+
await interaction.reply({ content: 'A4D is not set up in this server. Run `/a4d init` first.', ephemeral: true });
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
// Re-check concurrent session limit
|
|
308
|
+
const userSessions = sessionManager.getAllSessions().filter((s) => s.userId === interaction.user.id && s.guildId === guild.id);
|
|
309
|
+
if (userSessions.length >= MAX_SESSIONS_PER_USER) {
|
|
310
|
+
await interaction.update({
|
|
311
|
+
content: `You already have ${MAX_SESSIONS_PER_USER} active sessions. Stop one before starting a new one.`,
|
|
312
|
+
embeds: [],
|
|
313
|
+
components: [],
|
|
314
|
+
});
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
// Acknowledge -- channel creation + session start may take >3s
|
|
318
|
+
await interaction.update({
|
|
319
|
+
content: 'Creating session...',
|
|
320
|
+
embeds: [],
|
|
321
|
+
components: [],
|
|
322
|
+
});
|
|
323
|
+
try {
|
|
324
|
+
// Create session channel under Sessions category
|
|
325
|
+
const dirName = path.basename(cwdPath) || 'home';
|
|
326
|
+
const channel = await guild.channels.create({
|
|
327
|
+
name: `a4d-${dirName}`.slice(0, 100).toLowerCase(),
|
|
328
|
+
type: ChannelType.GuildText,
|
|
329
|
+
parent: guildConfig.sessionsCategoryId,
|
|
330
|
+
});
|
|
331
|
+
// Start Claude Code session with selected model
|
|
332
|
+
const session = sessionManager.createSession(guild.id, interaction.user.id, channel.id, cwdPath, model, async (toolName, input, options) => {
|
|
333
|
+
console.log(`[canUseTool] Called: tool=${toolName}, toolUseID=${options?.toolUseID}`);
|
|
334
|
+
const result = await requestPermission(channel, interaction.user.id, toolName, input);
|
|
335
|
+
console.log(`[canUseTool] Resolved: tool=${toolName}, behavior=${result.behavior}`);
|
|
336
|
+
return result;
|
|
337
|
+
});
|
|
338
|
+
// Persist to guild config
|
|
339
|
+
saveSessionToGuild(guild.id, channel.id, session.sessionId || '', cwdPath, interaction.user.id);
|
|
340
|
+
// Post and pin status embed with controls
|
|
341
|
+
const statusEmbed = buildStatusEmbed({
|
|
342
|
+
status: 'Session Active',
|
|
343
|
+
color: COLORS.IDLE,
|
|
344
|
+
cwd: displayPath(cwdPath),
|
|
345
|
+
model,
|
|
346
|
+
sessionId: session.sessionId || 'pending',
|
|
347
|
+
costUsd: 0,
|
|
348
|
+
startedAt: new Date().toISOString(),
|
|
349
|
+
});
|
|
350
|
+
const controlRow = new ActionRowBuilder().addComponents(new ButtonBuilder().setCustomId('a4d:session:stop').setLabel('Stop').setStyle(ButtonStyle.Danger), new ButtonBuilder().setCustomId('a4d:session:archive').setLabel('Archive').setStyle(ButtonStyle.Secondary));
|
|
351
|
+
const statusMsg = await channel.send({ embeds: [statusEmbed], components: [controlRow] });
|
|
352
|
+
await statusMsg.pin().catch(() => { });
|
|
353
|
+
// Update the ephemeral message with a link to the new channel
|
|
354
|
+
await interaction.editReply({
|
|
355
|
+
content: `Session started in <#${channel.id}>`,
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
catch (err) {
|
|
359
|
+
console.error('[session-start] Failed to create session:', err);
|
|
360
|
+
await interaction.editReply({
|
|
361
|
+
content: 'Failed to create session. Make sure the bot has permission to create channels.',
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Handle model cancel button -- dismiss the ephemeral model picker.
|
|
367
|
+
*/
|
|
368
|
+
export async function handleModelCancel(interaction) {
|
|
369
|
+
await interaction.update({ content: 'Cancelled.', embeds: [], components: [] });
|
|
370
|
+
}
|
|
371
|
+
// ---------------------------------------------------------------------------
|
|
372
|
+
// Relative time helper
|
|
373
|
+
// ---------------------------------------------------------------------------
|
|
374
|
+
function relativeTime(date) {
|
|
375
|
+
const seconds = Math.floor((Date.now() - date.getTime()) / 1000);
|
|
376
|
+
if (seconds < 60)
|
|
377
|
+
return 'just now';
|
|
378
|
+
const minutes = Math.floor(seconds / 60);
|
|
379
|
+
if (minutes < 60)
|
|
380
|
+
return `${minutes}m ago`;
|
|
381
|
+
const hours = Math.floor(minutes / 60);
|
|
382
|
+
if (hours < 24)
|
|
383
|
+
return `${hours}h ago`;
|
|
384
|
+
const days = Math.floor(hours / 24);
|
|
385
|
+
return `${days}d ago`;
|
|
386
|
+
}
|
|
387
|
+
// ---------------------------------------------------------------------------
|
|
388
|
+
// Build resume picker message
|
|
389
|
+
// ---------------------------------------------------------------------------
|
|
390
|
+
function buildResumePickerMessage(dirPath, sessions, selectedSessionId) {
|
|
391
|
+
const footerState = {
|
|
392
|
+
path: dirPath,
|
|
393
|
+
page: 0,
|
|
394
|
+
mode: 'resume',
|
|
395
|
+
selectedSessionId,
|
|
396
|
+
};
|
|
397
|
+
const footerText = selectedSessionId
|
|
398
|
+
? `${dirPath} | p0 | mode:resume | sid:${selectedSessionId}`
|
|
399
|
+
: `${dirPath} | p0 | mode:resume`;
|
|
400
|
+
const embed = new EmbedBuilder()
|
|
401
|
+
.setTitle('Resume Existing Session')
|
|
402
|
+
.setDescription(`Directory: ${displayPath(dirPath)}`)
|
|
403
|
+
.setFooter({ text: footerText })
|
|
404
|
+
.setColor(0x57f287);
|
|
405
|
+
// Sort by most recent first, limit to 25
|
|
406
|
+
const sorted = [...sessions]
|
|
407
|
+
.sort((a, b) => b.lastModified - a.lastModified)
|
|
408
|
+
.slice(0, MAX_SELECT_OPTIONS);
|
|
409
|
+
const selectMenu = new StringSelectMenuBuilder()
|
|
410
|
+
.setCustomId('a4d:resume:browse')
|
|
411
|
+
.setPlaceholder('Select a session to resume...');
|
|
412
|
+
for (const sess of sorted) {
|
|
413
|
+
const label = (sess.summary || sess.sessionId).slice(0, MAX_LABEL_LENGTH);
|
|
414
|
+
const description = relativeTime(new Date(sess.lastModified));
|
|
415
|
+
selectMenu.addOptions({
|
|
416
|
+
label,
|
|
417
|
+
description,
|
|
418
|
+
value: sess.sessionId,
|
|
419
|
+
default: sess.sessionId === selectedSessionId,
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
const selectRow = new ActionRowBuilder().addComponents(selectMenu);
|
|
423
|
+
const backButton = new ButtonBuilder()
|
|
424
|
+
.setCustomId('a4d:resume:back')
|
|
425
|
+
.setLabel('Back')
|
|
426
|
+
.setStyle(ButtonStyle.Secondary);
|
|
427
|
+
const resumeStartButton = new ButtonBuilder()
|
|
428
|
+
.setCustomId('a4d:resume:start')
|
|
429
|
+
.setLabel('Resume')
|
|
430
|
+
.setStyle(ButtonStyle.Success)
|
|
431
|
+
.setDisabled(!selectedSessionId);
|
|
432
|
+
const buttonRow = new ActionRowBuilder().addComponents(backButton, resumeStartButton);
|
|
433
|
+
return { embeds: [embed], components: [selectRow, buttonRow] };
|
|
434
|
+
}
|
|
435
|
+
// ---------------------------------------------------------------------------
|
|
436
|
+
// Resume interaction handlers
|
|
437
|
+
// ---------------------------------------------------------------------------
|
|
438
|
+
/**
|
|
439
|
+
* Handle the "Resume Session" button -- switch to session picker mode.
|
|
440
|
+
*/
|
|
441
|
+
export async function handleResumeSession(interaction) {
|
|
442
|
+
const state = parseFooterState(interaction);
|
|
443
|
+
let sessions;
|
|
444
|
+
try {
|
|
445
|
+
sessions = await listSessions({ dir: state.path, limit: MAX_SELECT_OPTIONS });
|
|
446
|
+
}
|
|
447
|
+
catch (err) {
|
|
448
|
+
console.error('[resume-session] Failed to list sessions:', err);
|
|
449
|
+
sessions = [];
|
|
450
|
+
}
|
|
451
|
+
if (sessions.length === 0) {
|
|
452
|
+
await interaction.reply({ content: 'No existing sessions for this directory.', ephemeral: true });
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
const message = buildResumePickerMessage(state.path, sessions);
|
|
456
|
+
await interaction.update(message);
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Handle session selection from the resume picker StringSelectMenu.
|
|
460
|
+
*/
|
|
461
|
+
export async function handleResumeBrowse(interaction) {
|
|
462
|
+
const state = parseFooterState(interaction);
|
|
463
|
+
const selectedId = interaction.values[0];
|
|
464
|
+
if (!selectedId)
|
|
465
|
+
return;
|
|
466
|
+
// Re-list sessions to rebuild the picker with the selection stored in footer
|
|
467
|
+
let sessions;
|
|
468
|
+
try {
|
|
469
|
+
sessions = await listSessions({ dir: state.path, limit: MAX_SELECT_OPTIONS });
|
|
470
|
+
}
|
|
471
|
+
catch (err) {
|
|
472
|
+
console.error('[resume-browse] Failed to list sessions:', err);
|
|
473
|
+
sessions = [];
|
|
474
|
+
}
|
|
475
|
+
if (sessions.length === 0) {
|
|
476
|
+
await interaction.reply({ content: 'No existing sessions for this directory.', ephemeral: true });
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
const message = buildResumePickerMessage(state.path, sessions, selectedId);
|
|
480
|
+
await interaction.update(message);
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Handle the "Back" button in the resume picker -- return to directory browser.
|
|
484
|
+
*/
|
|
485
|
+
export async function handleResumeBack(interaction) {
|
|
486
|
+
const state = parseFooterState(interaction);
|
|
487
|
+
const message = await buildBrowserMessage(state.path);
|
|
488
|
+
await interaction.update(message);
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Handle the "Resume" button in the resume picker -- resume the selected session.
|
|
492
|
+
*/
|
|
493
|
+
export async function handleResumeStart(interaction) {
|
|
494
|
+
const state = parseFooterState(interaction);
|
|
495
|
+
const guild = interaction.guild;
|
|
496
|
+
if (!state.selectedSessionId) {
|
|
497
|
+
await interaction.reply({ content: 'No session selected. Please select a session first.', ephemeral: true });
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
if (!guild) {
|
|
501
|
+
await interaction.reply({ content: 'This can only be used in a server.', ephemeral: true });
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
const guildConfig = loadGuildConfig(guild.id);
|
|
505
|
+
if (!guildConfig) {
|
|
506
|
+
await interaction.reply({ content: 'A4D is not set up in this server. Run `/a4d init` first.', ephemeral: true });
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
509
|
+
// Enforce concurrent session limit
|
|
510
|
+
const userSessions = sessionManager.getAllSessions().filter((s) => s.userId === interaction.user.id && s.guildId === guild.id);
|
|
511
|
+
if (userSessions.length >= MAX_SESSIONS_PER_USER) {
|
|
512
|
+
await interaction.reply({
|
|
513
|
+
content: `You already have ${MAX_SESSIONS_PER_USER} active sessions. Stop one before resuming another.`,
|
|
514
|
+
ephemeral: true,
|
|
515
|
+
});
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
await interaction.deferUpdate();
|
|
519
|
+
try {
|
|
520
|
+
// Create session channel under Sessions category
|
|
521
|
+
const dirName = path.basename(state.path) || 'home';
|
|
522
|
+
const channel = await guild.channels.create({
|
|
523
|
+
name: `a4d-${dirName}`.slice(0, 100).toLowerCase(),
|
|
524
|
+
type: ChannelType.GuildText,
|
|
525
|
+
parent: guildConfig.sessionsCategoryId,
|
|
526
|
+
});
|
|
527
|
+
// Resume Claude Code session
|
|
528
|
+
const session = sessionManager.resumeSession(guild.id, interaction.user.id, channel.id, state.selectedSessionId, state.path, undefined, // model
|
|
529
|
+
async (toolName, input, options) => {
|
|
530
|
+
console.log(`[canUseTool] Called: tool=${toolName}, toolUseID=${options?.toolUseID}`);
|
|
531
|
+
const result = await requestPermission(channel, interaction.user.id, toolName, input);
|
|
532
|
+
console.log(`[canUseTool] Resolved: tool=${toolName}, behavior=${result.behavior}`);
|
|
533
|
+
return result;
|
|
534
|
+
});
|
|
535
|
+
// Persist to guild config
|
|
536
|
+
saveSessionToGuild(guild.id, channel.id, session.sessionId, state.path, interaction.user.id);
|
|
537
|
+
// Post and pin status embed with controls
|
|
538
|
+
const statusEmbed = buildStatusEmbed({
|
|
539
|
+
status: 'Session Active',
|
|
540
|
+
color: COLORS.IDLE,
|
|
541
|
+
cwd: displayPath(state.path),
|
|
542
|
+
model: 'opus',
|
|
543
|
+
sessionId: session.sessionId || 'pending',
|
|
544
|
+
costUsd: 0,
|
|
545
|
+
startedAt: new Date().toISOString(),
|
|
546
|
+
});
|
|
547
|
+
const controlRow = new ActionRowBuilder().addComponents(new ButtonBuilder().setCustomId('a4d:session:stop').setLabel('Stop').setStyle(ButtonStyle.Danger), new ButtonBuilder().setCustomId('a4d:session:archive').setLabel('Archive').setStyle(ButtonStyle.Secondary));
|
|
548
|
+
const statusMsg = await channel.send({ embeds: [statusEmbed], components: [controlRow] });
|
|
549
|
+
await statusMsg.pin().catch(() => { });
|
|
550
|
+
// Post previous conversation history
|
|
551
|
+
await postSessionHistory(channel, state.selectedSessionId, state.path);
|
|
552
|
+
// Reset directory browser to home
|
|
553
|
+
const browserMsg = await buildBrowserMessage(HOMEDIR);
|
|
554
|
+
await interaction.editReply(browserMsg);
|
|
555
|
+
// Send followup linking to the new channel
|
|
556
|
+
await interaction.followUp({
|
|
557
|
+
content: `Session resumed in <#${channel.id}>`,
|
|
558
|
+
ephemeral: true,
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
catch (err) {
|
|
562
|
+
console.error('[resume-start] Failed to resume session:', err);
|
|
563
|
+
await interaction.followUp({
|
|
564
|
+
content: 'Failed to resume session. Make sure the bot has permission to create channels.',
|
|
565
|
+
ephemeral: true,
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* Load and post previous conversation history into a session channel.
|
|
571
|
+
*/
|
|
572
|
+
async function postSessionHistory(channel, sessionId, cwd) {
|
|
573
|
+
try {
|
|
574
|
+
const messages = await getSessionMessages(sessionId, { dir: cwd, limit: 50 });
|
|
575
|
+
if (messages.length === 0)
|
|
576
|
+
return;
|
|
577
|
+
await channel.send({
|
|
578
|
+
embeds: [new EmbedBuilder()
|
|
579
|
+
.setTitle('Previous Conversation')
|
|
580
|
+
.setDescription(`Showing last ${messages.length} messages from this session.`)
|
|
581
|
+
.setColor(0x95a5a6)],
|
|
582
|
+
});
|
|
583
|
+
for (const msg of messages) {
|
|
584
|
+
const content = msg.message;
|
|
585
|
+
let text = '';
|
|
586
|
+
if (typeof content.content === 'string') {
|
|
587
|
+
text = content.content;
|
|
588
|
+
}
|
|
589
|
+
else if (Array.isArray(content.content)) {
|
|
590
|
+
text = content.content
|
|
591
|
+
.filter((b) => b.type === 'text' && b.text)
|
|
592
|
+
.map((b) => b.text)
|
|
593
|
+
.join('\n');
|
|
594
|
+
}
|
|
595
|
+
if (!text)
|
|
596
|
+
continue;
|
|
597
|
+
const prefix = msg.type === 'user' ? '**You:**' : '**Claude:**';
|
|
598
|
+
const full = `${prefix}\n${text}`;
|
|
599
|
+
const chunks = chunkMessage(full);
|
|
600
|
+
for (const chunk of chunks) {
|
|
601
|
+
await channel.send(chunk);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
await channel.send('---\n*Session resumed. You can continue chatting.*');
|
|
605
|
+
}
|
|
606
|
+
catch (err) {
|
|
607
|
+
console.error('[history] Failed to load session history:', err);
|
|
608
|
+
await channel.send('*Could not load previous conversation history.*').catch(() => { });
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
//# sourceMappingURL=directoryBrowser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directoryBrowser.js","sourceRoot":"","sources":["../../src/interactions/directoryBrowser.ts"],"names":[],"mappings":"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"}
|