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.
Files changed (78) hide show
  1. package/README.ko.md +134 -0
  2. package/README.md +170 -0
  3. package/dist/bot.d.ts +1 -0
  4. package/dist/bot.js +114 -0
  5. package/dist/bot.js.map +1 -0
  6. package/dist/cli.d.ts +2 -0
  7. package/dist/cli.js +27 -0
  8. package/dist/cli.js.map +1 -0
  9. package/dist/commands/index.d.ts +9 -0
  10. package/dist/commands/index.js +44 -0
  11. package/dist/commands/index.js.map +1 -0
  12. package/dist/commands/init.d.ts +5 -0
  13. package/dist/commands/init.js +152 -0
  14. package/dist/commands/init.js.map +1 -0
  15. package/dist/commands/model.d.ts +5 -0
  16. package/dist/commands/model.js +65 -0
  17. package/dist/commands/model.js.map +1 -0
  18. package/dist/commands/resume.d.ts +6 -0
  19. package/dist/commands/resume.js +113 -0
  20. package/dist/commands/resume.js.map +1 -0
  21. package/dist/config.d.ts +12 -0
  22. package/dist/config.js +49 -0
  23. package/dist/config.js.map +1 -0
  24. package/dist/formatters/chunker.d.ts +5 -0
  25. package/dist/formatters/chunker.js +46 -0
  26. package/dist/formatters/chunker.js.map +1 -0
  27. package/dist/formatters/embedBuilder.d.ts +28 -0
  28. package/dist/formatters/embedBuilder.js +32 -0
  29. package/dist/formatters/embedBuilder.js.map +1 -0
  30. package/dist/formatters/toolFormatter.d.ts +4 -0
  31. package/dist/formatters/toolFormatter.js +90 -0
  32. package/dist/formatters/toolFormatter.js.map +1 -0
  33. package/dist/guild.d.ts +22 -0
  34. package/dist/guild.js +41 -0
  35. package/dist/guild.js.map +1 -0
  36. package/dist/interactions/directoryBrowser.d.ts +61 -0
  37. package/dist/interactions/directoryBrowser.js +611 -0
  38. package/dist/interactions/directoryBrowser.js.map +1 -0
  39. package/dist/interactions/index.d.ts +5 -0
  40. package/dist/interactions/index.js +92 -0
  41. package/dist/interactions/index.js.map +1 -0
  42. package/dist/interactions/permissionHandler.d.ts +11 -0
  43. package/dist/interactions/permissionHandler.js +107 -0
  44. package/dist/interactions/permissionHandler.js.map +1 -0
  45. package/dist/interactions/sessionControls.d.ts +9 -0
  46. package/dist/interactions/sessionControls.js +95 -0
  47. package/dist/interactions/sessionControls.js.map +1 -0
  48. package/dist/sessions/eventHandler.d.ts +3 -0
  49. package/dist/sessions/eventHandler.js +209 -0
  50. package/dist/sessions/eventHandler.js.map +1 -0
  51. package/dist/sessions/sessionManager.d.ts +29 -0
  52. package/dist/sessions/sessionManager.js +203 -0
  53. package/dist/sessions/sessionManager.js.map +1 -0
  54. package/dist/sessions/sessionStore.d.ts +4 -0
  55. package/dist/sessions/sessionStore.js +29 -0
  56. package/dist/sessions/sessionStore.js.map +1 -0
  57. package/dist/sessions/streamHandler.d.ts +18 -0
  58. package/dist/sessions/streamHandler.js +119 -0
  59. package/dist/sessions/streamHandler.js.map +1 -0
  60. package/dist/sessions/toolProgress.d.ts +14 -0
  61. package/dist/sessions/toolProgress.js +65 -0
  62. package/dist/sessions/toolProgress.js.map +1 -0
  63. package/dist/sessions/usageTracker.d.ts +12 -0
  64. package/dist/sessions/usageTracker.js +222 -0
  65. package/dist/sessions/usageTracker.js.map +1 -0
  66. package/dist/setup.d.ts +1 -0
  67. package/dist/setup.js +101 -0
  68. package/dist/setup.js.map +1 -0
  69. package/dist/utils/filesystem.d.ts +11 -0
  70. package/dist/utils/filesystem.js +26 -0
  71. package/dist/utils/filesystem.js.map +1 -0
  72. package/dist/utils/logger.d.ts +1 -0
  73. package/dist/utils/logger.js +3 -0
  74. package/dist/utils/logger.js.map +1 -0
  75. package/dist/utils/plugins.d.ts +6 -0
  76. package/dist/utils/plugins.js +66 -0
  77. package/dist/utils/plugins.js.map +1 -0
  78. package/package.json +45 -0
