@producible/cereworker-channels 26.520.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 (58) hide show
  1. package/LICENSE +21 -0
  2. package/dist/adapters/discord.d.ts +21 -0
  3. package/dist/adapters/discord.d.ts.map +1 -0
  4. package/dist/adapters/discord.js +183 -0
  5. package/dist/adapters/discord.js.map +1 -0
  6. package/dist/adapters/feishu.d.ts +10 -0
  7. package/dist/adapters/feishu.d.ts.map +1 -0
  8. package/dist/adapters/feishu.js +114 -0
  9. package/dist/adapters/feishu.js.map +1 -0
  10. package/dist/adapters/irc.d.ts +23 -0
  11. package/dist/adapters/irc.d.ts.map +1 -0
  12. package/dist/adapters/irc.js +158 -0
  13. package/dist/adapters/irc.js.map +1 -0
  14. package/dist/adapters/matrix.d.ts +9 -0
  15. package/dist/adapters/matrix.d.ts.map +1 -0
  16. package/dist/adapters/matrix.js +70 -0
  17. package/dist/adapters/matrix.js.map +1 -0
  18. package/dist/adapters/signal.d.ts +10 -0
  19. package/dist/adapters/signal.d.ts.map +1 -0
  20. package/dist/adapters/signal.js +116 -0
  21. package/dist/adapters/signal.js.map +1 -0
  22. package/dist/adapters/slack.d.ts +9 -0
  23. package/dist/adapters/slack.d.ts.map +1 -0
  24. package/dist/adapters/slack.js +75 -0
  25. package/dist/adapters/slack.js.map +1 -0
  26. package/dist/adapters/telegram.d.ts +7 -0
  27. package/dist/adapters/telegram.d.ts.map +1 -0
  28. package/dist/adapters/telegram.js +92 -0
  29. package/dist/adapters/telegram.js.map +1 -0
  30. package/dist/adapters/wechat.d.ts +8 -0
  31. package/dist/adapters/wechat.d.ts.map +1 -0
  32. package/dist/adapters/wechat.js +107 -0
  33. package/dist/adapters/wechat.js.map +1 -0
  34. package/dist/adapters/whatsapp.d.ts +7 -0
  35. package/dist/adapters/whatsapp.d.ts.map +1 -0
  36. package/dist/adapters/whatsapp.js +102 -0
  37. package/dist/adapters/whatsapp.js.map +1 -0
  38. package/dist/chunking.d.ts +18 -0
  39. package/dist/chunking.d.ts.map +1 -0
  40. package/dist/chunking.js +137 -0
  41. package/dist/chunking.js.map +1 -0
  42. package/dist/factory.d.ts +5 -0
  43. package/dist/factory.d.ts.map +1 -0
  44. package/dist/factory.js +86 -0
  45. package/dist/factory.js.map +1 -0
  46. package/dist/index.d.ts +15 -0
  47. package/dist/index.d.ts.map +1 -0
  48. package/dist/index.js +13 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/manager.d.ts +34 -0
  51. package/dist/manager.d.ts.map +1 -0
  52. package/dist/manager.js +97 -0
  53. package/dist/manager.js.map +1 -0
  54. package/dist/types.d.ts +49 -0
  55. package/dist/types.d.ts.map +1 -0
  56. package/dist/types.js +2 -0
  57. package/dist/types.js.map +1 -0
  58. package/package.json +39 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Producible
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,21 @@
1
+ import { GatewayIntentBits, Partials } from 'discord.js';
2
+ import type { ChannelPlugin, CommandDef } from '../types.js';
3
+ export interface DiscordChannelConfig {
4
+ token: string;
5
+ applicationId?: string;
6
+ allowFrom: string[];
7
+ channelIds: string[];
8
+ commands?: CommandDef[];
9
+ }
10
+ export declare function getDiscordClientOptions(): {
11
+ intents: GatewayIntentBits[];
12
+ partials: Partials[];
13
+ };
14
+ export declare function shouldHandleDiscordMessage(params: {
15
+ isDM: boolean;
16
+ isMentioned: boolean;
17
+ routeIds: string[];
18
+ channelIds: string[];
19
+ }): boolean;
20
+ export declare function createDiscordChannel(config: DiscordChannelConfig): ChannelPlugin;
21
+ //# sourceMappingURL=discord.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discord.d.ts","sourceRoot":"","sources":["../../src/adapters/discord.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,iBAAiB,EAEjB,QAAQ,EAMT,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,aAAa,EAAmD,UAAU,EAAE,MAAM,aAAa,CAAC;AAG9G,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAC;CACzB;AAED,wBAAgB,uBAAuB;;;EAUtC;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE;IACjD,IAAI,EAAE,OAAO,CAAC;IACd,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB,GAAG,OAAO,CAKV;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,oBAAoB,GAAG,aAAa,CAmLhF"}
@@ -0,0 +1,183 @@
1
+ import { Client, GatewayIntentBits, Events, Partials, REST, Routes, SlashCommandBuilder, } from 'discord.js';
2
+ import { chunkMarkdown, CHANNEL_LIMITS } from '../chunking.js';
3
+ export function getDiscordClientOptions() {
4
+ return {
5
+ intents: [
6
+ GatewayIntentBits.Guilds,
7
+ GatewayIntentBits.GuildMessages,
8
+ GatewayIntentBits.MessageContent,
9
+ GatewayIntentBits.DirectMessages,
10
+ ],
11
+ partials: [Partials.Channel],
12
+ };
13
+ }
14
+ export function shouldHandleDiscordMessage(params) {
15
+ if (params.isDM)
16
+ return true;
17
+ if (params.isMentioned)
18
+ return true;
19
+ if (params.channelIds.length === 0)
20
+ return false;
21
+ return params.routeIds.some((id) => params.channelIds.includes(id));
22
+ }
23
+ export function createDiscordChannel(config) {
24
+ let client = null;
25
+ let connected = false;
26
+ const limit = CHANNEL_LIMITS.discord;
27
+ async function registerSlashCommands() {
28
+ if (!config.applicationId || !config.commands?.length)
29
+ return;
30
+ try {
31
+ const rest = new REST({ version: '10' }).setToken(config.token);
32
+ const commands = config.commands.map((cmd) => {
33
+ const builder = new SlashCommandBuilder()
34
+ .setName(cmd.name)
35
+ .setDescription(cmd.description);
36
+ if (cmd.hasArgs) {
37
+ builder.addStringOption((opt) => opt.setName('args').setDescription('Arguments').setRequired(false));
38
+ }
39
+ return builder.toJSON();
40
+ });
41
+ await rest.put(Routes.applicationCommands(config.applicationId), { body: commands });
42
+ }
43
+ catch {
44
+ // Non-critical — bot works without slash commands
45
+ }
46
+ }
47
+ return {
48
+ id: 'discord',
49
+ meta: { name: 'Discord', emoji: 'D' },
50
+ async start(handler) {
51
+ client = new Client(getDiscordClientOptions());
52
+ client.on(Events.MessageCreate, async (message) => {
53
+ // Ignore bot's own messages
54
+ if (message.author.bot)
55
+ return;
56
+ // Reply in DMs, on mentions, or in explicitly configured server channels.
57
+ const isDM = !message.inGuild();
58
+ const isMentioned = client?.user && message.mentions.has(client.user);
59
+ const routeIds = [message.channelId];
60
+ if (message.channel.isThread() && message.channel.parentId) {
61
+ routeIds.push(message.channel.parentId);
62
+ }
63
+ if (!shouldHandleDiscordMessage({ isDM, isMentioned: Boolean(isMentioned), routeIds, channelIds: config.channelIds })) {
64
+ return;
65
+ }
66
+ // Strip mention from text
67
+ let text = message.content;
68
+ if (client?.user) {
69
+ text = text.replace(new RegExp(`<@!?${client.user.id}>`, 'g'), '').trim();
70
+ }
71
+ if (!text)
72
+ return;
73
+ const inbound = {
74
+ channelId: 'discord',
75
+ routeTo: message.channelId,
76
+ senderId: message.author.id,
77
+ senderName: message.author.username,
78
+ text,
79
+ sessionId: isDM
80
+ ? `dm:${message.channelId}`
81
+ : message.channel.isThread()
82
+ ? `thread:${message.channel.id}`
83
+ : `channel:${message.channelId}`,
84
+ threadId: message.channel.isThread() ? message.channel.id : undefined,
85
+ timestamp: message.createdTimestamp,
86
+ };
87
+ const response = await handler(inbound);
88
+ if (response) {
89
+ const chunks = chunkMarkdown(response, limit);
90
+ for (const chunk of chunks) {
91
+ await message.reply(chunk);
92
+ }
93
+ }
94
+ });
95
+ // Handle slash command interactions
96
+ client.on(Events.InteractionCreate, async (interaction) => {
97
+ if (!interaction.isChatInputCommand())
98
+ return;
99
+ const cmd = interaction;
100
+ if (!this.isAllowed(cmd.user.id)) {
101
+ await cmd.reply({ content: 'Not authorized.', ephemeral: true });
102
+ return;
103
+ }
104
+ // Enforce same channel routing as text messages:
105
+ // DMs always allowed; guild messages require mention OR configured channel
106
+ const isDM = !cmd.inGuild();
107
+ const isThread = cmd.channel?.isThread?.() ?? false;
108
+ const parentId = isThread ? cmd.channel.parentId ?? '' : '';
109
+ if (!isDM) {
110
+ const routeIds = [cmd.channelId ?? ''];
111
+ if (parentId)
112
+ routeIds.push(parentId);
113
+ if (!shouldHandleDiscordMessage({ isDM: false, isMentioned: false, routeIds, channelIds: config.channelIds })) {
114
+ await cmd.reply({ content: 'Not available in this channel.', ephemeral: true });
115
+ return;
116
+ }
117
+ }
118
+ // Read arguments for commands that accept them
119
+ const args = cmd.options.getString('args') ?? '';
120
+ const text = args ? `/${cmd.commandName} ${args}` : `/${cmd.commandName}`;
121
+ // Match session IDs with text message logic
122
+ const sessionId = isDM
123
+ ? `dm:${cmd.channelId}`
124
+ : isThread
125
+ ? `thread:${cmd.channelId}`
126
+ : `channel:${cmd.channelId}`;
127
+ const inbound = {
128
+ channelId: 'discord',
129
+ routeTo: cmd.channelId ?? undefined,
130
+ senderId: cmd.user.id,
131
+ senderName: cmd.user.username,
132
+ text,
133
+ sessionId,
134
+ threadId: isThread ? cmd.channelId ?? undefined : undefined,
135
+ timestamp: cmd.createdTimestamp,
136
+ };
137
+ // All slash command replies are ephemeral (only visible to invoking user)
138
+ await cmd.deferReply({ ephemeral: true });
139
+ const response = await handler(inbound);
140
+ if (response) {
141
+ const chunks = chunkMarkdown(response, limit);
142
+ await cmd.editReply(chunks[0]);
143
+ for (let i = 1; i < chunks.length; i++) {
144
+ await cmd.followUp({ content: chunks[i], ephemeral: true });
145
+ }
146
+ }
147
+ else {
148
+ await cmd.editReply('Done.');
149
+ }
150
+ });
151
+ await client.login(config.token);
152
+ connected = true;
153
+ // Register slash commands after login
154
+ await registerSlashCommands();
155
+ },
156
+ async stop() {
157
+ if (client) {
158
+ await client.destroy();
159
+ connected = false;
160
+ }
161
+ },
162
+ async send(msg) {
163
+ if (!client)
164
+ throw new Error('Discord not started');
165
+ const channel = await client.channels.fetch(msg.to);
166
+ if (channel && 'send' in channel) {
167
+ const chunks = chunkMarkdown(msg.text, limit);
168
+ for (const chunk of chunks) {
169
+ await channel.send(chunk);
170
+ }
171
+ }
172
+ },
173
+ isAllowed(senderId) {
174
+ if (config.allowFrom.length === 0)
175
+ return true;
176
+ return config.allowFrom.includes(senderId);
177
+ },
178
+ isConnected() {
179
+ return connected;
180
+ },
181
+ };
182
+ }
183
+ //# sourceMappingURL=discord.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discord.js","sourceRoot":"","sources":["../../src/adapters/discord.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { ChannelPlugin } from '../types.js';
2
+ export interface FeishuChannelConfig {
3
+ appId: string;
4
+ appSecret: string;
5
+ verificationToken?: string;
6
+ encryptKey?: string;
7
+ allowFrom: string[];
8
+ }
9
+ export declare function createFeishuChannel(config: FeishuChannelConfig): ChannelPlugin;
10
+ //# sourceMappingURL=feishu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feishu.d.ts","sourceRoot":"","sources":["../../src/adapters/feishu.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAmD,MAAM,aAAa,CAAC;AAGlG,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,aAAa,CAyH9E"}
@@ -0,0 +1,114 @@
1
+ import * as lark from '@larksuiteoapi/node-sdk';
2
+ import { chunkMarkdown, CHANNEL_LIMITS } from '../chunking.js';
3
+ export function createFeishuChannel(config) {
4
+ let client = null;
5
+ let eventDispatcher = null;
6
+ let wsClient = null;
7
+ let connected = false;
8
+ let messageHandler = null;
9
+ return {
10
+ id: 'feishu',
11
+ meta: { name: 'Feishu', emoji: 'F' },
12
+ async start(handler) {
13
+ messageHandler = handler;
14
+ client = new lark.Client({
15
+ appId: config.appId,
16
+ appSecret: config.appSecret,
17
+ appType: lark.AppType.SelfBuild,
18
+ });
19
+ eventDispatcher = new lark.EventDispatcher({
20
+ verificationToken: config.verificationToken,
21
+ encryptKey: config.encryptKey,
22
+ });
23
+ // Listen for messages
24
+ eventDispatcher.register({
25
+ 'im.message.receive_v1': async (data) => {
26
+ if (!messageHandler)
27
+ return;
28
+ const message = data.message;
29
+ if (!message)
30
+ return;
31
+ const msgType = message.message_type;
32
+ if (msgType !== 'text')
33
+ return;
34
+ let text = '';
35
+ try {
36
+ const content = JSON.parse(message.content);
37
+ text = content.text ?? '';
38
+ }
39
+ catch {
40
+ return;
41
+ }
42
+ if (!text)
43
+ return;
44
+ const sender = data.sender;
45
+ const senderId = sender?.sender_id?.open_id ?? '';
46
+ const inbound = {
47
+ channelId: 'feishu',
48
+ routeTo: message.chat_id,
49
+ senderId,
50
+ text,
51
+ sessionId: message.root_id
52
+ ? `thread:${message.root_id}`
53
+ : `chat:${message.chat_id}`,
54
+ threadId: message.root_id,
55
+ timestamp: Number(message.create_time ?? Date.now()),
56
+ };
57
+ const response = await messageHandler(inbound);
58
+ if (response && client) {
59
+ const chatId = message.chat_id;
60
+ const chunks = chunkMarkdown(response, CHANNEL_LIMITS.feishu);
61
+ for (const chunk of chunks) {
62
+ await client.im.message.create({
63
+ params: { receive_id_type: 'chat_id' },
64
+ data: {
65
+ receive_id: chatId,
66
+ msg_type: 'text',
67
+ content: JSON.stringify({ text: chunk }),
68
+ },
69
+ });
70
+ }
71
+ }
72
+ },
73
+ });
74
+ // Use WebSocket client for real-time events
75
+ wsClient = new lark.WSClient({
76
+ appId: config.appId,
77
+ appSecret: config.appSecret,
78
+ loggerLevel: lark.LoggerLevel.warn,
79
+ });
80
+ await wsClient.start({ eventDispatcher });
81
+ connected = true;
82
+ },
83
+ async stop() {
84
+ connected = false;
85
+ wsClient = null;
86
+ eventDispatcher = null;
87
+ client = null;
88
+ },
89
+ async send(msg) {
90
+ if (!client)
91
+ throw new Error('Feishu not started');
92
+ const chunks = chunkMarkdown(msg.text, CHANNEL_LIMITS.feishu);
93
+ for (const chunk of chunks) {
94
+ await client.im.message.create({
95
+ params: { receive_id_type: 'chat_id' },
96
+ data: {
97
+ receive_id: msg.to,
98
+ msg_type: 'text',
99
+ content: JSON.stringify({ text: chunk }),
100
+ },
101
+ });
102
+ }
103
+ },
104
+ isAllowed(senderId) {
105
+ if (config.allowFrom.length === 0)
106
+ return true;
107
+ return config.allowFrom.includes(senderId);
108
+ },
109
+ isConnected() {
110
+ return connected;
111
+ },
112
+ };
113
+ }
114
+ //# sourceMappingURL=feishu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feishu.js","sourceRoot":"","sources":["../../src/adapters/feishu.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { ChannelPlugin } from '../types.js';
2
+ /** Split a text chunk into individual IRC-safe PRIVMSG lines.
3
+ * Empty lines are sent as a single space to preserve formatting. */
4
+ export declare function splitIrcLines(text: string): string[];
5
+ export interface IrcChannelConfig {
6
+ host: string;
7
+ port: number;
8
+ tls: boolean;
9
+ nick: string;
10
+ password?: string;
11
+ channels: string[];
12
+ allowFrom: string[];
13
+ }
14
+ /** Parse a raw IRC protocol line into prefix, command, and params. */
15
+ export declare function parseIrcLine(line: string): {
16
+ prefix?: string;
17
+ command: string;
18
+ params: string[];
19
+ };
20
+ /** Extract the nickname from an IRC prefix (nick!user@host). */
21
+ export declare function extractIrcNick(prefix: string): string;
22
+ export declare function createIrcChannel(config: IrcChannelConfig): ChannelPlugin;
23
+ //# sourceMappingURL=irc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"irc.d.ts","sourceRoot":"","sources":["../../src/adapters/irc.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAmD,MAAM,aAAa,CAAC;AAGlG;oEACoE;AACpE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAEpD;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,sEAAsE;AACtE,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAuBjG;AAED,gEAAgE;AAChE,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGrD;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,aAAa,CAuIxE"}
@@ -0,0 +1,158 @@
1
+ import * as net from 'node:net';
2
+ import * as tls from 'node:tls';
3
+ import { chunkMarkdown, CHANNEL_LIMITS } from '../chunking.js';
4
+ /** Split a text chunk into individual IRC-safe PRIVMSG lines.
5
+ * Empty lines are sent as a single space to preserve formatting. */
6
+ export function splitIrcLines(text) {
7
+ return text.replace(/\r/g, '').split('\n').map((line) => line || ' ');
8
+ }
9
+ /** Parse a raw IRC protocol line into prefix, command, and params. */
10
+ export function parseIrcLine(line) {
11
+ let prefix;
12
+ let rest = line;
13
+ if (rest.startsWith(':')) {
14
+ const idx = rest.indexOf(' ');
15
+ prefix = rest.slice(1, idx);
16
+ rest = rest.slice(idx + 1);
17
+ }
18
+ const trailingIdx = rest.indexOf(' :');
19
+ let trailing;
20
+ if (trailingIdx !== -1) {
21
+ trailing = rest.slice(trailingIdx + 2);
22
+ rest = rest.slice(0, trailingIdx);
23
+ }
24
+ const parts = rest.split(' ').filter(Boolean);
25
+ const command = parts[0];
26
+ const params = parts.slice(1);
27
+ if (trailing !== undefined)
28
+ params.push(trailing);
29
+ return { prefix, command, params };
30
+ }
31
+ /** Extract the nickname from an IRC prefix (nick!user@host). */
32
+ export function extractIrcNick(prefix) {
33
+ const idx = prefix.indexOf('!');
34
+ return idx !== -1 ? prefix.slice(0, idx) : prefix;
35
+ }
36
+ export function createIrcChannel(config) {
37
+ let socket = null;
38
+ let connected = false;
39
+ let handler = null;
40
+ let buffer = '';
41
+ const limit = CHANNEL_LIMITS.irc;
42
+ function send(line) {
43
+ socket?.write(`${line}\r\n`);
44
+ }
45
+ return {
46
+ id: 'irc',
47
+ meta: { name: 'IRC', emoji: '#' },
48
+ async start(h) {
49
+ handler = h;
50
+ return new Promise((resolve, reject) => {
51
+ const onConnect = () => {
52
+ if (config.password)
53
+ send(`PASS ${config.password}`);
54
+ send(`NICK ${config.nick}`);
55
+ send(`USER ${config.nick} 0 * :CereWorker`);
56
+ };
57
+ if (config.tls) {
58
+ socket = tls.connect({ host: config.host, port: config.port }, onConnect);
59
+ }
60
+ else {
61
+ socket = net.connect({ host: config.host, port: config.port }, onConnect);
62
+ }
63
+ socket.setEncoding('utf-8');
64
+ socket.on('data', (data) => {
65
+ buffer += data;
66
+ const lines = buffer.split('\r\n');
67
+ buffer = lines.pop() ?? '';
68
+ for (const line of lines) {
69
+ if (!line)
70
+ continue;
71
+ void handleLine(line);
72
+ }
73
+ });
74
+ socket.on('error', (err) => {
75
+ if (!connected)
76
+ reject(err);
77
+ });
78
+ socket.on('close', () => {
79
+ connected = false;
80
+ });
81
+ async function handleLine(line) {
82
+ const parsed = parseIrcLine(line);
83
+ if (parsed.command === 'PING') {
84
+ send(`PONG :${parsed.params[0] ?? ''}`);
85
+ return;
86
+ }
87
+ // RPL_WELCOME — we're registered
88
+ if (parsed.command === '001') {
89
+ connected = true;
90
+ // Identify with NickServ if password set
91
+ if (config.password) {
92
+ send(`PRIVMSG NickServ :IDENTIFY ${config.password}`);
93
+ }
94
+ // Join channels
95
+ for (const ch of config.channels) {
96
+ send(`JOIN ${ch}`);
97
+ }
98
+ resolve();
99
+ return;
100
+ }
101
+ if (parsed.command === 'PRIVMSG' && parsed.prefix && handler) {
102
+ const nick = extractIrcNick(parsed.prefix);
103
+ if (nick === config.nick)
104
+ return; // skip own messages
105
+ const target = parsed.params[0]; // channel or nick
106
+ const text = parsed.params[1] ?? '';
107
+ const inbound = {
108
+ channelId: 'irc',
109
+ routeTo: target.startsWith('#') ? target : nick,
110
+ senderId: nick,
111
+ senderName: nick,
112
+ text,
113
+ sessionId: target.startsWith('#') ? `channel:${target}` : `dm:${nick}`,
114
+ timestamp: Date.now(),
115
+ };
116
+ const response = await handler(inbound);
117
+ if (response) {
118
+ const replyTarget = target.startsWith('#') ? target : nick;
119
+ const chunks = chunkMarkdown(response, limit);
120
+ for (const chunk of chunks) {
121
+ for (const line of splitIrcLines(chunk)) {
122
+ send(`PRIVMSG ${replyTarget} :${line}`);
123
+ }
124
+ }
125
+ }
126
+ }
127
+ }
128
+ });
129
+ },
130
+ async stop() {
131
+ if (socket) {
132
+ send('QUIT :CereWorker shutting down');
133
+ socket.destroy();
134
+ socket = null;
135
+ connected = false;
136
+ }
137
+ },
138
+ async send(msg) {
139
+ if (!socket)
140
+ throw new Error('IRC not started');
141
+ const chunks = chunkMarkdown(msg.text, limit);
142
+ for (const chunk of chunks) {
143
+ for (const line of splitIrcLines(chunk)) {
144
+ send(`PRIVMSG ${msg.to} :${line}`);
145
+ }
146
+ }
147
+ },
148
+ isAllowed(senderId) {
149
+ if (config.allowFrom.length === 0)
150
+ return true;
151
+ return config.allowFrom.includes(senderId);
152
+ },
153
+ isConnected() {
154
+ return connected;
155
+ },
156
+ };
157
+ }
158
+ //# sourceMappingURL=irc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"irc.js","sourceRoot":"","sources":["../../src/adapters/irc.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { ChannelPlugin } from '../types.js';
2
+ export interface MatrixChannelConfig {
3
+ homeserver: string;
4
+ token: string;
5
+ userId: string;
6
+ allowFrom: string[];
7
+ }
8
+ export declare function createMatrixChannel(config: MatrixChannelConfig): ChannelPlugin;
9
+ //# sourceMappingURL=matrix.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matrix.d.ts","sourceRoot":"","sources":["../../src/adapters/matrix.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAmD,MAAM,aAAa,CAAC;AAGlG,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,aAAa,CAuE9E"}