@songsid/agend 2.0.8-beta.9 → 2.0.9-beta.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.
Files changed (46) hide show
  1. package/README.md +8 -3
  2. package/dist/adapter-world.d.ts +1 -1
  3. package/dist/adapter-world.js +2 -2
  4. package/dist/adapter-world.js.map +1 -1
  5. package/dist/agent-endpoint.js +6 -0
  6. package/dist/agent-endpoint.js.map +1 -1
  7. package/dist/backend/codex.js +10 -3
  8. package/dist/backend/codex.js.map +1 -1
  9. package/dist/channel/adapters/discord.d.ts +4 -4
  10. package/dist/channel/adapters/discord.js +162 -111
  11. package/dist/channel/adapters/discord.js.map +1 -1
  12. package/dist/channel/adapters/telegram.d.ts +1 -1
  13. package/dist/channel/adapters/telegram.js +3 -1
  14. package/dist/channel/adapters/telegram.js.map +1 -1
  15. package/dist/channel/tool-router.js +4 -2
  16. package/dist/channel/tool-router.js.map +1 -1
  17. package/dist/channel/tool-tracker.js +2 -2
  18. package/dist/channel/tool-tracker.js.map +1 -1
  19. package/dist/channel/types.d.ts +14 -6
  20. package/dist/cli.js +150 -95
  21. package/dist/cli.js.map +1 -1
  22. package/dist/daemon.d.ts +25 -1
  23. package/dist/daemon.js +149 -43
  24. package/dist/daemon.js.map +1 -1
  25. package/dist/fleet-manager.d.ts +47 -5
  26. package/dist/fleet-manager.js +362 -139
  27. package/dist/fleet-manager.js.map +1 -1
  28. package/dist/instance-lifecycle.js +9 -0
  29. package/dist/instance-lifecycle.js.map +1 -1
  30. package/dist/logger.d.ts +9 -1
  31. package/dist/logger.js +17 -7
  32. package/dist/logger.js.map +1 -1
  33. package/dist/outbound-handlers.d.ts +3 -0
  34. package/dist/outbound-handlers.js +17 -0
  35. package/dist/outbound-handlers.js.map +1 -1
  36. package/dist/outbound-schemas.d.ts +1 -1
  37. package/dist/tmux-control.d.ts +10 -0
  38. package/dist/tmux-control.js +29 -0
  39. package/dist/tmux-control.js.map +1 -1
  40. package/dist/tmux-manager.d.ts +6 -0
  41. package/dist/tmux-manager.js +17 -0
  42. package/dist/tmux-manager.js.map +1 -1
  43. package/dist/topic-commands.d.ts +21 -0
  44. package/dist/topic-commands.js +73 -6
  45. package/dist/topic-commands.js.map +1 -1
  46. package/package.json +3 -1
package/README.md CHANGED
@@ -35,7 +35,7 @@ AgEnD (**Agent Engineering Daemon**) turns your Telegram or Discord into a comma
35
35
 
36
36
  🚀 **Fleet Management** — One bot, N projects. Each Telegram Forum Topic is an isolated agent session.
37
37
 
38
- 🔄 **Multi-Backend** — Claude Code, Gemini CLI, Codex, OpenCode, Kiro CLI, Antigravity CLI. Switch or mix freely.
38
+ 🔄 **Multi-Backend** — Claude Code, Codex, OpenCode, Kiro CLI, Antigravity CLI. Switch or mix freely.
39
39
 
40
40
  🤝 **Agent Collaboration** — Agents discover, wake, and message each other via MCP tools. A General Topic routes tasks to the right agent using natural language.
41
41
 
@@ -51,6 +51,10 @@ AgEnD (**Agent Engineering Daemon**) turns your Telegram or Discord into a comma
51
51
 
52
52
  🪞 **Mirror Topic** — Cross-instance visibility. Watch another agent's work in real time from a separate topic.
53
53
 
