pi-courier 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 (86) hide show
  1. package/README.md +363 -0
  2. package/README.zh-CN.md +362 -0
  3. package/deploy/pi-msg-bridge.service +26 -0
  4. package/deploy/pi-msg-bridge.user.service +37 -0
  5. package/dist/auth/challenge-auth.d.ts +76 -0
  6. package/dist/auth/challenge-auth.d.ts.map +1 -0
  7. package/dist/auth/challenge-auth.js +337 -0
  8. package/dist/auth/challenge-auth.js.map +1 -0
  9. package/dist/cli.d.ts +3 -0
  10. package/dist/cli.d.ts.map +1 -0
  11. package/dist/cli.js +265 -0
  12. package/dist/cli.js.map +1 -0
  13. package/dist/config.d.ts +10 -0
  14. package/dist/config.d.ts.map +1 -0
  15. package/dist/config.js +49 -0
  16. package/dist/config.js.map +1 -0
  17. package/dist/formatting.d.ts +22 -0
  18. package/dist/formatting.d.ts.map +1 -0
  19. package/dist/formatting.js +74 -0
  20. package/dist/formatting.js.map +1 -0
  21. package/dist/lock.d.ts +3 -0
  22. package/dist/lock.d.ts.map +1 -0
  23. package/dist/lock.js +75 -0
  24. package/dist/lock.js.map +1 -0
  25. package/dist/rpc/command-map.d.ts +19 -0
  26. package/dist/rpc/command-map.d.ts.map +1 -0
  27. package/dist/rpc/command-map.js +191 -0
  28. package/dist/rpc/command-map.js.map +1 -0
  29. package/dist/rpc/message-router.d.ts +30 -0
  30. package/dist/rpc/message-router.d.ts.map +1 -0
  31. package/dist/rpc/message-router.js +110 -0
  32. package/dist/rpc/message-router.js.map +1 -0
  33. package/dist/rpc/pi-rpc.d.ts +79 -0
  34. package/dist/rpc/pi-rpc.d.ts.map +1 -0
  35. package/dist/rpc/pi-rpc.js +199 -0
  36. package/dist/rpc/pi-rpc.js.map +1 -0
  37. package/dist/setup.d.ts +10 -0
  38. package/dist/setup.d.ts.map +1 -0
  39. package/dist/setup.js +159 -0
  40. package/dist/setup.js.map +1 -0
  41. package/dist/standalone.d.ts +13 -0
  42. package/dist/standalone.d.ts.map +1 -0
  43. package/dist/standalone.js +184 -0
  44. package/dist/standalone.js.map +1 -0
  45. package/dist/transports/discord.d.ts +33 -0
  46. package/dist/transports/discord.d.ts.map +1 -0
  47. package/dist/transports/discord.js +216 -0
  48. package/dist/transports/discord.js.map +1 -0
  49. package/dist/transports/interface.d.ts +42 -0
  50. package/dist/transports/interface.d.ts.map +1 -0
  51. package/dist/transports/interface.js +2 -0
  52. package/dist/transports/interface.js.map +1 -0
  53. package/dist/transports/manager.d.ts +54 -0
  54. package/dist/transports/manager.d.ts.map +1 -0
  55. package/dist/transports/manager.js +98 -0
  56. package/dist/transports/manager.js.map +1 -0
  57. package/dist/transports/matrix-utils.d.ts +31 -0
  58. package/dist/transports/matrix-utils.d.ts.map +1 -0
  59. package/dist/transports/matrix-utils.js +99 -0
  60. package/dist/transports/matrix-utils.js.map +1 -0
  61. package/dist/transports/matrix-utils.test.d.ts +2 -0
  62. package/dist/transports/matrix-utils.test.d.ts.map +1 -0
  63. package/dist/transports/matrix-utils.test.js +246 -0
  64. package/dist/transports/matrix-utils.test.js.map +1 -0
  65. package/dist/transports/matrix.d.ts +34 -0
  66. package/dist/transports/matrix.d.ts.map +1 -0
  67. package/dist/transports/matrix.js +240 -0
  68. package/dist/transports/matrix.js.map +1 -0
  69. package/dist/transports/slack.d.ts +31 -0
  70. package/dist/transports/slack.d.ts.map +1 -0
  71. package/dist/transports/slack.js +203 -0
  72. package/dist/transports/slack.js.map +1 -0
  73. package/dist/transports/telegram.d.ts +38 -0
  74. package/dist/transports/telegram.d.ts.map +1 -0
  75. package/dist/transports/telegram.js +167 -0
  76. package/dist/transports/telegram.js.map +1 -0
  77. package/dist/transports/whatsapp.d.ts +31 -0
  78. package/dist/transports/whatsapp.d.ts.map +1 -0
  79. package/dist/transports/whatsapp.js +235 -0
  80. package/dist/transports/whatsapp.js.map +1 -0
  81. package/dist/types.d.ts +69 -0
  82. package/dist/types.d.ts.map +1 -0
  83. package/dist/types.js +2 -0
  84. package/dist/types.js.map +1 -0
  85. package/extensions/index.ts +42 -0
  86. package/package.json +71 -0
