@suzuke/agend 0.0.1 → 1.0.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 (202) hide show
  1. package/README.md +557 -1
  2. package/README.zh-TW.md +504 -0
  3. package/dist/access-path.d.ts +7 -0
  4. package/dist/access-path.js +12 -0
  5. package/dist/access-path.js.map +1 -0
  6. package/dist/approval/approval-server.d.ts +30 -0
  7. package/dist/approval/approval-server.js +156 -0
  8. package/dist/approval/approval-server.js.map +1 -0
  9. package/dist/approval/tmux-prompt-detector.d.ts +34 -0
  10. package/dist/approval/tmux-prompt-detector.js +264 -0
  11. package/dist/approval/tmux-prompt-detector.js.map +1 -0
  12. package/dist/backend/approval-strategy.d.ts +14 -0
  13. package/dist/backend/approval-strategy.js +2 -0
  14. package/dist/backend/approval-strategy.js.map +1 -0
  15. package/dist/backend/claude-code.d.ts +13 -0
  16. package/dist/backend/claude-code.js +114 -0
  17. package/dist/backend/claude-code.js.map +1 -0
  18. package/dist/backend/codex.d.ts +10 -0
  19. package/dist/backend/codex.js +58 -0
  20. package/dist/backend/codex.js.map +1 -0
  21. package/dist/backend/factory.d.ts +2 -0
  22. package/dist/backend/factory.js +19 -0
  23. package/dist/backend/factory.js.map +1 -0
  24. package/dist/backend/gemini-cli.d.ts +10 -0
  25. package/dist/backend/gemini-cli.js +68 -0
  26. package/dist/backend/gemini-cli.js.map +1 -0
  27. package/dist/backend/hook-based-approval.d.ts +20 -0
  28. package/dist/backend/hook-based-approval.js +41 -0
  29. package/dist/backend/hook-based-approval.js.map +1 -0
  30. package/dist/backend/index.d.ts +6 -0
  31. package/dist/backend/index.js +6 -0
  32. package/dist/backend/index.js.map +1 -0
  33. package/dist/backend/opencode.d.ts +10 -0
  34. package/dist/backend/opencode.js +63 -0
  35. package/dist/backend/opencode.js.map +1 -0
  36. package/dist/backend/types.d.ts +26 -0
  37. package/dist/backend/types.js +2 -0
  38. package/dist/backend/types.js.map +1 -0
  39. package/dist/channel/access-manager.d.ts +18 -0
  40. package/dist/channel/access-manager.js +149 -0
  41. package/dist/channel/access-manager.js.map +1 -0
  42. package/dist/channel/adapters/discord.d.ts +45 -0
  43. package/dist/channel/adapters/discord.js +366 -0
  44. package/dist/channel/adapters/discord.js.map +1 -0
  45. package/dist/channel/adapters/telegram.d.ts +58 -0
  46. package/dist/channel/adapters/telegram.js +569 -0
  47. package/dist/channel/adapters/telegram.js.map +1 -0
  48. package/dist/channel/attachment-handler.d.ts +15 -0
  49. package/dist/channel/attachment-handler.js +55 -0
  50. package/dist/channel/attachment-handler.js.map +1 -0
  51. package/dist/channel/factory.d.ts +12 -0
  52. package/dist/channel/factory.js +38 -0
  53. package/dist/channel/factory.js.map +1 -0
  54. package/dist/channel/ipc-bridge.d.ts +26 -0
  55. package/dist/channel/ipc-bridge.js +170 -0
  56. package/dist/channel/ipc-bridge.js.map +1 -0
  57. package/dist/channel/mcp-server.d.ts +10 -0
  58. package/dist/channel/mcp-server.js +196 -0
  59. package/dist/channel/mcp-server.js.map +1 -0
  60. package/dist/channel/mcp-tools.d.ts +909 -0
  61. package/dist/channel/mcp-tools.js +346 -0
  62. package/dist/channel/mcp-tools.js.map +1 -0
  63. package/dist/channel/message-bus.d.ts +17 -0
  64. package/dist/channel/message-bus.js +86 -0
  65. package/dist/channel/message-bus.js.map +1 -0
  66. package/dist/channel/message-queue.d.ts +39 -0
  67. package/dist/channel/message-queue.js +248 -0
  68. package/dist/channel/message-queue.js.map +1 -0
  69. package/dist/channel/tool-router.d.ts +6 -0
  70. package/dist/channel/tool-router.js +69 -0
  71. package/dist/channel/tool-router.js.map +1 -0
  72. package/dist/channel/tool-tracker.d.ts +13 -0
  73. package/dist/channel/tool-tracker.js +58 -0
  74. package/dist/channel/tool-tracker.js.map +1 -0
  75. package/dist/channel/types.d.ts +116 -0
  76. package/dist/channel/types.js +2 -0
  77. package/dist/channel/types.js.map +1 -0
  78. package/dist/cli.d.ts +2 -0
  79. package/dist/cli.js +782 -0
  80. package/dist/cli.js.map +1 -0
  81. package/dist/config.d.ts +8 -0
  82. package/dist/config.js +85 -0
  83. package/dist/config.js.map +1 -0
  84. package/dist/container-manager.d.ts +24 -0
  85. package/dist/container-manager.js +148 -0
  86. package/dist/container-manager.js.map +1 -0
  87. package/dist/context-guardian.d.ts +29 -0
  88. package/dist/context-guardian.js +123 -0
  89. package/dist/context-guardian.js.map +1 -0
  90. package/dist/cost-guard.d.ts +21 -0
  91. package/dist/cost-guard.js +113 -0
  92. package/dist/cost-guard.js.map +1 -0
  93. package/dist/daemon-entry.d.ts +1 -0
  94. package/dist/daemon-entry.js +29 -0
  95. package/dist/daemon-entry.js.map +1 -0
  96. package/dist/daemon.d.ts +88 -0
  97. package/dist/daemon.js +820 -0
  98. package/dist/daemon.js.map +1 -0
  99. package/dist/daily-summary.d.ts +13 -0
  100. package/dist/daily-summary.js +55 -0
  101. package/dist/daily-summary.js.map +1 -0
  102. package/dist/db.d.ts +10 -0
  103. package/dist/db.js +43 -0
  104. package/dist/db.js.map +1 -0
  105. package/dist/event-log.d.ts +22 -0
  106. package/dist/event-log.js +66 -0
  107. package/dist/event-log.js.map +1 -0
  108. package/dist/export-import.d.ts +2 -0
  109. package/dist/export-import.js +110 -0
  110. package/dist/export-import.js.map +1 -0
  111. package/dist/fleet-context.d.ts +36 -0
  112. package/dist/fleet-context.js +4 -0
  113. package/dist/fleet-context.js.map +1 -0
  114. package/dist/fleet-manager.d.ts +115 -0
  115. package/dist/fleet-manager.js +1742 -0
  116. package/dist/fleet-manager.js.map +1 -0
  117. package/dist/fleet-system-prompt.d.ts +11 -0
  118. package/dist/fleet-system-prompt.js +60 -0
  119. package/dist/fleet-system-prompt.js.map +1 -0
  120. package/dist/hang-detector.d.ts +16 -0
  121. package/dist/hang-detector.js +53 -0
  122. package/dist/hang-detector.js.map +1 -0
  123. package/dist/index.d.ts +8 -0
  124. package/dist/index.js +6 -0
  125. package/dist/index.js.map +1 -0
  126. package/dist/install-recorder.d.ts +30 -0
  127. package/dist/install-recorder.js +159 -0
  128. package/dist/install-recorder.js.map +1 -0
  129. package/dist/logger.d.ts +3 -0
  130. package/dist/logger.js +63 -0
  131. package/dist/logger.js.map +1 -0
  132. package/dist/meeting/orchestrator.d.ts +30 -0
  133. package/dist/meeting/orchestrator.js +355 -0
  134. package/dist/meeting/orchestrator.js.map +1 -0
  135. package/dist/meeting/prompt-builder.d.ts +12 -0
  136. package/dist/meeting/prompt-builder.js +96 -0
  137. package/dist/meeting/prompt-builder.js.map +1 -0
  138. package/dist/meeting/role-assigner.d.ts +2 -0
  139. package/dist/meeting/role-assigner.js +25 -0
  140. package/dist/meeting/role-assigner.js.map +1 -0
  141. package/dist/meeting/types.d.ts +21 -0
  142. package/dist/meeting/types.js +2 -0
  143. package/dist/meeting/types.js.map +1 -0
  144. package/dist/meeting-manager.d.ts +10 -0
  145. package/dist/meeting-manager.js +38 -0
  146. package/dist/meeting-manager.js.map +1 -0
  147. package/dist/memory-layer.d.ts +13 -0
  148. package/dist/memory-layer.js +44 -0
  149. package/dist/memory-layer.js.map +1 -0
  150. package/dist/plugin/agend/.claude-plugin/plugin.json +5 -0
  151. package/dist/plugin/agend/.mcp.json +9 -0
  152. package/dist/plugin/ccd-channel/.claude-plugin/plugin.json +5 -0
  153. package/dist/plugin/ccd-channel/.mcp.json +9 -0
  154. package/dist/process-manager.d.ts +31 -0
  155. package/dist/process-manager.js +264 -0
  156. package/dist/process-manager.js.map +1 -0
  157. package/dist/scheduler/db.d.ts +16 -0
  158. package/dist/scheduler/db.js +132 -0
  159. package/dist/scheduler/db.js.map +1 -0
  160. package/dist/scheduler/db.test.d.ts +1 -0
  161. package/dist/scheduler/db.test.js +92 -0
  162. package/dist/scheduler/db.test.js.map +1 -0
  163. package/dist/scheduler/index.d.ts +4 -0
  164. package/dist/scheduler/index.js +4 -0
  165. package/dist/scheduler/index.js.map +1 -0
  166. package/dist/scheduler/scheduler.d.ts +25 -0
  167. package/dist/scheduler/scheduler.js +119 -0
  168. package/dist/scheduler/scheduler.js.map +1 -0
  169. package/dist/scheduler/scheduler.test.d.ts +1 -0
  170. package/dist/scheduler/scheduler.test.js +119 -0
  171. package/dist/scheduler/scheduler.test.js.map +1 -0
  172. package/dist/scheduler/types.d.ts +47 -0
  173. package/dist/scheduler/types.js +7 -0
  174. package/dist/scheduler/types.js.map +1 -0
  175. package/dist/service-installer.d.ts +14 -0
  176. package/dist/service-installer.js +91 -0
  177. package/dist/service-installer.js.map +1 -0
  178. package/dist/setup-wizard.d.ts +14 -0
  179. package/dist/setup-wizard.js +517 -0
  180. package/dist/setup-wizard.js.map +1 -0
  181. package/dist/stt.d.ts +10 -0
  182. package/dist/stt.js +33 -0
  183. package/dist/stt.js.map +1 -0
  184. package/dist/tmux-manager.d.ts +22 -0
  185. package/dist/tmux-manager.js +131 -0
  186. package/dist/tmux-manager.js.map +1 -0
  187. package/dist/topic-commands.d.ts +22 -0
  188. package/dist/topic-commands.js +176 -0
  189. package/dist/topic-commands.js.map +1 -0
  190. package/dist/transcript-monitor.d.ts +21 -0
  191. package/dist/transcript-monitor.js +149 -0
  192. package/dist/transcript-monitor.js.map +1 -0
  193. package/dist/types.d.ts +153 -0
  194. package/dist/types.js +2 -0
  195. package/dist/types.js.map +1 -0
  196. package/dist/webhook-emitter.d.ts +15 -0
  197. package/dist/webhook-emitter.js +41 -0
  198. package/dist/webhook-emitter.js.map +1 -0
  199. package/package.json +60 -4
  200. package/templates/launchd.plist.ejs +29 -0
  201. package/templates/systemd.service.ejs +15 -0
  202. package/index.js +0 -1
