@openclaw/irc 2026.11.3 → 2026.11.5-beta.2
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/.setup/{channel-Bi4lj8N2.mjs → channel-DgvKz42q.mjs} +254 -299
- package/dist/.setup/channel-plugin-api-WXJUjGsf.mjs +2 -0
- package/dist/.setup/channel-runtime-D4vKt7TE.mjs +582 -0
- package/dist/.setup/{config-schema-Cy9tItsu.mjs → config-schema-CHwjI_aV.mjs} +1 -3
- package/dist/.setup/secret-contract-api-4IT9_EK6.mjs +2 -0
- package/dist/.source-module-urls/4751df78f545ae971ceb22b6e4bff6086f63313240899a1d9884b970424a305e.json +1 -0
- package/dist/api.js +1 -1
- package/dist/channel-config-api.js +1 -2
- package/dist/channel-plugin-api.js +1 -2
- package/dist/runtime-api.js +1 -2
- package/dist/secret-contract-api.js +1 -2
- package/dist/setup-entry.js +2 -2
- package/node_modules/zod/package.json +1 -1
- package/node_modules/zod/src/v4/classic/tests/array.test.ts +27 -0
- package/node_modules/zod/src/v4/classic/tests/map.test.ts +7 -0
- package/node_modules/zod/src/v4/classic/tests/set.test.ts +6 -0
- package/node_modules/zod/src/v4/core/compile.ts +9 -0
- package/node_modules/zod/src/v4/core/schemas.ts +35 -1
- package/node_modules/zod/src/v4/core/util.ts +13 -0
- package/node_modules/zod/src/v4/core/versions.ts +1 -1
- package/node_modules/zod/v4/core/compile.cjs +8 -0
- package/node_modules/zod/v4/core/compile.js +8 -0
- package/node_modules/zod/v4/core/schemas.cjs +30 -0
- package/node_modules/zod/v4/core/schemas.d.cts +3 -1
- package/node_modules/zod/v4/core/schemas.d.ts +3 -1
- package/node_modules/zod/v4/core/schemas.js +30 -0
- package/node_modules/zod/v4/core/util.cjs +15 -0
- package/node_modules/zod/v4/core/util.d.cts +2 -0
- package/node_modules/zod/v4/core/util.d.ts +2 -0
- package/node_modules/zod/v4/core/util.js +14 -0
- package/node_modules/zod/v4/core/versions.cjs +1 -1
- package/node_modules/zod/v4/core/versions.js +1 -1
- package/package.json +5 -5
- package/dist/.setup/channel-plugin-api-U3Pg1KLp.mjs +0 -3
- package/dist/.setup/channel-runtime-B4OMtNnX.mjs +0 -652
- package/dist/.setup/secret-contract-api-ClqD0Rpm.mjs +0 -3
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import { t as IrcChannelConfigSchema } from "./config-schema-
|
|
2
|
-
import { n as getOptionalIrcRuntime } from "./runtime-C_V9tmpk.mjs";
|
|
1
|
+
import { t as IrcChannelConfigSchema } from "./config-schema-CHwjI_aV.mjs";
|
|
3
2
|
import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-C5i-29Hz.mjs";
|
|
3
|
+
import { n as getOptionalIrcRuntime } from "./runtime-C_V9tmpk.mjs";
|
|
4
4
|
import { createAccountListHelpers, describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
|
|
5
5
|
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
|
|
6
6
|
import { formatNormalizedAllowFromEntries } from "openclaw/plugin-sdk/allow-from";
|
|
7
7
|
import { adaptScopedAccountAccessor, createScopedChannelConfigAdapter, createScopedDmSecurityResolver } from "openclaw/plugin-sdk/channel-config-helpers";
|
|
8
8
|
import { buildChannelOutboundSessionRoute, createChatChannelPlugin, parseOptionalDelimitedEntries } from "openclaw/plugin-sdk/channel-core";
|
|
9
9
|
import { defineStableChannelIngressIdentity, identityEntryAuthenticationClassifier } from "openclaw/plugin-sdk/channel-ingress-runtime";
|
|
10
|
+
import { createAccountStatusSink, createMessageReceiptFromOutboundResults, createReplyToFanout, defineChannelMessageAdapter, runPassiveAccountLifecycle, sanitizeForPlainText } from "openclaw/plugin-sdk/channel-outbound";
|
|
10
11
|
import { buildMutableAllowEntryDetector, collectStandardAllowlistLists, createAllowlistProviderOpenWarningCollector, createConditionalWarningCollector, createDangerousNameMatchingMutableAllowlistWarningCollector, resolveScopeKeyCaseInsensitive, resolveScopeRequireMention, resolveScopeToolsPolicy } from "openclaw/plugin-sdk/channel-policy";
|
|
12
|
+
import { attachChannelToResult } from "openclaw/plugin-sdk/channel-send-result";
|
|
11
13
|
import { PAIRING_APPROVED_MESSAGE } from "openclaw/plugin-sdk/channel-status";
|
|
12
14
|
import { createChannelDirectoryAdapter, createResolvedDirectoryEntriesLister } from "openclaw/plugin-sdk/directory-runtime";
|
|
13
15
|
import { buildProbeChannelStatusSummary, createComputedAccountStatusAdapter, createDefaultChannelRuntimeState } from "openclaw/plugin-sdk/status-helpers";
|
|
@@ -17,20 +19,18 @@ import { isTruthyEnvValue } from "openclaw/plugin-sdk/runtime-env";
|
|
|
17
19
|
import { tryReadSecretFileSync } from "openclaw/plugin-sdk/secret-file-runtime";
|
|
18
20
|
import { resolveSecretInputString } from "openclaw/plugin-sdk/secret-input";
|
|
19
21
|
import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeStringEntries, normalizeStringifiedOptionalString, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
20
|
-
import { createAccountStatusSink, createMessageReceiptFromOutboundResults, createReplyToFanout, defineChannelMessageAdapter, runPassiveAccountLifecycle, sanitizeForPlainText } from "openclaw/plugin-sdk/channel-outbound";
|
|
21
22
|
import { containsAsciiControlCharacter as hasIrcControlChars } from "openclaw/plugin-sdk/string-normalization-runtime";
|
|
22
|
-
import { attachChannelToResult } from "openclaw/plugin-sdk/channel-send-result";
|
|
23
23
|
import { chunkTextForOutbound, convertMarkdownTables, sanitizeAssistantVisibleText, stripMarkdown } from "openclaw/plugin-sdk/text-chunking";
|
|
24
|
-
import { randomUUID } from "node:crypto";
|
|
25
|
-
import { createChannelPartialDeliveryError, isChannelPartialDeliveryError } from "openclaw/plugin-sdk/channel-inbound";
|
|
26
|
-
import { captureEffectAuthority } from "openclaw/plugin-sdk/fetch-runtime";
|
|
27
|
-
import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
|
|
28
|
-
import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
|
|
29
24
|
import net from "node:net";
|
|
30
25
|
import tls from "node:tls";
|
|
26
|
+
import { createChannelPartialDeliveryError, isChannelPartialDeliveryError } from "openclaw/plugin-sdk/channel-inbound";
|
|
31
27
|
import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
|
|
28
|
+
import { captureEffectAuthority } from "openclaw/plugin-sdk/fetch-runtime";
|
|
32
29
|
import { withTimeout } from "openclaw/plugin-sdk/security-runtime";
|
|
33
30
|
import { assertSecretOwnerAvailable } from "openclaw/plugin-sdk/channel-secret-owner-runtime";
|
|
31
|
+
import { randomUUID } from "node:crypto";
|
|
32
|
+
import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
|
|
33
|
+
import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
|
|
34
34
|
import { defineChannelSetupContract } from "openclaw/plugin-sdk/channel-setup";
|
|
35
35
|
import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$1, normalizeAccountId as normalizeAccountId$1 } from "openclaw/plugin-sdk/routing";
|
|
36
36
|
import { applyAccountNameToChannelSection, createAllowFromSection, createPromptParsedAllowFromForAccount, createSetupInputPresenceValidator, createSetupTranslator, createStandardChannelSetupStatus, createTopLevelChannelAllowFromSetter, createTopLevelChannelDmPolicySetter, formatDocsLink, patchScopedAccountConfig, setSetupChannelEnabled, splitSetupEntries } from "openclaw/plugin-sdk/setup";
|
|
@@ -187,42 +187,6 @@ function listEnabledIrcAccounts(cfg) {
|
|
|
187
187
|
})).filter((account) => account.enabled);
|
|
188
188
|
}
|
|
189
189
|
//#endregion
|
|
190
|
-
//#region extensions/irc/src/doctor.ts
|
|
191
|
-
const isIrcMutableAllowEntry = buildMutableAllowEntryDetector({ stableIdPattern: /^(?:(?:irc|user):)*[^@]*@/i });
|
|
192
|
-
const collectIrcMutableAllowlistWarnings = createDangerousNameMatchingMutableAllowlistWarningCollector({
|
|
193
|
-
channel: "irc",
|
|
194
|
-
detector: isIrcMutableAllowEntry,
|
|
195
|
-
collectLists: (scope) => collectStandardAllowlistLists(scope, {
|
|
196
|
-
includeGroups: true,
|
|
197
|
-
groupField: "allowFrom"
|
|
198
|
-
})
|
|
199
|
-
});
|
|
200
|
-
//#endregion
|
|
201
|
-
//#region extensions/irc/src/gateway.ts
|
|
202
|
-
async function startIrcGatewayAccount(ctx) {
|
|
203
|
-
const account = ctx.account;
|
|
204
|
-
const statusSink = createAccountStatusSink({
|
|
205
|
-
accountId: ctx.accountId,
|
|
206
|
-
setStatus: ctx.setStatus
|
|
207
|
-
});
|
|
208
|
-
if (!account.configured) throw new Error(`IRC is not configured for account "${account.accountId}" (need host and nick in channels.irc).`);
|
|
209
|
-
ctx.log?.info?.(`[${account.accountId}] starting IRC provider (${account.host}:${account.port}${account.tls ? " tls" : ""})`);
|
|
210
|
-
const { monitorIrcProvider } = await import("./channel-runtime-B4OMtNnX.mjs");
|
|
211
|
-
await runPassiveAccountLifecycle({
|
|
212
|
-
abortSignal: ctx.abortSignal,
|
|
213
|
-
start: async () => await monitorIrcProvider({
|
|
214
|
-
accountId: account.accountId,
|
|
215
|
-
config: ctx.cfg,
|
|
216
|
-
runtime: ctx.runtime,
|
|
217
|
-
abortSignal: ctx.abortSignal,
|
|
218
|
-
statusSink
|
|
219
|
-
}),
|
|
220
|
-
stop: async (monitor) => {
|
|
221
|
-
await monitor.stop();
|
|
222
|
-
}
|
|
223
|
-
});
|
|
224
|
-
}
|
|
225
|
-
//#endregion
|
|
226
190
|
//#region extensions/irc/src/control-chars.ts
|
|
227
191
|
function isIrcControlChar(charCode) {
|
|
228
192
|
return charCode <= 31 || charCode === 127;
|
|
@@ -283,17 +247,6 @@ function normalizeIrcAllowEntry(raw) {
|
|
|
283
247
|
if (value.startsWith("user:")) value = value.slice(5);
|
|
284
248
|
return value.trim();
|
|
285
249
|
}
|
|
286
|
-
function buildIrcAllowlistCandidates(message, params) {
|
|
287
|
-
const nick = normalizeLowercaseStringOrEmpty(message.senderNick);
|
|
288
|
-
const user = normalizeOptionalLowercaseString(message.senderUser);
|
|
289
|
-
const host = normalizeOptionalLowercaseString(message.senderHost);
|
|
290
|
-
const candidates = /* @__PURE__ */ new Set();
|
|
291
|
-
if (nick && params?.allowNameMatching === true) candidates.add(nick);
|
|
292
|
-
if (nick && user) candidates.add(`${nick}!${user}`);
|
|
293
|
-
if (nick && host) candidates.add(`${nick}@${host}`);
|
|
294
|
-
if (nick && user && host) candidates.add(`${nick}!${user}@${host}`);
|
|
295
|
-
return [...candidates];
|
|
296
|
-
}
|
|
297
250
|
const ircIngressIdentity = defineStableChannelIngressIdentity({
|
|
298
251
|
key: "irc-id",
|
|
299
252
|
authentication: "asserted",
|
|
@@ -358,14 +311,20 @@ function normalizeIrcNickEntry(value) {
|
|
|
358
311
|
return normalized;
|
|
359
312
|
}
|
|
360
313
|
function createIrcIngressSubject(message) {
|
|
361
|
-
const candidates = buildIrcAllowlistCandidates(message, { allowNameMatching: true });
|
|
362
|
-
const stableCandidates = candidates.filter((candidate) => hasVerifiedHost(candidate));
|
|
363
314
|
const nick = normalizeLowercaseStringOrEmpty(message.senderNick);
|
|
315
|
+
const user = normalizeOptionalLowercaseString(message.senderUser);
|
|
316
|
+
const host = normalizeOptionalLowercaseString(message.senderHost);
|
|
317
|
+
const candidates = [
|
|
318
|
+
nick,
|
|
319
|
+
nick && user ? `${nick}!${user}` : "",
|
|
320
|
+
nick && host ? `${nick}@${host}` : "",
|
|
321
|
+
nick && user && host ? `${nick}!${user}@${host}` : ""
|
|
322
|
+
];
|
|
364
323
|
return {
|
|
365
|
-
stableId:
|
|
324
|
+
stableId: candidates.findLast(hasVerifiedHost) ?? nick,
|
|
366
325
|
aliases: {
|
|
367
326
|
"irc-id-nick-user": candidates.find((candidate) => isHostlessNickUser(candidate)),
|
|
368
|
-
"irc-id-nick-host":
|
|
327
|
+
"irc-id-nick-host": candidates.find((candidate) => hasVerifiedHost(candidate) && !candidate.includes("!")),
|
|
369
328
|
"irc-nick": nick
|
|
370
329
|
}
|
|
371
330
|
};
|
|
@@ -383,6 +342,50 @@ const ircOutboundBaseAdapter = {
|
|
|
383
342
|
sanitizeText: ({ text }) => sanitizeIrcAssistantText(text)
|
|
384
343
|
};
|
|
385
344
|
//#endregion
|
|
345
|
+
//#region extensions/irc/src/policy.ts
|
|
346
|
+
function resolveIrcGroupScope(params) {
|
|
347
|
+
const { "*": wildcard, ...groups } = params.groups ?? {};
|
|
348
|
+
const project = (entry) => ({
|
|
349
|
+
requireMention: entry.requireMention,
|
|
350
|
+
tools: entry.tools
|
|
351
|
+
});
|
|
352
|
+
const tree = {
|
|
353
|
+
defaults: wildcard ? project(wildcard) : void 0,
|
|
354
|
+
scopes: Object.fromEntries(Object.entries(groups).map(([key, entry]) => [key, project(entry)]))
|
|
355
|
+
};
|
|
356
|
+
const key = resolveScopeKeyCaseInsensitive(tree, params.target);
|
|
357
|
+
return {
|
|
358
|
+
tree,
|
|
359
|
+
path: key ? [key] : []
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
function resolveIrcGroupMatch(params) {
|
|
363
|
+
const { path } = resolveIrcGroupScope(params);
|
|
364
|
+
const key = path[0];
|
|
365
|
+
const groupConfig = key ? params.groups?.[key] : void 0;
|
|
366
|
+
const wildcardConfig = params.groups?.["*"];
|
|
367
|
+
return {
|
|
368
|
+
allowed: Boolean(groupConfig ?? wildcardConfig),
|
|
369
|
+
groupConfig,
|
|
370
|
+
wildcardConfig,
|
|
371
|
+
hasConfiguredGroups: Object.keys(params.groups ?? {}).length > 0
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
function resolveIrcGroupRequireMention(params) {
|
|
375
|
+
const { tree, path } = resolveIrcGroupScope(params);
|
|
376
|
+
return resolveScopeRequireMention({
|
|
377
|
+
tree,
|
|
378
|
+
path
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
function resolveIrcGroupToolPolicy(params) {
|
|
382
|
+
const { tree, path } = resolveIrcGroupScope(params);
|
|
383
|
+
return resolveScopeToolsPolicy({
|
|
384
|
+
tree,
|
|
385
|
+
path
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
//#endregion
|
|
386
389
|
//#region packages/normalization-core/src/utf16-slice.ts
|
|
387
390
|
function isHighSurrogate(codeUnit) {
|
|
388
391
|
return codeUnit >= 55296 && codeUnit <= 56319;
|
|
@@ -457,7 +460,6 @@ function parseIrcLine(line) {
|
|
|
457
460
|
cursor = cursor.slice(spaceIdx + 1);
|
|
458
461
|
}
|
|
459
462
|
return {
|
|
460
|
-
raw,
|
|
461
463
|
prefix,
|
|
462
464
|
command: command.toUpperCase(),
|
|
463
465
|
params,
|
|
@@ -484,8 +486,7 @@ function parseIrcPrefix(prefix) {
|
|
|
484
486
|
user
|
|
485
487
|
};
|
|
486
488
|
}
|
|
487
|
-
|
|
488
|
-
return { nick: prefix };
|
|
489
|
+
return prefix.includes(".") ? {} : { nick: prefix };
|
|
489
490
|
}
|
|
490
491
|
function sanitizeIrcOutboundText(text) {
|
|
491
492
|
return stripIrcControlChars(text.replace(/\r?\n/g, " ")).trim();
|
|
@@ -700,7 +701,6 @@ async function connectIrcClient(options) {
|
|
|
700
701
|
buffer = buffer.slice(idx + 1);
|
|
701
702
|
idx = buffer.indexOf("\n");
|
|
702
703
|
if (!rawLine) continue;
|
|
703
|
-
options.onLine?.(rawLine);
|
|
704
704
|
const line = parseIrcLine(rawLine);
|
|
705
705
|
if (!line) continue;
|
|
706
706
|
if (line.command === "PING") {
|
|
@@ -811,7 +811,6 @@ async function connectIrcClient(options) {
|
|
|
811
811
|
return currentNick;
|
|
812
812
|
},
|
|
813
813
|
isReady: () => ready && !closed,
|
|
814
|
-
sendRaw,
|
|
815
814
|
join,
|
|
816
815
|
sendPrivmsg,
|
|
817
816
|
quit,
|
|
@@ -831,17 +830,46 @@ function buildIrcConnectOptions(account, overrides = {}) {
|
|
|
831
830
|
username: account.username,
|
|
832
831
|
realname: account.realname,
|
|
833
832
|
password: account.password,
|
|
834
|
-
nickserv:
|
|
835
|
-
enabled: account.config.nickserv?.enabled,
|
|
836
|
-
service: account.config.nickserv?.service,
|
|
837
|
-
password: account.config.nickserv?.password,
|
|
838
|
-
register: account.config.nickserv?.register,
|
|
839
|
-
registerEmail: account.config.nickserv?.registerEmail
|
|
840
|
-
},
|
|
833
|
+
nickserv: account.config.nickserv,
|
|
841
834
|
...overrides
|
|
842
835
|
};
|
|
843
836
|
}
|
|
844
837
|
//#endregion
|
|
838
|
+
//#region extensions/irc/src/probe.ts
|
|
839
|
+
async function probeIrc(cfg, opts) {
|
|
840
|
+
const account = resolveIrcAccount({
|
|
841
|
+
cfg,
|
|
842
|
+
accountId: opts?.accountId
|
|
843
|
+
});
|
|
844
|
+
const base = {
|
|
845
|
+
ok: false,
|
|
846
|
+
host: account.host,
|
|
847
|
+
port: account.port,
|
|
848
|
+
tls: account.tls,
|
|
849
|
+
nick: account.nick
|
|
850
|
+
};
|
|
851
|
+
if (!account.configured) return {
|
|
852
|
+
...base,
|
|
853
|
+
error: "missing host or nick"
|
|
854
|
+
};
|
|
855
|
+
const started = Date.now();
|
|
856
|
+
try {
|
|
857
|
+
const client = await connectIrcClient(buildIrcConnectOptions(account, { connectTimeoutMs: opts?.timeoutMs ?? 8e3 }));
|
|
858
|
+
const elapsed = Date.now() - started;
|
|
859
|
+
client.quit("probe");
|
|
860
|
+
return {
|
|
861
|
+
...base,
|
|
862
|
+
ok: true,
|
|
863
|
+
latencyMs: elapsed
|
|
864
|
+
};
|
|
865
|
+
} catch (err) {
|
|
866
|
+
return {
|
|
867
|
+
...base,
|
|
868
|
+
error: err instanceof Error ? err.message : typeof err === "string" ? err : JSON.stringify(err)
|
|
869
|
+
};
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
//#endregion
|
|
845
873
|
//#region extensions/irc/src/send.ts
|
|
846
874
|
async function sendIrcMessages(to, text, opts, planMessages = (preparedText) => [{
|
|
847
875
|
text: preparedText,
|
|
@@ -866,15 +894,14 @@ async function sendIrcMessages(to, text, opts, planMessages = (preparedText) =>
|
|
|
866
894
|
if (!prepared.trim()) throw new Error("Message must be non-empty for IRC sends");
|
|
867
895
|
const messages = planMessages(prepared);
|
|
868
896
|
opts.abortSignal?.throwIfAborted();
|
|
869
|
-
|
|
870
|
-
const client = opts.client?.isReady() ? opts.client : transient = await connectIrcClient(buildIrcConnectOptions(account, {
|
|
897
|
+
const client = await connectIrcClient(buildIrcConnectOptions(account, {
|
|
871
898
|
connectTimeoutMs: 12e3,
|
|
872
899
|
abortSignal: opts.abortSignal
|
|
873
900
|
}));
|
|
874
901
|
const results = [];
|
|
875
902
|
try {
|
|
876
903
|
opts.abortSignal?.throwIfAborted();
|
|
877
|
-
if (
|
|
904
|
+
if (target.startsWith("#") || target.startsWith("&")) await effect.initiate(() => {
|
|
878
905
|
opts.abortSignal?.throwIfAborted();
|
|
879
906
|
if (!client.isReady()) throw new Error("IRC connection closed before join");
|
|
880
907
|
client.join(target);
|
|
@@ -931,7 +958,7 @@ async function sendIrcMessages(to, text, opts, planMessages = (preparedText) =>
|
|
|
931
958
|
visibleReplySent: true
|
|
932
959
|
});
|
|
933
960
|
} finally {
|
|
934
|
-
|
|
961
|
+
client.quit("sent");
|
|
935
962
|
}
|
|
936
963
|
}
|
|
937
964
|
async function sendMessageIrc(to, text, opts) {
|
|
@@ -940,139 +967,6 @@ async function sendMessageIrc(to, text, opts) {
|
|
|
940
967
|
return result;
|
|
941
968
|
}
|
|
942
969
|
//#endregion
|
|
943
|
-
//#region extensions/irc/src/message-adapter.ts
|
|
944
|
-
function toIrcMessageResult({ target, ...result }) {
|
|
945
|
-
return {
|
|
946
|
-
...result,
|
|
947
|
-
target: {
|
|
948
|
-
kind: "conversation",
|
|
949
|
-
id: target
|
|
950
|
-
}
|
|
951
|
-
};
|
|
952
|
-
}
|
|
953
|
-
async function sendIrcMessage(ctx, text = ctx.text) {
|
|
954
|
-
return toIrcMessageResult(await sendMessageIrc(ctx.to, text, {
|
|
955
|
-
cfg: ctx.cfg,
|
|
956
|
-
accountId: ctx.accountId ?? void 0,
|
|
957
|
-
replyTo: ctx.replyToId ?? void 0,
|
|
958
|
-
abortSignal: ctx.signal,
|
|
959
|
-
onPlatformSendDispatch: ctx.onPlatformSendDispatch
|
|
960
|
-
}));
|
|
961
|
-
}
|
|
962
|
-
const sendFormattedIrcText = async (ctx) => {
|
|
963
|
-
const { chunkTextWithMode, resolveChunkMode, resolveTextChunkLimit } = await import("openclaw/plugin-sdk/reply-chunking");
|
|
964
|
-
const accountId = ctx.accountId ?? void 0;
|
|
965
|
-
const textLimit = ctx.formatting?.textLimit ?? resolveTextChunkLimit(ctx.cfg, "irc", accountId, { fallbackLimit: ircOutboundBaseAdapter.textChunkLimit });
|
|
966
|
-
const chunkMode = ctx.formatting?.chunkMode ?? resolveChunkMode(ctx.cfg, "irc", accountId);
|
|
967
|
-
const nextReplyToId = createReplyToFanout(ctx);
|
|
968
|
-
return (await sendIrcMessages(ctx.to, ctx.text, {
|
|
969
|
-
cfg: ctx.cfg,
|
|
970
|
-
accountId,
|
|
971
|
-
abortSignal: ctx.abortSignal,
|
|
972
|
-
onPlatformSendDispatch: ctx.onPlatformSendDispatch
|
|
973
|
-
}, (preparedText) => chunkTextWithMode(preparedText, textLimit, chunkMode).map((text) => ({
|
|
974
|
-
text,
|
|
975
|
-
replyTo: nextReplyToId()
|
|
976
|
-
})), async (result) => {
|
|
977
|
-
await ctx.onDeliveryResult?.(attachChannelToResult("irc", toIrcMessageResult(result)));
|
|
978
|
-
})).map((result) => attachChannelToResult("irc", toIrcMessageResult(result)));
|
|
979
|
-
};
|
|
980
|
-
const ircMessageAdapter = defineChannelMessageAdapter({
|
|
981
|
-
id: "irc",
|
|
982
|
-
durableFinal: { capabilities: {
|
|
983
|
-
text: true,
|
|
984
|
-
media: true,
|
|
985
|
-
replyTo: true
|
|
986
|
-
} },
|
|
987
|
-
send: {
|
|
988
|
-
text: sendIrcMessage,
|
|
989
|
-
media: (ctx) => sendIrcMessage(ctx, ctx.mediaUrl ? `${ctx.text}\n\nAttachment: ${ctx.mediaUrl}` : ctx.text)
|
|
990
|
-
}
|
|
991
|
-
});
|
|
992
|
-
//#endregion
|
|
993
|
-
//#region extensions/irc/src/policy.ts
|
|
994
|
-
function resolveIrcGroupScope(params) {
|
|
995
|
-
const { "*": wildcard, ...groups } = params.groups ?? {};
|
|
996
|
-
const project = (entry) => ({
|
|
997
|
-
requireMention: entry.requireMention,
|
|
998
|
-
tools: entry.tools
|
|
999
|
-
});
|
|
1000
|
-
const tree = {
|
|
1001
|
-
defaults: wildcard ? project(wildcard) : void 0,
|
|
1002
|
-
scopes: Object.fromEntries(Object.entries(groups).map(([key, entry]) => [key, project(entry)]))
|
|
1003
|
-
};
|
|
1004
|
-
const key = resolveScopeKeyCaseInsensitive(tree, params.target);
|
|
1005
|
-
return {
|
|
1006
|
-
tree,
|
|
1007
|
-
path: key ? [key] : []
|
|
1008
|
-
};
|
|
1009
|
-
}
|
|
1010
|
-
function resolveIrcGroupMatch(params) {
|
|
1011
|
-
const { path } = resolveIrcGroupScope(params);
|
|
1012
|
-
const key = path[0];
|
|
1013
|
-
const groupConfig = key ? params.groups?.[key] : void 0;
|
|
1014
|
-
const wildcardConfig = params.groups?.["*"];
|
|
1015
|
-
return {
|
|
1016
|
-
allowed: Boolean(groupConfig ?? wildcardConfig),
|
|
1017
|
-
groupConfig,
|
|
1018
|
-
wildcardConfig,
|
|
1019
|
-
hasConfiguredGroups: Object.keys(params.groups ?? {}).length > 0
|
|
1020
|
-
};
|
|
1021
|
-
}
|
|
1022
|
-
function resolveIrcGroupRequireMention(params) {
|
|
1023
|
-
const { tree, path } = resolveIrcGroupScope(params);
|
|
1024
|
-
return resolveScopeRequireMention({
|
|
1025
|
-
tree,
|
|
1026
|
-
path
|
|
1027
|
-
});
|
|
1028
|
-
}
|
|
1029
|
-
function resolveIrcGroupToolPolicy(params) {
|
|
1030
|
-
const { tree, path } = resolveIrcGroupScope(params);
|
|
1031
|
-
return resolveScopeToolsPolicy({
|
|
1032
|
-
tree,
|
|
1033
|
-
path
|
|
1034
|
-
});
|
|
1035
|
-
}
|
|
1036
|
-
//#endregion
|
|
1037
|
-
//#region extensions/irc/src/probe.ts
|
|
1038
|
-
function formatError(err) {
|
|
1039
|
-
if (err instanceof Error) return err.message;
|
|
1040
|
-
return typeof err === "string" ? err : JSON.stringify(err);
|
|
1041
|
-
}
|
|
1042
|
-
async function probeIrc(cfg, opts) {
|
|
1043
|
-
const account = resolveIrcAccount({
|
|
1044
|
-
cfg,
|
|
1045
|
-
accountId: opts?.accountId
|
|
1046
|
-
});
|
|
1047
|
-
const base = {
|
|
1048
|
-
ok: false,
|
|
1049
|
-
host: account.host,
|
|
1050
|
-
port: account.port,
|
|
1051
|
-
tls: account.tls,
|
|
1052
|
-
nick: account.nick
|
|
1053
|
-
};
|
|
1054
|
-
if (!account.configured) return {
|
|
1055
|
-
...base,
|
|
1056
|
-
error: "missing host or nick"
|
|
1057
|
-
};
|
|
1058
|
-
const started = Date.now();
|
|
1059
|
-
try {
|
|
1060
|
-
const client = await connectIrcClient(buildIrcConnectOptions(account, { connectTimeoutMs: opts?.timeoutMs ?? 8e3 }));
|
|
1061
|
-
const elapsed = Date.now() - started;
|
|
1062
|
-
client.quit("probe");
|
|
1063
|
-
return {
|
|
1064
|
-
...base,
|
|
1065
|
-
ok: true,
|
|
1066
|
-
latencyMs: elapsed
|
|
1067
|
-
};
|
|
1068
|
-
} catch (err) {
|
|
1069
|
-
return {
|
|
1070
|
-
...base,
|
|
1071
|
-
error: formatError(err)
|
|
1072
|
-
};
|
|
1073
|
-
}
|
|
1074
|
-
}
|
|
1075
|
-
//#endregion
|
|
1076
970
|
//#region extensions/irc/src/setup-core.ts
|
|
1077
971
|
const channel$1 = "irc";
|
|
1078
972
|
const setIrcDmPolicy = createTopLevelChannelDmPolicySetter({ channel: channel$1 });
|
|
@@ -1253,67 +1147,16 @@ function normalizeGroupEntry(raw) {
|
|
|
1253
1147
|
return `#${normalized.replace(/^#+/, "")}`;
|
|
1254
1148
|
}
|
|
1255
1149
|
function parseAutoJoinChannels(value) {
|
|
1256
|
-
return splitSetupEntries(value).map(normalizeGroupEntry).filter((entry) => Boolean(entry && entry !== "*"))
|
|
1150
|
+
return splitSetupEntries(value).map(normalizeGroupEntry).filter((entry) => Boolean(entry && entry !== "*"));
|
|
1257
1151
|
}
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
noteTitle: t("wizard.irc.allowlistTitle"),
|
|
1261
|
-
noteLines: [
|
|
1152
|
+
function ircAllowlistHelpLines() {
|
|
1153
|
+
return [
|
|
1262
1154
|
t("wizard.irc.allowlistIntro"),
|
|
1263
1155
|
t("wizard.irc.examples"),
|
|
1264
1156
|
"- alice",
|
|
1265
1157
|
"- alice!ident@example.org",
|
|
1266
1158
|
t("wizard.irc.multipleEntries")
|
|
1267
|
-
]
|
|
1268
|
-
message: t("wizard.irc.allowFromPrompt"),
|
|
1269
|
-
placeholder: "alice, bob!ident@example.org",
|
|
1270
|
-
parseEntries: (raw) => ({ entries: normalizeStringEntries(splitSetupEntries(raw).map(normalizeIrcAllowEntry)) }),
|
|
1271
|
-
getExistingAllowFrom: ({ cfg }) => cfg.channels?.irc?.allowFrom ?? [],
|
|
1272
|
-
applyAllowFrom: ({ cfg, allowFrom }) => setIrcAllowFrom(cfg, allowFrom)
|
|
1273
|
-
});
|
|
1274
|
-
async function promptIrcNickServConfig(params) {
|
|
1275
|
-
const existing = resolveIrcAccount({
|
|
1276
|
-
cfg: params.cfg,
|
|
1277
|
-
accountId: params.accountId
|
|
1278
|
-
}).config.nickserv;
|
|
1279
|
-
const hasExisting = Boolean(existing?.password || existing?.passwordFile);
|
|
1280
|
-
if (!await params.prompter.confirm({
|
|
1281
|
-
message: hasExisting ? t("wizard.irc.nickServUpdatePrompt") : t("wizard.irc.nickServConfigurePrompt"),
|
|
1282
|
-
initialValue: hasExisting
|
|
1283
|
-
})) return params.cfg;
|
|
1284
|
-
const service = (await params.prompter.text({
|
|
1285
|
-
message: t("wizard.irc.nickServServicePrompt"),
|
|
1286
|
-
initialValue: existing?.service || "NickServ",
|
|
1287
|
-
validate: (value) => normalizeStringifiedOptionalString(value) ? void 0 : "Required"
|
|
1288
|
-
})).trim();
|
|
1289
|
-
const useEnvPassword = params.accountId === DEFAULT_ACCOUNT_ID$1 && Boolean(process.env.IRC_NICKSERV_PASSWORD?.trim()) && !(existing?.password || existing?.passwordFile) ? await params.prompter.confirm({
|
|
1290
|
-
message: t("wizard.irc.nickServPasswordEnvPrompt"),
|
|
1291
|
-
initialValue: true
|
|
1292
|
-
}) : false;
|
|
1293
|
-
const password = useEnvPassword ? void 0 : (await params.prompter.text({
|
|
1294
|
-
message: t("wizard.irc.nickServPasswordPrompt"),
|
|
1295
|
-
validate: () => void 0
|
|
1296
|
-
})).trim();
|
|
1297
|
-
if (!password && !useEnvPassword) return setIrcNickServ(params.cfg, params.accountId, {
|
|
1298
|
-
enabled: false,
|
|
1299
|
-
service
|
|
1300
|
-
});
|
|
1301
|
-
const register = await params.prompter.confirm({
|
|
1302
|
-
message: t("wizard.irc.nickServRegisterPrompt"),
|
|
1303
|
-
initialValue: existing?.register ?? false
|
|
1304
|
-
});
|
|
1305
|
-
const registerEmail = register ? (await params.prompter.text({
|
|
1306
|
-
message: t("wizard.irc.nickServRegisterEmailPrompt"),
|
|
1307
|
-
initialValue: existing?.registerEmail || (params.accountId === DEFAULT_ACCOUNT_ID$1 ? process.env.IRC_NICKSERV_REGISTER_EMAIL : void 0),
|
|
1308
|
-
validate: (value) => normalizeStringifiedOptionalString(value) ? void 0 : "Required"
|
|
1309
|
-
})).trim() : void 0;
|
|
1310
|
-
return setIrcNickServ(params.cfg, params.accountId, {
|
|
1311
|
-
enabled: true,
|
|
1312
|
-
service,
|
|
1313
|
-
...password ? { password } : {},
|
|
1314
|
-
register,
|
|
1315
|
-
...registerEmail ? { registerEmail } : {}
|
|
1316
|
-
});
|
|
1159
|
+
];
|
|
1317
1160
|
}
|
|
1318
1161
|
const ircDmPolicy = {
|
|
1319
1162
|
label: "IRC",
|
|
@@ -1322,7 +1165,16 @@ const ircDmPolicy = {
|
|
|
1322
1165
|
allowFromKey: "channels.irc.allowFrom",
|
|
1323
1166
|
getCurrent: (cfg) => cfg.channels?.irc?.dmPolicy ?? "pairing",
|
|
1324
1167
|
setPolicy: (cfg, policy) => setIrcDmPolicy(cfg, policy),
|
|
1325
|
-
promptAllowFrom:
|
|
1168
|
+
promptAllowFrom: createPromptParsedAllowFromForAccount({
|
|
1169
|
+
defaultAccountId: resolveDefaultIrcAccountId,
|
|
1170
|
+
noteTitle: t("wizard.irc.allowlistTitle"),
|
|
1171
|
+
noteLines: ircAllowlistHelpLines(),
|
|
1172
|
+
message: t("wizard.irc.allowFromPrompt"),
|
|
1173
|
+
placeholder: "alice, bob!ident@example.org",
|
|
1174
|
+
parseEntries: (raw) => ({ entries: normalizeStringEntries(splitSetupEntries(raw).map(normalizeIrcAllowEntry)) }),
|
|
1175
|
+
getExistingAllowFrom: ({ cfg }) => cfg.channels?.irc?.allowFrom ?? [],
|
|
1176
|
+
applyAllowFrom: ({ cfg, allowFrom }) => setIrcAllowFrom(cfg, allowFrom)
|
|
1177
|
+
})
|
|
1326
1178
|
};
|
|
1327
1179
|
const ircSetupWizard = {
|
|
1328
1180
|
channel,
|
|
@@ -1487,13 +1339,7 @@ const ircSetupWizard = {
|
|
|
1487
1339
|
},
|
|
1488
1340
|
allowFrom: createAllowFromSection({
|
|
1489
1341
|
helpTitle: t("wizard.irc.allowlistTitle"),
|
|
1490
|
-
helpLines:
|
|
1491
|
-
t("wizard.irc.allowlistIntro"),
|
|
1492
|
-
t("wizard.irc.examples"),
|
|
1493
|
-
"- alice",
|
|
1494
|
-
"- alice!ident@example.org",
|
|
1495
|
-
t("wizard.irc.multipleEntries")
|
|
1496
|
-
],
|
|
1342
|
+
helpLines: ircAllowlistHelpLines(),
|
|
1497
1343
|
message: t("wizard.irc.allowFromPrompt"),
|
|
1498
1344
|
placeholder: "alice, bob!ident@example.org",
|
|
1499
1345
|
invalidWithoutCredentialNote: t("wizard.irc.allowFromInvalid"),
|
|
@@ -1523,11 +1369,51 @@ const ircSetupWizard = {
|
|
|
1523
1369
|
}
|
|
1524
1370
|
}
|
|
1525
1371
|
}
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1372
|
+
const nickServConfig = next;
|
|
1373
|
+
next = await (async () => {
|
|
1374
|
+
const existing = resolveIrcAccount({
|
|
1375
|
+
cfg: nickServConfig,
|
|
1376
|
+
accountId
|
|
1377
|
+
}).config.nickserv;
|
|
1378
|
+
const hasExisting = Boolean(existing?.password || existing?.passwordFile);
|
|
1379
|
+
if (!await prompter.confirm({
|
|
1380
|
+
message: hasExisting ? t("wizard.irc.nickServUpdatePrompt") : t("wizard.irc.nickServConfigurePrompt"),
|
|
1381
|
+
initialValue: hasExisting
|
|
1382
|
+
})) return nickServConfig;
|
|
1383
|
+
const service = (await prompter.text({
|
|
1384
|
+
message: t("wizard.irc.nickServServicePrompt"),
|
|
1385
|
+
initialValue: existing?.service || "NickServ",
|
|
1386
|
+
validate: (value) => normalizeStringifiedOptionalString(value) ? void 0 : "Required"
|
|
1387
|
+
})).trim();
|
|
1388
|
+
const useEnvPassword = accountId === DEFAULT_ACCOUNT_ID$1 && Boolean(process.env.IRC_NICKSERV_PASSWORD?.trim()) && !(existing?.password || existing?.passwordFile) ? await prompter.confirm({
|
|
1389
|
+
message: t("wizard.irc.nickServPasswordEnvPrompt"),
|
|
1390
|
+
initialValue: true
|
|
1391
|
+
}) : false;
|
|
1392
|
+
const password = useEnvPassword ? void 0 : (await prompter.text({
|
|
1393
|
+
message: t("wizard.irc.nickServPasswordPrompt"),
|
|
1394
|
+
validate: () => void 0
|
|
1395
|
+
})).trim();
|
|
1396
|
+
if (!password && !useEnvPassword) return setIrcNickServ(nickServConfig, accountId, {
|
|
1397
|
+
enabled: false,
|
|
1398
|
+
service
|
|
1399
|
+
});
|
|
1400
|
+
const register = await prompter.confirm({
|
|
1401
|
+
message: t("wizard.irc.nickServRegisterPrompt"),
|
|
1402
|
+
initialValue: existing?.register ?? false
|
|
1403
|
+
});
|
|
1404
|
+
const registerEmail = register ? (await prompter.text({
|
|
1405
|
+
message: t("wizard.irc.nickServRegisterEmailPrompt"),
|
|
1406
|
+
initialValue: existing?.registerEmail || (accountId === DEFAULT_ACCOUNT_ID$1 ? process.env.IRC_NICKSERV_REGISTER_EMAIL : void 0),
|
|
1407
|
+
validate: (value) => normalizeStringifiedOptionalString(value) ? void 0 : "Required"
|
|
1408
|
+
})).trim() : void 0;
|
|
1409
|
+
return setIrcNickServ(nickServConfig, accountId, {
|
|
1410
|
+
enabled: true,
|
|
1411
|
+
service,
|
|
1412
|
+
...password ? { password } : {},
|
|
1413
|
+
register,
|
|
1414
|
+
...registerEmail ? { registerEmail } : {}
|
|
1415
|
+
});
|
|
1416
|
+
})();
|
|
1531
1417
|
return { cfg: next };
|
|
1532
1418
|
},
|
|
1533
1419
|
completionNote: {
|
|
@@ -1543,6 +1429,73 @@ const ircSetupWizard = {
|
|
|
1543
1429
|
};
|
|
1544
1430
|
//#endregion
|
|
1545
1431
|
//#region extensions/irc/src/channel.ts
|
|
1432
|
+
function ircAccountDetails(account) {
|
|
1433
|
+
return {
|
|
1434
|
+
host: account.host,
|
|
1435
|
+
port: account.port,
|
|
1436
|
+
tls: account.tls,
|
|
1437
|
+
nick: account.nick,
|
|
1438
|
+
passwordSource: account.passwordSource,
|
|
1439
|
+
tokenStatus: account.tokenStatus
|
|
1440
|
+
};
|
|
1441
|
+
}
|
|
1442
|
+
function toIrcMessageResult({ target, ...result }) {
|
|
1443
|
+
return {
|
|
1444
|
+
...result,
|
|
1445
|
+
target: {
|
|
1446
|
+
kind: "conversation",
|
|
1447
|
+
id: target
|
|
1448
|
+
}
|
|
1449
|
+
};
|
|
1450
|
+
}
|
|
1451
|
+
async function sendIrcMessage(ctx, text = ctx.text) {
|
|
1452
|
+
return toIrcMessageResult(await sendMessageIrc(ctx.to, text, {
|
|
1453
|
+
cfg: ctx.cfg,
|
|
1454
|
+
accountId: ctx.accountId ?? void 0,
|
|
1455
|
+
replyTo: ctx.replyToId ?? void 0,
|
|
1456
|
+
abortSignal: ctx.signal,
|
|
1457
|
+
onPlatformSendDispatch: ctx.onPlatformSendDispatch
|
|
1458
|
+
}));
|
|
1459
|
+
}
|
|
1460
|
+
const sendFormattedIrcText = async (ctx) => {
|
|
1461
|
+
const { chunkTextWithMode, resolveChunkMode, resolveTextChunkLimit } = await import("openclaw/plugin-sdk/reply-chunking");
|
|
1462
|
+
const accountId = ctx.accountId ?? void 0;
|
|
1463
|
+
const textLimit = ctx.formatting?.textLimit ?? resolveTextChunkLimit(ctx.cfg, "irc", accountId, { fallbackLimit: ircOutboundBaseAdapter.textChunkLimit });
|
|
1464
|
+
const chunkMode = ctx.formatting?.chunkMode ?? resolveChunkMode(ctx.cfg, "irc", accountId);
|
|
1465
|
+
const nextReplyToId = createReplyToFanout(ctx);
|
|
1466
|
+
return (await sendIrcMessages(ctx.to, ctx.text, {
|
|
1467
|
+
cfg: ctx.cfg,
|
|
1468
|
+
accountId,
|
|
1469
|
+
abortSignal: ctx.abortSignal,
|
|
1470
|
+
onPlatformSendDispatch: ctx.onPlatformSendDispatch
|
|
1471
|
+
}, (preparedText) => chunkTextWithMode(preparedText, textLimit, chunkMode).map((text) => ({
|
|
1472
|
+
text,
|
|
1473
|
+
replyTo: nextReplyToId()
|
|
1474
|
+
})), async (result) => {
|
|
1475
|
+
await ctx.onDeliveryResult?.(attachChannelToResult("irc", toIrcMessageResult(result)));
|
|
1476
|
+
})).map((result) => attachChannelToResult("irc", toIrcMessageResult(result)));
|
|
1477
|
+
};
|
|
1478
|
+
const ircMessageAdapter = defineChannelMessageAdapter({
|
|
1479
|
+
id: "irc",
|
|
1480
|
+
durableFinal: { capabilities: {
|
|
1481
|
+
text: true,
|
|
1482
|
+
media: true,
|
|
1483
|
+
replyTo: true
|
|
1484
|
+
} },
|
|
1485
|
+
send: {
|
|
1486
|
+
text: sendIrcMessage,
|
|
1487
|
+
media: (ctx) => sendIrcMessage(ctx, ctx.mediaUrl ? `${ctx.text}\n\nAttachment: ${ctx.mediaUrl}` : ctx.text)
|
|
1488
|
+
}
|
|
1489
|
+
});
|
|
1490
|
+
const isIrcMutableAllowEntry = buildMutableAllowEntryDetector({ stableIdPattern: /^(?:(?:irc|user):)*[^@]*@/i });
|
|
1491
|
+
const collectIrcMutableAllowlistWarnings = createDangerousNameMatchingMutableAllowlistWarningCollector({
|
|
1492
|
+
channel: "irc",
|
|
1493
|
+
detector: isIrcMutableAllowEntry,
|
|
1494
|
+
collectLists: (scope) => collectStandardAllowlistLists(scope, {
|
|
1495
|
+
includeGroups: true,
|
|
1496
|
+
groupField: "allowFrom"
|
|
1497
|
+
})
|
|
1498
|
+
});
|
|
1546
1499
|
const meta = {
|
|
1547
1500
|
id: "irc",
|
|
1548
1501
|
label: "IRC",
|
|
@@ -1658,14 +1611,7 @@ const ircPlugin = createChatChannelPlugin({
|
|
|
1658
1611
|
describeAccount: (account) => describeAccountSnapshot({
|
|
1659
1612
|
account,
|
|
1660
1613
|
configured: account.configured,
|
|
1661
|
-
extra:
|
|
1662
|
-
host: account.host,
|
|
1663
|
-
port: account.port,
|
|
1664
|
-
tls: account.tls,
|
|
1665
|
-
nick: account.nick,
|
|
1666
|
-
passwordSource: account.passwordSource,
|
|
1667
|
-
tokenStatus: account.tokenStatus
|
|
1668
|
-
}
|
|
1614
|
+
extra: ircAccountDetails(account)
|
|
1669
1615
|
})
|
|
1670
1616
|
},
|
|
1671
1617
|
secrets: {
|
|
@@ -1768,20 +1714,29 @@ const ircPlugin = createChatChannelPlugin({
|
|
|
1768
1714
|
name: account.name,
|
|
1769
1715
|
enabled: account.enabled,
|
|
1770
1716
|
configured: account.configured,
|
|
1771
|
-
extra:
|
|
1772
|
-
host: account.host,
|
|
1773
|
-
port: account.port,
|
|
1774
|
-
tls: account.tls,
|
|
1775
|
-
nick: account.nick,
|
|
1776
|
-
passwordSource: account.passwordSource,
|
|
1777
|
-
tokenStatus: account.tokenStatus
|
|
1778
|
-
}
|
|
1717
|
+
extra: ircAccountDetails(account)
|
|
1779
1718
|
})
|
|
1780
1719
|
}),
|
|
1781
|
-
gateway: { startAccount: async (ctx) =>
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1720
|
+
gateway: { startAccount: async (ctx) => {
|
|
1721
|
+
const account = ctx.account;
|
|
1722
|
+
const statusSink = createAccountStatusSink(ctx);
|
|
1723
|
+
if (!account.configured) throw new Error(`IRC is not configured for account "${account.accountId}" (need host and nick in channels.irc).`);
|
|
1724
|
+
ctx.log?.info?.(`[${account.accountId}] starting IRC provider (${account.host}:${account.port}${account.tls ? " tls" : ""})`);
|
|
1725
|
+
const { monitorIrcProvider } = await import("./channel-runtime-D4vKt7TE.mjs");
|
|
1726
|
+
await runPassiveAccountLifecycle({
|
|
1727
|
+
abortSignal: ctx.abortSignal,
|
|
1728
|
+
start: async () => await monitorIrcProvider({
|
|
1729
|
+
accountId: account.accountId,
|
|
1730
|
+
config: ctx.cfg,
|
|
1731
|
+
runtime: ctx.runtime,
|
|
1732
|
+
abortSignal: ctx.abortSignal,
|
|
1733
|
+
statusSink
|
|
1734
|
+
}),
|
|
1735
|
+
stop: async (monitor) => {
|
|
1736
|
+
await monitor.stop();
|
|
1737
|
+
}
|
|
1738
|
+
});
|
|
1739
|
+
} }
|
|
1785
1740
|
},
|
|
1786
1741
|
pairing: { text: {
|
|
1787
1742
|
idLabel: "ircUser",
|
|
@@ -1790,7 +1745,7 @@ const ircPlugin = createChatChannelPlugin({
|
|
|
1790
1745
|
notify: async ({ cfg, id, message, accountId }) => {
|
|
1791
1746
|
const target = normalizePairingTarget(id);
|
|
1792
1747
|
if (!target) throw new Error(`invalid IRC pairing id: ${id}`);
|
|
1793
|
-
const { sendMessageIrc } = await import("./channel-runtime-
|
|
1748
|
+
const { sendMessageIrc } = await import("./channel-runtime-D4vKt7TE.mjs");
|
|
1794
1749
|
await sendMessageIrc(target, message, {
|
|
1795
1750
|
cfg,
|
|
1796
1751
|
accountId
|
|
@@ -1817,4 +1772,4 @@ const ircPlugin = createChatChannelPlugin({
|
|
|
1817
1772
|
}
|
|
1818
1773
|
});
|
|
1819
1774
|
//#endregion
|
|
1820
|
-
export { listIrcAccountIds as _,
|
|
1775
|
+
export { listIrcAccountIds as _, buildIrcConnectOptions as a, parseIrcPrefix as c, sanitizeIrcAssistantText as d, createIrcIngressSubject as f, listEnabledIrcAccounts as g, normalizeIrcAllowEntry as h, sendMessageIrc as i, resolveIrcGroupMatch as l, isChannelTarget as m, ircSetupWizard as n, connectIrcClient as o, ircIngressIdentity as p, ircSetupAdapter as r, parseIrcLine as s, ircPlugin as t, resolveIrcGroupRequireMention as u, resolveDefaultIrcAccountId as v, resolveIrcAccount as y };
|