@@ -0,0 +1,184 @@
1
+ /**
2
+ * Standalone entry — runs the bridge as its own process (systemd-friendly),
3
+ * talking to pi over RPC mode instead of living inside pi as an extension.
4
+ *
5
+ * Usage:
6
+ * node dist/standalone.js [--workdir <dir>] [--pi-cli <path>] [--session-dir <dir>] [--debug]
7
+ *
8
+ * Architecture:
9
+ * Messenger (Matrix/Telegram/...) ──> bridge ──> pi --mode rpc (JSONL over stdio)
10
+ * Messenger <── replies <────────── bridge <── agent events (stdout JSONL)
11
+ */
12
+ import { pathToFileURL } from "node:url";
13
+ import { ChallengeAuth } from "./auth/challenge-auth.js";
14
+ import { loadConfig, saveConfig } from "./config.js";
15
+ import { acquireLock, releaseLock } from "./lock.js";
16
+ import { createMessageRouter } from "./rpc/message-router.js";
17
+ import { PiRpc } from "./rpc/pi-rpc.js";
18
+ import { TransportManager } from "./transports/manager.js";
19
+ import { MatrixProvider } from "./transports/matrix.js";
20
+ // Suppress the known `util._extend` deprecation warning emitted by some
21
+ // transport dependencies at load time — it pollutes interactive output.
22
+ {
23
+ const orig = process.emitWarning;
24
+ process.emitWarning = ((warning, ...rest) => {
25
+ const msg = typeof warning === "string" ? warning : warning?.message ?? "";
26
+ if (msg.includes("util._extend"))
27
+ return;
28
+ orig.call(process, warning, ...rest);
29
+ });
30
+ }
31
+ function parseArgs(argv) {
32
+ const result = {};
33
+ for (let i = 0; i < argv.length; i++) {
34
+ const arg = argv[i];
35
+ switch (arg) {
36
+ case "--workdir":
37
+ result.workdir = argv[++i];
38
+ break;
39
+ case "--setup":
40
+ case "--configure":
41
+ console.warn("⚠️ 旧参数已废弃,请用 `pi-remote setup`");
42
+ break;
43
+ case "--pi-cli":
44
+ console.warn("⚠️ 旧参数已废弃,请在 ~/.pi/msg-bridge.json 配置 cliPath,或设 PI_CLI_PATH");
45
+ i++;
46
+ break;
47
+ case "--session-dir":
48
+ console.warn("⚠️ 旧参数已废弃,请在 ~/.pi/msg-bridge.json 配置 sessionDir");
49
+ i++;
50
+ break;
51
+ case "--debug":
52
+ console.warn("⚠️ 旧参数已废弃,请在 ~/.pi/msg-bridge.json 配置 debug: true");
53
+ break;
54
+ default:
55
+ console.warn(`[bridge] ignoring unknown argument: ${arg}`);
56
+ }
57
+ }
58
+ return result;
59
+ }
60
+ function log(...args) {
61
+ console.log(`[${new Date().toISOString()}]`, ...args);
62
+ }
63
+ export async function main(argv = process.argv.slice(2)) {
64
+ const args = parseArgs(argv);
65
+ // Single-instance guard (same lock file as the extension mode)
66
+ if (!acquireLock()) {
67
+ console.error("[bridge] another msg-bridge instance is already running — exiting");
68
+ process.exit(1);
69
+ }
70
+ const config = loadConfig();
71
+ const debug = config.debug === true;
72
+ const workdir = args.workdir ?? config.workdir;
73
+ const sessionDir = config.sessionDir;
74
+ const cliPath = config.cliPath;
75
+ const auth = new ChallengeAuth((code, username) => log(`🔐 Challenge code for @${username}: ${code}`), (message, level) => log(`[auth:${level ?? "info"}] ${message}`), async (_chatId, _message) => {
76
+ // Challenge prompts are sent via the transport's sendMessage
77
+ }, () => {
78
+ const cfg = loadConfig();
79
+ cfg.auth = auth.exportConfig();
80
+ saveConfig(cfg);
81
+ });
82
+ if (config.auth) {
83
+ auth.loadFromConfig(config.auth);
84
+ }
85
+ const transportManager = new TransportManager();
86
+ const addTransport = (transport) => {
87
+ transportManager.addTransport(transport);
88
+ };
89
+ if (config.matrix?.homeserverUrl && config.matrix?.accessToken) {
90
+ addTransport(new MatrixProvider(config.matrix, auth));
91
+ }
92
+ if (transportManager.getAllTransports().length === 0) {
93
+ console.error("[bridge] no transports configured. Configure ~/.pi/msg-bridge.json or set PI_* env vars (see README).");
94
+ releaseLock();
95
+ process.exit(1);
96
+ }
97
+ // ---- pi RPC -------------------------------------------------------------
98
+ // --continue: resume the most recent session on restart (same as `pi -c`),
99
+ // so bridge/service restarts and /reload keep the conversation context.
100
+ const rpcArgs = ["--continue"];
101
+ if (sessionDir) {
102
+ rpcArgs.push("--session-dir", sessionDir);
103
+ }
104
+ const rpc = new PiRpc({
105
+ cliPath,
106
+ cwd: workdir,
107
+ args: rpcArgs,
108
+ });
109
+ // ---- message routing ------------------------------------------------------
110
+ const sendReply = async (chatId, transport, text) => {
111
+ try {
112
+ await transportManager.sendMessage(chatId, transport, text);
113
+ }
114
+ catch (err) {
115
+ log(`⚠️ failed to send reply via ${transport}:`, err.message);
116
+ }
117
+ };
118
+ const router = createMessageRouter({
119
+ rpc,
120
+ auth,
121
+ transportManager,
122
+ sendReply,
123
+ log,
124
+ debug,
125
+ });
126
+ transportManager.onMessage((msg) => {
127
+ router.handleIncoming(msg).catch((err) => {
128
+ log("❌ message handling error:", err.message);
129
+ });
130
+ });
131
+ transportManager.onError((err, transport) => {
132
+ log(`❌ ${transport} error:`, err.message);
133
+ });
134
+ // ---- agent events → replies ------------------------------------------------
135
+ rpc.onEvent((event) => {
136
+ router.handleEvent(event);
137
+ });
138
+ // ---- startup ----------------------------------------------------------------
139
+ try {
140
+ await transportManager.connectAll();
141
+ log(`✅ transports connected: ${transportManager
142
+ .getStatus()
143
+ .map((s) => `${s.type}=${s.connected ? "up" : "down"}`)
144
+ .join(", ")}`);
145
+ }
146
+ catch (err) {
147
+ log("⚠️ some transports failed to connect:", err.message);
148
+ }
149
+ try {
150
+ await rpc.start();
151
+ const state = await rpc.getState();
152
+ log(`✅ pi RPC connected (model: ${state.model?.id ?? "unknown"}, session: ${state.sessionId ?? "?"})`);
153
+ }
154
+ catch (err) {
155
+ console.error("[bridge] failed to start pi RPC:", err.message);
156
+ await transportManager.disconnectAll();
157
+ releaseLock();
158
+ process.exit(1);
159
+ }
160
+ // ---- shutdown ----------------------------------------------------------------
161
+ let shuttingDown = false;
162
+ const shutdown = async (signal) => {
163
+ if (shuttingDown)
164
+ return;
165
+ shuttingDown = true;
166
+ log(`🛑 ${signal} received — shutting down`);
167
+ await rpc.stop().catch(() => { });
168
+ await transportManager.disconnectAll();
169
+ releaseLock();
170
+ process.exit(0);
171
+ };
172
+ process.on("SIGTERM", () => void shutdown("SIGTERM"));
173
+ process.on("SIGINT", () => void shutdown("SIGINT"));
174
+ log("🚀 msg-bridge standalone ready. Waiting for messages...");
175
+ }
176
+ // Direct execution: `node dist/standalone.js [--workdir ...]`
177
+ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
178
+ main().catch((err) => {
179
+ console.error("[bridge] fatal:", err);
180
+ releaseLock();
181
+ process.exit(1);
182
+ });
183
+ }
184
+ //# sourceMappingURL=standalone.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"standalone.js","sourceRoot":"","sources":["../src/standalone.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import type { ChallengeAuth } from "../auth/challenge-auth.js";
2
+ import type { ExternalMessage } from "../types.js";
3
+ import type { ITransportProvider } from "./interface.js";
4
+ /**
5
+ * Discord transport provider using discord.js
6
+ */
7
+ export declare class DiscordProvider implements ITransportProvider {
8
+ private config;
9
+ private auth;
10
+ readonly type = "discord";
11
+ private client;
12
+ private _isConnected;
13
+ private botUserId;
14
+ private messageHandler?;
15
+ private errorHandler?;
16
+ private lastProcessedMessageId;
17
+ constructor(config: {
18
+ token: string;
19
+ }, auth: ChallengeAuth);
20
+ get isConnected(): boolean;
21
+ connect(): Promise<void>;
22
+ disconnect(): Promise<void>;
23
+ sendMessage(chatId: string, text: string): Promise<void>;
24
+ sendTyping(chatId: string): Promise<void>;
25
+ onMessage(handler: (message: ExternalMessage) => void): void;
26
+ onError(handler: (error: Error) => void): void;
27
+ /**
28
+ * Split a message into chunks that fit Discord's 2000 char limit.
29
+ * Tries to split at newlines or spaces when possible.
30
+ */
31
+ private splitMessage;
32
+ }
33
+ //# sourceMappingURL=discord.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discord.d.ts","sourceRoot":"","sources":["../../src/transports/discord.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAWzD;;GAEG;AACH,qBAAa,eAAgB,YAAW,kBAAkB;IAUtD,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,IAAI;IAVd,QAAQ,CAAC,IAAI,aAAa;IAC1B,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,cAAc,CAAC,CAAqC;IAC5D,OAAO,CAAC,YAAY,CAAC,CAAyB;IAC9C,OAAO,CAAC,sBAAsB,CAAM;gBAG1B,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,EACzB,IAAI,EAAE,aAAa;IAG7B,IAAI,WAAW,IAAI,OAAO,CAEzB;IAEK,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA8IxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAS3B,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBxD,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAe/C,SAAS,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,GAAG,IAAI;IAI5D,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;IAI9C;;;OAGG;IACH,OAAO,CAAC,YAAY;CA+BrB"}
@@ -0,0 +1,216 @@
1
+ async function loadDiscordJS() {
2
+ const discord = await import("discord.js");
3
+ return discord;
4
+ }
5
+ /**
6
+ * Discord transport provider using discord.js
7
+ */
8
+ export class DiscordProvider {
9
+ config;
10
+ auth;
11
+ type = "discord";
12
+ client = null;
13
+ _isConnected = false;
14
+ botUserId = "";
15
+ messageHandler;
16
+ errorHandler;
17
+ lastProcessedMessageId = "";
18
+ constructor(config, auth) {
19
+ this.config = config;
20
+ this.auth = auth;
21
+ }
22
+ get isConnected() {
23
+ return this._isConnected;
24
+ }
25
+ async connect() {
26
+ if (this._isConnected)
27
+ return;
28
+ const { token } = this.config;
29
+ if (!token) {
30
+ throw new Error("Discord bot token required");
31
+ }
32
+ const discord = await loadDiscordJS();
33
+ this.client = new discord.Client({
34
+ intents: [
35
+ discord.GatewayIntentBits.Guilds,
36
+ discord.GatewayIntentBits.GuildMessages,
37
+ discord.GatewayIntentBits.DirectMessages,
38
+ discord.GatewayIntentBits.MessageContent, // Privileged intent - must enable in Discord Developer Portal
39
+ ],
40
+ partials: [
41
+ discord.Partials.Channel,
42
+ discord.Partials.Message,
43
+ ],
44
+ });
45
+ // Handle incoming messages
46
+ this.client.on(discord.Events.MessageCreate, async (message) => {
47
+ // Ignore bot's own messages
48
+ if (message.author.bot) {
49
+ return;
50
+ }
51
+ // Skip empty messages (attachments only, etc.)
52
+ if (!message.content) {
53
+ return;
54
+ }
55
+ // Filter out duplicate messages
56
+ if (message.id === this.lastProcessedMessageId) {
57
+ return;
58
+ }
59
+ this.lastProcessedMessageId = message.id;
60
+ // Detect if this is a DM
61
+ const isDM = message.channel.type === discord.ChannelType.DM;
62
+ // Detect bot mention: <@BOT_USER_ID> or <@!BOT_USER_ID> (nickname mention)
63
+ const wasMentioned = this.botUserId
64
+ ? message.content.includes(`<@${this.botUserId}>`) ||
65
+ message.content.includes(`<@!${this.botUserId}>`) ||
66
+ message.mentions.users.has(this.botUserId)
67
+ : false;
68
+ const userId = message.author.id;
69
+ const chatId = message.channelId;
70
+ const username = message.author.username;
71
+ const text = message.content.trim();
72
+ const isGroupChat = !isDM;
73
+ // Check authorization
74
+ const sendMessageToUser = async (cId, text) => {
75
+ if (this.client) {
76
+ const channel = await this.client.channels.fetch(cId);
77
+ if (channel && "send" in channel) {
78
+ await channel.send(text);
79
+ }
80
+ }
81
+ };
82
+ const isAuthorized = await this.auth.checkAuthorization(userId, chatId, username, isGroupChat, wasMentioned, sendMessageToUser, this.type);
83
+ // Handle admin commands and challenge codes in DM
84
+ if (!isGroupChat && (text.startsWith("/") || text.match(/^\d{6}$/))) {
85
+ const handled = await this.auth.handleAdminCommand(text, chatId, userId, async (text) => await this.sendMessage(chatId, text), this.type);
86
+ if (handled) {
87
+ return;
88
+ }
89
+ }
90
+ if (!isAuthorized) {
91
+ return; // Auth handler already sent challenge/error messages
92
+ }
93
+ // Forward to message handler
94
+ if (this.messageHandler) {
95
+ const externalMessage = {
96
+ chatId,
97
+ transport: this.type,
98
+ content: text,
99
+ username: username,
100
+ userId: userId,
101
+ timestamp: message.createdAt,
102
+ messageId: message.id,
103
+ isGroupChat,
104
+ wasMentioned,
105
+ };
106
+ this.messageHandler(externalMessage);
107
+ }
108
+ });
109
+ // Handle ready event
110
+ this.client.once(discord.Events.ClientReady, (readyClient) => {
111
+ this.botUserId = readyClient.user.id;
112
+ console.log(`✅ Discord logged in as ${readyClient.user.tag} (ID: ${this.botUserId})`);
113
+ this._isConnected = true;
114
+ });
115
+ // Handle errors
116
+ this.client.on(discord.Events.Error, (error) => {
117
+ console.error("[Discord] Error:", error);
118
+ if (this.errorHandler) {
119
+ this.errorHandler(error);
120
+ }
121
+ });
122
+ // Handle disconnection
123
+ this.client.on(discord.Events.ShardDisconnect, () => {
124
+ console.log("[Discord] Disconnected");
125
+ this._isConnected = false;
126
+ });
127
+ try {
128
+ await this.client.login(token);
129
+ }
130
+ catch (error) {
131
+ throw new Error(`Discord login failed: ${error.message}`);
132
+ }
133
+ }
134
+ async disconnect() {
135
+ if (this.client) {
136
+ this.client.destroy();
137
+ this.client = null;
138
+ }
139
+ this._isConnected = false;
140
+ console.log("[Discord] Disconnected");
141
+ }
142
+ async sendMessage(chatId, text) {
143
+ if (!this.client) {
144
+ throw new Error("Discord not connected");
145
+ }
146
+ if (!text?.trim())
147
+ return;
148
+ try {
149
+ const channel = await this.client.channels.fetch(chatId);
150
+ if (!channel?.isTextBased()) {
151
+ throw new Error(`Cannot send to channel ${chatId}`);
152
+ }
153
+ // Discord has 2000 char limit - split long messages
154
+ const chunks = this.splitMessage(text, 2000);
155
+ for (const chunk of chunks) {
156
+ if ("send" in channel) {
157
+ await channel.send(chunk);
158
+ }
159
+ }
160
+ }
161
+ catch (error) {
162
+ throw new Error(`Discord send failed: ${error.message}`);
163
+ }
164
+ }
165
+ async sendTyping(chatId) {
166
+ if (!this.client) {
167
+ return;
168
+ }
169
+ try {
170
+ const channel = await this.client.channels.fetch(chatId);
171
+ if (channel && "sendTyping" in channel) {
172
+ await channel.sendTyping();
173
+ }
174
+ }
175
+ catch (error) {
176
+ console.warn("[Discord] Failed to send typing:", error);
177
+ }
178
+ }
179
+ onMessage(handler) {
180
+ this.messageHandler = handler;
181
+ }
182
+ onError(handler) {
183
+ this.errorHandler = handler;
184
+ }
185
+ /**
186
+ * Split a message into chunks that fit Discord's 2000 char limit.
187
+ * Tries to split at newlines or spaces when possible.
188
+ */
189
+ splitMessage(text, limit) {
190
+ if (text.length <= limit) {
191
+ return [text];
192
+ }
193
+ const chunks = [];
194
+ let remaining = text;
195
+ while (remaining.length > 0) {
196
+ if (remaining.length <= limit) {
197
+ chunks.push(remaining);
198
+ break;
199
+ }
200
+ // Try to find a good split point (newline or space)
201
+ let splitAt = limit;
202
+ const newlineIdx = remaining.lastIndexOf("\n", limit);
203
+ const spaceIdx = remaining.lastIndexOf(" ", limit);
204
+ if (newlineIdx > limit * 0.5) {
205
+ splitAt = newlineIdx + 1;
206
+ }
207
+ else if (spaceIdx > limit * 0.5) {
208
+ splitAt = spaceIdx + 1;
209
+ }
210
+ chunks.push(remaining.substring(0, splitAt).trimEnd());
211
+ remaining = remaining.substring(splitAt).trimStart();
212
+ }
213
+ return chunks;
214
+ }
215
+ }
216
+ //# sourceMappingURL=discord.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discord.js","sourceRoot":"","sources":["../../src/transports/discord.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import type { ExternalMessage } from "../types.js";
2
+ /**
3
+ * Transport provider interface
4
+ * Adapts different messenger platforms (Telegram, WhatsApp, Slack, Discord)
5
+ */
6
+ export interface ITransportProvider {
7
+ /** Transport type identifier */
8
+ readonly type: string;
9
+ /** Is the transport currently connected? */
10
+ readonly isConnected: boolean;
11
+ /**
12
+ * Connect to the messenger service
13
+ * @throws Error if connection fails
14
+ */
15
+ connect(): Promise<void>;
16
+ /**
17
+ * Disconnect from the messenger service
18
+ */
19
+ disconnect(): Promise<void>;
20
+ /**
21
+ * Send a text message to a chat
22
+ * @param chatId - Chat/channel identifier
23
+ * @param text - Message content
24
+ */
25
+ sendMessage(chatId: string, text: string): Promise<void>;
26
+ /**
27
+ * Send typing indicator to a chat
28
+ * @param chatId - Chat/channel identifier
29
+ */
30
+ sendTyping(chatId: string): Promise<void>;
31
+ /**
32
+ * Register callback for incoming messages
33
+ * @param handler - Message handler function
34
+ */
35
+ onMessage(handler: (message: ExternalMessage) => void): void;
36
+ /**
37
+ * Register callback for errors
38
+ * @param handler - Error handler function
39
+ */
40
+ onError(handler: (error: Error) => void): void;
41
+ }
42
+ //# sourceMappingURL=interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/transports/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,gCAAgC;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,4CAA4C;IAC5C,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAE9B;;;OAGG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzB;;OAEG;IACH,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5B;;;;OAIG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzD;;;OAGG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1C;;;OAGG;IACH,SAAS,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,GAAG,IAAI,CAAC;IAE7D;;;OAGG;IACH,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;CAChD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interface.js","sourceRoot":"","sources":["../../src/transports/interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,54 @@
1
+ import type { ExternalMessage } from "../types.js";
2
+ import type { ITransportProvider } from "./interface.js";
3
+ /**
4
+ * Manages multiple transport providers and routes messages
5
+ */
6
+ export declare class TransportManager {
7
+ private transports;
8
+ private messageHandler?;
9
+ private errorHandler?;
10
+ /**
11
+ * Register a transport provider
12
+ */
13
+ addTransport(transport: ITransportProvider): void;
14
+ /**
15
+ * Get a specific transport by type
16
+ */
17
+ getTransport(type: string): ITransportProvider | undefined;
18
+ /**
19
+ * Get all registered transports
20
+ */
21
+ getAllTransports(): ITransportProvider[];
22
+ /**
23
+ * Connect all registered transports
24
+ */
25
+ connectAll(): Promise<void>;
26
+ /**
27
+ * Disconnect all transports
28
+ */
29
+ disconnectAll(): Promise<void>;
30
+ /**
31
+ * Send a message to a specific chat via a specific transport
32
+ */
33
+ sendMessage(chatId: string, transportType: string, text: string): Promise<void>;
34
+ /**
35
+ * Send typing indicator to a chat via a specific transport
36
+ */
37
+ sendTyping(chatId: string, transportType: string): Promise<void>;
38
+ /**
39
+ * Register handler for incoming messages from all transports
40
+ */
41
+ onMessage(handler: (message: ExternalMessage) => void): void;
42
+ /**
43
+ * Register handler for errors from all transports
44
+ */
45
+ onError(handler: (error: Error, transport: string) => void): void;
46
+ /**
47
+ * Get connection status for all transports
48
+ */
49
+ getStatus(): Array<{
50
+ type: string;
51
+ connected: boolean;
52
+ }>;
53
+ }
54
+ //# sourceMappingURL=manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/transports/manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEzD;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,UAAU,CAAyC;IAC3D,OAAO,CAAC,cAAc,CAAC,CAAqC;IAC5D,OAAO,CAAC,YAAY,CAAC,CAA4C;IAEjE;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,kBAAkB,GAAG,IAAI;IAkBjD;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAI1D;;OAEG;IACH,gBAAgB,IAAI,kBAAkB,EAAE;IAIxC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IASjC;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAOpC;;OAEG;IACG,WAAW,CACf,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC;IAWhB;;OAEG;IACG,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOtE;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,GAAG,IAAI;IAI5D;;OAEG;IACH,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAIjE;;OAEG;IACH,SAAS,IAAI,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC;CAMzD"}