54
+ 🛑 **Cancel Button** — Interrupt agent generation with a single tap. Inline button appears on every message; works across TG and Discord.
55
+
56
+ 📬 **Delivery Status** — See message delivery progress: 👀 received → ⏳ processing → ✅ done (or ❌ failed).
57
+
54
58
  🖥️ **Web Dashboard** — Live fleet monitoring in the browser with SSE updates and integrated chat UI.
55
59
 
56
60
  🔌 **Extensible** — Discord adapter, webhook notifications, health endpoint, external session support via IPC.
@@ -93,7 +97,7 @@ graph LR
93
97
  subgraph Fleet
94
98
  Daemon --> General["General<br/>Dispatcher"]
95
99
  Daemon --> A["Instance A<br/>Claude Code<br/>Project X"]
96
- Daemon --> B["Instance B<br/>Gemini CLI<br/>Project Y"]
100
+ Daemon --> B["Instance B<br/>Antigravity CLI<br/>Project Y"]
97
101
  A <-.->|MCP Tools| B
98
102
  General -.->|routes tasks| A
99
103
  General -.->|routes tasks| B
@@ -192,7 +196,7 @@ defaults:
192
196
  channels:
193
197
  "1234567890": # Discord channel ID
194
198
  name: dev-help
195
- backend: gemini-cli # Override for this channel
199
+ backend: kiro-cli # Override for this channel
196
200
  ```
197
201
 
198
202
  Backend fallback: channel → `defaults.backend` → `fleet.yaml` defaults → `claude-code`
@@ -202,6 +206,7 @@ Backend fallback: channel → `defaults.backend` → `fleet.yaml` defaults → `
202
206
  - macOS (launchd) and Linux (systemd) supported; Windows is not
203
207
  - Official Telegram plugin in global `enabledPlugins` causes 409 polling conflicts
204
208
  - OpenCode and Kiro CLI do not read MCP server `instructions` field — fleet context and workflow templates are not injected into these backends' system prompts. Awaiting upstream fix.
209
+ - Gemini CLI is deprecated since 2026-06-18 — use Antigravity CLI (`agy`) instead
205
210
 
206
211
  ## License
207
212
 
