@openclaw/irc 2026.7.1-beta.1 → 2026.7.1-beta.4
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/dist/api.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { g as resolveIrcAccount, h as resolveDefaultIrcAccountId, m as listIrcAccountIds, n as ircSetupWizard, p as listEnabledIrcAccounts, r as ircSetupAdapter, t as ircPlugin } from "./channel-
|
|
1
|
+
import { g as resolveIrcAccount, h as resolveDefaultIrcAccountId, m as listIrcAccountIds, n as ircSetupWizard, p as listEnabledIrcAccounts, r as ircSetupAdapter, t as ircPlugin } from "./channel-C-P2GolT.js";
|
|
2
2
|
import { n as setIrcRuntime } from "./runtime-DZfYm3vY.js";
|
|
3
3
|
export { ircPlugin, ircSetupAdapter, ircSetupWizard, listEnabledIrcAccounts, listIrcAccountIds, resolveDefaultIrcAccountId, resolveIrcAccount, setIrcRuntime };
|
|
@@ -4,9 +4,10 @@ import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries
|
|
|
4
4
|
import { createAccountListHelpers, describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
|
|
5
5
|
import { formatNormalizedAllowFromEntries } from "openclaw/plugin-sdk/allow-from";
|
|
6
6
|
import { adaptScopedAccountAccessor, createScopedChannelConfigAdapter, createScopedDmSecurityResolver } from "openclaw/plugin-sdk/channel-config-helpers";
|
|
7
|
-
import { createChatChannelPlugin, parseOptionalDelimitedEntries, tryReadSecretFileSync } from "openclaw/plugin-sdk/channel-core";
|
|
7
|
+
import { buildChannelOutboundSessionRoute, createChatChannelPlugin, parseOptionalDelimitedEntries, tryReadSecretFileSync } from "openclaw/plugin-sdk/channel-core";
|
|
8
8
|
import { composeAccountWarningCollectors, createAllowlistProviderOpenWarningCollector, createDangerousNameMatchingMutableAllowlistWarningCollector } from "openclaw/plugin-sdk/channel-policy";
|
|
9
9
|
import { createChannelDirectoryAdapter, createResolvedDirectoryEntriesLister } from "openclaw/plugin-sdk/directory-runtime";
|
|
10
|
+
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
10
11
|
import { buildBaseChannelStatusSummary, createComputedAccountStatusAdapter, createDefaultChannelRuntimeState } from "openclaw/plugin-sdk/status-helpers";
|
|
11
12
|
import { DEFAULT_ACCOUNT_ID, DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$2, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
|
|
12
13
|
import { resolveMergedAccountConfig } from "openclaw/plugin-sdk/account-resolution";
|
|
@@ -26,7 +27,7 @@ import { randomUUID } from "node:crypto";
|
|
|
26
27
|
import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$1, normalizeAccountId as normalizeAccountId$1 } from "openclaw/plugin-sdk/routing";
|
|
27
28
|
import { applyAccountNameToChannelSection, createAllowFromSection, createPromptParsedAllowFromForAccount, createSetupInputPresenceValidator, createSetupTranslator, createStandardChannelSetupStatus, createTopLevelChannelAllowFromSetter, createTopLevelChannelDmPolicySetter, formatDocsLink, patchScopedAccountConfig, setSetupChannelEnabled } from "openclaw/plugin-sdk/setup";
|
|
28
29
|
//#region extensions/irc/src/accounts.ts
|
|
29
|
-
const TRUTHY_ENV = new Set([
|
|
30
|
+
const TRUTHY_ENV = /* @__PURE__ */ new Set([
|
|
30
31
|
"true",
|
|
31
32
|
"1",
|
|
32
33
|
"yes",
|
|
@@ -196,11 +197,7 @@ const collectIrcMutableAllowlistWarnings = createDangerousNameMatchingMutableAll
|
|
|
196
197
|
});
|
|
197
198
|
//#endregion
|
|
198
199
|
//#region extensions/irc/src/gateway.ts
|
|
199
|
-
|
|
200
|
-
async function loadIrcChannelRuntime$1() {
|
|
201
|
-
ircChannelRuntimePromise$1 ??= import("./channel-runtime-BUK62iQX.js");
|
|
202
|
-
return await ircChannelRuntimePromise$1;
|
|
203
|
-
}
|
|
200
|
+
const loadIrcChannelRuntime$1 = createLazyRuntimeModule(() => import("./channel-runtime-CLTE89ol.js"));
|
|
204
201
|
async function startIrcGatewayAccount(ctx) {
|
|
205
202
|
const account = ctx.account;
|
|
206
203
|
const statusSink = createAccountStatusSink({
|
|
@@ -324,12 +321,30 @@ function makeIrcMessageId() {
|
|
|
324
321
|
}
|
|
325
322
|
//#endregion
|
|
326
323
|
//#region extensions/irc/src/client.ts
|
|
327
|
-
const IRC_ERROR_CODES = new Set([
|
|
324
|
+
const IRC_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
328
325
|
"432",
|
|
329
326
|
"464",
|
|
330
327
|
"465"
|
|
331
328
|
]);
|
|
332
|
-
const IRC_NICK_COLLISION_CODES = new Set(["433", "436"]);
|
|
329
|
+
const IRC_NICK_COLLISION_CODES = /* @__PURE__ */ new Set(["433", "436"]);
|
|
330
|
+
const IRC_MAX_LINE_BYTES = 512;
|
|
331
|
+
function takeIrcPrivmsgChunk(text, maxChars, maxBytes) {
|
|
332
|
+
let end = 0;
|
|
333
|
+
let bytes = 0;
|
|
334
|
+
for (const codePoint of text) {
|
|
335
|
+
const codePointBytes = Buffer.byteLength(codePoint, "utf8");
|
|
336
|
+
if (end > 0 && end + codePoint.length > maxChars || bytes + codePointBytes > maxBytes) break;
|
|
337
|
+
end += codePoint.length;
|
|
338
|
+
bytes += codePointBytes;
|
|
339
|
+
}
|
|
340
|
+
if (end === 0) throw new Error("IRC target leaves no room for message text within the 512-byte line limit");
|
|
341
|
+
if (end === text.length) return text;
|
|
342
|
+
const fitted = text.slice(0, end);
|
|
343
|
+
if (text[end] === " ") return fitted;
|
|
344
|
+
const splitAt = fitted.lastIndexOf(" ");
|
|
345
|
+
if (splitAt >= Math.floor(fitted.length / 2)) return fitted.slice(0, splitAt);
|
|
346
|
+
return fitted;
|
|
347
|
+
}
|
|
333
348
|
function toError(err) {
|
|
334
349
|
if (err instanceof Error) return err;
|
|
335
350
|
return new Error(typeof err === "string" ? err : JSON.stringify(err));
|
|
@@ -361,7 +376,7 @@ function buildIrcNickServCommands(options) {
|
|
|
361
376
|
}
|
|
362
377
|
async function connectIrcClient(options) {
|
|
363
378
|
const timeoutMs = options.connectTimeoutMs != null ? options.connectTimeoutMs : 15e3;
|
|
364
|
-
const messageChunkMaxChars =
|
|
379
|
+
const messageChunkMaxChars = Math.max(1, Math.floor(options.messageChunkMaxChars ?? 350));
|
|
365
380
|
if (!options.host.trim()) throw new Error("IRC host is required");
|
|
366
381
|
if (!options.nick.trim()) throw new Error("IRC nick is required");
|
|
367
382
|
const desiredNick = options.nick.trim();
|
|
@@ -410,7 +425,8 @@ async function connectIrcClient(options) {
|
|
|
410
425
|
if (nickServEnabled && !nickServRecoverAttempted && nickservPassword) {
|
|
411
426
|
nickServRecoverAttempted = true;
|
|
412
427
|
try {
|
|
413
|
-
|
|
428
|
+
const service = sanitizeIrcTarget(options.nickserv?.service?.trim() || "NickServ");
|
|
429
|
+
sendRaw(`PRIVMSG ${service} :GHOST ${desiredNick} ${nickservPassword}`);
|
|
414
430
|
sendRaw(`NICK ${desiredNick}`);
|
|
415
431
|
return true;
|
|
416
432
|
} catch (err) {
|
|
@@ -439,15 +455,11 @@ async function connectIrcClient(options) {
|
|
|
439
455
|
const normalizedTarget = sanitizeIrcTarget(target);
|
|
440
456
|
const cleaned = sanitizeIrcOutboundText(text);
|
|
441
457
|
if (!cleaned) return;
|
|
458
|
+
const lineOverheadBytes = Buffer.byteLength(`PRIVMSG ${normalizedTarget} :\r\n`, "utf8");
|
|
459
|
+
const maxChunkBytes = IRC_MAX_LINE_BYTES - lineOverheadBytes;
|
|
442
460
|
let remaining = cleaned;
|
|
443
461
|
while (remaining.length > 0) {
|
|
444
|
-
|
|
445
|
-
if (chunk.length > messageChunkMaxChars) {
|
|
446
|
-
let splitAt = chunk.lastIndexOf(" ", messageChunkMaxChars);
|
|
447
|
-
if (splitAt < Math.floor(messageChunkMaxChars / 2)) splitAt = messageChunkMaxChars;
|
|
448
|
-
chunk = chunk.slice(0, splitAt).trim();
|
|
449
|
-
}
|
|
450
|
-
if (!chunk) break;
|
|
462
|
+
const chunk = takeIrcPrivmsgChunk(remaining, messageChunkMaxChars, maxChunkBytes).trim();
|
|
451
463
|
sendRaw(`PRIVMSG ${normalizedTarget} :${chunk}`);
|
|
452
464
|
remaining = remaining.slice(chunk.length).trimStart();
|
|
453
465
|
}
|
|
@@ -484,7 +496,8 @@ async function connectIrcClient(options) {
|
|
|
484
496
|
const line = parseIrcLine(rawLine);
|
|
485
497
|
if (!line) continue;
|
|
486
498
|
if (line.command === "PING") {
|
|
487
|
-
|
|
499
|
+
const payload = line.trailing != null ? line.trailing : line.params[0] != null ? line.params[0] : "";
|
|
500
|
+
sendRaw(`PONG :${payload}`);
|
|
488
501
|
continue;
|
|
489
502
|
}
|
|
490
503
|
if (line.command === "NICK") {
|
|
@@ -569,7 +582,10 @@ async function connectIrcClient(options) {
|
|
|
569
582
|
socket.once("close", () => {
|
|
570
583
|
if (!closed) {
|
|
571
584
|
closed = true;
|
|
585
|
+
removeAbortListener?.();
|
|
586
|
+
removeAbortListener = null;
|
|
572
587
|
if (!ready) fail(/* @__PURE__ */ new Error("IRC connection closed before ready"));
|
|
588
|
+
else options.onDisconnect?.();
|
|
573
589
|
}
|
|
574
590
|
});
|
|
575
591
|
if (options.abortSignal) {
|
|
@@ -586,7 +602,12 @@ async function connectIrcClient(options) {
|
|
|
586
602
|
removeAbortListener = () => options.abortSignal?.removeEventListener("abort", abort);
|
|
587
603
|
}
|
|
588
604
|
}
|
|
589
|
-
|
|
605
|
+
try {
|
|
606
|
+
await withTimeout(readyPromise, timeoutMs, "IRC connect");
|
|
607
|
+
} catch (error) {
|
|
608
|
+
close();
|
|
609
|
+
throw error;
|
|
610
|
+
}
|
|
590
611
|
return {
|
|
591
612
|
get nick() {
|
|
592
613
|
return currentNick;
|
|
@@ -639,6 +660,25 @@ function normalizeIrcMessagingTarget(raw) {
|
|
|
639
660
|
if (!target || !looksLikeIrcTargetId(target)) return;
|
|
640
661
|
return target;
|
|
641
662
|
}
|
|
663
|
+
function resolveIrcOutboundSessionRoute(params) {
|
|
664
|
+
const target = normalizeIrcMessagingTarget(params.target);
|
|
665
|
+
if (!target) return null;
|
|
666
|
+
const chatType = isChannelTarget(target) ? "group" : "direct";
|
|
667
|
+
return buildChannelOutboundSessionRoute({
|
|
668
|
+
cfg: params.cfg,
|
|
669
|
+
agentId: params.agentId,
|
|
670
|
+
channel: "irc",
|
|
671
|
+
accountId: params.accountId,
|
|
672
|
+
recipientSessionExact: chatType === "direct" ? "direct-alias" : false,
|
|
673
|
+
peer: {
|
|
674
|
+
kind: chatType,
|
|
675
|
+
id: target
|
|
676
|
+
},
|
|
677
|
+
chatType,
|
|
678
|
+
from: `irc:${target}`,
|
|
679
|
+
to: target
|
|
680
|
+
});
|
|
681
|
+
}
|
|
642
682
|
function looksLikeIrcTargetId(raw) {
|
|
643
683
|
const trimmed = raw.trim();
|
|
644
684
|
if (!trimmed) return false;
|
|
@@ -906,21 +946,22 @@ const ircSetupAdapter = {
|
|
|
906
946
|
name: setupInput.name
|
|
907
947
|
});
|
|
908
948
|
const portInput = typeof setupInput.port === "number" ? String(setupInput.port) : setupInput.port ?? "";
|
|
949
|
+
const patch = {
|
|
950
|
+
enabled: true,
|
|
951
|
+
host: setupInput.host?.trim(),
|
|
952
|
+
port: portInput ? parsePort(portInput, setupInput.tls === false ? 6667 : 6697) : void 0,
|
|
953
|
+
tls: setupInput.tls,
|
|
954
|
+
nick: setupInput.nick?.trim(),
|
|
955
|
+
username: setupInput.username?.trim(),
|
|
956
|
+
realname: setupInput.realname?.trim(),
|
|
957
|
+
password: setupInput.password?.trim(),
|
|
958
|
+
channels: setupInput.channels
|
|
959
|
+
};
|
|
909
960
|
return patchScopedAccountConfig({
|
|
910
961
|
cfg: namedConfig,
|
|
911
962
|
channelKey: channel$1,
|
|
912
963
|
accountId,
|
|
913
|
-
patch
|
|
914
|
-
enabled: true,
|
|
915
|
-
host: setupInput.host?.trim(),
|
|
916
|
-
port: portInput ? parsePort(portInput, setupInput.tls === false ? 6667 : 6697) : void 0,
|
|
917
|
-
tls: setupInput.tls,
|
|
918
|
-
nick: setupInput.nick?.trim(),
|
|
919
|
-
username: setupInput.username?.trim(),
|
|
920
|
-
realname: setupInput.realname?.trim(),
|
|
921
|
-
password: setupInput.password?.trim(),
|
|
922
|
-
channels: setupInput.channels
|
|
923
|
-
}
|
|
964
|
+
patch
|
|
924
965
|
});
|
|
925
966
|
}
|
|
926
967
|
};
|
|
@@ -1289,11 +1330,7 @@ const meta = {
|
|
|
1289
1330
|
systemImage: "number",
|
|
1290
1331
|
markdownCapable: true
|
|
1291
1332
|
};
|
|
1292
|
-
|
|
1293
|
-
async function loadIrcChannelRuntime() {
|
|
1294
|
-
ircChannelRuntimePromise ??= import("./channel-runtime-BUK62iQX.js");
|
|
1295
|
-
return await ircChannelRuntimePromise;
|
|
1296
|
-
}
|
|
1333
|
+
const loadIrcChannelRuntime = createLazyRuntimeModule(() => import("./channel-runtime-CLTE89ol.js"));
|
|
1297
1334
|
function normalizePairingTarget(raw) {
|
|
1298
1335
|
const normalized = normalizeIrcAllowEntry(raw);
|
|
1299
1336
|
if (!normalized) return "";
|
|
@@ -1430,6 +1467,7 @@ const ircPlugin = createChatChannelPlugin({
|
|
|
1430
1467
|
messaging: {
|
|
1431
1468
|
targetPrefixes: ["irc"],
|
|
1432
1469
|
normalizeTarget: normalizeIrcMessagingTarget,
|
|
1470
|
+
resolveOutboundSessionRoute: (params) => resolveIrcOutboundSessionRoute(params),
|
|
1433
1471
|
targetResolver: {
|
|
1434
1472
|
looksLikeId: looksLikeIrcTargetId,
|
|
1435
1473
|
hint: "<#channel|nick>"
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as ircPlugin } from "./channel-
|
|
1
|
+
import { t as ircPlugin } from "./channel-C-P2GolT.js";
|
|
2
2
|
export { ircPlugin };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as resolveIrcRequireMention, c as isChannelTarget, d as connectIrcClient, f as makeIrcMessageId, g as resolveIrcAccount, i as resolveIrcGroupMatch, l as normalizeIrcAllowEntry, o as sendMessageIrc, s as buildIrcAllowlistCandidates, u as buildIrcConnectOptions } from "./channel-
|
|
1
|
+
import { a as resolveIrcRequireMention, c as isChannelTarget, d as connectIrcClient, f as makeIrcMessageId, g as resolveIrcAccount, i as resolveIrcGroupMatch, l as normalizeIrcAllowEntry, o as sendMessageIrc, s as buildIrcAllowlistCandidates, u as buildIrcConnectOptions } from "./channel-C-P2GolT.js";
|
|
2
2
|
import { t as getIrcRuntime } from "./runtime-DZfYm3vY.js";
|
|
3
3
|
import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
4
4
|
import { resolveLoggerBackedRuntime } from "openclaw/plugin-sdk/extension-shared";
|
|
@@ -331,6 +331,7 @@ async function handleIrcInbound(params) {
|
|
|
331
331
|
}
|
|
332
332
|
//#endregion
|
|
333
333
|
//#region extensions/irc/src/monitor.ts
|
|
334
|
+
const IRC_MONITOR_RECONNECT_DELAY_MS = 1e3;
|
|
334
335
|
function resolveIrcInboundTarget(params) {
|
|
335
336
|
const rawTarget = params.target;
|
|
336
337
|
if (isChannelTarget(rawTarget)) return {
|
|
@@ -358,67 +359,114 @@ async function monitorIrcProvider(opts) {
|
|
|
358
359
|
accountId: account.accountId
|
|
359
360
|
});
|
|
360
361
|
let client = null;
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
target: inboundTarget.target,
|
|
383
|
-
rawTarget: inboundTarget.rawTarget,
|
|
384
|
-
senderNick: event.senderNick,
|
|
385
|
-
senderUser: event.senderUser,
|
|
386
|
-
senderHost: event.senderHost,
|
|
387
|
-
text: event.text,
|
|
388
|
-
timestamp: Date.now(),
|
|
389
|
-
isGroup: inboundTarget.isGroup
|
|
390
|
-
};
|
|
391
|
-
core.channel.activity.record({
|
|
392
|
-
channel: "irc",
|
|
393
|
-
accountId: account.accountId,
|
|
394
|
-
direction: "inbound",
|
|
395
|
-
at: message.timestamp
|
|
362
|
+
let reconnectTimer = null;
|
|
363
|
+
let stopped = false;
|
|
364
|
+
const monitorAbort = new AbortController();
|
|
365
|
+
let removeAbortListener = null;
|
|
366
|
+
if (opts.abortSignal) {
|
|
367
|
+
const forwardAbort = () => monitorAbort.abort();
|
|
368
|
+
if (opts.abortSignal.aborted) forwardAbort();
|
|
369
|
+
else {
|
|
370
|
+
opts.abortSignal.addEventListener("abort", forwardAbort, { once: true });
|
|
371
|
+
removeAbortListener = () => opts.abortSignal?.removeEventListener("abort", forwardAbort);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
function scheduleReconnect() {
|
|
375
|
+
if (stopped || monitorAbort.signal.aborted || reconnectTimer) return;
|
|
376
|
+
reconnectTimer = setTimeout(() => {
|
|
377
|
+
reconnectTimer = null;
|
|
378
|
+
connect().catch((error) => {
|
|
379
|
+
if (stopped || monitorAbort.signal.aborted) return;
|
|
380
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
381
|
+
logger.error(`[${account.accountId}] IRC reconnect failed: ${message}`);
|
|
382
|
+
scheduleReconnect();
|
|
396
383
|
});
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
384
|
+
}, IRC_MONITOR_RECONNECT_DELAY_MS);
|
|
385
|
+
}
|
|
386
|
+
async function connect() {
|
|
387
|
+
if (stopped || monitorAbort.signal.aborted) return;
|
|
388
|
+
const nextClient = await connectIrcClient(buildIrcConnectOptions(account, {
|
|
389
|
+
channels: account.config.channels,
|
|
390
|
+
abortSignal: monitorAbort.signal,
|
|
391
|
+
onLine: (line) => {
|
|
392
|
+
if (core.logging.shouldLogVerbose()) logger.debug?.(`[${account.accountId}] << ${line}`);
|
|
393
|
+
},
|
|
394
|
+
onNotice: (text, target) => {
|
|
395
|
+
if (core.logging.shouldLogVerbose()) logger.debug?.(`[${account.accountId}] notice ${target ?? ""}: ${text}`);
|
|
396
|
+
},
|
|
397
|
+
onError: (error) => {
|
|
398
|
+
logger.error(`[${account.accountId}] IRC error: ${error.message}`);
|
|
399
|
+
},
|
|
400
|
+
onDisconnect: () => {
|
|
401
|
+
if (stopped || monitorAbort.signal.aborted) return;
|
|
402
|
+
client = null;
|
|
403
|
+
logger.warn?.(`[${account.accountId}] IRC connection closed; reconnecting in ${IRC_MONITOR_RECONNECT_DELAY_MS}ms`);
|
|
404
|
+
scheduleReconnect();
|
|
405
|
+
},
|
|
406
|
+
onPrivmsg: async (event) => {
|
|
407
|
+
if (!client) return;
|
|
408
|
+
if (normalizeLowercaseStringOrEmpty(event.senderNick) === normalizeLowercaseStringOrEmpty(client.nick)) return;
|
|
409
|
+
const inboundTarget = resolveIrcInboundTarget({
|
|
410
|
+
target: event.target,
|
|
411
|
+
senderNick: event.senderNick
|
|
412
|
+
});
|
|
413
|
+
const message = {
|
|
414
|
+
messageId: makeIrcMessageId(),
|
|
415
|
+
target: inboundTarget.target,
|
|
416
|
+
rawTarget: inboundTarget.rawTarget,
|
|
417
|
+
senderNick: event.senderNick,
|
|
418
|
+
senderUser: event.senderUser,
|
|
419
|
+
senderHost: event.senderHost,
|
|
420
|
+
text: event.text,
|
|
421
|
+
timestamp: Date.now(),
|
|
422
|
+
isGroup: inboundTarget.isGroup
|
|
423
|
+
};
|
|
424
|
+
core.channel.activity.record({
|
|
425
|
+
channel: "irc",
|
|
426
|
+
accountId: account.accountId,
|
|
427
|
+
direction: "inbound",
|
|
428
|
+
at: message.timestamp
|
|
429
|
+
});
|
|
430
|
+
if (opts.onMessage) {
|
|
431
|
+
await opts.onMessage(message, client);
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
await handleIrcInbound({
|
|
435
|
+
message,
|
|
436
|
+
account,
|
|
437
|
+
config: cfg,
|
|
438
|
+
runtime,
|
|
439
|
+
connectedNick: client.nick,
|
|
440
|
+
sendReply: async (target, text) => {
|
|
441
|
+
client?.sendPrivmsg(target, text);
|
|
442
|
+
opts.statusSink?.({ lastOutboundAt: Date.now() });
|
|
443
|
+
core.channel.activity.record({
|
|
444
|
+
channel: "irc",
|
|
445
|
+
accountId: account.accountId,
|
|
446
|
+
direction: "outbound"
|
|
447
|
+
});
|
|
448
|
+
},
|
|
449
|
+
statusSink: opts.statusSink
|
|
450
|
+
});
|
|
400
451
|
}
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
runtime,
|
|
406
|
-
connectedNick: client.nick,
|
|
407
|
-
sendReply: async (target, text) => {
|
|
408
|
-
client?.sendPrivmsg(target, text);
|
|
409
|
-
opts.statusSink?.({ lastOutboundAt: Date.now() });
|
|
410
|
-
core.channel.activity.record({
|
|
411
|
-
channel: "irc",
|
|
412
|
-
accountId: account.accountId,
|
|
413
|
-
direction: "outbound"
|
|
414
|
-
});
|
|
415
|
-
},
|
|
416
|
-
statusSink: opts.statusSink
|
|
417
|
-
});
|
|
452
|
+
}));
|
|
453
|
+
if (stopped || monitorAbort.signal.aborted) {
|
|
454
|
+
nextClient.quit("shutdown");
|
|
455
|
+
return;
|
|
418
456
|
}
|
|
419
|
-
|
|
420
|
-
|
|
457
|
+
client = nextClient;
|
|
458
|
+
logger.info(`[${account.accountId}] connected to ${account.host}:${account.port}${account.tls ? " (tls)" : ""} as ${nextClient.nick}`);
|
|
459
|
+
}
|
|
460
|
+
await connect();
|
|
421
461
|
return { stop: () => {
|
|
462
|
+
stopped = true;
|
|
463
|
+
removeAbortListener?.();
|
|
464
|
+
removeAbortListener = null;
|
|
465
|
+
if (!monitorAbort.signal.aborted) monitorAbort.abort();
|
|
466
|
+
if (reconnectTimer) {
|
|
467
|
+
clearTimeout(reconnectTimer);
|
|
468
|
+
reconnectTimer = null;
|
|
469
|
+
}
|
|
422
470
|
client?.quit("shutdown");
|
|
423
471
|
client = null;
|
|
424
472
|
} };
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/irc",
|
|
3
|
-
"version": "2026.7.1-beta.
|
|
3
|
+
"version": "2026.7.1-beta.4",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@openclaw/irc",
|
|
9
|
-
"version": "2026.7.1-beta.
|
|
9
|
+
"version": "2026.7.1-beta.4",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"zod": "4.4.3"
|
|
12
12
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/irc",
|
|
3
|
-
"version": "2026.7.1-beta.
|
|
3
|
+
"version": "2026.7.1-beta.4",
|
|
4
4
|
"description": "OpenClaw IRC channel plugin",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"openclaw": {
|
|
@@ -39,10 +39,10 @@
|
|
|
39
39
|
}
|
|
40
40
|
},
|
|
41
41
|
"compat": {
|
|
42
|
-
"pluginApi": ">=2026.7.1-beta.
|
|
42
|
+
"pluginApi": ">=2026.7.1-beta.4"
|
|
43
43
|
},
|
|
44
44
|
"build": {
|
|
45
|
-
"openclawVersion": "2026.7.1-beta.
|
|
45
|
+
"openclawVersion": "2026.7.1-beta.4",
|
|
46
46
|
"bundledDist": false
|
|
47
47
|
},
|
|
48
48
|
"release": {
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"README.md"
|
|
69
69
|
],
|
|
70
70
|
"peerDependencies": {
|
|
71
|
-
"openclaw": ">=2026.7.1-beta.
|
|
71
|
+
"openclaw": ">=2026.7.1-beta.4"
|
|
72
72
|
},
|
|
73
73
|
"peerDependenciesMeta": {
|
|
74
74
|
"openclaw": {
|