@songsid/agend 2.0.8-beta.9 → 2.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -3
- package/dist/adapter-world.d.ts +1 -1
- package/dist/adapter-world.js +2 -2
- package/dist/adapter-world.js.map +1 -1
- package/dist/agent-endpoint.js +6 -0
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/backend/codex.js +10 -3
- package/dist/backend/codex.js.map +1 -1
- package/dist/channel/adapters/discord.d.ts +4 -4
- package/dist/channel/adapters/discord.js +162 -111
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/adapters/telegram.d.ts +1 -1
- package/dist/channel/adapters/telegram.js +3 -1
- package/dist/channel/adapters/telegram.js.map +1 -1
- package/dist/channel/tool-router.js +4 -2
- package/dist/channel/tool-router.js.map +1 -1
- package/dist/channel/tool-tracker.js +2 -2
- package/dist/channel/tool-tracker.js.map +1 -1
- package/dist/channel/types.d.ts +14 -6
- package/dist/cli.js +150 -95
- package/dist/cli.js.map +1 -1
- package/dist/daemon.d.ts +25 -1
- package/dist/daemon.js +149 -43
- package/dist/daemon.js.map +1 -1
- package/dist/fleet-manager.d.ts +47 -5
- package/dist/fleet-manager.js +362 -139
- package/dist/fleet-manager.js.map +1 -1
- package/dist/instance-lifecycle.js +9 -0
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/logger.d.ts +9 -1
- package/dist/logger.js +17 -7
- package/dist/logger.js.map +1 -1
- package/dist/outbound-handlers.d.ts +3 -0
- package/dist/outbound-handlers.js +17 -0
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +1 -1
- package/dist/tmux-control.d.ts +10 -0
- package/dist/tmux-control.js +29 -0
- package/dist/tmux-control.js.map +1 -1
- package/dist/tmux-manager.d.ts +6 -0
- package/dist/tmux-manager.js +17 -0
- package/dist/tmux-manager.js.map +1 -1
- package/dist/topic-commands.d.ts +21 -0
- package/dist/topic-commands.js +73 -6
- package/dist/topic-commands.js.map +1 -1
- 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,
|
|
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/>
|
|
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:
|
|
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
|
|
package/dist/adapter-world.d.ts
CHANGED
|
@@ -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>;
|
package/dist/adapter-world.js
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/agent-endpoint.js
CHANGED
|
@@ -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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"}
|
package/dist/backend/codex.js
CHANGED
|
@@ -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
|
-
|
|
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 {
|
|
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
|
-
|
|
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":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACnH,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAqG,mBAAmB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAClL,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEnE,MAAM,2BAA2B,GAAG,MAAM,CAAC;AAE3C,MAAM,OAAO,YAAY;IAIH;IAHX,UAAU,GAAG,OAAO,CAAC;IACtB,UAAU,CAAS;IAE3B,YAAoB,WAAmB;QAAnB,gBAAW,GAAX,WAAW,CAAQ;QACrC,IAAI,CAAC,UAAU,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IAC3C,CAAC;IAED,YAAY,CAAC,MAAwB;QACnC,MAAM,YAAY,GAAG,MAAM,CAAC,eAAe,KAAK,KAAK;YACnD,CAAC,CAAC,4CAA4C;YAC9C,CAAC,CAAC,aAAa,CAAC;QAElB,wEAAwE;QACxE,yEAAyE;QACzE,yDAAyD;QACzD,kFAAkF;QAClF,IAAI,GAAW,CAAC;QAChB,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACtB,GAAG,GAAG,GAAG,IAAI,CAAC,UAAU,IAAI,YAAY,EAAE,CAAC;QAC7C,CAAC;aAAM,CAAC;YACN,GAAG,GAAG,GAAG,IAAI,CAAC,UAAU,kBAAkB,YAAY,EAAE,CAAC;QAC3D,CAAC;QACD,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;YAC3C,GAAG,IAAI,cAAc,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC;QACtD,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,WAAW,CAAC,MAAwB;QAClC,4DAA4D;QAC5D,uEAAuE;QACvE,sEAAsE;QACtE,8DAA8D;QAC9D,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9D,MAAM,OAAO,GAAG,GAAG,IAAI,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;
|
|
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
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
//
|
|
92
|
-
if (
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
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
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
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
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
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
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
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
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
349
|
-
//
|
|
350
|
-
//
|
|
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/${
|
|
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
|