@@ -0,0 +1,366 @@
1
+ import { EventEmitter } from "node:events";
2
+ import { randomBytes } from "node:crypto";
3
+ import { mkdirSync } from "node:fs";
4
+ import { Client, GatewayIntentBits, ActionRowBuilder, ButtonBuilder, ButtonStyle, ChannelType, } from "discord.js";
5
+ import { MessageQueue } from "../message-queue.js";
6
+ const DISCORD_MAX_LENGTH = 2000;
7
+ export class DiscordAdapter extends EventEmitter {
8
+ type = "discord";
9
+ topology = "channels";
10
+ id;
11
+ client;
12
+ botToken;
13
+ accessManager;
14
+ inboxDir;
15
+ guildId;
16
+ categoryName;
17
+ generalChannelId;
18
+ queue;
19
+ lastChatId = null;
20
+ constructor(opts) {
21
+ super();
22
+ this.id = opts.id;
23
+ this.botToken = opts.botToken;
24
+ this.accessManager = opts.accessManager;
25
+ this.inboxDir = opts.inboxDir;
26
+ this.guildId = opts.guildId;
27
+ this.categoryName = opts.categoryName ?? "CCD Agents";
28
+ this.generalChannelId = opts.generalChannelId;
29
+ mkdirSync(this.inboxDir, { recursive: true });
30
+ this.client = new Client({
31
+ intents: [
32
+ GatewayIntentBits.Guilds,
33
+ GatewayIntentBits.GuildMessages,
34
+ GatewayIntentBits.MessageContent,
35
+ ],
36
+ });
37
+ this.queue = new MessageQueue({
38
+ send: async (chatId, threadId, text) => {
39
+ const channel = await this._fetchTextChannel(threadId ?? chatId);
40
+ const msg = await channel.send(text);
41
+ return { messageId: msg.id };
42
+ },
43
+ edit: async (chatId, messageId, text) => {
44
+ const channel = await this._fetchTextChannel(chatId);
45
+ const msg = await channel.messages.fetch(messageId);
46
+ await msg.edit(text);
47
+ },
48
+ sendFile: async (chatId, threadId, filePath) => {
49
+ const channel = await this._fetchTextChannel(threadId ?? chatId);
50
+ const msg = await channel.send({ files: [filePath] });
51
+ return { messageId: msg.id };
52
+ },
53
+ });
54
+ this._registerHandlers();
55
+ }
56
+ async _fetchTextChannel(channelId) {
57
+ const channel = await this.client.channels.fetch(channelId);
58
+ if (!channel?.isTextBased()) {
59
+ throw new Error(`Channel ${channelId} is not a text channel`);
60
+ }
61
+ return channel;
62
+ }
63
+ _registerHandlers() {
64
+ this.client.on("messageCreate", async (msg) => {
65
+ if (msg.author.bot)
66
+ return;
67
+ if (msg.guildId !== this.guildId)
68
+ return;
69
+ const userId = msg.author.id;
70
+ // Access control — Discord snowflake IDs are strings, parseInt for AccessManager
71
+ if (!this.accessManager.isAllowed(Number(userId))) {
72
+ return;
73
+ }
74
+ const chatId = this.guildId;
75
+ const threadId = msg.channelId;
76
+ const messageId = msg.id;
77
+ const username = msg.author.username;
78
+ const text = msg.content;
79
+ // Collect attachments
80
+ const attachments = msg.attachments.map((att) => ({
81
+ kind: "document",
82
+ fileId: att.id,
83
+ mime: att.contentType ?? undefined,
84
+ size: att.size,
85
+ filename: att.name ?? undefined,
86
+ }));
87
+ this.emit("message", {
88
+ source: "discord",
89
+ adapterId: this.id,
90
+ chatId,
91
+ threadId,
92
+ messageId,
93
+ userId,
94
+ username,
95
+ text,
96
+ timestamp: msg.createdAt,
97
+ attachments: attachments.length > 0 ? attachments : undefined,
98
+ replyTo: msg.reference?.messageId ?? undefined,
99
+ });
100
+ });
101
+ // Handle button interactions
102
+ this.client.on("interactionCreate", async (interaction) => {
103
+ if (!interaction.isButton())
104
+ return;
105
+ await interaction.deferUpdate();
106
+ this.emit("callback_query", {
107
+ callbackData: interaction.customId,
108
+ chatId: this.guildId,
109
+ threadId: interaction.channelId,
110
+ messageId: interaction.message.id,
111
+ });
112
+ });
113
+ // Handle channel deletion (equivalent to topic_closed)
114
+ this.client.on("channelDelete", (channel) => {
115
+ if (!("guildId" in channel))
116
+ return;
117
+ if (channel.guildId !== this.guildId)
118
+ return;
119
+ this.emit("topic_closed", {
120
+ chatId: this.guildId,
121
+ threadId: channel.id,
122
+ });
123
+ });
124
+ }
125
+ // ── Lifecycle ──────────────────────────────────────────────────────────
126
+ async start() {
127
+ this.queue.start();
128
+ this.client.once("ready", () => {
129
+ this.emit("started", this.client.user?.username ?? "discord-bot");
130
+ });
131
+ await this.client.login(this.botToken);
132
+ }
133
+ async stop() {
134
+ this.queue.stop();
135
+ this.client.destroy();
136
+ }
137
+ // ── Text / file sending ────────────────────────────────────────────────
138
+ async sendText(chatId, text, opts) {
139
+ const channelId = opts?.threadId ?? chatId;
140
+ const channel = await this._fetchTextChannel(channelId);
141
+ const chunkLimit = opts?.chunkLimit ?? DISCORD_MAX_LENGTH;
142
+ const chunks = splitText(text, chunkLimit);
143
+ if (chunks.length === 0)
144
+ throw new Error("Empty text");
145
+ const first = await channel.send(chunks[0]);
146
+ // Enqueue remaining chunks
147
+ for (let i = 1; i < chunks.length; i++) {
148
+ this.queue.enqueue(chatId, opts?.threadId, { type: "content", text: chunks[i] });
149
+ }
150
+ return {
151
+ messageId: first.id,
152
+ chatId,
153
+ threadId: opts?.threadId,
154
+ };
155
+ }
156
+ async sendFile(chatId, filePath, opts) {
157
+ const channelId = opts?.threadId ?? chatId;
158
+ const channel = await this._fetchTextChannel(channelId);
159
+ const msg = await channel.send({ files: [filePath] });
160
+ return { messageId: msg.id, chatId, threadId: opts?.threadId };
161
+ }
162
+ async editMessage(chatId, messageId, text) {
163
+ // chatId is guild ID in channels topology, but messageId is in a channel.
164
+ // We need to find the message. Try all text channels in the guild.
165
+ // Optimization: caller usually provides the channel via sendText return value.
166
+ try {
167
+ // Try the general channel first, then search
168
+ const guild = await this.client.guilds.fetch(this.guildId);
169
+ const channels = guild.channels.cache.filter((c) => c.type === ChannelType.GuildText);
170
+ for (const [, ch] of channels) {
171
+ try {
172
+ const textCh = ch;
173
+ const msg = await textCh.messages.fetch(messageId);
174
+ await msg.edit(text.slice(0, DISCORD_MAX_LENGTH));
175
+ return;
176
+ }
177
+ catch {
178
+ continue;
179
+ }
180
+ }
181
+ throw new Error(`Message ${messageId} not found in any channel`);
182
+ }
183
+ catch (err) {
184
+ // Fallback: send a new message if edit fails
185
+ if (this.generalChannelId) {
186
+ const channel = await this._fetchTextChannel(this.generalChannelId);
187
+ await channel.send(text.slice(0, DISCORD_MAX_LENGTH));
188
+ }
189
+ }
190
+ }
191
+ async react(chatId, messageId, emoji) {
192
+ try {
193
+ const guild = await this.client.guilds.fetch(this.guildId);
194
+ const channels = guild.channels.cache.filter((c) => c.type === ChannelType.GuildText);
195
+ for (const [, ch] of channels) {
196
+ try {
197
+ const textCh = ch;
198
+ const msg = await textCh.messages.fetch(messageId);
199
+ await msg.react(emoji);
200
+ return;
201
+ }
202
+ catch {
203
+ continue;
204
+ }
205
+ }
206
+ }
207
+ catch {
208
+ // No-op per degradation strategy
209
+ }
210
+ }
211
+ // ── Approval ───────────────────────────────────────────────────────────
212
+ async sendApproval(prompt, callback, signal, threadId) {
213
+ const nonce = randomBytes(5).toString("hex");
214
+ const approveData = `approval:approve:${nonce}`;
215
+ const alwaysData = `approval:approve_always:${nonce}`;
216
+ const denyData = `approval:deny:${nonce}`;
217
+ const row = new ActionRowBuilder().addComponents(new ButtonBuilder()
218
+ .setCustomId(approveData)
219
+ .setLabel("Allow")
220
+ .setStyle(ButtonStyle.Success), new ButtonBuilder()
221
+ .setCustomId(alwaysData)
222
+ .setLabel("Always")
223
+ .setStyle(ButtonStyle.Success), new ButtonBuilder()
224
+ .setCustomId(denyData)
225
+ .setLabel("Deny")
226
+ .setStyle(ButtonStyle.Danger));
227
+ let text = `⚠️ **Permission Request**\nTool: \`${prompt.tool_name}\``;
228
+ if (prompt.input_preview) {
229
+ const preview = prompt.input_preview.length > 200
230
+ ? prompt.input_preview.slice(0, 200) + "…"
231
+ : prompt.input_preview;
232
+ text += `\n\`\`\`\n${preview}\n\`\`\``;
233
+ }
234
+ else if (prompt.description) {
235
+ text += `\n${prompt.description}`;
236
+ }
237
+ const cleanup = () => {
238
+ this.off("callback_query", handler);
239
+ };
240
+ const handler = (query) => {
241
+ if (!query.callbackData)
242
+ return;
243
+ const isApprove = query.callbackData === approveData;
244
+ const isAlways = query.callbackData === alwaysData;
245
+ const isDeny = query.callbackData === denyData;
246
+ if (!isApprove && !isAlways && !isDeny)
247
+ return;
248
+ cleanup();
249
+ // Update the message to show the decision
250
+ if (query.threadId && query.messageId) {
251
+ this._fetchTextChannel(query.threadId).then((ch) => {
252
+ ch.messages.fetch(query.messageId).then((msg) => {
253
+ const label = isDeny ? "❌ Denied" : isAlways ? "✅ Always Allowed" : "✅ Allowed";
254
+ msg.edit({
255
+ content: `${label}\nTool: \`${prompt.tool_name}\``,
256
+ components: [],
257
+ }).catch(() => { });
258
+ }).catch(() => { });
259
+ }).catch(() => { });
260
+ }
261
+ callback(isDeny ? "deny" : isAlways ? "approve_always" : "approve");
262
+ };
263
+ this.on("callback_query", handler);
264
+ if (signal) {
265
+ signal.addEventListener("abort", () => cleanup());
266
+ }
267
+ const channelId = threadId ?? this.generalChannelId;
268
+ if (channelId) {
269
+ const channel = await this._fetchTextChannel(channelId);
270
+ await channel.send({ content: text, components: [row] });
271
+ }
272
+ else {
273
+ this.emit("approval_request", { prompt: text, components: [row], nonce });
274
+ }
275
+ return { cancel: cleanup };
276
+ }
277
+ // ── Chat ID management ──────────────────────────────────────────────────
278
+ getChatId() { return this.lastChatId; }
279
+ setChatId(chatId) { this.lastChatId = chatId; }
280
+ // ── File download ──────────────────────────────────────────────────────
281
+ async downloadAttachment(fileId) {
282
+ // Discord attachment fileId is the attachment ID. We need to find the URL.
283
+ // Since Discord attachments include URLs directly, we'll search for the message
284
+ // containing this attachment. For MVP, we store the URL in the attachment metadata.
285
+ // Here we try to download via the Discord CDN URL pattern.
286
+ // In practice, the inbound message handler should store the URL.
287
+ throw new Error("downloadAttachment not yet implemented for Discord — use attachment URL directly");
288
+ }
289
+ // ── Intent-oriented methods ──────────────────────────────────────────
290
+ async promptUser(chatId, text, choices, opts) {
291
+ const channelId = opts?.threadId ?? chatId;
292
+ const channel = await this._fetchTextChannel(channelId);
293
+ const row = new ActionRowBuilder();
294
+ for (const choice of choices) {
295
+ row.addComponents(new ButtonBuilder()
296
+ .setCustomId(choice.id)
297
+ .setLabel(choice.label.slice(0, 80)) // Discord button label max 80 chars
298
+ .setStyle(ButtonStyle.Primary));
299
+ }
300
+ const msg = await channel.send({ content: text, components: [row] });
301
+ return msg.id;
302
+ }
303
+ async notifyAlert(chatId, alert, opts) {
304
+ if (alert.choices && alert.choices.length > 0) {
305
+ const channelId = opts?.threadId ?? chatId;
306
+ const channel = await this._fetchTextChannel(channelId);
307
+ const row = new ActionRowBuilder();
308
+ for (const choice of alert.choices) {
309
+ row.addComponents(new ButtonBuilder()
310
+ .setCustomId(choice.id)
311
+ .setLabel(choice.label.slice(0, 80))
312
+ .setStyle(ButtonStyle.Secondary));
313
+ }
314
+ const msg = await channel.send({ content: alert.message, components: [row] });
315
+ return { messageId: msg.id, chatId, threadId: opts?.threadId };
316
+ }
317
+ return this.sendText(chatId, alert.message, opts);
318
+ }
319
+ // ── Topology: create channel ────────────────────────────────────────────
320
+ async createTopic(name) {
321
+ const guild = await this.client.guilds.fetch(this.guildId);
322
+ // Find or create the category
323
+ let category = guild.channels.cache.find((c) => c.type === ChannelType.GuildCategory && c.name === this.categoryName);
324
+ if (!category) {
325
+ category = await guild.channels.create({
326
+ name: this.categoryName,
327
+ type: ChannelType.GuildCategory,
328
+ });
329
+ }
330
+ const channelOpts = {
331
+ name,
332
+ type: ChannelType.GuildText,
333
+ parent: category.id,
334
+ };
335
+ const channel = await guild.channels.create(channelOpts);
336
+ return parseInt(channel.id);
337
+ }
338
+ async topicExists(topicId) {
339
+ try {
340
+ const channel = await this.client.channels.fetch(String(topicId));
341
+ return channel != null;
342
+ }
343
+ catch {
344
+ return false;
345
+ }
346
+ }
347
+ // ── Pairing ────────────────────────────────────────────────────────────
348
+ async handlePairing(chatId, userId) {
349
+ const code = this.accessManager.generateCode(Number(userId));
350
+ return code;
351
+ }
352
+ async confirmPairing(code) {
353
+ return this.accessManager.confirmCode(code);
354
+ }
355
+ }
356
+ // ── Helpers ──────────────────────────────────────────────────────────────
357
+ function splitText(text, limit) {
358
+ const chunks = [];
359
+ let offset = 0;
360
+ while (offset < text.length) {
361
+ chunks.push(text.slice(offset, offset + limit));
362
+ offset += limit;
363
+ }
364
+ return chunks;
365
+ }
366
+ //# sourceMappingURL=discord.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discord.js","sourceRoot":"","sources":["../../../src/channel/adapters/discord.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import { EventEmitter } from "node:events";
2
+ import { Bot } from "grammy";
3
+ import type { ChannelAdapter, ApprovalHandle, SendOpts, SentMessage, PermissionPrompt, Choice, AlertData } from "../types.js";
4
+ import type { AccessManager } from "../access-manager.js";
5
+ export interface TelegramAdapterOptions {
6
+ id: string;
7
+ botToken: string;
8
+ accessManager: AccessManager;
9
+ inboxDir: string;
10
+ }
11
+ export declare class TelegramAdapter extends EventEmitter implements ChannelAdapter {
12
+ readonly type = "telegram";
13
+ readonly topology: "topics";
14
+ readonly id: string;
15
+ private bot;
16
+ private accessManager;
17
+ private inboxDir;
18
+ private queue;
19
+ private cleanupTimer;
20
+ constructor(opts: TelegramAdapterOptions);
21
+ private _registerHandlers;
22
+ private _extractAttachments;
23
+ /** Returns true if the message is a Telegram service event with no user content. */
24
+ private _isServiceMessage;
25
+ private _handlePairCommand;
26
+ /** Expose bot for fleet manager operations (topic existence checks etc.) */
27
+ getBot(): Bot;
28
+ start(): Promise<void>;
29
+ stop(): Promise<void>;
30
+ /** Delete inbox files older than 1 hour */
31
+ private _pruneInbox;
32
+ sendText(chatId: string, text: string, opts?: SendOpts): Promise<SentMessage>;
33
+ sendFile(chatId: string, filePath: string, opts?: SendOpts): Promise<SentMessage>;
34
+ editMessage(chatId: string, messageId: string, text: string): Promise<void>;
35
+ react(chatId: string, messageId: string, emoji: string): Promise<void>;
36
+ sendApproval(prompt: PermissionPrompt, callback: (decision: "approve" | "approve_always" | "deny") => void, signal?: AbortSignal, threadId?: string): Promise<ApprovalHandle>;
37
+ /** Get the last known chatId (group ID for topic mode) */
38
+ private lastChatId;
39
+ getChatId(): string | null;
40
+ setChatId(chatId: string): void;
41
+ downloadAttachment(fileId: string): Promise<string>;
42
+ promptUser(chatId: string, text: string, choices: Choice[], opts?: SendOpts): Promise<string>;
43
+ notifyAlert(chatId: string, alert: AlertData, opts?: SendOpts): Promise<SentMessage>;
44
+ createTopic(name: string): Promise<number>;
45
+ topicExists(topicId: number): Promise<boolean>;
46
+ closeForumTopic(threadId: number): Promise<void>;
47
+ reopenForumTopic(threadId: number): Promise<void>;
48
+ editForumTopic(threadId: number, opts: {
49
+ name?: string;
50
+ iconCustomEmojiId?: string;
51
+ }): Promise<void>;
52
+ getTopicIconStickers(): Promise<{
53
+ customEmojiId: string;
54
+ emoji: string;
55
+ }[]>;
56
+ handlePairing(chatId: string, userId: string): Promise<string>;
57
+ confirmPairing(code: string): Promise<boolean>;
58
+ }