@@ -0,0 +1,203 @@
1
+ // Session lifecycle -- AGE-016
2
+ import { EventEmitter } from 'node:events';
3
+ import { query, } from '@anthropic-ai/claude-agent-sdk';
4
+ import { resolvePlugins } from '../utils/plugins.js';
5
+ class SessionManager extends EventEmitter {
6
+ sessions = new Map();
7
+ createSession(guildId, userId, channelId, cwd, model, canUseTool) {
8
+ const controller = new AbortController();
9
+ let resolveNext = null;
10
+ async function* messageStream() {
11
+ while (true) {
12
+ const msg = await new Promise((resolve) => {
13
+ resolveNext = resolve;
14
+ });
15
+ yield msg;
16
+ }
17
+ }
18
+ const plugins = resolvePlugins();
19
+ const q = query({
20
+ prompt: messageStream(),
21
+ options: {
22
+ cwd,
23
+ model: model || 'opus',
24
+ permissionMode: 'default',
25
+ includePartialMessages: true,
26
+ abortController: controller,
27
+ canUseTool,
28
+ plugins,
29
+ },
30
+ });
31
+ const session = {
32
+ query: q,
33
+ channelId,
34
+ guildId,
35
+ userId,
36
+ sessionId: '',
37
+ cwd,
38
+ state: 'running',
39
+ totalCostUsd: 0,
40
+ createdAt: new Date().toISOString(),
41
+ resolveNext: null,
42
+ abortController: controller,
43
+ };
44
+ // Wire up resolveNext -- the generator captures the outer variable,
45
+ // but ActiveSession needs its own reference so sendMessage can call it.
46
+ // Because the generator closure mutates the local `resolveNext`, we
47
+ // need a proxy that always reads the latest value.
48
+ Object.defineProperty(session, 'resolveNext', {
49
+ get: () => resolveNext,
50
+ set: (v) => {
51
+ resolveNext = v;
52
+ },
53
+ enumerable: true,
54
+ configurable: true,
55
+ });
56
+ this.sessions.set(channelId, session);
57
+ void this._processEvents(session);
58
+ return session;
59
+ }
60
+ resumeSession(guildId, userId, channelId, sessionId, cwd, model, canUseTool) {
61
+ const controller = new AbortController();
62
+ let resolveNext = null;
63
+ async function* messageStream() {
64
+ while (true) {
65
+ const msg = await new Promise((resolve) => {
66
+ resolveNext = resolve;
67
+ });
68
+ yield msg;
69
+ }
70
+ }
71
+ const plugins = resolvePlugins();
72
+ const q = query({
73
+ prompt: messageStream(),
74
+ options: {
75
+ cwd,
76
+ model: model || 'opus',
77
+ permissionMode: 'default',
78
+ includePartialMessages: true,
79
+ abortController: controller,
80
+ resume: sessionId,
81
+ canUseTool,
82
+ plugins,
83
+ },
84
+ });
85
+ const session = {
86
+ query: q,
87
+ channelId,
88
+ guildId,
89
+ userId,
90
+ sessionId,
91
+ cwd,
92
+ state: 'running',
93
+ totalCostUsd: 0,
94
+ createdAt: new Date().toISOString(),
95
+ resolveNext: null,
96
+ abortController: controller,
97
+ };
98
+ Object.defineProperty(session, 'resolveNext', {
99
+ get: () => resolveNext,
100
+ set: (v) => {
101
+ resolveNext = v;
102
+ },
103
+ enumerable: true,
104
+ configurable: true,
105
+ });
106
+ this.sessions.set(channelId, session);
107
+ void this._processEvents(session);
108
+ return session;
109
+ }
110
+ sendMessage(channelId, content) {
111
+ const session = this.sessions.get(channelId);
112
+ if (!session) {
113
+ throw new Error(`No session found for channel ${channelId}`);
114
+ }
115
+ if (session.state === 'stopped' || session.state === 'archived') {
116
+ throw new Error(`Session for channel ${channelId} is ${session.state}`);
117
+ }
118
+ session.state = 'running';
119
+ if (session.resolveNext) {
120
+ session.resolveNext({
121
+ type: 'user',
122
+ message: { role: 'user', content },
123
+ parent_tool_use_id: null,
124
+ });
125
+ }
126
+ }
127
+ getSession(channelId) {
128
+ return this.sessions.get(channelId) ?? null;
129
+ }
130
+ stopSession(channelId) {
131
+ const session = this.sessions.get(channelId);
132
+ if (!session)
133
+ return;
134
+ session.query.close();
135
+ session.state = 'stopped';
136
+ }
137
+ removeSession(channelId) {
138
+ const session = this.sessions.get(channelId);
139
+ if (!session)
140
+ return;
141
+ if (session.state !== 'stopped' && session.state !== 'archived') {
142
+ this.stopSession(channelId);
143
+ }
144
+ this.sessions.delete(channelId);
145
+ }
146
+ getAllSessions() {
147
+ return [...this.sessions.values()];
148
+ }
149
+ async _processEvents(session) {
150
+ try {
151
+ for await (const msg of session.query) {
152
+ // Log all non-stream messages for debugging
153
+ if (msg.type !== 'stream_event' && msg.type !== 'tool_progress') {
154
+ console.log(`[sdk:${msg.type}]`, JSON.stringify(msg, null, 2).slice(0, 500));
155
+ }
156
+ switch (msg.type) {
157
+ case 'system': {
158
+ const sysMsg = msg;
159
+ if (sysMsg.subtype === 'init' && sysMsg.session_id) {
160
+ session.sessionId = sysMsg.session_id;
161
+ }
162
+ session.state = 'idle';
163
+ break;
164
+ }
165
+ case 'assistant': {
166
+ this.emit('assistant', session.channelId, msg);
167
+ break;
168
+ }
169
+ case 'result': {
170
+ const resultMsg = msg;
171
+ console.log(`[sdk:result] subtype=${resultMsg.subtype}, cost=$${resultMsg.total_cost_usd}`);
172
+ session.totalCostUsd = resultMsg.total_cost_usd ?? session.totalCostUsd;
173
+ session.state = 'idle';
174
+ this.emit('result', session.channelId, resultMsg);
175
+ break;
176
+ }
177
+ case 'stream_event':
178
+ this.emit('stream_event', session.channelId, msg);
179
+ break;
180
+ case 'tool_progress':
181
+ this.emit('tool_progress', session.channelId, msg);
182
+ break;
183
+ default: {
184
+ // Handle rate_limit_event
185
+ const anyMsg = msg;
186
+ if (anyMsg.type === 'rate_limit_event' && anyMsg.rate_limit_info) {
187
+ console.log('[sdk:rate_limit]', JSON.stringify(anyMsg.rate_limit_info));
188
+ this.emit('rate_limit', session.guildId, anyMsg.rate_limit_info);
189
+ }
190
+ break;
191
+ }
192
+ }
193
+ }
194
+ }
195
+ catch (err) {
196
+ console.error(`[session] Event processing error for channel ${session.channelId}:`, err);
197
+ session.state = 'stopped';
198
+ this.emit('error', session.channelId, err);
199
+ }
200
+ }
201
+ }
202
+ export const sessionManager = new SessionManager();
203
+ //# sourceMappingURL=sessionManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessionManager.js","sourceRoot":"","sources":["../../src/sessions/sessionManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { type SessionEntry } from '../guild.js';
2
+ export declare function saveSessionToGuild(guildId: string, channelId: string, sessionId: string, cwd: string, userId: string): void;
3
+ export declare function removeSessionFromGuild(guildId: string, channelId: string): void;
4
+ export declare function getSessionsForGuild(guildId: string): Record<string, SessionEntry>;
@@ -0,0 +1,29 @@
1
+ // Persist session metadata to guild config -- AGE-016
2
+ import { loadGuildConfig, saveGuildConfig, } from '../guild.js';
3
+ export function saveSessionToGuild(guildId, channelId, sessionId, cwd, userId) {
4
+ const config = loadGuildConfig(guildId);
5
+ if (!config) {
6
+ throw new Error(`Guild config not found for guild ${guildId}`);
7
+ }
8
+ config.activeSessions[channelId] = {
9
+ sessionId,
10
+ cwd,
11
+ createdAt: new Date().toISOString(),
12
+ userId,
13
+ };
14
+ saveGuildConfig(config);
15
+ }
16
+ export function removeSessionFromGuild(guildId, channelId) {
17
+ const config = loadGuildConfig(guildId);
18
+ if (!config)
19
+ return;
20
+ delete config.activeSessions[channelId];
21
+ saveGuildConfig(config);
22
+ }
23
+ export function getSessionsForGuild(guildId) {
24
+ const config = loadGuildConfig(guildId);
25
+ if (!config)
26
+ return {};
27
+ return config.activeSessions;
28
+ }
29
+ //# sourceMappingURL=sessionStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessionStore.js","sourceRoot":"","sources":["../../src/sessions/sessionStore.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,OAAO,EACL,eAAe,EACf,eAAe,GAEhB,MAAM,aAAa,CAAC;AAErB,MAAM,UAAU,kBAAkB,CAChC,OAAe,EACf,SAAiB,EACjB,SAAiB,EACjB,GAAW,EACX,MAAc;IAEd,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACxC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,oCAAoC,OAAO,EAAE,CAAC,CAAC;IACjE,CAAC;IAED,MAAM,CAAC,cAAc,CAAC,SAAS,CAAC,GAAG;QACjC,SAAS;QACT,GAAG;QACH,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,MAAM;KACP,CAAC;IAEF,eAAe,CAAC,MAAM,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,OAAe,EACf,SAAiB;IAEjB,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACxC,IAAI,CAAC,MAAM;QAAE,OAAO;IAEpB,OAAO,MAAM,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;IACxC,eAAe,CAAC,MAAM,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,OAAe;IAEf,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACxC,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IACvB,OAAO,MAAM,CAAC,cAAc,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { type TextChannel } from 'discord.js';
2
+ export declare class StreamHandler {
3
+ private channel;
4
+ private buffer;
5
+ private tokenCount;
6
+ private startTime;
7
+ private messageId;
8
+ private timer;
9
+ private debounceMs;
10
+ private type;
11
+ private finalized;
12
+ constructor(channel: TextChannel, type: 'text' | 'thinking', debounceMs?: number);
13
+ push(text: string): void;
14
+ private flush;
15
+ private sendOrEdit;
16
+ finalize(): Promise<void>;
17
+ getMessageId(): string | null;
18
+ }
@@ -0,0 +1,119 @@
1
+ import { EmbedBuilder } from 'discord.js';
2
+ import { COLORS } from '../formatters/embedBuilder.js';
3
+ export class StreamHandler {
4
+ channel;
5
+ buffer = '';
6
+ tokenCount = 0;
7
+ startTime = Date.now();
8
+ messageId = null;
9
+ timer = null;
10
+ debounceMs;
11
+ type;
12
+ finalized = false;
13
+ constructor(channel, type, debounceMs) {
14
+ this.channel = channel;
15
+ this.type = type;
16
+ this.debounceMs = debounceMs ?? (type === 'text' ? 1000 : 2000);
17
+ }
18
+ push(text) {
19
+ this.buffer += text;
20
+ this.tokenCount++;
21
+ if (!this.timer) {
22
+ this.timer = setTimeout(() => void this.flush(), this.debounceMs);
23
+ }
24
+ }
25
+ async flush() {
26
+ this.timer = null;
27
+ const elapsed = ((Date.now() - this.startTime) / 1000).toFixed(1);
28
+ if (this.type === 'text') {
29
+ // Streaming text: yellow embed with accumulated text
30
+ const description = this.buffer.length > 4090 ? this.buffer.slice(-4090) + '...' : this.buffer;
31
+ const embed = new EmbedBuilder()
32
+ .setTitle('Responding...')
33
+ .setDescription(description)
34
+ .setColor(COLORS.STREAMING)
35
+ .setFooter({ text: `${elapsed}s \u00b7 ${this.tokenCount} tokens` });
36
+ await this.sendOrEdit(embed);
37
+ }
38
+ else {
39
+ // Thinking: purple embed with only token count and time
40
+ const embed = new EmbedBuilder()
41
+ .setTitle('Thinking...')
42
+ .setColor(COLORS.THINKING)
43
+ .setFooter({ text: `${elapsed}s \u00b7 ${this.tokenCount} tokens` });
44
+ await this.sendOrEdit(embed);
45
+ }
46
+ }
47
+ async sendOrEdit(embed) {
48
+ try {
49
+ if (this.messageId) {
50
+ const msg = await this.channel.messages.fetch(this.messageId).catch(() => null);
51
+ if (msg) {
52
+ await msg.edit({ embeds: [embed] });
53
+ return;
54
+ }
55
+ }
56
+ const msg = await this.channel.send({ embeds: [embed] });
57
+ this.messageId = msg.id;
58
+ }
59
+ catch (err) {
60
+ console.error('[stream] Failed to update embed:', err);
61
+ }
62
+ }
63
+ async finalize() {
64
+ if (this.finalized)
65
+ return;
66
+ this.finalized = true;
67
+ // Clear any pending timer
68
+ if (this.timer) {
69
+ clearTimeout(this.timer);
70
+ this.timer = null;
71
+ }
72
+ const elapsed = ((Date.now() - this.startTime) / 1000).toFixed(1);
73
+ if (this.type === 'text') {
74
+ // Replace streaming embed with plain message(s)
75
+ if (this.messageId) {
76
+ try {
77
+ const msg = await this.channel.messages.fetch(this.messageId).catch(() => null);
78
+ if (msg)
79
+ await msg.delete().catch(() => { });
80
+ }
81
+ catch {
82
+ /* best-effort */
83
+ }
84
+ }
85
+ // Send as plain text, chunked if needed
86
+ if (this.buffer.length > 0) {
87
+ const { chunkMessage } = await import('../formatters/chunker.js');
88
+ const chunks = chunkMessage(this.buffer);
89
+ for (const chunk of chunks) {
90
+ await this.channel.send(chunk);
91
+ }
92
+ }
93
+ }
94
+ else {
95
+ // Thinking: finalize embed with "Thought for Xs"
96
+ const embed = new EmbedBuilder()
97
+ .setTitle(`Thought for ${elapsed}s`)
98
+ .setColor(COLORS.THINKING)
99
+ .setFooter({ text: `${this.tokenCount} tokens` });
100
+ if (this.messageId) {
101
+ try {
102
+ const msg = await this.channel.messages.fetch(this.messageId).catch(() => null);
103
+ if (msg) {
104
+ await msg.edit({ embeds: [embed] });
105
+ return;
106
+ }
107
+ }
108
+ catch {
109
+ /* best-effort */
110
+ }
111
+ }
112
+ await this.channel.send({ embeds: [embed] });
113
+ }
114
+ }
115
+ getMessageId() {
116
+ return this.messageId;
117
+ }
118
+ }
119
+ //# sourceMappingURL=streamHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streamHandler.js","sourceRoot":"","sources":["../../src/sessions/streamHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAoB,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAEvD,MAAM,OAAO,aAAa;IAChB,OAAO,CAAc;IACrB,MAAM,GAAG,EAAE,CAAC;IACZ,UAAU,GAAG,CAAC,CAAC;IACf,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,SAAS,GAAkB,IAAI,CAAC;IAChC,KAAK,GAAyC,IAAI,CAAC;IACnD,UAAU,CAAS;IACnB,IAAI,CAAsB;IAC1B,SAAS,GAAG,KAAK,CAAC;IAE1B,YAAY,OAAoB,EAAE,IAAyB,EAAE,UAAmB;QAC9E,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,UAAU,GAAG,UAAU,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAClE,CAAC;IAED,IAAI,CAAC,IAAY;QACf,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC;QACpB,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,KAAK;QACjB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,MAAM,OAAO,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAElE,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACzB,qDAAqD;YACrD,MAAM,WAAW,GACf,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;YAC7E,MAAM,KAAK,GAAG,IAAI,YAAY,EAAE;iBAC7B,QAAQ,CAAC,eAAe,CAAC;iBACzB,cAAc,CAAC,WAAW,CAAC;iBAC3B,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC;iBAC1B,SAAS,CAAC,EAAE,IAAI,EAAE,GAAG,OAAO,YAAY,IAAI,CAAC,UAAU,SAAS,EAAE,CAAC,CAAC;YAEvE,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;aAAM,CAAC;YACN,wDAAwD;YACxD,MAAM,KAAK,GAAG,IAAI,YAAY,EAAE;iBAC7B,QAAQ,CAAC,aAAa,CAAC;iBACvB,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC;iBACzB,SAAS,CAAC,EAAE,IAAI,EAAE,GAAG,OAAO,YAAY,IAAI,CAAC,UAAU,SAAS,EAAE,CAAC,CAAC;YAEvE,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,UAAU,CAAC,KAAmB;QAC1C,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACnB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;gBAChF,IAAI,GAAG,EAAE,CAAC;oBACR,MAAM,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;oBACpC,OAAO;gBACT,CAAC;YACH,CAAC;YACD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACzD,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC,EAAE,CAAC;QAC1B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,GAAG,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO;QAC3B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QAEtB,0BAA0B;QAC1B,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACzB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QACpB,CAAC;QAED,MAAM,OAAO,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAElE,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACzB,gDAAgD;YAChD,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACnB,IAAI,CAAC;oBACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;oBAChF,IAAI,GAAG;wBAAE,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;gBAC9C,CAAC;gBAAC,MAAM,CAAC;oBACP,iBAAiB;gBACnB,CAAC;YACH,CAAC;YACD,wCAAwC;YACxC,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3B,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,0BAA0B,CAAC,CAAC;gBAClE,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACzC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;oBAC3B,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACjC,CAAC;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,iDAAiD;YACjD,MAAM,KAAK,GAAG,IAAI,YAAY,EAAE;iBAC7B,QAAQ,CAAC,eAAe,OAAO,GAAG,CAAC;iBACnC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC;iBACzB,SAAS,CAAC,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,UAAU,SAAS,EAAE,CAAC,CAAC;YAEpD,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACnB,IAAI,CAAC;oBACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;oBAChF,IAAI,GAAG,EAAE,CAAC;wBACR,MAAM,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;wBACpC,OAAO;oBACT,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,iBAAiB;gBACnB,CAAC;YACH,CAAC;YACD,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAED,YAAY;QACV,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;CACF"}
@@ -0,0 +1,14 @@
1
+ import { type TextChannel } from 'discord.js';
2
+ export declare class ToolProgressHandler {
3
+ private channel;
4
+ private messageId;
5
+ private startTime;
6
+ private timer;
7
+ private toolName;
8
+ constructor(channel: TextChannel, toolName: string);
9
+ update(): void;
10
+ private flush;
11
+ private sendOrEdit;
12
+ finalize(): Promise<void>;
13
+ getMessageId(): string | null;
14
+ }
@@ -0,0 +1,65 @@
1
+ import { EmbedBuilder } from 'discord.js';
2
+ import { COLORS } from '../formatters/embedBuilder.js';
3
+ export class ToolProgressHandler {
4
+ channel;
5
+ messageId = null;
6
+ startTime = Date.now();
7
+ timer = null;
8
+ toolName;
9
+ constructor(channel, toolName) {
10
+ this.channel = channel;
11
+ this.toolName = toolName;
12
+ }
13
+ update() {
14
+ // Debounce at ~3s
15
+ if (!this.timer) {
16
+ this.timer = setTimeout(() => void this.flush(), 3000);
17
+ }
18
+ }
19
+ async flush() {
20
+ this.timer = null;
21
+ const elapsed = ((Date.now() - this.startTime) / 1000).toFixed(1);
22
+ const embed = new EmbedBuilder()
23
+ .setTitle(`Executing: ${this.toolName}`)
24
+ .setColor(COLORS.TOOL_PROGRESS)
25
+ .setFooter({ text: `${elapsed}s` });
26
+ await this.sendOrEdit(embed);
27
+ }
28
+ async sendOrEdit(embed) {
29
+ try {
30
+ if (this.messageId) {
31
+ const msg = await this.channel.messages.fetch(this.messageId).catch(() => null);
32
+ if (msg) {
33
+ await msg.edit({ embeds: [embed] });
34
+ return;
35
+ }
36
+ }
37
+ const msg = await this.channel.send({ embeds: [embed] });
38
+ this.messageId = msg.id;
39
+ }
40
+ catch (err) {
41
+ console.error('[tool-progress] Failed to update embed:', err);
42
+ }
43
+ }
44
+ async finalize() {
45
+ if (this.timer) {
46
+ clearTimeout(this.timer);
47
+ this.timer = null;
48
+ }
49
+ // Delete the progress embed (tool result will replace it)
50
+ if (this.messageId) {
51
+ try {
52
+ const msg = await this.channel.messages.fetch(this.messageId).catch(() => null);
53
+ if (msg)
54
+ await msg.delete().catch(() => { });
55
+ }
56
+ catch {
57
+ /* best-effort */
58
+ }
59
+ }
60
+ }
61
+ getMessageId() {
62
+ return this.messageId;
63
+ }
64
+ }
65
+ //# sourceMappingURL=toolProgress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolProgress.js","sourceRoot":"","sources":["../../src/sessions/toolProgress.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { EmbedBuilder, type Client } from 'discord.js';
2
+ import type { SDKRateLimitInfo } from '@anthropic-ai/claude-agent-sdk';
3
+ interface RateLimitState {
4
+ fiveHour?: SDKRateLimitInfo;
5
+ sevenDayOpus?: SDKRateLimitInfo;
6
+ sevenDaySonnet?: SDKRateLimitInfo;
7
+ sevenDay?: SDKRateLimitInfo;
8
+ lastUpdated: number;
9
+ }
10
+ export declare function buildUsageEmbed(state?: RateLimitState): EmbedBuilder;
11
+ export declare function setupUsageTracker(client: Client): void;
12
+ export {};