@openclaw/irc 2026.10.10 → 2026.11.5-beta.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.
- package/dist/.setup/{channel-t-k-A5n4.mjs → channel-DRdPa321.mjs} +252 -294
- package/dist/.setup/channel-plugin-api-DFjxQCOi.mjs +2 -0
- package/dist/.setup/channel-runtime-D2sqTm8e.mjs +579 -0
- package/dist/.setup/{config-schema-DFqPW9AB.mjs → config-schema-CQuAQW7O.mjs} +1 -2
- package/dist/.source-module-urls/4751df78f545ae971ceb22b6e4bff6086f63313240899a1d9884b970424a305e.json +1 -1
- package/dist/api.js +1 -1
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/setup-entry.js +1 -1
- 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-DRR9Fg5C.mjs +0 -2
- package/dist/.setup/channel-runtime-exb5AWhn.mjs +0 -648
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import { t as IrcChannelConfigSchema } from "./config-schema-
|
|
2
|
-
import { n as getOptionalIrcRuntime } from "./runtime-CsdAoZex.mjs";
|
|
1
|
+
import { t as IrcChannelConfigSchema } from "./config-schema-CQuAQW7O.mjs";
|
|
3
2
|
import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-0Ccz8X9F.mjs";
|
|
3
|
+
import { n as getOptionalIrcRuntime } from "./runtime-CsdAoZex.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";
|
|
@@ -186,40 +186,6 @@ function listEnabledIrcAccounts(cfg) {
|
|
|
186
186
|
accountId
|
|
187
187
|
})).filter((account) => account.enabled);
|
|
188
188
|
}
|
|
189
|
-
// extensions/irc/src/doctor.ts
|
|
190
|
-
const isIrcMutableAllowEntry = buildMutableAllowEntryDetector({ stableIdPattern: /^(?:(?:irc|user):)*[^@]*@/i });
|
|
191
|
-
const collectIrcMutableAllowlistWarnings = createDangerousNameMatchingMutableAllowlistWarningCollector({
|
|
192
|
-
channel: "irc",
|
|
193
|
-
detector: isIrcMutableAllowEntry,
|
|
194
|
-
collectLists: (scope) => collectStandardAllowlistLists(scope, {
|
|
195
|
-
includeGroups: true,
|
|
196
|
-
groupField: "allowFrom"
|
|
197
|
-
})
|
|
198
|
-
});
|
|
199
|
-
// extensions/irc/src/gateway.ts
|
|
200
|
-
async function startIrcGatewayAccount(ctx) {
|
|
201
|
-
const account = ctx.account;
|
|
202
|
-
const statusSink = createAccountStatusSink({
|
|
203
|
-
accountId: ctx.accountId,
|
|
204
|
-
setStatus: ctx.setStatus
|
|
205
|
-
});
|
|
206
|
-
if (!account.configured) throw new Error(`IRC is not configured for account "${account.accountId}" (need host and nick in channels.irc).`);
|
|
207
|
-
ctx.log?.info?.(`[${account.accountId}] starting IRC provider (${account.host}:${account.port}${account.tls ? " tls" : ""})`);
|
|
208
|
-
const { monitorIrcProvider } = await import("./channel-runtime-exb5AWhn.mjs");
|
|
209
|
-
await runPassiveAccountLifecycle({
|
|
210
|
-
abortSignal: ctx.abortSignal,
|
|
211
|
-
start: async () => await monitorIrcProvider({
|
|
212
|
-
accountId: account.accountId,
|
|
213
|
-
config: ctx.cfg,
|
|
214
|
-
runtime: ctx.runtime,
|
|
215
|
-
abortSignal: ctx.abortSignal,
|
|
216
|
-
statusSink
|
|
217
|
-
}),
|
|
218
|
-
stop: async (monitor) => {
|
|
219
|
-
await monitor.stop();
|
|
220
|
-
}
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
189
|
// extensions/irc/src/control-chars.ts
|
|
224
190
|
function isIrcControlChar(charCode) {
|
|
225
191
|
return charCode <= 31 || charCode === 127;
|
|
@@ -279,17 +245,6 @@ function normalizeIrcAllowEntry(raw) {
|
|
|
279
245
|
if (value.startsWith("user:")) value = value.slice(5);
|
|
280
246
|
return value.trim();
|
|
281
247
|
}
|
|
282
|
-
function buildIrcAllowlistCandidates(message, params) {
|
|
283
|
-
const nick = normalizeLowercaseStringOrEmpty(message.senderNick);
|
|
284
|
-
const user = normalizeOptionalLowercaseString(message.senderUser);
|
|
285
|
-
const host = normalizeOptionalLowercaseString(message.senderHost);
|
|
286
|
-
const candidates = /* @__PURE__ */ new Set();
|
|
287
|
-
if (nick && params?.allowNameMatching === true) candidates.add(nick);
|
|
288
|
-
if (nick && user) candidates.add(`${nick}!${user}`);
|
|
289
|
-
if (nick && host) candidates.add(`${nick}@${host}`);
|
|
290
|
-
if (nick && user && host) candidates.add(`${nick}!${user}@${host}`);
|
|
291
|
-
return [...candidates];
|
|
292
|
-
}
|
|
293
248
|
const ircIngressIdentity = defineStableChannelIngressIdentity({
|
|
294
249
|
key: "irc-id",
|
|
295
250
|
authentication: "asserted",
|
|
@@ -354,14 +309,20 @@ function normalizeIrcNickEntry(value) {
|
|
|
354
309
|
return normalized;
|
|
355
310
|
}
|
|
356
311
|
function createIrcIngressSubject(message) {
|
|
357
|
-
const candidates = buildIrcAllowlistCandidates(message, { allowNameMatching: true });
|
|
358
|
-
const stableCandidates = candidates.filter((candidate) => hasVerifiedHost(candidate));
|
|
359
312
|
const nick = normalizeLowercaseStringOrEmpty(message.senderNick);
|
|
313
|
+
const user = normalizeOptionalLowercaseString(message.senderUser);
|
|
314
|
+
const host = normalizeOptionalLowercaseString(message.senderHost);
|
|
315
|
+
const candidates = [
|
|
316
|
+
nick,
|
|
317
|
+
nick && user ? `${nick}!${user}` : "",
|
|
318
|
+
nick && host ? `${nick}@${host}` : "",
|
|
319
|
+
nick && user && host ? `${nick}!${user}@${host}` : ""
|
|
320
|
+
];
|
|
360
321
|
return {
|
|
361
|
-
stableId:
|
|
322
|
+
stableId: candidates.findLast(hasVerifiedHost) ?? nick,
|
|
362
323
|
aliases: {
|
|
363
324
|
"irc-id-nick-user": candidates.find((candidate) => isHostlessNickUser(candidate)),
|
|
364
|
-
"irc-id-nick-host":
|
|
325
|
+
"irc-id-nick-host": candidates.find((candidate) => hasVerifiedHost(candidate) && !candidate.includes("!")),
|
|
365
326
|
"irc-nick": nick
|
|
366
327
|
}
|
|
367
328
|
};
|
|
@@ -377,6 +338,49 @@ const ircOutboundBaseAdapter = {
|
|
|
377
338
|
textChunkLimit: 350,
|
|
378
339
|
sanitizeText: ({ text }) => sanitizeIrcAssistantText(text)
|
|
379
340
|
};
|
|
341
|
+
// extensions/irc/src/policy.ts
|
|
342
|
+
function resolveIrcGroupScope(params) {
|
|
343
|
+
const { "*": wildcard, ...groups } = params.groups ?? {};
|
|
344
|
+
const project = (entry) => ({
|
|
345
|
+
requireMention: entry.requireMention,
|
|
346
|
+
tools: entry.tools
|
|
347
|
+
});
|
|
348
|
+
const tree = {
|
|
349
|
+
defaults: wildcard ? project(wildcard) : void 0,
|
|
350
|
+
scopes: Object.fromEntries(Object.entries(groups).map(([key, entry]) => [key, project(entry)]))
|
|
351
|
+
};
|
|
352
|
+
const key = resolveScopeKeyCaseInsensitive(tree, params.target);
|
|
353
|
+
return {
|
|
354
|
+
tree,
|
|
355
|
+
path: key ? [key] : []
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
function resolveIrcGroupMatch(params) {
|
|
359
|
+
const { path } = resolveIrcGroupScope(params);
|
|
360
|
+
const key = path[0];
|
|
361
|
+
const groupConfig = key ? params.groups?.[key] : void 0;
|
|
362
|
+
const wildcardConfig = params.groups?.["*"];
|
|
363
|
+
return {
|
|
364
|
+
allowed: Boolean(groupConfig ?? wildcardConfig),
|
|
365
|
+
groupConfig,
|
|
366
|
+
wildcardConfig,
|
|
367
|
+
hasConfiguredGroups: Object.keys(params.groups ?? {}).length > 0
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
function resolveIrcGroupRequireMention(params) {
|
|
371
|
+
const { tree, path } = resolveIrcGroupScope(params);
|
|
372
|
+
return resolveScopeRequireMention({
|
|
373
|
+
tree,
|
|
374
|
+
path
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
function resolveIrcGroupToolPolicy(params) {
|
|
378
|
+
const { tree, path } = resolveIrcGroupScope(params);
|
|
379
|
+
return resolveScopeToolsPolicy({
|
|
380
|
+
tree,
|
|
381
|
+
path
|
|
382
|
+
});
|
|
383
|
+
}
|
|
380
384
|
// packages/normalization-core/src/utf16-slice.ts
|
|
381
385
|
function isHighSurrogate(codeUnit) {
|
|
382
386
|
return codeUnit >= 55296 && codeUnit <= 56319;
|
|
@@ -449,7 +453,6 @@ function parseIrcLine(line) {
|
|
|
449
453
|
cursor = cursor.slice(spaceIdx + 1);
|
|
450
454
|
}
|
|
451
455
|
return {
|
|
452
|
-
raw,
|
|
453
456
|
prefix,
|
|
454
457
|
command: command.toUpperCase(),
|
|
455
458
|
params,
|
|
@@ -476,8 +479,7 @@ function parseIrcPrefix(prefix) {
|
|
|
476
479
|
user
|
|
477
480
|
};
|
|
478
481
|
}
|
|
479
|
-
|
|
480
|
-
return { nick: prefix };
|
|
482
|
+
return prefix.includes(".") ? {} : { nick: prefix };
|
|
481
483
|
}
|
|
482
484
|
function sanitizeIrcOutboundText(text) {
|
|
483
485
|
return stripIrcControlChars(text.replace(/\r?\n/g, " ")).trim();
|
|
@@ -691,7 +693,6 @@ async function connectIrcClient(options) {
|
|
|
691
693
|
buffer = buffer.slice(idx + 1);
|
|
692
694
|
idx = buffer.indexOf("\n");
|
|
693
695
|
if (!rawLine) continue;
|
|
694
|
-
options.onLine?.(rawLine);
|
|
695
696
|
const line = parseIrcLine(rawLine);
|
|
696
697
|
if (!line) continue;
|
|
697
698
|
if (line.command === "PING") {
|
|
@@ -802,7 +803,6 @@ async function connectIrcClient(options) {
|
|
|
802
803
|
return currentNick;
|
|
803
804
|
},
|
|
804
805
|
isReady: () => ready && !closed,
|
|
805
|
-
sendRaw,
|
|
806
806
|
join,
|
|
807
807
|
sendPrivmsg,
|
|
808
808
|
quit,
|
|
@@ -821,16 +821,44 @@ function buildIrcConnectOptions(account, overrides = {}) {
|
|
|
821
821
|
username: account.username,
|
|
822
822
|
realname: account.realname,
|
|
823
823
|
password: account.password,
|
|
824
|
-
nickserv:
|
|
825
|
-
enabled: account.config.nickserv?.enabled,
|
|
826
|
-
service: account.config.nickserv?.service,
|
|
827
|
-
password: account.config.nickserv?.password,
|
|
828
|
-
register: account.config.nickserv?.register,
|
|
829
|
-
registerEmail: account.config.nickserv?.registerEmail
|
|
830
|
-
},
|
|
824
|
+
nickserv: account.config.nickserv,
|
|
831
825
|
...overrides
|
|
832
826
|
};
|
|
833
827
|
}
|
|
828
|
+
// extensions/irc/src/probe.ts
|
|
829
|
+
async function probeIrc(cfg, opts) {
|
|
830
|
+
const account = resolveIrcAccount({
|
|
831
|
+
cfg,
|
|
832
|
+
accountId: opts?.accountId
|
|
833
|
+
});
|
|
834
|
+
const base = {
|
|
835
|
+
ok: false,
|
|
836
|
+
host: account.host,
|
|
837
|
+
port: account.port,
|
|
838
|
+
tls: account.tls,
|
|
839
|
+
nick: account.nick
|
|
840
|
+
};
|
|
841
|
+
if (!account.configured) return {
|
|
842
|
+
...base,
|
|
843
|
+
error: "missing host or nick"
|
|
844
|
+
};
|
|
845
|
+
const started = Date.now();
|
|
846
|
+
try {
|
|
847
|
+
const client = await connectIrcClient(buildIrcConnectOptions(account, { connectTimeoutMs: opts?.timeoutMs ?? 8e3 }));
|
|
848
|
+
const elapsed = Date.now() - started;
|
|
849
|
+
client.quit("probe");
|
|
850
|
+
return {
|
|
851
|
+
...base,
|
|
852
|
+
ok: true,
|
|
853
|
+
latencyMs: elapsed
|
|
854
|
+
};
|
|
855
|
+
} catch (err) {
|
|
856
|
+
return {
|
|
857
|
+
...base,
|
|
858
|
+
error: err instanceof Error ? err.message : typeof err === "string" ? err : JSON.stringify(err)
|
|
859
|
+
};
|
|
860
|
+
}
|
|
861
|
+
}
|
|
834
862
|
// extensions/irc/src/send.ts
|
|
835
863
|
async function sendIrcMessages(to, text, opts, planMessages = (preparedText) => [{
|
|
836
864
|
text: preparedText,
|
|
@@ -855,15 +883,14 @@ async function sendIrcMessages(to, text, opts, planMessages = (preparedText) =>
|
|
|
855
883
|
if (!prepared.trim()) throw new Error("Message must be non-empty for IRC sends");
|
|
856
884
|
const messages = planMessages(prepared);
|
|
857
885
|
opts.abortSignal?.throwIfAborted();
|
|
858
|
-
|
|
859
|
-
const client = opts.client?.isReady() ? opts.client : transient = await connectIrcClient(buildIrcConnectOptions(account, {
|
|
886
|
+
const client = await connectIrcClient(buildIrcConnectOptions(account, {
|
|
860
887
|
connectTimeoutMs: 12e3,
|
|
861
888
|
abortSignal: opts.abortSignal
|
|
862
889
|
}));
|
|
863
890
|
const results = [];
|
|
864
891
|
try {
|
|
865
892
|
opts.abortSignal?.throwIfAborted();
|
|
866
|
-
if (
|
|
893
|
+
if (target.startsWith("#") || target.startsWith("&")) await effect.initiate(() => {
|
|
867
894
|
opts.abortSignal?.throwIfAborted();
|
|
868
895
|
if (!client.isReady()) throw new Error("IRC connection closed before join");
|
|
869
896
|
client.join(target);
|
|
@@ -920,7 +947,7 @@ async function sendIrcMessages(to, text, opts, planMessages = (preparedText) =>
|
|
|
920
947
|
visibleReplySent: true
|
|
921
948
|
});
|
|
922
949
|
} finally {
|
|
923
|
-
|
|
950
|
+
client.quit("sent");
|
|
924
951
|
}
|
|
925
952
|
}
|
|
926
953
|
async function sendMessageIrc(to, text, opts) {
|
|
@@ -928,136 +955,6 @@ async function sendMessageIrc(to, text, opts) {
|
|
|
928
955
|
if (!result) throw new Error("Message must be non-empty for IRC sends");
|
|
929
956
|
return result;
|
|
930
957
|
}
|
|
931
|
-
// extensions/irc/src/message-adapter.ts
|
|
932
|
-
function toIrcMessageResult({ target, ...result }) {
|
|
933
|
-
return {
|
|
934
|
-
...result,
|
|
935
|
-
target: {
|
|
936
|
-
kind: "conversation",
|
|
937
|
-
id: target
|
|
938
|
-
}
|
|
939
|
-
};
|
|
940
|
-
}
|
|
941
|
-
async function sendIrcMessage(ctx, text = ctx.text) {
|
|
942
|
-
return toIrcMessageResult(await sendMessageIrc(ctx.to, text, {
|
|
943
|
-
cfg: ctx.cfg,
|
|
944
|
-
accountId: ctx.accountId ?? void 0,
|
|
945
|
-
replyTo: ctx.replyToId ?? void 0,
|
|
946
|
-
abortSignal: ctx.signal,
|
|
947
|
-
onPlatformSendDispatch: ctx.onPlatformSendDispatch
|
|
948
|
-
}));
|
|
949
|
-
}
|
|
950
|
-
const sendFormattedIrcText = async (ctx) => {
|
|
951
|
-
const { chunkTextWithMode, resolveChunkMode, resolveTextChunkLimit } = await import("openclaw/plugin-sdk/reply-chunking");
|
|
952
|
-
const accountId = ctx.accountId ?? void 0;
|
|
953
|
-
const textLimit = ctx.formatting?.textLimit ?? resolveTextChunkLimit(ctx.cfg, "irc", accountId, { fallbackLimit: ircOutboundBaseAdapter.textChunkLimit });
|
|
954
|
-
const chunkMode = ctx.formatting?.chunkMode ?? resolveChunkMode(ctx.cfg, "irc", accountId);
|
|
955
|
-
const nextReplyToId = createReplyToFanout(ctx);
|
|
956
|
-
return (await sendIrcMessages(ctx.to, ctx.text, {
|
|
957
|
-
cfg: ctx.cfg,
|
|
958
|
-
accountId,
|
|
959
|
-
abortSignal: ctx.abortSignal,
|
|
960
|
-
onPlatformSendDispatch: ctx.onPlatformSendDispatch
|
|
961
|
-
}, (preparedText) => chunkTextWithMode(preparedText, textLimit, chunkMode).map((text) => ({
|
|
962
|
-
text,
|
|
963
|
-
replyTo: nextReplyToId()
|
|
964
|
-
})), async (result) => {
|
|
965
|
-
await ctx.onDeliveryResult?.(attachChannelToResult("irc", toIrcMessageResult(result)));
|
|
966
|
-
})).map((result) => attachChannelToResult("irc", toIrcMessageResult(result)));
|
|
967
|
-
};
|
|
968
|
-
const ircMessageAdapter = defineChannelMessageAdapter({
|
|
969
|
-
id: "irc",
|
|
970
|
-
durableFinal: { capabilities: {
|
|
971
|
-
text: true,
|
|
972
|
-
media: true,
|
|
973
|
-
replyTo: true
|
|
974
|
-
} },
|
|
975
|
-
send: {
|
|
976
|
-
text: sendIrcMessage,
|
|
977
|
-
media: (ctx) => sendIrcMessage(ctx, ctx.mediaUrl ? `${ctx.text}\n\nAttachment: ${ctx.mediaUrl}` : ctx.text)
|
|
978
|
-
}
|
|
979
|
-
});
|
|
980
|
-
// extensions/irc/src/policy.ts
|
|
981
|
-
function resolveIrcGroupScope(params) {
|
|
982
|
-
const { "*": wildcard, ...groups } = params.groups ?? {};
|
|
983
|
-
const project = (entry) => ({
|
|
984
|
-
requireMention: entry.requireMention,
|
|
985
|
-
tools: entry.tools
|
|
986
|
-
});
|
|
987
|
-
const tree = {
|
|
988
|
-
defaults: wildcard ? project(wildcard) : void 0,
|
|
989
|
-
scopes: Object.fromEntries(Object.entries(groups).map(([key, entry]) => [key, project(entry)]))
|
|
990
|
-
};
|
|
991
|
-
const key = resolveScopeKeyCaseInsensitive(tree, params.target);
|
|
992
|
-
return {
|
|
993
|
-
tree,
|
|
994
|
-
path: key ? [key] : []
|
|
995
|
-
};
|
|
996
|
-
}
|
|
997
|
-
function resolveIrcGroupMatch(params) {
|
|
998
|
-
const { path } = resolveIrcGroupScope(params);
|
|
999
|
-
const key = path[0];
|
|
1000
|
-
const groupConfig = key ? params.groups?.[key] : void 0;
|
|
1001
|
-
const wildcardConfig = params.groups?.["*"];
|
|
1002
|
-
return {
|
|
1003
|
-
allowed: Boolean(groupConfig ?? wildcardConfig),
|
|
1004
|
-
groupConfig,
|
|
1005
|
-
wildcardConfig,
|
|
1006
|
-
hasConfiguredGroups: Object.keys(params.groups ?? {}).length > 0
|
|
1007
|
-
};
|
|
1008
|
-
}
|
|
1009
|
-
function resolveIrcGroupRequireMention(params) {
|
|
1010
|
-
const { tree, path } = resolveIrcGroupScope(params);
|
|
1011
|
-
return resolveScopeRequireMention({
|
|
1012
|
-
tree,
|
|
1013
|
-
path
|
|
1014
|
-
});
|
|
1015
|
-
}
|
|
1016
|
-
function resolveIrcGroupToolPolicy(params) {
|
|
1017
|
-
const { tree, path } = resolveIrcGroupScope(params);
|
|
1018
|
-
return resolveScopeToolsPolicy({
|
|
1019
|
-
tree,
|
|
1020
|
-
path
|
|
1021
|
-
});
|
|
1022
|
-
}
|
|
1023
|
-
// extensions/irc/src/probe.ts
|
|
1024
|
-
function formatError(err) {
|
|
1025
|
-
if (err instanceof Error) return err.message;
|
|
1026
|
-
return typeof err === "string" ? err : JSON.stringify(err);
|
|
1027
|
-
}
|
|
1028
|
-
async function probeIrc(cfg, opts) {
|
|
1029
|
-
const account = resolveIrcAccount({
|
|
1030
|
-
cfg,
|
|
1031
|
-
accountId: opts?.accountId
|
|
1032
|
-
});
|
|
1033
|
-
const base = {
|
|
1034
|
-
ok: false,
|
|
1035
|
-
host: account.host,
|
|
1036
|
-
port: account.port,
|
|
1037
|
-
tls: account.tls,
|
|
1038
|
-
nick: account.nick
|
|
1039
|
-
};
|
|
1040
|
-
if (!account.configured) return {
|
|
1041
|
-
...base,
|
|
1042
|
-
error: "missing host or nick"
|
|
1043
|
-
};
|
|
1044
|
-
const started = Date.now();
|
|
1045
|
-
try {
|
|
1046
|
-
const client = await connectIrcClient(buildIrcConnectOptions(account, { connectTimeoutMs: opts?.timeoutMs ?? 8e3 }));
|
|
1047
|
-
const elapsed = Date.now() - started;
|
|
1048
|
-
client.quit("probe");
|
|
1049
|
-
return {
|
|
1050
|
-
...base,
|
|
1051
|
-
ok: true,
|
|
1052
|
-
latencyMs: elapsed
|
|
1053
|
-
};
|
|
1054
|
-
} catch (err) {
|
|
1055
|
-
return {
|
|
1056
|
-
...base,
|
|
1057
|
-
error: formatError(err)
|
|
1058
|
-
};
|
|
1059
|
-
}
|
|
1060
|
-
}
|
|
1061
958
|
// extensions/irc/src/setup-core.ts
|
|
1062
959
|
const channel$1 = "irc";
|
|
1063
960
|
const setIrcDmPolicy = createTopLevelChannelDmPolicySetter({ channel: channel$1 });
|
|
@@ -1237,67 +1134,16 @@ function normalizeGroupEntry(raw) {
|
|
|
1237
1134
|
return `#${normalized.replace(/^#+/, "")}`;
|
|
1238
1135
|
}
|
|
1239
1136
|
function parseAutoJoinChannels(value) {
|
|
1240
|
-
return splitSetupEntries(value).map(normalizeGroupEntry).filter((entry) => Boolean(entry && entry !== "*"))
|
|
1137
|
+
return splitSetupEntries(value).map(normalizeGroupEntry).filter((entry) => Boolean(entry && entry !== "*"));
|
|
1241
1138
|
}
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
noteTitle: t("wizard.irc.allowlistTitle"),
|
|
1245
|
-
noteLines: [
|
|
1139
|
+
function ircAllowlistHelpLines() {
|
|
1140
|
+
return [
|
|
1246
1141
|
t("wizard.irc.allowlistIntro"),
|
|
1247
1142
|
t("wizard.irc.examples"),
|
|
1248
1143
|
"- alice",
|
|
1249
1144
|
"- alice!ident@example.org",
|
|
1250
1145
|
t("wizard.irc.multipleEntries")
|
|
1251
|
-
]
|
|
1252
|
-
message: t("wizard.irc.allowFromPrompt"),
|
|
1253
|
-
placeholder: "alice, bob!ident@example.org",
|
|
1254
|
-
parseEntries: (raw) => ({ entries: normalizeStringEntries(splitSetupEntries(raw).map(normalizeIrcAllowEntry)) }),
|
|
1255
|
-
getExistingAllowFrom: ({ cfg }) => cfg.channels?.irc?.allowFrom ?? [],
|
|
1256
|
-
applyAllowFrom: ({ cfg, allowFrom }) => setIrcAllowFrom(cfg, allowFrom)
|
|
1257
|
-
});
|
|
1258
|
-
async function promptIrcNickServConfig(params) {
|
|
1259
|
-
const existing = resolveIrcAccount({
|
|
1260
|
-
cfg: params.cfg,
|
|
1261
|
-
accountId: params.accountId
|
|
1262
|
-
}).config.nickserv;
|
|
1263
|
-
const hasExisting = Boolean(existing?.password || existing?.passwordFile);
|
|
1264
|
-
if (!await params.prompter.confirm({
|
|
1265
|
-
message: hasExisting ? t("wizard.irc.nickServUpdatePrompt") : t("wizard.irc.nickServConfigurePrompt"),
|
|
1266
|
-
initialValue: hasExisting
|
|
1267
|
-
})) return params.cfg;
|
|
1268
|
-
const service = (await params.prompter.text({
|
|
1269
|
-
message: t("wizard.irc.nickServServicePrompt"),
|
|
1270
|
-
initialValue: existing?.service || "NickServ",
|
|
1271
|
-
validate: (value) => normalizeStringifiedOptionalString(value) ? void 0 : "Required"
|
|
1272
|
-
})).trim();
|
|
1273
|
-
const useEnvPassword = params.accountId === DEFAULT_ACCOUNT_ID$1 && Boolean(process.env.IRC_NICKSERV_PASSWORD?.trim()) && !(existing?.password || existing?.passwordFile) ? await params.prompter.confirm({
|
|
1274
|
-
message: t("wizard.irc.nickServPasswordEnvPrompt"),
|
|
1275
|
-
initialValue: true
|
|
1276
|
-
}) : false;
|
|
1277
|
-
const password = useEnvPassword ? void 0 : (await params.prompter.text({
|
|
1278
|
-
message: t("wizard.irc.nickServPasswordPrompt"),
|
|
1279
|
-
validate: () => void 0
|
|
1280
|
-
})).trim();
|
|
1281
|
-
if (!password && !useEnvPassword) return setIrcNickServ(params.cfg, params.accountId, {
|
|
1282
|
-
enabled: false,
|
|
1283
|
-
service
|
|
1284
|
-
});
|
|
1285
|
-
const register = await params.prompter.confirm({
|
|
1286
|
-
message: t("wizard.irc.nickServRegisterPrompt"),
|
|
1287
|
-
initialValue: existing?.register ?? false
|
|
1288
|
-
});
|
|
1289
|
-
const registerEmail = register ? (await params.prompter.text({
|
|
1290
|
-
message: t("wizard.irc.nickServRegisterEmailPrompt"),
|
|
1291
|
-
initialValue: existing?.registerEmail || (params.accountId === DEFAULT_ACCOUNT_ID$1 ? process.env.IRC_NICKSERV_REGISTER_EMAIL : void 0),
|
|
1292
|
-
validate: (value) => normalizeStringifiedOptionalString(value) ? void 0 : "Required"
|
|
1293
|
-
})).trim() : void 0;
|
|
1294
|
-
return setIrcNickServ(params.cfg, params.accountId, {
|
|
1295
|
-
enabled: true,
|
|
1296
|
-
service,
|
|
1297
|
-
...password ? { password } : {},
|
|
1298
|
-
register,
|
|
1299
|
-
...registerEmail ? { registerEmail } : {}
|
|
1300
|
-
});
|
|
1146
|
+
];
|
|
1301
1147
|
}
|
|
1302
1148
|
const ircDmPolicy = {
|
|
1303
1149
|
label: "IRC",
|
|
@@ -1306,7 +1152,16 @@ const ircDmPolicy = {
|
|
|
1306
1152
|
allowFromKey: "channels.irc.allowFrom",
|
|
1307
1153
|
getCurrent: (cfg) => cfg.channels?.irc?.dmPolicy ?? "pairing",
|
|
1308
1154
|
setPolicy: (cfg, policy) => setIrcDmPolicy(cfg, policy),
|
|
1309
|
-
promptAllowFrom:
|
|
1155
|
+
promptAllowFrom: createPromptParsedAllowFromForAccount({
|
|
1156
|
+
defaultAccountId: resolveDefaultIrcAccountId,
|
|
1157
|
+
noteTitle: t("wizard.irc.allowlistTitle"),
|
|
1158
|
+
noteLines: ircAllowlistHelpLines(),
|
|
1159
|
+
message: t("wizard.irc.allowFromPrompt"),
|
|
1160
|
+
placeholder: "alice, bob!ident@example.org",
|
|
1161
|
+
parseEntries: (raw) => ({ entries: normalizeStringEntries(splitSetupEntries(raw).map(normalizeIrcAllowEntry)) }),
|
|
1162
|
+
getExistingAllowFrom: ({ cfg }) => cfg.channels?.irc?.allowFrom ?? [],
|
|
1163
|
+
applyAllowFrom: ({ cfg, allowFrom }) => setIrcAllowFrom(cfg, allowFrom)
|
|
1164
|
+
})
|
|
1310
1165
|
};
|
|
1311
1166
|
const ircSetupWizard = {
|
|
1312
1167
|
channel,
|
|
@@ -1471,13 +1326,7 @@ const ircSetupWizard = {
|
|
|
1471
1326
|
},
|
|
1472
1327
|
allowFrom: createAllowFromSection({
|
|
1473
1328
|
helpTitle: t("wizard.irc.allowlistTitle"),
|
|
1474
|
-
helpLines:
|
|
1475
|
-
t("wizard.irc.allowlistIntro"),
|
|
1476
|
-
t("wizard.irc.examples"),
|
|
1477
|
-
"- alice",
|
|
1478
|
-
"- alice!ident@example.org",
|
|
1479
|
-
t("wizard.irc.multipleEntries")
|
|
1480
|
-
],
|
|
1329
|
+
helpLines: ircAllowlistHelpLines(),
|
|
1481
1330
|
message: t("wizard.irc.allowFromPrompt"),
|
|
1482
1331
|
placeholder: "alice, bob!ident@example.org",
|
|
1483
1332
|
invalidWithoutCredentialNote: t("wizard.irc.allowFromInvalid"),
|
|
@@ -1507,11 +1356,51 @@ const ircSetupWizard = {
|
|
|
1507
1356
|
}
|
|
1508
1357
|
}
|
|
1509
1358
|
}
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1359
|
+
const nickServConfig = next;
|
|
1360
|
+
next = await (async () => {
|
|
1361
|
+
const existing = resolveIrcAccount({
|
|
1362
|
+
cfg: nickServConfig,
|
|
1363
|
+
accountId
|
|
1364
|
+
}).config.nickserv;
|
|
1365
|
+
const hasExisting = Boolean(existing?.password || existing?.passwordFile);
|
|
1366
|
+
if (!await prompter.confirm({
|
|
1367
|
+
message: hasExisting ? t("wizard.irc.nickServUpdatePrompt") : t("wizard.irc.nickServConfigurePrompt"),
|
|
1368
|
+
initialValue: hasExisting
|
|
1369
|
+
})) return nickServConfig;
|
|
1370
|
+
const service = (await prompter.text({
|
|
1371
|
+
message: t("wizard.irc.nickServServicePrompt"),
|
|
1372
|
+
initialValue: existing?.service || "NickServ",
|
|
1373
|
+
validate: (value) => normalizeStringifiedOptionalString(value) ? void 0 : "Required"
|
|
1374
|
+
})).trim();
|
|
1375
|
+
const useEnvPassword = accountId === DEFAULT_ACCOUNT_ID$1 && Boolean(process.env.IRC_NICKSERV_PASSWORD?.trim()) && !(existing?.password || existing?.passwordFile) ? await prompter.confirm({
|
|
1376
|
+
message: t("wizard.irc.nickServPasswordEnvPrompt"),
|
|
1377
|
+
initialValue: true
|
|
1378
|
+
}) : false;
|
|
1379
|
+
const password = useEnvPassword ? void 0 : (await prompter.text({
|
|
1380
|
+
message: t("wizard.irc.nickServPasswordPrompt"),
|
|
1381
|
+
validate: () => void 0
|
|
1382
|
+
})).trim();
|
|
1383
|
+
if (!password && !useEnvPassword) return setIrcNickServ(nickServConfig, accountId, {
|
|
1384
|
+
enabled: false,
|
|
1385
|
+
service
|
|
1386
|
+
});
|
|
1387
|
+
const register = await prompter.confirm({
|
|
1388
|
+
message: t("wizard.irc.nickServRegisterPrompt"),
|
|
1389
|
+
initialValue: existing?.register ?? false
|
|
1390
|
+
});
|
|
1391
|
+
const registerEmail = register ? (await prompter.text({
|
|
1392
|
+
message: t("wizard.irc.nickServRegisterEmailPrompt"),
|
|
1393
|
+
initialValue: existing?.registerEmail || (accountId === DEFAULT_ACCOUNT_ID$1 ? process.env.IRC_NICKSERV_REGISTER_EMAIL : void 0),
|
|
1394
|
+
validate: (value) => normalizeStringifiedOptionalString(value) ? void 0 : "Required"
|
|
1395
|
+
})).trim() : void 0;
|
|
1396
|
+
return setIrcNickServ(nickServConfig, accountId, {
|
|
1397
|
+
enabled: true,
|
|
1398
|
+
service,
|
|
1399
|
+
...password ? { password } : {},
|
|
1400
|
+
register,
|
|
1401
|
+
...registerEmail ? { registerEmail } : {}
|
|
1402
|
+
});
|
|
1403
|
+
})();
|
|
1515
1404
|
return { cfg: next };
|
|
1516
1405
|
},
|
|
1517
1406
|
completionNote: {
|
|
@@ -1526,6 +1415,73 @@ const ircSetupWizard = {
|
|
|
1526
1415
|
disable: (cfg) => setSetupChannelEnabled(cfg, channel, false)
|
|
1527
1416
|
};
|
|
1528
1417
|
// extensions/irc/src/channel.ts
|
|
1418
|
+
function ircAccountDetails(account) {
|
|
1419
|
+
return {
|
|
1420
|
+
host: account.host,
|
|
1421
|
+
port: account.port,
|
|
1422
|
+
tls: account.tls,
|
|
1423
|
+
nick: account.nick,
|
|
1424
|
+
passwordSource: account.passwordSource,
|
|
1425
|
+
tokenStatus: account.tokenStatus
|
|
1426
|
+
};
|
|
1427
|
+
}
|
|
1428
|
+
function toIrcMessageResult({ target, ...result }) {
|
|
1429
|
+
return {
|
|
1430
|
+
...result,
|
|
1431
|
+
target: {
|
|
1432
|
+
kind: "conversation",
|
|
1433
|
+
id: target
|
|
1434
|
+
}
|
|
1435
|
+
};
|
|
1436
|
+
}
|
|
1437
|
+
async function sendIrcMessage(ctx, text = ctx.text) {
|
|
1438
|
+
return toIrcMessageResult(await sendMessageIrc(ctx.to, text, {
|
|
1439
|
+
cfg: ctx.cfg,
|
|
1440
|
+
accountId: ctx.accountId ?? void 0,
|
|
1441
|
+
replyTo: ctx.replyToId ?? void 0,
|
|
1442
|
+
abortSignal: ctx.signal,
|
|
1443
|
+
onPlatformSendDispatch: ctx.onPlatformSendDispatch
|
|
1444
|
+
}));
|
|
1445
|
+
}
|
|
1446
|
+
const sendFormattedIrcText = async (ctx) => {
|
|
1447
|
+
const { chunkTextWithMode, resolveChunkMode, resolveTextChunkLimit } = await import("openclaw/plugin-sdk/reply-chunking");
|
|
1448
|
+
const accountId = ctx.accountId ?? void 0;
|
|
1449
|
+
const textLimit = ctx.formatting?.textLimit ?? resolveTextChunkLimit(ctx.cfg, "irc", accountId, { fallbackLimit: ircOutboundBaseAdapter.textChunkLimit });
|
|
1450
|
+
const chunkMode = ctx.formatting?.chunkMode ?? resolveChunkMode(ctx.cfg, "irc", accountId);
|
|
1451
|
+
const nextReplyToId = createReplyToFanout(ctx);
|
|
1452
|
+
return (await sendIrcMessages(ctx.to, ctx.text, {
|
|
1453
|
+
cfg: ctx.cfg,
|
|
1454
|
+
accountId,
|
|
1455
|
+
abortSignal: ctx.abortSignal,
|
|
1456
|
+
onPlatformSendDispatch: ctx.onPlatformSendDispatch
|
|
1457
|
+
}, (preparedText) => chunkTextWithMode(preparedText, textLimit, chunkMode).map((text) => ({
|
|
1458
|
+
text,
|
|
1459
|
+
replyTo: nextReplyToId()
|
|
1460
|
+
})), async (result) => {
|
|
1461
|
+
await ctx.onDeliveryResult?.(attachChannelToResult("irc", toIrcMessageResult(result)));
|
|
1462
|
+
})).map((result) => attachChannelToResult("irc", toIrcMessageResult(result)));
|
|
1463
|
+
};
|
|
1464
|
+
const ircMessageAdapter = defineChannelMessageAdapter({
|
|
1465
|
+
id: "irc",
|
|
1466
|
+
durableFinal: { capabilities: {
|
|
1467
|
+
text: true,
|
|
1468
|
+
media: true,
|
|
1469
|
+
replyTo: true
|
|
1470
|
+
} },
|
|
1471
|
+
send: {
|
|
1472
|
+
text: sendIrcMessage,
|
|
1473
|
+
media: (ctx) => sendIrcMessage(ctx, ctx.mediaUrl ? `${ctx.text}\n\nAttachment: ${ctx.mediaUrl}` : ctx.text)
|
|
1474
|
+
}
|
|
1475
|
+
});
|
|
1476
|
+
const isIrcMutableAllowEntry = buildMutableAllowEntryDetector({ stableIdPattern: /^(?:(?:irc|user):)*[^@]*@/i });
|
|
1477
|
+
const collectIrcMutableAllowlistWarnings = createDangerousNameMatchingMutableAllowlistWarningCollector({
|
|
1478
|
+
channel: "irc",
|
|
1479
|
+
detector: isIrcMutableAllowEntry,
|
|
1480
|
+
collectLists: (scope) => collectStandardAllowlistLists(scope, {
|
|
1481
|
+
includeGroups: true,
|
|
1482
|
+
groupField: "allowFrom"
|
|
1483
|
+
})
|
|
1484
|
+
});
|
|
1529
1485
|
const meta = {
|
|
1530
1486
|
id: "irc",
|
|
1531
1487
|
label: "IRC",
|
|
@@ -1641,14 +1597,7 @@ const ircPlugin = createChatChannelPlugin({
|
|
|
1641
1597
|
describeAccount: (account) => describeAccountSnapshot({
|
|
1642
1598
|
account,
|
|
1643
1599
|
configured: account.configured,
|
|
1644
|
-
extra:
|
|
1645
|
-
host: account.host,
|
|
1646
|
-
port: account.port,
|
|
1647
|
-
tls: account.tls,
|
|
1648
|
-
nick: account.nick,
|
|
1649
|
-
passwordSource: account.passwordSource,
|
|
1650
|
-
tokenStatus: account.tokenStatus
|
|
1651
|
-
}
|
|
1600
|
+
extra: ircAccountDetails(account)
|
|
1652
1601
|
})
|
|
1653
1602
|
},
|
|
1654
1603
|
secrets: {
|
|
@@ -1751,20 +1700,29 @@ const ircPlugin = createChatChannelPlugin({
|
|
|
1751
1700
|
name: account.name,
|
|
1752
1701
|
enabled: account.enabled,
|
|
1753
1702
|
configured: account.configured,
|
|
1754
|
-
extra:
|
|
1755
|
-
host: account.host,
|
|
1756
|
-
port: account.port,
|
|
1757
|
-
tls: account.tls,
|
|
1758
|
-
nick: account.nick,
|
|
1759
|
-
passwordSource: account.passwordSource,
|
|
1760
|
-
tokenStatus: account.tokenStatus
|
|
1761
|
-
}
|
|
1703
|
+
extra: ircAccountDetails(account)
|
|
1762
1704
|
})
|
|
1763
1705
|
}),
|
|
1764
|
-
gateway: { startAccount: async (ctx) =>
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1706
|
+
gateway: { startAccount: async (ctx) => {
|
|
1707
|
+
const account = ctx.account;
|
|
1708
|
+
const statusSink = createAccountStatusSink(ctx);
|
|
1709
|
+
if (!account.configured) throw new Error(`IRC is not configured for account "${account.accountId}" (need host and nick in channels.irc).`);
|
|
1710
|
+
ctx.log?.info?.(`[${account.accountId}] starting IRC provider (${account.host}:${account.port}${account.tls ? " tls" : ""})`);
|
|
1711
|
+
const { monitorIrcProvider } = await import("./channel-runtime-D2sqTm8e.mjs");
|
|
1712
|
+
await runPassiveAccountLifecycle({
|
|
1713
|
+
abortSignal: ctx.abortSignal,
|
|
1714
|
+
start: async () => await monitorIrcProvider({
|
|
1715
|
+
accountId: account.accountId,
|
|
1716
|
+
config: ctx.cfg,
|
|
1717
|
+
runtime: ctx.runtime,
|
|
1718
|
+
abortSignal: ctx.abortSignal,
|
|
1719
|
+
statusSink
|
|
1720
|
+
}),
|
|
1721
|
+
stop: async (monitor) => {
|
|
1722
|
+
await monitor.stop();
|
|
1723
|
+
}
|
|
1724
|
+
});
|
|
1725
|
+
} }
|
|
1768
1726
|
},
|
|
1769
1727
|
pairing: { text: {
|
|
1770
1728
|
idLabel: "ircUser",
|
|
@@ -1773,7 +1731,7 @@ const ircPlugin = createChatChannelPlugin({
|
|
|
1773
1731
|
notify: async ({ cfg, id, message, accountId }) => {
|
|
1774
1732
|
const target = normalizePairingTarget(id);
|
|
1775
1733
|
if (!target) throw new Error(`invalid IRC pairing id: ${id}`);
|
|
1776
|
-
const { sendMessageIrc } = await import("./channel-runtime-
|
|
1734
|
+
const { sendMessageIrc } = await import("./channel-runtime-D2sqTm8e.mjs");
|
|
1777
1735
|
await sendMessageIrc(target, message, {
|
|
1778
1736
|
cfg,
|
|
1779
1737
|
accountId
|
|
@@ -1799,4 +1757,4 @@ const ircPlugin = createChatChannelPlugin({
|
|
|
1799
1757
|
}
|
|
1800
1758
|
}
|
|
1801
1759
|
});
|
|
1802
|
-
export { listIrcAccountIds as _,
|
|
1760
|
+
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 };
|