@openclaw/irc 2026.7.1-beta.2 → 2026.7.1-beta.5
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,7 +4,7 @@ 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
10
|
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
@@ -27,7 +27,7 @@ import { randomUUID } from "node:crypto";
|
|
|
27
27
|
import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$1, normalizeAccountId as normalizeAccountId$1 } from "openclaw/plugin-sdk/routing";
|
|
28
28
|
import { applyAccountNameToChannelSection, createAllowFromSection, createPromptParsedAllowFromForAccount, createSetupInputPresenceValidator, createSetupTranslator, createStandardChannelSetupStatus, createTopLevelChannelAllowFromSetter, createTopLevelChannelDmPolicySetter, formatDocsLink, patchScopedAccountConfig, setSetupChannelEnabled } from "openclaw/plugin-sdk/setup";
|
|
29
29
|
//#region extensions/irc/src/accounts.ts
|
|
30
|
-
const TRUTHY_ENV = new Set([
|
|
30
|
+
const TRUTHY_ENV = /* @__PURE__ */ new Set([
|
|
31
31
|
"true",
|
|
32
32
|
"1",
|
|
33
33
|
"yes",
|
|
@@ -197,7 +197,7 @@ const collectIrcMutableAllowlistWarnings = createDangerousNameMatchingMutableAll
|
|
|
197
197
|
});
|
|
198
198
|
//#endregion
|
|
199
199
|
//#region extensions/irc/src/gateway.ts
|
|
200
|
-
const loadIrcChannelRuntime$1 = createLazyRuntimeModule(() => import("./channel-runtime-
|
|
200
|
+
const loadIrcChannelRuntime$1 = createLazyRuntimeModule(() => import("./channel-runtime-CLTE89ol.js"));
|
|
201
201
|
async function startIrcGatewayAccount(ctx) {
|
|
202
202
|
const account = ctx.account;
|
|
203
203
|
const statusSink = createAccountStatusSink({
|
|
@@ -321,12 +321,30 @@ function makeIrcMessageId() {
|
|
|
321
321
|
}
|
|
322
322
|
//#endregion
|
|
323
323
|
//#region extensions/irc/src/client.ts
|
|
324
|
-
const IRC_ERROR_CODES = new Set([
|
|
324
|
+
const IRC_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
325
325
|
"432",
|
|
326
326
|
"464",
|
|
327
327
|
"465"
|
|
328
328
|
]);
|
|
329
|
-
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
|
+
}
|
|
330
348
|
function toError(err) {
|
|
331
349
|
if (err instanceof Error) return err;
|
|
332
350
|
return new Error(typeof err === "string" ? err : JSON.stringify(err));
|
|
@@ -358,7 +376,7 @@ function buildIrcNickServCommands(options) {
|
|
|
358
376
|
}
|
|
359
377
|
async function connectIrcClient(options) {
|
|
360
378
|
const timeoutMs = options.connectTimeoutMs != null ? options.connectTimeoutMs : 15e3;
|
|
361
|
-
const messageChunkMaxChars =
|
|
379
|
+
const messageChunkMaxChars = Math.max(1, Math.floor(options.messageChunkMaxChars ?? 350));
|
|
362
380
|
if (!options.host.trim()) throw new Error("IRC host is required");
|
|
363
381
|
if (!options.nick.trim()) throw new Error("IRC nick is required");
|
|
364
382
|
const desiredNick = options.nick.trim();
|
|
@@ -407,7 +425,8 @@ async function connectIrcClient(options) {
|
|
|
407
425
|
if (nickServEnabled && !nickServRecoverAttempted && nickservPassword) {
|
|
408
426
|
nickServRecoverAttempted = true;
|
|
409
427
|
try {
|
|
410
|
-
|
|
428
|
+
const service = sanitizeIrcTarget(options.nickserv?.service?.trim() || "NickServ");
|
|
429
|
+
sendRaw(`PRIVMSG ${service} :GHOST ${desiredNick} ${nickservPassword}`);
|
|
411
430
|
sendRaw(`NICK ${desiredNick}`);
|
|
412
431
|
return true;
|
|
413
432
|
} catch (err) {
|
|
@@ -436,15 +455,11 @@ async function connectIrcClient(options) {
|
|
|
436
455
|
const normalizedTarget = sanitizeIrcTarget(target);
|
|
437
456
|
const cleaned = sanitizeIrcOutboundText(text);
|
|
438
457
|
if (!cleaned) return;
|
|
458
|
+
const lineOverheadBytes = Buffer.byteLength(`PRIVMSG ${normalizedTarget} :\r\n`, "utf8");
|
|
459
|
+
const maxChunkBytes = IRC_MAX_LINE_BYTES - lineOverheadBytes;
|
|
439
460
|
let remaining = cleaned;
|
|
440
461
|
while (remaining.length > 0) {
|
|
441
|
-
|
|
442
|
-
if (chunk.length > messageChunkMaxChars) {
|
|
443
|
-
let splitAt = chunk.lastIndexOf(" ", messageChunkMaxChars);
|
|
444
|
-
if (splitAt < Math.floor(messageChunkMaxChars / 2)) splitAt = messageChunkMaxChars;
|
|
445
|
-
chunk = chunk.slice(0, splitAt).trim();
|
|
446
|
-
}
|
|
447
|
-
if (!chunk) break;
|
|
462
|
+
const chunk = takeIrcPrivmsgChunk(remaining, messageChunkMaxChars, maxChunkBytes).trim();
|
|
448
463
|
sendRaw(`PRIVMSG ${normalizedTarget} :${chunk}`);
|
|
449
464
|
remaining = remaining.slice(chunk.length).trimStart();
|
|
450
465
|
}
|
|
@@ -481,7 +496,8 @@ async function connectIrcClient(options) {
|
|
|
481
496
|
const line = parseIrcLine(rawLine);
|
|
482
497
|
if (!line) continue;
|
|
483
498
|
if (line.command === "PING") {
|
|
484
|
-
|
|
499
|
+
const payload = line.trailing != null ? line.trailing : line.params[0] != null ? line.params[0] : "";
|
|
500
|
+
sendRaw(`PONG :${payload}`);
|
|
485
501
|
continue;
|
|
486
502
|
}
|
|
487
503
|
if (line.command === "NICK") {
|
|
@@ -566,7 +582,10 @@ async function connectIrcClient(options) {
|
|
|
566
582
|
socket.once("close", () => {
|
|
567
583
|
if (!closed) {
|
|
568
584
|
closed = true;
|
|
585
|
+
removeAbortListener?.();
|
|
586
|
+
removeAbortListener = null;
|
|
569
587
|
if (!ready) fail(/* @__PURE__ */ new Error("IRC connection closed before ready"));
|
|
588
|
+
else options.onDisconnect?.();
|
|
570
589
|
}
|
|
571
590
|
});
|
|
572
591
|
if (options.abortSignal) {
|
|
@@ -583,7 +602,12 @@ async function connectIrcClient(options) {
|
|
|
583
602
|
removeAbortListener = () => options.abortSignal?.removeEventListener("abort", abort);
|
|
584
603
|
}
|
|
585
604
|
}
|
|
586
|
-
|
|
605
|
+
try {
|
|
606
|
+
await withTimeout(readyPromise, timeoutMs, "IRC connect");
|
|
607
|
+
} catch (error) {
|
|
608
|
+
close();
|
|
609
|
+
throw error;
|
|
610
|
+
}
|
|
587
611
|
return {
|
|
588
612
|
get nick() {
|
|
589
613
|
return currentNick;
|
|
@@ -636,6 +660,25 @@ function normalizeIrcMessagingTarget(raw) {
|
|
|
636
660
|
if (!target || !looksLikeIrcTargetId(target)) return;
|
|
637
661
|
return target;
|
|
638
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
|
+
}
|
|
639
682
|
function looksLikeIrcTargetId(raw) {
|
|
640
683
|
const trimmed = raw.trim();
|
|
641
684
|
if (!trimmed) return false;
|
|
@@ -903,21 +946,22 @@ const ircSetupAdapter = {
|
|
|
903
946
|
name: setupInput.name
|
|
904
947
|
});
|
|
905
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
|
+
};
|
|
906
960
|
return patchScopedAccountConfig({
|
|
907
961
|
cfg: namedConfig,
|
|
908
962
|
channelKey: channel$1,
|
|
909
963
|
accountId,
|
|
910
|
-
patch
|
|
911
|
-
enabled: true,
|
|
912
|
-
host: setupInput.host?.trim(),
|
|
913
|
-
port: portInput ? parsePort(portInput, setupInput.tls === false ? 6667 : 6697) : void 0,
|
|
914
|
-
tls: setupInput.tls,
|
|
915
|
-
nick: setupInput.nick?.trim(),
|
|
916
|
-
username: setupInput.username?.trim(),
|
|
917
|
-
realname: setupInput.realname?.trim(),
|
|
918
|
-
password: setupInput.password?.trim(),
|
|
919
|
-
channels: setupInput.channels
|
|
920
|
-
}
|
|
964
|
+
patch
|
|
921
965
|
});
|
|
922
966
|
}
|
|
923
967
|
};
|
|
@@ -1286,7 +1330,7 @@ const meta = {
|
|
|
1286
1330
|
systemImage: "number",
|
|
1287
1331
|
markdownCapable: true
|
|
1288
1332
|
};
|
|
1289
|
-
const loadIrcChannelRuntime = createLazyRuntimeModule(() => import("./channel-runtime-
|
|
1333
|
+
const loadIrcChannelRuntime = createLazyRuntimeModule(() => import("./channel-runtime-CLTE89ol.js"));
|
|
1290
1334
|
function normalizePairingTarget(raw) {
|
|
1291
1335
|
const normalized = normalizeIrcAllowEntry(raw);
|
|
1292
1336
|
if (!normalized) return "";
|
|
@@ -1423,6 +1467,7 @@ const ircPlugin = createChatChannelPlugin({
|
|
|
1423
1467
|
messaging: {
|
|
1424
1468
|
targetPrefixes: ["irc"],
|
|
1425
1469
|
normalizeTarget: normalizeIrcMessagingTarget,
|
|
1470
|
+
resolveOutboundSessionRoute: (params) => resolveIrcOutboundSessionRoute(params),
|
|
1426
1471
|
targetResolver: {
|
|
1427
1472
|
looksLikeId: looksLikeIrcTargetId,
|
|
1428
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.5",
|
|
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.5",
|
|
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.5",
|
|
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.5"
|
|
43
43
|
},
|
|
44
44
|
"build": {
|
|
45
|
-
"openclawVersion": "2026.7.1-beta.
|
|
45
|
+
"openclawVersion": "2026.7.1-beta.5",
|
|
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.5"
|
|
72
72
|
},
|
|
73
73
|
"peerDependenciesMeta": {
|
|
74
74
|
"openclaw": {
|