@@ -18,7 +18,7 @@ export declare class AdapterWorld {
18
18
  get type(): string;
19
19
  sendText(chatId: string, text: string, opts?: SendOpts): Promise<SentMessage>;
20
20
  react(chatId: string, messageId: string, emoji: string): Promise<void>;
21
- editMessage(chatId: string, messageId: string, text: string): Promise<void>;
21
+ editMessage(chatId: string, messageId: string, text: string, threadId?: string): Promise<void>;
22
22
  downloadAttachment(fileId: string): Promise<string>;
23
23
  isAllowed(userId: string | number): boolean;
24
24
  stop(): Promise<void>;
@@ -25,8 +25,8 @@ export class AdapterWorld {
25
25
  react(chatId, messageId, emoji) {
26
26
  return this.adapter.react(chatId, messageId, emoji);
27
27
  }
28
- editMessage(chatId, messageId, text) {
29
- return this.adapter.editMessage(chatId, messageId, text);
28
+ editMessage(chatId, messageId, text, threadId) {
29
+ return this.adapter.editMessage(chatId, messageId, text, threadId);
30
30
  }
31
31
  downloadAttachment(fileId) {
32
32
  return this.adapter.downloadAttachment(fileId);
@@ -1 +1 @@
1
- {"version":3,"file":"adapter-world.js","sourceRoot":"","sources":["../src/adapter-world.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,MAAM,OAAO,YAAY;IAKZ;IACA;IACA;IACA;IAPX,WAAW,CAAU;IACrB,SAAS,CAAU;IAEnB,YACW,EAAU,EACV,OAAuB,EACvB,aAA4B,EAC5B,aAA4B;QAH5B,OAAE,GAAF,EAAE,CAAQ;QACV,YAAO,GAAP,OAAO,CAAgB;QACvB,kBAAa,GAAb,aAAa,CAAe;QAC5B,kBAAa,GAAb,aAAa,CAAe;IACpC,CAAC;IAEJ,IAAI,OAAO,KAAa,OAAO,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3E,IAAI,IAAI,KAAa,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;IAEtD,mCAAmC;IAEnC,QAAQ,CAAC,MAAc,EAAE,IAAY,EAAE,IAAe;QACpD,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACnD,CAAC;IAED,KAAK,CAAC,MAAc,EAAE,SAAiB,EAAE,KAAa;QACpD,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IACtD,CAAC;IAED,WAAW,CAAC,MAAc,EAAE,SAAiB,EAAE,IAAY;QACzD,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IAC3D,CAAC;IAED,kBAAkB,CAAC,MAAc;QAC/B,OAAO,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;IACjD,CAAC;IAED,SAAS,CAAC,MAAuB;QAC/B,OAAO,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IAC5B,CAAC;CACF"}
1
+ {"version":3,"file":"adapter-world.js","sourceRoot":"","sources":["../src/adapter-world.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,MAAM,OAAO,YAAY;IAKZ;IACA;IACA;IACA;IAPX,WAAW,CAAU;IACrB,SAAS,CAAU;IAEnB,YACW,EAAU,EACV,OAAuB,EACvB,aAA4B,EAC5B,aAA4B;QAH5B,OAAE,GAAF,EAAE,CAAQ;QACV,YAAO,GAAP,OAAO,CAAgB;QACvB,kBAAa,GAAb,aAAa,CAAe;QAC5B,kBAAa,GAAb,aAAa,CAAe;IACpC,CAAC;IAEJ,IAAI,OAAO,KAAa,OAAO,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3E,IAAI,IAAI,KAAa,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;IAEtD,mCAAmC;IAEnC,QAAQ,CAAC,MAAc,EAAE,IAAY,EAAE,IAAe;QACpD,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACnD,CAAC;IAED,KAAK,CAAC,MAAc,EAAE,SAAiB,EAAE,KAAa;QACpD,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IACtD,CAAC;IAED,WAAW,CAAC,MAAc,EAAE,SAAiB,EAAE,IAAY,EAAE,QAAiB;QAC5E,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IACrE,CAAC;IAED,kBAAkB,CAAC,MAAc;QAC/B,OAAO,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;IACjD,CAAC;IAED,SAAS,CAAC,MAAuB;QAC/B,OAAO,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IAC5B,CAAC;CACF"}
@@ -142,6 +142,12 @@ async function dispatch(ctx, instance, op, args) {
142
142
  const fullArgs = { ...args, chat_id: chatId, thread_id: threadId };
143
143
  const adapter = ctx.getAdapterForInstance?.(instance) ?? ctx.adapter;
144
144
  const handled = routeToolCall(adapter, tool, fullArgs, threadId, (result, error) => {
145
+ // A successful reply retires the instance's cancel button — mirroring the
146
+ // MCP path (handleOutboundFromInstance). HTTP agents (e.g. Antigravity,
147
+ // which replies via POST /agent instead of an MCP tool call) never hit
148
+ // that path, so without this their cancel button would never clear.
149
+ if (!error && tool === "reply")
150
+ ctx.clearCancelButton?.(instance);
145
151
  resolve(error ? { error } : result);
146
152
  });
147
153
  if (!handled)
@@ -1 +1 @@
1
- {"version":3,"file":"agent-endpoint.js","sourceRoot":"","sources":["../src/agent-endpoint.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent-endpoint.js","sourceRoot":"","sources":["../src/agent-endpoint.ts"],"names":[],"mappings":"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"}
@@ -40,7 +40,10 @@ export class CodexBackend {
40
40
  // containing JSON (e.g. AGEND_DECISIONS). Use namespaced key to avoid
41
41
  // conflicts when multiple Codex instances run simultaneously.
42
42
  for (const [name, entry] of Object.entries(config.mcpServers)) {
43
- const mcpName = `${name}-${config.instanceName}`;
43
+ // Codex rejects non-ASCII MCP server names (e.g. CJK instance names) and
44
+ // would otherwise fail silently, leaving the instance with no reply MCP
45
+ // server. Sanitize to the safe charset codex accepts.
46
+ const mcpName = `${name}-${config.instanceName}`.replace(/[^A-Za-z0-9_-]/g, "_");
44
47
  const allEnv = { ...entry.env, AGEND_INSTANCE_NAME: config.instanceName };
45
48
  const args = ["mcp", "add", mcpName];
46
49
  for (const [k, v] of Object.entries(allEnv)) {
@@ -52,10 +55,13 @@ export class CodexBackend {
52
55
  execFileSync(this.binaryPath, ["mcp", "remove", mcpName], { stdio: "ignore" });
53
56
  }
54
57
  catch { /* may not exist */ }
58
+ // Surface add failures — a silent failure means no reply MCP server.
55
59
  try {
56
60
  execFileSync(this.binaryPath, args, { stdio: "ignore" });
57
61
  }
58
- catch { /* best effort */ }
62
+ catch (e) {
63
+ console.warn(`[codex] mcp add "${mcpName}" failed: ${e.message}`);
64
+ }
59
65
  }
60
66
  // Clean up old non-namespaced key if present (one-time migration)
61
67
  try {
@@ -132,7 +138,8 @@ export class CodexBackend {
132
138
  getQuitCommand() { return "/quit"; }
133
139
  cleanup(config) {
134
140
  for (const name of Object.keys(config.mcpServers)) {
135
- const mcpName = `${name}-${config.instanceName}`;
141
+ // Must match the sanitized name used in writeConfig, or removal misses it.
142
+ const mcpName = `${name}-${config.instanceName}`.replace(/[^A-Za-z0-9_-]/g, "_");
136
143
  try {
137
144
  execFileSync(this.binaryPath, ["mcp", "remove", mcpName], { stdio: "ignore" });
138
145
  }
@@ -1 +1 @@
1
- {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/backend/codex.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/backend/codex.ts"],"names":[],"mappings":"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"}
@@ -35,12 +35,12 @@ export declare class DiscordAdapter extends EventEmitter implements ChannelAdapt
35
35
  stop(): Promise<void>;
36
36
  sendText(chatId: string, text: string, opts?: SendOpts): Promise<SentMessage>;
37
37
  sendFile(chatId: string, filePath: string, opts?: SendOpts): Promise<SentMessage>;
38
- editMessage(chatId: string, messageId: string, text: string): Promise<void>;
38
+ editMessage(chatId: string, messageId: string, text: string, threadId?: string): Promise<void>;
39
39
  /** Edit text and clear components (Discord keeps components on a plain edit,
40
40
  * so we must pass an empty array to drop the Cancel button). */
41
- editMessageRemoveButtons(chatId: string, messageId: string, text: string): Promise<void>;
42
- deleteMessage(chatId: string, messageId: string): Promise<void>;
43
- react(chatId: string, messageId: string, emoji: string): Promise<void>;
41
+ editMessageRemoveButtons(chatId: string, messageId: string, text: string, threadId?: string): Promise<void>;
42
+ deleteMessage(chatId: string, messageId: string, threadId?: string): Promise<void>;
43
+ react(chatId: string, messageId: string, emoji: string, threadId?: string): Promise<void>;
44
44
  sendApproval(prompt: PermissionPrompt, callback: (decision: "approve" | "approve_always" | "deny") => void, signal?: AbortSignal, threadId?: string): Promise<ApprovalHandle>;
45
45
  getChatId(): string | null;
46
46
  setChatId(chatId: string): void;
@@ -68,126 +68,145 @@ export class DiscordAdapter extends EventEmitter {
68
68
  return channel;
69
69
  }
70
70
  _registerHandlers() {
71
+ // Client/shard errors (WebSocket hiccups, gateway resumes, etc.). discord.js
72
+ // auto-reconnects; we just need a listener so Node's EventEmitter doesn't
73
+ // rethrow on "error" — without one it surfaces as an uncaughtException and
74
+ // the process-level handler tears down the whole fleet (the built-in adapter
75
+ // shares the fleet process).
76
+ this.client.on("error", (err) => console.warn(`[discord] client error: ${err?.message ?? err}`));
77
+ this.client.on("shardError", (err) => console.warn(`[discord] shard error: ${err?.message ?? err}`));
71
78
  this.client.on("messageCreate", async (msg) => {
72
- if (msg.author.id === this.client.user?.id)
73
- return; // Ignore own messages
74
- if (!msg.guildId)
75
- return;
76
- if (msg.guildId !== this.guildId) {
77
- if (!this.openChannels.has(msg.channelId))
79
+ try {
80
+ if (msg.author.id === this.client.user?.id)
81
+ return; // Ignore own messages
82
+ if (!msg.guildId)
78
83
  return;
79
- console.log(`[discord] classic channel message from non-primary guild ${msg.guildId} channel ${msg.channelId}`);
80
- }
81
- const userId = msg.author.id;
82
- // Access control moved to fleet-manager to allow classic channels for all users
83
- const chatId = this.guildId;
84
- const threadId = msg.channelId;
85
- const messageId = msg.id;
86
- const username = msg.author.username;
87
- let text = msg.content;
88
- // Handle forwarded messages (messageSnapshots) and embeds
89
- if (!text) {
90
- const parts = [];
91
- // Forwarded message snapshots (Discord forward feature)
92
- if (msg.messageSnapshots?.size > 0) {
93
- for (const [, snap] of msg.messageSnapshots) {
94
- if (snap.message?.content)
95
- parts.push(snap.message.content);
96
- if (snap.message?.embeds?.length) {
97
- for (const e of snap.message.embeds) {
98
- if (e.title)
99
- parts.push(e.title);
100
- if (e.description)
101
- parts.push(e.description);
84
+ if (msg.guildId !== this.guildId) {
85
+ if (!this.openChannels.has(msg.channelId))
86
+ return;
87
+ // Allowed: an open classic channel in a non-primary guild.
88
+ }
89
+ const userId = msg.author.id;
90
+ // Access control moved to fleet-manager to allow classic channels for all users
91
+ const chatId = this.guildId;
92
+ const threadId = msg.channelId;
93
+ const messageId = msg.id;
94
+ const username = msg.author.username;
95
+ let text = msg.content;
96
+ // Handle forwarded messages (messageSnapshots) and embeds
97
+ if (!text) {
98
+ const parts = [];
99
+ // Forwarded message snapshots (Discord forward feature)
100
+ if (msg.messageSnapshots?.size > 0) {
101
+ for (const [, snap] of msg.messageSnapshots) {
102
+ if (snap.message?.content)
103
+ parts.push(snap.message.content);
104
+ if (snap.message?.embeds?.length) {
105
+ for (const e of snap.message.embeds) {
106
+ if (e.title)
107
+ parts.push(e.title);
108
+ if (e.description)
109
+ parts.push(e.description);
110
+ }
111
+ }
112
+ // Forward attachments (images, files) into the main message
113
+ if (snap.message?.attachments?.size > 0) {
114
+ for (const [, att] of snap.message.attachments) {
115
+ msg.attachments.set(att.id, att);
116
+ }
102
117
  }
103
118
  }
104
- // Forward attachments (images, files) into the main message
105
- if (snap.message?.attachments?.size > 0) {
106
- for (const [, att] of snap.message.attachments) {
107
- msg.attachments.set(att.id, att);
119
+ }
120
+ // Rich embeds (links, bot messages, etc.)
121
+ if (parts.length === 0 && msg.embeds.length > 0) {
122
+ for (const e of msg.embeds) {
123
+ if (e.title)
124
+ parts.push(e.title);
125
+ if (e.description)
126
+ parts.push(e.description);
127
+ if (e.fields?.length) {
128
+ for (const f of e.fields)
129
+ parts.push(`${f.name}: ${f.value}`);
108
130
  }
109
131
  }
110
132
  }
133
+ if (parts.length > 0)
134
+ text = parts.join("\n");
111
135
  }
112
- // Rich embeds (links, bot messages, etc.)
113
- if (parts.length === 0 && msg.embeds.length > 0) {
114
- for (const e of msg.embeds) {
115
- if (e.title)
116
- parts.push(e.title);
117
- if (e.description)
118
- parts.push(e.description);
119
- if (e.fields?.length) {
120
- for (const f of e.fields)
121
- parts.push(`${f.name}: ${f.value}`);
122
- }
136
+ const isBotMessage = msg.author.bot;
137
+ // Collect attachments
138
+ const attachments = msg.attachments.map((att) => ({
139
+ kind: (att.contentType?.startsWith("image/") ? "photo"
140
+ : att.contentType?.startsWith("video/") ? "video"
141
+ : att.contentType?.startsWith("audio/") ? "audio"
142
+ : "document"),
143
+ fileId: att.id,
144
+ mime: att.contentType ?? undefined,
145
+ size: att.size,
146
+ filename: att.name ?? undefined,
147
+ }));
148
+ // Store attachment URLs for later download
149
+ for (const att of msg.attachments.values()) {
150
+ this.attachmentUrls.set(att.id, att.url);
151
+ }
152
+ while (this.attachmentUrls.size > 1000) {
153
+ const first = this.attachmentUrls.keys().next().value;
154
+ if (first)
155
+ this.attachmentUrls.delete(first);
156
+ else
157
+ break;
158
+ }
159
+ let replyToText;
160
+ if (msg.reference?.messageId) {
161
+ try {
162
+ const ref = await msg.fetchReference();
163
+ replyToText = ref.content || ref.embeds?.[0]?.description || undefined;
123
164
  }
165
+ catch { /* deleted message or no permission */ }
124
166
  }
125
- if (parts.length > 0)
126
- text = parts.join("\n");
127
- }
128
- const isBotMessage = msg.author.bot;
129
- // Collect attachments
130
- const attachments = msg.attachments.map((att) => ({
131
- kind: (att.contentType?.startsWith("image/") ? "photo"
132
- : att.contentType?.startsWith("video/") ? "video"
133
- : att.contentType?.startsWith("audio/") ? "audio"
134
- : "document"),
135
- fileId: att.id,
136
- mime: att.contentType ?? undefined,
137
- size: att.size,
138
- filename: att.name ?? undefined,
139
- }));
140
- // Store attachment URLs for later download
141
- for (const att of msg.attachments.values()) {
142
- this.attachmentUrls.set(att.id, att.url);
143
- }
144
- while (this.attachmentUrls.size > 1000) {
145
- const first = this.attachmentUrls.keys().next().value;
146
- if (first)
147
- this.attachmentUrls.delete(first);
148
- else
149
- break;
167
+ this.emit("message", {
168
+ source: "discord",
169
+ adapterId: this.id,
170
+ chatId,
171
+ threadId,
172
+ messageId,
173
+ userId,
174
+ username,
175
+ text,
176
+ timestamp: msg.createdAt,
177
+ isBotMessage,
178
+ attachments: attachments.length > 0 ? attachments : undefined,
179
+ replyTo: msg.reference?.messageId ?? undefined,
180
+ replyToText,
181
+ });
150
182
  }
151
- let replyToText;
152
- if (msg.reference?.messageId) {
153
- try {
154
- const ref = await msg.fetchReference();
155
- replyToText = ref.content || ref.embeds?.[0]?.description || undefined;
156
- }
157
- catch { /* deleted message or no permission */ }
183
+ catch (err) {
184
+ // A throw here would become an unhandledRejection → process.exit(1) for
185
+ // the whole fleet. Contain it like the interactionCreate handler does.
186
+ console.warn(`[discord] messageCreate handler error (${err.message})`);
158
187
  }
159
- this.emit("message", {
160
- source: "discord",
161
- adapterId: this.id,
162
- chatId,
163
- threadId,
164
- messageId,
165
- userId,
166
- username,
167
- text,
168
- timestamp: msg.createdAt,
169
- isBotMessage,
170
- attachments: attachments.length > 0 ? attachments : undefined,
171
- replyTo: msg.reference?.messageId ?? undefined,
172
- replyToText,
173
- });
174
188
  });
175
189
  // Handle button interactions and slash commands
176
190
  // Trust boundary: interaction responses can throw DiscordAPIError[10062] if the
177
191
  // interaction expires (>3s). Catch to prevent crashing the entire daemon.
178
192
  this.client.on("interactionCreate", async (interaction) => {
179
193
  try {
180
- if (interaction.guildId !== this.guildId) {
181
- // Allow slash commands through guild whitelist is checked by fleet-manager.
182
- // Only block non-slash interactions (buttons) from unknown channels.
183
- if (!interaction.isChatInputCommand() && !this.openChannels.has(interaction.channelId ?? ""))
194
+ // Buttons: acknowledge IMMEDIATELY, before any guild/channel filtering.
195
+ // A button has a 3s ack window; any early return (unknown guild/channel)
196
+ // or a downstream no-op (e.g. the cancel button was already cleared) would
197
+ // otherwise leave it unacknowledged and Discord shows "interaction failed /
198
+ // expired" right away. deferUpdate is a no-op edit, safe even if we then
199
+ // decide not to act on it.
200
+ if (interaction.isButton()) {
201
+ try {
202
+ await interaction.deferUpdate();
203
+ }
204
+ catch { /* already acknowledged / unknown interaction */ }
205
+ // Only act on buttons from the primary guild or a known open channel.
206
+ if (interaction.guildId !== this.guildId && !this.openChannels.has(interaction.channelId ?? "")) {
207
+ // console.log(`[discord] ignoring button from non-primary guild ${interaction.guildId} channel ${interaction.channelId}`);
184
208
  return;
185
- if (!interaction.isChatInputCommand()) {
186
- console.log(`[discord] classic channel interaction from non-primary guild ${interaction.guildId} channel ${interaction.channelId}`);
187
209
  }
188
- }
189
- if (interaction.isButton()) {
190
- await interaction.deferUpdate();
191
210
  this.emit("callback_query", {
192
211
  callbackData: interaction.customId,
193
212
  chatId: this.guildId,
@@ -196,6 +215,11 @@ export class DiscordAdapter extends EventEmitter {
196
215
  });
197
216
  return;
198
217
  }
218
+ if (interaction.guildId !== this.guildId) {
219
+ // Allow slash commands through — guild whitelist is checked by fleet-manager.
220
+ if (!interaction.isChatInputCommand() && !this.openChannels.has(interaction.channelId ?? ""))
221
+ return;
222
+ }
199
223
  if (interaction.isChatInputCommand()) {
200
224
  const channelName = interaction.channel && "name" in interaction.channel ? (interaction.channel.name ?? "") : "";
201
225
  const username = interaction.user.username;
@@ -260,7 +284,7 @@ export class DiscordAdapter extends EventEmitter {
260
284
  if (channel.guildId !== this.guildId) {
261
285
  if (!this.openChannels.has(channel.id))
262
286
  return;
263
- console.log(`[discord] classic channel deleted from non-primary guild ${channel.guildId} channel ${channel.id}`);
287
+ // Allowed: an open classic channel in a non-primary guild was deleted.
264
288
  }
265
289
  this.emit("topic_closed", {
266
290
  chatId: this.guildId,
@@ -271,7 +295,7 @@ export class DiscordAdapter extends EventEmitter {
271
295
  /** Mark channels as open (skip access control) — used for classic bot channels */
272
296
  setOpenChannels(channelIds) {
273
297
  this.openChannels = new Set(channelIds);
274
- console.log(`[AgEnD] setOpenChannels: ${channelIds.length} channels`, channelIds);
298
+ // console.log(`[AgEnD] setOpenChannels: ${channelIds.length} channels`, channelIds);
275
299
  }
276
300
  // ── Lifecycle ──────────────────────────────────────────────────────────
277
301
  async start() {
@@ -344,12 +368,18 @@ export class DiscordAdapter extends EventEmitter {
344
368
  const msg = await channel.send({ files: [filePath] });
345
369
  return { messageId: msg.id, chatId, threadId: opts?.threadId };
346
370
  }
347
- async editMessage(chatId, messageId, text) {
348
- // chatId is guild ID in channels topology, but messageId is in a channel.
349
- // We need to find the message. Try all text channels in the guild.
350
- // Optimization: caller usually provides the channel via sendText return value.
371
+ async editMessage(chatId, messageId, text, threadId) {
372
+ // Prefer the exact channel (handles forum-topic threads, which a GuildText
373
+ // scan misses). chatId is the guild id in the channels topology, so the
374
+ // message actually lives in threadId (when set) or a specific text channel.
375
+ try {
376
+ const channel = await this._fetchTextChannel(threadId ?? chatId);
377
+ const msg = await channel.messages.fetch(messageId);
378
+ await msg.edit(text.slice(0, DISCORD_MAX_LENGTH));
379
+ return;
380
+ }
381
+ catch { /* not in that channel — fall through to scan */ }
351
382
  try {
352
- // Try the general channel first, then search
353
383
  const guild = await this.client.guilds.fetch(this.guildId);
354
384
  const channels = guild.channels.cache.filter((c) => c.type === ChannelType.GuildText);
355
385
  for (const [, ch] of channels) {
@@ -375,7 +405,16 @@ export class DiscordAdapter extends EventEmitter {
375
405
  }
376
406
  /** Edit text and clear components (Discord keeps components on a plain edit,
377
407
  * so we must pass an empty array to drop the Cancel button). */
378
- async editMessageRemoveButtons(chatId, messageId, text) {
408
+ async editMessageRemoveButtons(chatId, messageId, text, threadId) {
409
+ // Prefer the exact channel (handles forum-topic threads, which a GuildText
410
+ // scan misses); fall back to scanning top-level text channels.
411
+ try {
412
+ const channel = await this._fetchTextChannel(threadId ?? chatId);
413
+ const msg = await channel.messages.fetch(messageId);
414
+ await msg.edit({ content: text.slice(0, DISCORD_MAX_LENGTH), components: [] });
415
+ return;
416
+ }
417
+ catch { /* not in that channel — fall through to scan */ }
379
418
  try {
380
419
  const guild = await this.client.guilds.fetch(this.guildId);
381
420
  const channels = guild.channels.cache.filter((c) => c.type === ChannelType.GuildText);
@@ -393,7 +432,16 @@ export class DiscordAdapter extends EventEmitter {
393
432
  }
394
433
  catch { /* message gone — nothing to clear */ }
395
434
  }
396
- async deleteMessage(chatId, messageId) {
435
+ async deleteMessage(chatId, messageId, threadId) {
436
+ // Prefer the exact channel (handles forum-topic threads, which a GuildText
437
+ // scan misses); fall back to scanning top-level text channels.
438
+ try {
439
+ const channel = await this._fetchTextChannel(threadId ?? chatId);
440
+ const msg = await channel.messages.fetch(messageId);
441
+ await msg.delete();
442
+ return;
443
+ }
444
+ catch { /* not in that channel — fall through to scan */ }
397
445
  try {
398
446
  const guild = await this.client.guilds.fetch(this.guildId);
399
447
  const channels = guild.channels.cache.filter((c) => c.type === ChannelType.GuildText);
@@ -411,11 +459,14 @@ export class DiscordAdapter extends EventEmitter {
411
459
  }
412
460
  catch { /* message already gone */ }
413
461
  }
414
- async react(chatId, messageId, emoji) {
462
+ async react(chatId, messageId, emoji, threadId) {
415
463
  try {
464
+ // A Discord thread is its own channel — a message posted in a topic thread
465
+ // lives there, not in the parent channel, so react on threadId when given.
466
+ const channelId = threadId ?? chatId;
416
467
  // Direct REST call — single API request instead of 3 (fetchChannel → fetchMessage → react)
417
468
  const encoded = encodeURIComponent(emoji);
418
- await this.client.rest.put(`/channels/${chatId}/messages/${messageId}/reactions/${encoded}/@me`);
469
+ await this.client.rest.put(`/channels/${channelId}/messages/${messageId}/reactions/${encoded}/@me`);
419
470
  }
420
471
  catch {
421
472
  // No-op per degradation strategy