@openclaw/buzz 2026.10.1-beta.2 → 2026.10.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/{adapter.runtime-DE9Zjy2H.mjs → adapter.runtime-Diltpvcm.mjs} +4 -8
- package/dist/.setup/{channel-BbJ5DvVO.mjs → channel-Ba25iqfd.mjs} +46 -41
- package/dist/.setup/{message-event-X_aBiM1X.mjs → message-event-Do0ixXJ6.mjs} +21 -43
- package/dist/.setup/{room-membership-CDDvS9rG.mjs → room-membership-F-VBtTXf.mjs} +5 -10
- package/dist/.setup/setup-plugin-api-DOqDYVDO.mjs +2 -0
- package/dist/.setup/{setup-plugin-api-1zcpIc0A.mjs → setup-plugin-api-mJRSnC3g.mjs} +1 -1
- package/dist/.setup/{setup-surface-D3hfsPy6.mjs → setup-surface-CtPEPYrT.mjs} +178 -199
- package/dist/api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/qa-runner-api.js +1 -1
- package/dist/setup-entry.js +1 -1
- package/dist/setup-plugin-api.js +1 -1
- package/package.json +4 -4
- package/dist/.setup/setup-plugin-api-ebTNvTyI.mjs +0 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { m as parseBuzzTarget, n as decodeBuzzPrivateKey, o as resolveBuzzPublicKey, u as buildBuzzTarget } from "./types-DRUZMyTx.mjs";
|
|
2
|
-
import { c as openBuzzRelaySubscription, i as parseBuzzRoomMembershipEvent, l as queryBuzzRelaySnapshot, m as isNewerBuzzRevision, o as connectAuthenticatedBuzzRelaySession, s as parseBuzzAuthTag, t as BUZZ_ROOM_MEMBERSHIP_KIND } from "./room-membership-
|
|
3
|
-
import { i as buildBuzzMessageTags, s as parseBuzzMessageEvent } from "./message-event-
|
|
2
|
+
import { c as openBuzzRelaySubscription, i as parseBuzzRoomMembershipEvent, l as queryBuzzRelaySnapshot, m as isNewerBuzzRevision, o as connectAuthenticatedBuzzRelaySession, s as parseBuzzAuthTag, t as BUZZ_ROOM_MEMBERSHIP_KIND } from "./room-membership-F-VBtTXf.mjs";
|
|
3
|
+
import { i as buildBuzzMessageTags, s as parseBuzzMessageEvent } from "./message-event-Do0ixXJ6.mjs";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
import { finalizeEvent } from "nostr-tools";
|
|
6
6
|
import { isLoopbackHost } from "openclaw/plugin-sdk/ssrf-runtime";
|
|
@@ -10,12 +10,8 @@ import fs from "node:fs/promises";
|
|
|
10
10
|
import path from "node:path";
|
|
11
11
|
//#region extensions/buzz/src/qa/credentials.ts
|
|
12
12
|
function isSafeBuzzQaRelayUrl(value) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
return relayUrl.protocol === "wss:" || relayUrl.protocol === "ws:" && isLoopbackHost(relayUrl.hostname);
|
|
16
|
-
} catch {
|
|
17
|
-
return false;
|
|
18
|
-
}
|
|
13
|
+
const relayUrl = URL.parse(value);
|
|
14
|
+
return relayUrl?.protocol === "wss:" || relayUrl?.protocol === "ws:" && isLoopbackHost(relayUrl.hostname);
|
|
19
15
|
}
|
|
20
16
|
const buzzQaCredentialPayloadSchema = z.object({
|
|
21
17
|
relayUrl: z.string().url().refine(isSafeBuzzQaRelayUrl),
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { a as resolveBuzzAccountConfig, c as BuzzConfigSchema, d as isConfiguredBuzzChannel, f as looksLikeBuzzTarget, i as resolveBuzzAccount, m as parseBuzzTarget, n as decodeBuzzPrivateKey, o as resolveBuzzPublicKey, p as normalizeBuzzTarget, r as listBuzzAccountIds, s as resolveDefaultBuzzAccountId, t as assertBuzzAccountAvailable, u as buildBuzzTarget } from "./types-DRUZMyTx.mjs";
|
|
2
2
|
import { n as listBuzzDirectoryPeersFromConfig, t as listBuzzDirectoryGroupsFromConfig } from "./directory-config-M9KSexdh.mjs";
|
|
3
|
-
import { a as connectAuthenticatedBuzzRelay, c as openBuzzRelaySubscription, d as resolveBuzzSubscriptionBudget, f as BUZZ_ROOM_METADATA_KIND, i as parseBuzzRoomMembershipEvent, l as queryBuzzRelaySnapshot, m as isNewerBuzzRevision, n as BUZZ_ROOM_SYSTEM_KIND, o as connectAuthenticatedBuzzRelaySession, p as BuzzDirectoryState, r as parseBuzzRoomMembershipChangeEvent, s as parseBuzzAuthTag, t as BUZZ_ROOM_MEMBERSHIP_KIND, u as BUZZ_MAX_CONFIGURED_ROOMS } from "./room-membership-
|
|
4
|
-
import { a as formatBuzzMessageForAgent, c as inspectBuzzMentionSyntax, i as buildBuzzMessageTags, l as resolveBuzzMessageMentions, n as BUZZ_INBOUND_MESSAGE_KINDS, o as isBuzzInboundMessageKind, r as BUZZ_TYPING_INDICATOR_KIND, s as parseBuzzMessageEvent, t as BUZZ_DIFF_MESSAGE_KIND } from "./message-event-
|
|
5
|
-
import { i as startBuzzRoomMembershipNotifications, n as buzzSetupContract, r as discoverBuzzRooms, t as buzzSetupWizard } from "./setup-surface-
|
|
3
|
+
import { a as connectAuthenticatedBuzzRelay, c as openBuzzRelaySubscription, d as resolveBuzzSubscriptionBudget, f as BUZZ_ROOM_METADATA_KIND, i as parseBuzzRoomMembershipEvent, l as queryBuzzRelaySnapshot, m as isNewerBuzzRevision, n as BUZZ_ROOM_SYSTEM_KIND, o as connectAuthenticatedBuzzRelaySession, p as BuzzDirectoryState, r as parseBuzzRoomMembershipChangeEvent, s as parseBuzzAuthTag, t as BUZZ_ROOM_MEMBERSHIP_KIND, u as BUZZ_MAX_CONFIGURED_ROOMS } from "./room-membership-F-VBtTXf.mjs";
|
|
4
|
+
import { a as formatBuzzMessageForAgent, c as inspectBuzzMentionSyntax, i as buildBuzzMessageTags, l as resolveBuzzMessageMentions, n as BUZZ_INBOUND_MESSAGE_KINDS, o as isBuzzInboundMessageKind, r as BUZZ_TYPING_INDICATOR_KIND, s as parseBuzzMessageEvent, t as BUZZ_DIFF_MESSAGE_KIND } from "./message-event-Do0ixXJ6.mjs";
|
|
5
|
+
import { i as startBuzzRoomMembershipNotifications, n as buzzSetupContract, r as discoverBuzzRooms, t as buzzSetupWizard } from "./setup-surface-CtPEPYrT.mjs";
|
|
6
6
|
import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-B2-Mrm4v.mjs";
|
|
7
7
|
import { describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
|
|
8
8
|
import { buildChannelOutboundSessionRoute, buildThreadAwareOutboundSessionRoute, createChatChannelPlugin } from "openclaw/plugin-sdk/channel-core";
|
|
9
9
|
import { createChannelMessageAdapterFromOutbound, waitUntilAbort } from "openclaw/plugin-sdk/channel-outbound";
|
|
10
10
|
import { createChannelDirectoryAdapter } from "openclaw/plugin-sdk/directory-runtime";
|
|
11
|
-
import { parseThreadSessionSuffix } from "openclaw/plugin-sdk/routing";
|
|
11
|
+
import { parseThreadSessionSuffix, resolveAgentRoute } from "openclaw/plugin-sdk/routing";
|
|
12
12
|
import { createComputedAccountStatusAdapter, createDefaultChannelRuntimeState } from "openclaw/plugin-sdk/status-helpers";
|
|
13
13
|
import { compareEvents, finalizeEvent, verifyEvent } from "nostr-tools";
|
|
14
14
|
import { asNonArrayRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
@@ -18,11 +18,12 @@ import { attachChannelToResult } from "openclaw/plugin-sdk/channel-send-result";
|
|
|
18
18
|
import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
|
|
19
19
|
import { channelReadyPatch } from "openclaw/plugin-sdk/gateway-runtime";
|
|
20
20
|
import { computeBackoff, sleepWithAbort } from "openclaw/plugin-sdk/runtime-env";
|
|
21
|
+
import { captureEffectAuthority } from "openclaw/plugin-sdk/fetch-runtime";
|
|
21
22
|
import { createChannelReplayGuard } from "openclaw/plugin-sdk/persistent-dedupe";
|
|
22
23
|
import { createDeferred as createDeferred$1 } from "openclaw/plugin-sdk/concurrency-runtime";
|
|
23
24
|
import { createAsyncLock } from "openclaw/plugin-sdk/async-lock-runtime";
|
|
24
25
|
import { normalizeURL } from "nostr-tools/utils";
|
|
25
|
-
import { buildChannelInboundEventContext, logInboundDrop, recordDroppedChannelInboundHistory
|
|
26
|
+
import { buildChannelInboundEventContext, createChannelInboundEnvelopeBuilderAsync, logInboundDrop, recordDroppedChannelInboundHistory } from "openclaw/plugin-sdk/channel-inbound";
|
|
26
27
|
import { createSubsystemLogger } from "openclaw/plugin-sdk/logging-core";
|
|
27
28
|
import { buildHistoryContext, createChannelHistoryWindow } from "openclaw/plugin-sdk/reply-history";
|
|
28
29
|
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";
|
|
@@ -63,7 +64,6 @@ async function queryBuzzDirectoryProfiles(params) {
|
|
|
63
64
|
onEvent: (event) => {
|
|
64
65
|
params.state.applyProfileEvent(event);
|
|
65
66
|
},
|
|
66
|
-
onTimeout: params.onTimeout,
|
|
67
67
|
signal: params.signal
|
|
68
68
|
});
|
|
69
69
|
}
|
|
@@ -238,10 +238,21 @@ function hasConfiguredAuthTag(event, authTag) {
|
|
|
238
238
|
const authTags = event?.tags.filter((tag) => tag[0] === "auth") ?? [];
|
|
239
239
|
return authTags.length === 1 && JSON.stringify(authTags[0]) === JSON.stringify(authTag);
|
|
240
240
|
}
|
|
241
|
-
|
|
241
|
+
function buildProfileEvent(params) {
|
|
242
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
243
|
+
return finalizeEvent({
|
|
244
|
+
kind: params.kind,
|
|
245
|
+
content: JSON.stringify(params.content),
|
|
246
|
+
created_at: params.current ? Math.max(now, params.current.created_at + 1) : now,
|
|
247
|
+
tags: params.tags
|
|
248
|
+
}, params.secretKey);
|
|
249
|
+
}
|
|
250
|
+
async function syncBuzzProfile(params) {
|
|
251
|
+
const displayName = params.displayName.trim();
|
|
252
|
+
if (!displayName) return;
|
|
242
253
|
params.signal?.throwIfAborted();
|
|
243
|
-
const
|
|
244
|
-
|
|
254
|
+
const currentProfiles = /* @__PURE__ */ new Map();
|
|
255
|
+
await queryBuzzRelaySnapshot({
|
|
245
256
|
relay: params.relay,
|
|
246
257
|
filters: [{
|
|
247
258
|
kinds: [PROFILE_KIND],
|
|
@@ -259,27 +270,10 @@ async function queryCurrentProfiles(params) {
|
|
|
259
270
|
closeReason: "profile query complete",
|
|
260
271
|
closeMessage: (reason) => `Buzz profile query closed: ${reason}`,
|
|
261
272
|
onEvent: (event) => {
|
|
262
|
-
const current =
|
|
263
|
-
if (!current || compareEvents(event, current) < 0)
|
|
273
|
+
const current = currentProfiles.get(event.kind);
|
|
274
|
+
if (!current || compareEvents(event, current) < 0) currentProfiles.set(event.kind, event);
|
|
264
275
|
},
|
|
265
|
-
result: () =>
|
|
266
|
-
onTimeout: params.onTimeout
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
function buildProfileEvent(params) {
|
|
270
|
-
const now = Math.floor(Date.now() / 1e3);
|
|
271
|
-
return finalizeEvent({
|
|
272
|
-
kind: params.kind,
|
|
273
|
-
content: JSON.stringify(params.content),
|
|
274
|
-
created_at: params.current ? Math.max(now, params.current.created_at + 1) : now,
|
|
275
|
-
tags: params.tags
|
|
276
|
-
}, params.secretKey);
|
|
277
|
-
}
|
|
278
|
-
async function syncBuzzProfile(params) {
|
|
279
|
-
const displayName = params.displayName.trim();
|
|
280
|
-
if (!displayName) return { status: "unchanged" };
|
|
281
|
-
const currentProfiles = await queryCurrentProfiles({
|
|
282
|
-
...params,
|
|
276
|
+
result: () => currentProfiles,
|
|
283
277
|
onTimeout: params.onFatalError
|
|
284
278
|
});
|
|
285
279
|
params.signal?.throwIfAborted();
|
|
@@ -320,16 +314,13 @@ async function syncBuzzProfile(params) {
|
|
|
320
314
|
secretKey: params.secretKey
|
|
321
315
|
}));
|
|
322
316
|
const lastEvent = events.at(-1);
|
|
323
|
-
if (!lastEvent) return
|
|
317
|
+
if (!lastEvent) return;
|
|
324
318
|
for (const event of events) {
|
|
325
319
|
params.signal?.throwIfAborted();
|
|
326
320
|
await params.relay.publish(event);
|
|
327
321
|
}
|
|
328
322
|
params.signal?.throwIfAborted();
|
|
329
|
-
return
|
|
330
|
-
status: "published",
|
|
331
|
-
eventId: lastEvent.id
|
|
332
|
-
};
|
|
323
|
+
return lastEvent.id;
|
|
333
324
|
}
|
|
334
325
|
//#endregion
|
|
335
326
|
//#region extensions/buzz/src/replay-dispatch.ts
|
|
@@ -973,6 +964,7 @@ function buildBuzzTextEvent(params) {
|
|
|
973
964
|
}, params.secretKey);
|
|
974
965
|
}
|
|
975
966
|
async function sendBuzzTextOneShot(params) {
|
|
967
|
+
const effect = captureEffectAuthority();
|
|
976
968
|
const secretKey = decodeBuzzPrivateKey(params.privateKey);
|
|
977
969
|
const mentionSyntax = inspectBuzzMentionSyntax(params.text);
|
|
978
970
|
const needsDirectory = mentionSyntax.hasAtMention || mentionSyntax.hasExplicitIdentity;
|
|
@@ -1019,7 +1011,10 @@ async function sendBuzzTextOneShot(params) {
|
|
|
1019
1011
|
secretKey,
|
|
1020
1012
|
mentionedPubkeys
|
|
1021
1013
|
});
|
|
1022
|
-
await
|
|
1014
|
+
await effect.initiate(() => {
|
|
1015
|
+
signal?.throwIfAborted();
|
|
1016
|
+
return relay.publish(event);
|
|
1017
|
+
});
|
|
1023
1018
|
return event.id;
|
|
1024
1019
|
} finally {
|
|
1025
1020
|
relay.close();
|
|
@@ -1125,6 +1120,7 @@ async function startBuzzBus(options) {
|
|
|
1125
1120
|
return root?.channelId === channelId && root.isBotOwned;
|
|
1126
1121
|
},
|
|
1127
1122
|
sendText: async ({ channelId, text, threadId, replyToId }) => {
|
|
1123
|
+
const effect = captureEffectAuthority();
|
|
1128
1124
|
signal.throwIfAborted();
|
|
1129
1125
|
const mentionSyntax = inspectBuzzMentionSyntax(text);
|
|
1130
1126
|
const mentionedPubkeys = mentionSyntax.hasAtMention || mentionSyntax.hasExplicitIdentity ? resolveBuzzMessageMentions({
|
|
@@ -1140,7 +1136,10 @@ async function startBuzzBus(options) {
|
|
|
1140
1136
|
replyToId,
|
|
1141
1137
|
mentionedPubkeys
|
|
1142
1138
|
});
|
|
1143
|
-
await
|
|
1139
|
+
await effect.initiate(() => {
|
|
1140
|
+
signal.throwIfAborted();
|
|
1141
|
+
return relay.publish(event);
|
|
1142
|
+
});
|
|
1144
1143
|
rememberThreadRoot(event);
|
|
1145
1144
|
return event.id;
|
|
1146
1145
|
},
|
|
@@ -1156,7 +1155,10 @@ async function startBuzzBus(options) {
|
|
|
1156
1155
|
replyToId
|
|
1157
1156
|
})
|
|
1158
1157
|
}, secretKey);
|
|
1159
|
-
await
|
|
1158
|
+
await captureEffectAuthority().initiate(() => {
|
|
1159
|
+
signal.throwIfAborted();
|
|
1160
|
+
return relay.send(JSON.stringify(["EVENT", event]));
|
|
1161
|
+
});
|
|
1160
1162
|
},
|
|
1161
1163
|
close: async () => {
|
|
1162
1164
|
lifecycleAbort.abort(/* @__PURE__ */ new Error("Buzz bus closed"));
|
|
@@ -1282,8 +1284,8 @@ async function startBuzzBus(options) {
|
|
|
1282
1284
|
authTag,
|
|
1283
1285
|
onFatalError: reportFatalError,
|
|
1284
1286
|
signal
|
|
1285
|
-
}).then((
|
|
1286
|
-
if (!signal.aborted &&
|
|
1287
|
+
}).then((eventId) => {
|
|
1288
|
+
if (!signal.aborted && eventId !== void 0) options.onProfilePublished?.(eventId);
|
|
1287
1289
|
}).catch((error) => {
|
|
1288
1290
|
if (signal.aborted) return;
|
|
1289
1291
|
options.onProfileError?.(error instanceof Error ? error : new Error("Buzz profile sync failed", { cause: error }));
|
|
@@ -1386,7 +1388,7 @@ async function handleBuzzInbound(params) {
|
|
|
1386
1388
|
const channelId = parseBuzzTarget(message.channelId);
|
|
1387
1389
|
const target = buildBuzzTarget(channelId);
|
|
1388
1390
|
const textForAgent = formatBuzzMessageForAgent(message);
|
|
1389
|
-
const
|
|
1391
|
+
const route = resolveAgentRoute({
|
|
1390
1392
|
cfg,
|
|
1391
1393
|
channel: "buzz",
|
|
1392
1394
|
accountId: account.accountId,
|
|
@@ -1482,7 +1484,10 @@ async function handleBuzzInbound(params) {
|
|
|
1482
1484
|
});
|
|
1483
1485
|
const senderName = bus.directory.resolveSenderName(message.senderPubkey);
|
|
1484
1486
|
const roomName = bus.directory.resolveRoomName(channelId);
|
|
1485
|
-
const body =
|
|
1487
|
+
const body = (await createChannelInboundEnvelopeBuilderAsync({
|
|
1488
|
+
cfg,
|
|
1489
|
+
route
|
|
1490
|
+
}))({
|
|
1486
1491
|
channel: "Buzz",
|
|
1487
1492
|
from: senderName,
|
|
1488
1493
|
timestamp: /* @__PURE__ */ new Date(message.createdAt * 1e3),
|
|
@@ -3,8 +3,6 @@ import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
|
3
3
|
import { Buffer } from "node:buffer";
|
|
4
4
|
const BUZZ_AMBIGUITY_CANDIDATE_LIMIT = 5;
|
|
5
5
|
const HEX_PUBLIC_KEY_PATTERN$1 = /^[0-9a-f]{64}$/u;
|
|
6
|
-
const NIP_27_PREFIX = "nostr:npub1";
|
|
7
|
-
const NPUB_LENGTH = 63;
|
|
8
6
|
function asciiLowercase(value) {
|
|
9
7
|
return value.replace(/[A-Z]/gu, (character) => character.toLowerCase());
|
|
10
8
|
}
|
|
@@ -58,31 +56,18 @@ function stripCodeRegions(content) {
|
|
|
58
56
|
return output;
|
|
59
57
|
}
|
|
60
58
|
function extractNostrPubkeys(content) {
|
|
61
|
-
const publicKeys =
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const
|
|
66
|
-
if (
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
searchFrom = start + 11;
|
|
70
|
-
if (candidate.length !== NPUB_LENGTH || !/^[0-9a-z]+$/iu.test(candidate)) continue;
|
|
71
|
-
try {
|
|
72
|
-
const decoded = nip19.decode(asciiLowercase(candidate));
|
|
73
|
-
if (decoded.type !== "npub" || typeof decoded.data !== "string") continue;
|
|
74
|
-
const publicKey = decoded.data.toLowerCase();
|
|
75
|
-
if (HEX_PUBLIC_KEY_PATTERN$1.test(publicKey) && !seen.has(publicKey)) {
|
|
76
|
-
seen.add(publicKey);
|
|
77
|
-
publicKeys.push(publicKey);
|
|
78
|
-
}
|
|
79
|
-
} catch {}
|
|
80
|
-
}
|
|
81
|
-
return publicKeys;
|
|
59
|
+
const publicKeys = /* @__PURE__ */ new Set();
|
|
60
|
+
for (const match of content.matchAll(/nostr:npub1[0-9a-zA-Z]{58}/gu)) try {
|
|
61
|
+
const decoded = nip19.decode(asciiLowercase(match[0].slice(6)));
|
|
62
|
+
if (decoded.type !== "npub" || typeof decoded.data !== "string") continue;
|
|
63
|
+
const publicKey = decoded.data.toLowerCase();
|
|
64
|
+
if (HEX_PUBLIC_KEY_PATTERN$1.test(publicKey)) publicKeys.add(publicKey);
|
|
65
|
+
} catch {}
|
|
66
|
+
return [...publicKeys];
|
|
82
67
|
}
|
|
83
68
|
function extractMentionNames(content, knownNames) {
|
|
84
69
|
if (!content.includes("@")) return [];
|
|
85
|
-
const sortedNames = knownNames.
|
|
70
|
+
const sortedNames = knownNames.toSorted((left, right) => right.length - left.length);
|
|
86
71
|
const names = [];
|
|
87
72
|
const seen = /* @__PURE__ */ new Set();
|
|
88
73
|
for (let index = 0; index < content.length; index += 1) {
|
|
@@ -103,8 +88,7 @@ function extractMentionNames(content, knownNames) {
|
|
|
103
88
|
return names;
|
|
104
89
|
}
|
|
105
90
|
function hasAtMentionCandidate(content) {
|
|
106
|
-
|
|
107
|
-
return false;
|
|
91
|
+
return /(?:^|[\t-\r ])@[^\t-\r ]/u.test(content);
|
|
108
92
|
}
|
|
109
93
|
function normalizeMembers(members) {
|
|
110
94
|
const normalized = /* @__PURE__ */ new Map();
|
|
@@ -128,12 +112,12 @@ function inspectBuzzMentionSyntax(text) {
|
|
|
128
112
|
function resolveBuzzMessageMentions(params) {
|
|
129
113
|
const stripped = stripCodeRegions(params.text);
|
|
130
114
|
const explicitPublicKeys = extractNostrPubkeys(stripped);
|
|
131
|
-
|
|
115
|
+
const hasAtMention = hasAtMentionCandidate(stripped);
|
|
116
|
+
if (!hasAtMention && explicitPublicKeys.length === 0) return [];
|
|
132
117
|
if (!params.members) throw new Error("Buzz room membership is unavailable; retry after the room directory loads");
|
|
133
118
|
const members = normalizeMembers(params.members);
|
|
134
119
|
const senderPublicKey = params.senderPublicKey.trim().toLowerCase();
|
|
135
|
-
const mentions =
|
|
136
|
-
for (const publicKey of explicitPublicKeys) if (publicKey !== senderPublicKey && !mentions.includes(publicKey)) mentions.push(publicKey);
|
|
120
|
+
const mentions = explicitPublicKeys.filter((publicKey) => publicKey !== senderPublicKey);
|
|
137
121
|
if (mentions.length > 50) throw new Error(`Buzz messages support at most 50 mentions`);
|
|
138
122
|
const missingPublicKeys = mentions.filter((publicKey) => !members.has(publicKey));
|
|
139
123
|
if (missingPublicKeys.length > 0) throw new Error(`Buzz mentioned public key is not a current room member: ${missingPublicKeys.join(", ")}`);
|
|
@@ -145,8 +129,8 @@ function resolveBuzzMessageMentions(params) {
|
|
|
145
129
|
matches.push(member.publicKey);
|
|
146
130
|
namesToPublicKeys.set(name, matches);
|
|
147
131
|
}
|
|
148
|
-
const names = extractMentionNames(stripped, [...
|
|
149
|
-
if (
|
|
132
|
+
const names = extractMentionNames(stripped, [...namesToPublicKeys.keys()]);
|
|
133
|
+
if (hasAtMention && names.length === 0 && explicitPublicKeys.length === 0) throw new Error("Buzz mention does not match a current room member; use nostr:npub... for an explicit identity");
|
|
150
134
|
for (const name of names) {
|
|
151
135
|
const matches = namesToPublicKeys.get(name) ?? [];
|
|
152
136
|
if (matches.length === 0) {
|
|
@@ -160,9 +144,7 @@ function resolveBuzzMessageMentions(params) {
|
|
|
160
144
|
const candidateSuffix = hiddenCandidateCount > 0 ? `, and ${hiddenCandidateCount} more` : "";
|
|
161
145
|
throw new Error(`Buzz mention "@${name}" is ambiguous; candidates: ${visibleCandidates}${candidateSuffix}. Use nostr:npub... for an explicit identity`);
|
|
162
146
|
}
|
|
163
|
-
const publicKey
|
|
164
|
-
if (!publicKey) throw new Error("Buzz mention resolution lost its unique room member");
|
|
165
|
-
if (publicKey !== senderPublicKey && !mentions.includes(publicKey)) {
|
|
147
|
+
for (const publicKey of matches) if (publicKey !== senderPublicKey && !mentions.includes(publicKey)) {
|
|
166
148
|
if (mentions.length >= 50) throw new Error(`Buzz messages support at most 50 mentions`);
|
|
167
149
|
mentions.push(publicKey);
|
|
168
150
|
}
|
|
@@ -187,16 +169,12 @@ const BUZZ_INBOUND_MESSAGE_KIND_SET = new Set(BUZZ_INBOUND_MESSAGE_KINDS);
|
|
|
187
169
|
function isBuzzInboundMessageKind(kind) {
|
|
188
170
|
return BUZZ_INBOUND_MESSAGE_KIND_SET.has(kind);
|
|
189
171
|
}
|
|
190
|
-
function tagValue(event, name) {
|
|
191
|
-
const value = event.tags.find((tag) => tag[0] === name)?.[1]?.trim();
|
|
192
|
-
return value ? value : void 0;
|
|
193
|
-
}
|
|
194
172
|
function markerTagValue(event, marker) {
|
|
195
173
|
const value = event.tags.find((tag) => tag[0] === "e" && tag[3] === marker)?.[1]?.trim();
|
|
196
174
|
return value ? value : void 0;
|
|
197
175
|
}
|
|
198
|
-
function
|
|
199
|
-
return value.length >=
|
|
176
|
+
function isCommitSha(value) {
|
|
177
|
+
return value.length >= 7 && /^[a-f0-9]+$/iu.test(value);
|
|
200
178
|
}
|
|
201
179
|
function parseBuzzDiffMetadata(event) {
|
|
202
180
|
let repoUrl;
|
|
@@ -220,14 +198,14 @@ function parseBuzzDiffMetadata(event) {
|
|
|
220
198
|
repoUrl ??= value;
|
|
221
199
|
break;
|
|
222
200
|
case "commit":
|
|
223
|
-
if (!
|
|
201
|
+
if (!isCommitSha(value)) return null;
|
|
224
202
|
commitSha ??= value;
|
|
225
203
|
break;
|
|
226
204
|
case "file":
|
|
227
205
|
filePath ??= value;
|
|
228
206
|
break;
|
|
229
207
|
case "parent-commit":
|
|
230
|
-
if (!
|
|
208
|
+
if (!isCommitSha(value)) return null;
|
|
231
209
|
parentCommitSha ??= value;
|
|
232
210
|
break;
|
|
233
211
|
case "branch":
|
|
@@ -302,7 +280,7 @@ function formatBuzzMessageForAgent(message) {
|
|
|
302
280
|
}
|
|
303
281
|
function parseBuzzMessageEvent(event) {
|
|
304
282
|
if (!isBuzzInboundMessageKind(event.kind) || !event.content.trim() || Buffer.byteLength(event.content, "utf8") > (event.kind === 40008 ? BUZZ_DIFF_CONTENT_MAX_BYTES : BUZZ_MESSAGE_CONTENT_MAX_BYTES)) return null;
|
|
305
|
-
const channelId =
|
|
283
|
+
const channelId = event.tags.find((tag) => tag[0] === "h")?.[1]?.trim();
|
|
306
284
|
if (!channelId) return null;
|
|
307
285
|
const rootId = markerTagValue(event, "root");
|
|
308
286
|
const replyToId = markerTagValue(event, "reply");
|
|
@@ -365,12 +365,6 @@ async function waitWithSignal(promise, signal) {
|
|
|
365
365
|
promise.then(resolve, reject).finally(() => signal.removeEventListener("abort", onAbort));
|
|
366
366
|
});
|
|
367
367
|
}
|
|
368
|
-
function createBuzzAuthSigner(params) {
|
|
369
|
-
return async (template) => finalizeEvent({
|
|
370
|
-
...template,
|
|
371
|
-
tags: params.authTag ? [...template.tags, params.authTag] : template.tags
|
|
372
|
-
}, params.secretKey);
|
|
373
|
-
}
|
|
374
368
|
function isLoopbackRelayUrl(relayUrl) {
|
|
375
369
|
const hostname = new URL(relayUrl).hostname.toLowerCase();
|
|
376
370
|
return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "[::1]";
|
|
@@ -401,10 +395,11 @@ async function resolveBuzzRelayPublicKey(params) {
|
|
|
401
395
|
}
|
|
402
396
|
}
|
|
403
397
|
async function connectAndAuthenticateBuzzRelay(params) {
|
|
404
|
-
const
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
398
|
+
const { secretKey, authTag } = params;
|
|
399
|
+
const signAuth = async (template) => finalizeEvent({
|
|
400
|
+
...template,
|
|
401
|
+
tags: authTag ? [...template.tags, authTag] : template.tags
|
|
402
|
+
}, secretKey);
|
|
408
403
|
await params.relay.connect({ abort: params.signal });
|
|
409
404
|
await authenticateBuzzRelay({
|
|
410
405
|
relay: params.relay,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { c as BuzzConfigSchema, i as resolveBuzzAccount, r as listBuzzAccountIds, s as resolveDefaultBuzzAccountId } from "./types-DRUZMyTx.mjs";
|
|
2
|
-
import { n as buzzSetupContract, t as buzzSetupWizard } from "./setup-surface-
|
|
2
|
+
import { n as buzzSetupContract, t as buzzSetupWizard } from "./setup-surface-CtPEPYrT.mjs";
|
|
3
3
|
import { describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
|
|
4
4
|
//#region extensions/buzz/src/channel.setup.ts
|
|
5
5
|
const buzzSetupPlugin = {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as resolveBuzzAccountConfig, i as resolveBuzzAccount, l as BUZZ_CHANNEL_ID_PATTERN, m as parseBuzzTarget, n as decodeBuzzPrivateKey, o as resolveBuzzPublicKey, r as listBuzzAccountIds } from "./types-DRUZMyTx.mjs";
|
|
2
|
-
import { c as openBuzzRelaySubscription, i as parseBuzzRoomMembershipEvent, l as queryBuzzRelaySnapshot, m as isNewerBuzzRevision, o as connectAuthenticatedBuzzRelaySession, s as parseBuzzAuthTag, t as BUZZ_ROOM_MEMBERSHIP_KIND } from "./room-membership-
|
|
2
|
+
import { c as openBuzzRelaySubscription, i as parseBuzzRoomMembershipEvent, l as queryBuzzRelaySnapshot, m as isNewerBuzzRevision, o as connectAuthenticatedBuzzRelaySession, s as parseBuzzAuthTag, t as BUZZ_ROOM_MEMBERSHIP_KIND } from "./room-membership-F-VBtTXf.mjs";
|
|
3
3
|
import { generateSecretKey, nip19 } from "nostr-tools";
|
|
4
4
|
import { sleep, sleepWithAbort } from "openclaw/plugin-sdk/runtime-env";
|
|
5
5
|
import { defineChannelSetupContract } from "openclaw/plugin-sdk/channel-setup";
|
|
@@ -149,12 +149,8 @@ async function discoverBuzzRooms(params) {
|
|
|
149
149
|
//#endregion
|
|
150
150
|
//#region extensions/buzz/src/setup-core.ts
|
|
151
151
|
function validRelayUrl(value) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
return url.protocol === "ws:" || url.protocol === "wss:";
|
|
155
|
-
} catch {
|
|
156
|
-
return false;
|
|
157
|
-
}
|
|
152
|
+
const url = URL.parse(value ?? "");
|
|
153
|
+
return url?.protocol === "ws:" || url?.protocol === "wss:";
|
|
158
154
|
}
|
|
159
155
|
function patchBuzzAccountConfig(params) {
|
|
160
156
|
const { accountId, allowEnv } = resolveBuzzAccountConfig(params);
|
|
@@ -260,9 +256,6 @@ const DISCOVERY_RETRY_DELAYS_MS = [
|
|
|
260
256
|
1500
|
|
261
257
|
];
|
|
262
258
|
const DISCOVERY_POLL_INTERVAL_MS = 2e3;
|
|
263
|
-
function hasTag(event, name, value) {
|
|
264
|
-
return event.tags.some((tag) => tag[0] === name && tag[1] === value);
|
|
265
|
-
}
|
|
266
259
|
function hasValidRoomTag(event) {
|
|
267
260
|
return event.tags.some((tag) => tag[0] === "h" && Boolean(tag[1]?.toLowerCase().match(BUZZ_CHANNEL_ID_PATTERN)));
|
|
268
261
|
}
|
|
@@ -354,7 +347,7 @@ async function waitForBuzzRoomAccess(params) {
|
|
|
354
347
|
since: Math.floor(Date.now() / 1e3) - 30
|
|
355
348
|
}], {
|
|
356
349
|
onevent: (event) => {
|
|
357
|
-
if (event.kind !== 44100 || seenEvents.has(event.id) || !
|
|
350
|
+
if (event.kind !== 44100 || seenEvents.has(event.id) || !event.tags.some((tag) => tag[0] === "p" && tag[1] === publicKey) || !hasValidRoomTag(event)) return;
|
|
358
351
|
seenEvents.add(event.id);
|
|
359
352
|
checkRooms(true);
|
|
360
353
|
},
|
|
@@ -441,12 +434,9 @@ async function verifyBuzzAfterSetup(params) {
|
|
|
441
434
|
//#region extensions/buzz/src/setup-surface.ts
|
|
442
435
|
const channel = "buzz";
|
|
443
436
|
function validateRelayUrl(value) {
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
} catch {
|
|
448
|
-
return "Enter a valid Buzz relay WebSocket URL";
|
|
449
|
-
}
|
|
437
|
+
const url = URL.parse(value.trim());
|
|
438
|
+
if (!url) return "Enter a valid Buzz relay WebSocket URL";
|
|
439
|
+
return url.protocol === "ws:" || url.protocol === "wss:" ? void 0 : "Use a ws:// or wss:// relay URL";
|
|
450
440
|
}
|
|
451
441
|
function isRemoteInsecureRelayUrl(value) {
|
|
452
442
|
const url = new URL(value);
|
|
@@ -500,14 +490,14 @@ async function resolvePrivateKey(params) {
|
|
|
500
490
|
};
|
|
501
491
|
}
|
|
502
492
|
if (params.secretInputMode !== "ref") {
|
|
503
|
-
let accountKeys =
|
|
493
|
+
let accountKeys = generatedPrivateKeys.get(params.prompter);
|
|
504
494
|
if (!accountKeys) {
|
|
505
495
|
accountKeys = /* @__PURE__ */ new Map();
|
|
506
|
-
|
|
496
|
+
generatedPrivateKeys.set(params.prompter, accountKeys);
|
|
507
497
|
}
|
|
508
498
|
let privateKey = accountKeys.get(params.accountId);
|
|
509
499
|
if (!privateKey) {
|
|
510
|
-
privateKey = nip19.nsecEncode(
|
|
500
|
+
privateKey = nip19.nsecEncode(generateSecretKey());
|
|
511
501
|
accountKeys.set(params.accountId, privateKey);
|
|
512
502
|
}
|
|
513
503
|
return {
|
|
@@ -523,7 +513,7 @@ async function resolvePrivateKey(params) {
|
|
|
523
513
|
resolvedPrivateKey: privateKey
|
|
524
514
|
};
|
|
525
515
|
}
|
|
526
|
-
const secretStep = await
|
|
516
|
+
const secretStep = await runSingleChannelSecretStep({
|
|
527
517
|
cfg: params.cfg,
|
|
528
518
|
prompter: params.prompter,
|
|
529
519
|
providerHint: channel,
|
|
@@ -596,190 +586,179 @@ async function noteBuzzAccessInstructions(params) {
|
|
|
596
586
|
"Never paste that human private key into OpenClaw."
|
|
597
587
|
].join("\n"), "Buzz room access required");
|
|
598
588
|
}
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
let discoveryError;
|
|
673
|
-
const authTag = await resolveSetupCredential({
|
|
674
|
-
cfg: next,
|
|
675
|
-
accountId,
|
|
676
|
-
field: "authTag"
|
|
677
|
-
});
|
|
678
|
-
const discoverAuthorizedRooms = async () => {
|
|
679
|
-
try {
|
|
680
|
-
const rooms = await discoverRooms({
|
|
681
|
-
relayUrl,
|
|
682
|
-
privateKey,
|
|
683
|
-
...authTag ? { authTag } : {}
|
|
684
|
-
});
|
|
685
|
-
discoveryError = rooms.length === 0 ? "No authorized rooms were returned for this bot." : void 0;
|
|
686
|
-
return rooms;
|
|
687
|
-
} catch (error) {
|
|
688
|
-
discoveryError = `Authenticated room discovery failed: ${error instanceof Error ? error.message : String(error)}.`;
|
|
689
|
-
return [];
|
|
690
|
-
}
|
|
691
|
-
};
|
|
692
|
-
discoveredRooms = await discoverAuthorizedRooms();
|
|
693
|
-
if (discoveredRooms.length === 0) {
|
|
694
|
-
await noteBuzzAccessInstructions({
|
|
589
|
+
const generatedPrivateKeys = /* @__PURE__ */ new WeakMap();
|
|
590
|
+
const buzzSetupWizard = {
|
|
591
|
+
channel,
|
|
592
|
+
getStatus: async ({ cfg, accountOverrides }) => {
|
|
593
|
+
const { configured, enabled } = resolveBuzzAccount({
|
|
594
|
+
cfg,
|
|
595
|
+
accountId: accountOverrides.buzz
|
|
596
|
+
});
|
|
597
|
+
const status = !configured ? "needs relay URL and bot identity" : enabled ? "configured" : "configured but disabled";
|
|
598
|
+
return {
|
|
599
|
+
channel,
|
|
600
|
+
configured,
|
|
601
|
+
statusLines: [`Buzz: ${status}`],
|
|
602
|
+
selectionHint: status
|
|
603
|
+
};
|
|
604
|
+
},
|
|
605
|
+
configure: async ({ cfg, prompter, options, accountOverrides, shouldPromptAccountIds }) => {
|
|
606
|
+
let accountId = resolveBuzzAccountConfig({
|
|
607
|
+
cfg,
|
|
608
|
+
accountId: accountOverrides.buzz
|
|
609
|
+
}).accountId;
|
|
610
|
+
if (shouldPromptAccountIds && !accountOverrides.buzz?.trim()) accountId = await promptAccountId({
|
|
611
|
+
cfg,
|
|
612
|
+
prompter,
|
|
613
|
+
label: "Buzz",
|
|
614
|
+
currentId: accountId,
|
|
615
|
+
listAccountIds: listBuzzAccountIds,
|
|
616
|
+
defaultAccountId: accountId
|
|
617
|
+
});
|
|
618
|
+
const { config: existingBuzzConfig } = resolveBuzzAccountConfig({
|
|
619
|
+
cfg,
|
|
620
|
+
accountId
|
|
621
|
+
});
|
|
622
|
+
const rootPolicy = cfg.channels?.buzz;
|
|
623
|
+
const rawAccount = rootPolicy?.accounts?.[accountId];
|
|
624
|
+
const hasExistingAccessConfig = rootPolicy?.groupPolicy !== void 0 || rootPolicy?.groupAllowFrom !== void 0 || rawAccount?.groupPolicy !== void 0 || rawAccount?.groupAllowFrom !== void 0 || existingBuzzConfig.groups !== void 0;
|
|
625
|
+
const existingAccount = resolveBuzzAccount({
|
|
626
|
+
cfg,
|
|
627
|
+
accountId
|
|
628
|
+
});
|
|
629
|
+
const useFreshAccessDefaults = !existingAccount.configured && !hasExistingAccessConfig;
|
|
630
|
+
const configuredRelayUrl = existingAccount.relayUrl;
|
|
631
|
+
const relayUrl = await resolveRelayUrl({
|
|
632
|
+
configuredValue: configuredRelayUrl,
|
|
633
|
+
prompter
|
|
634
|
+
});
|
|
635
|
+
let next = patchBuzzAccountConfig({
|
|
636
|
+
cfg,
|
|
637
|
+
accountId,
|
|
638
|
+
patch: {
|
|
639
|
+
enabled: true,
|
|
640
|
+
relayUrl
|
|
641
|
+
}
|
|
642
|
+
});
|
|
643
|
+
const identity = await resolvePrivateKey({
|
|
644
|
+
cfg: next,
|
|
645
|
+
accountId,
|
|
646
|
+
prompter,
|
|
647
|
+
secretInputMode: options?.secretInputMode
|
|
648
|
+
});
|
|
649
|
+
next = identity.cfg;
|
|
650
|
+
const privateKey = identity.resolvedPrivateKey;
|
|
651
|
+
const publicKey = resolveBuzzPublicKey(privateKey);
|
|
652
|
+
let discoveredRooms = [];
|
|
653
|
+
let discoveryError;
|
|
654
|
+
const authTag = await resolveSetupCredential({
|
|
655
|
+
cfg: next,
|
|
656
|
+
accountId,
|
|
657
|
+
field: "authTag"
|
|
658
|
+
});
|
|
659
|
+
const discoverAuthorizedRooms = async () => {
|
|
660
|
+
try {
|
|
661
|
+
const rooms = await discoverBuzzRooms({
|
|
695
662
|
relayUrl,
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
discoveryError
|
|
663
|
+
privateKey,
|
|
664
|
+
...authTag ? { authTag } : {}
|
|
699
665
|
});
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
...authTag ? { authTag } : {}
|
|
706
|
-
});
|
|
707
|
-
progress.stop(discoveredRooms.length > 0 ? "Buzz room access confirmed" : "Buzz room access wait expired");
|
|
708
|
-
} catch (error) {
|
|
709
|
-
progress.stop("Buzz room access check failed");
|
|
710
|
-
await prompter.note(error instanceof Error ? error.message : String(error), "Buzz room access check failed");
|
|
711
|
-
}
|
|
666
|
+
discoveryError = rooms.length === 0 ? "No authorized rooms were returned for this bot." : void 0;
|
|
667
|
+
return rooms;
|
|
668
|
+
} catch (error) {
|
|
669
|
+
discoveryError = `Authenticated room discovery failed: ${error instanceof Error ? error.message : String(error)}.`;
|
|
670
|
+
return [];
|
|
712
671
|
}
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
672
|
+
};
|
|
673
|
+
discoveredRooms = await discoverAuthorizedRooms();
|
|
674
|
+
if (discoveredRooms.length === 0) {
|
|
675
|
+
await noteBuzzAccessInstructions({
|
|
676
|
+
relayUrl,
|
|
677
|
+
publicKey,
|
|
678
|
+
prompter,
|
|
679
|
+
discoveryError
|
|
680
|
+
});
|
|
681
|
+
const progress = prompter.progress("Waiting for Buzz room access...");
|
|
682
|
+
try {
|
|
683
|
+
discoveredRooms = await waitForBuzzRoomAccess({
|
|
684
|
+
relayUrl,
|
|
685
|
+
privateKey,
|
|
686
|
+
...authTag ? { authTag } : {}
|
|
722
687
|
});
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
progress.stop(
|
|
726
|
-
|
|
688
|
+
progress.stop(discoveredRooms.length > 0 ? "Buzz room access confirmed" : "Buzz room access wait expired");
|
|
689
|
+
} catch (error) {
|
|
690
|
+
progress.stop("Buzz room access check failed");
|
|
691
|
+
await prompter.note(error instanceof Error ? error.message : String(error), "Buzz room access check failed");
|
|
727
692
|
}
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
return {
|
|
739
|
-
value: roomId,
|
|
740
|
-
label: discoveredRooms.find((candidate) => candidate.id === roomId)?.name ?? roomId,
|
|
741
|
-
hint: roomId
|
|
742
|
-
};
|
|
743
|
-
}),
|
|
744
|
-
initialValue: existingDefault && roomIds.includes(existingDefault) ? existingDefault : roomIds[0]
|
|
745
|
-
});
|
|
746
|
-
next = patchBuzzAccountConfig({
|
|
747
|
-
cfg: next,
|
|
748
|
-
accountId,
|
|
749
|
-
patch: {
|
|
750
|
-
...useFreshAccessDefaults ? {
|
|
751
|
-
groupPolicy: "open",
|
|
752
|
-
groupAllowFrom: void 0
|
|
753
|
-
} : {},
|
|
754
|
-
groups: Object.fromEntries(roomIds.map((roomId) => [roomId, {
|
|
755
|
-
...configuredGroups[roomId],
|
|
756
|
-
enabled: configuredGroups[roomId]?.enabled ?? true,
|
|
757
|
-
requireMention: configuredGroups[roomId]?.requireMention ?? !useFreshAccessDefaults
|
|
758
|
-
}])),
|
|
759
|
-
defaultTo
|
|
760
|
-
}
|
|
761
|
-
});
|
|
762
|
-
options?.onPostWriteHook?.({
|
|
763
|
-
channel,
|
|
764
|
-
accountId,
|
|
765
|
-
run: async ({ runtime }) => await verifyAfterWrite({
|
|
766
|
-
accountId,
|
|
767
|
-
target: defaultTo,
|
|
768
|
-
runtime
|
|
769
|
-
})
|
|
693
|
+
}
|
|
694
|
+
while (discoveredRooms.length === 0) {
|
|
695
|
+
await prompter.select({
|
|
696
|
+
message: "Buzz room access is not ready",
|
|
697
|
+
options: [{
|
|
698
|
+
value: "retry",
|
|
699
|
+
label: "Retry authenticated room discovery",
|
|
700
|
+
hint: "Use after the bot has been added to a room with the Bot role"
|
|
701
|
+
}],
|
|
702
|
+
initialValue: "retry"
|
|
770
703
|
});
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
}
|
|
776
|
-
|
|
777
|
-
|
|
704
|
+
const progress = prompter.progress("Checking Buzz room access...");
|
|
705
|
+
discoveredRooms = await discoverAuthorizedRooms();
|
|
706
|
+
progress.stop(discoveredRooms.length > 0 ? "Buzz room access confirmed" : "Buzz room access not found");
|
|
707
|
+
if (discoveredRooms.length === 0 && discoveryError) await prompter.note(discoveryError, "Buzz room access not ready");
|
|
708
|
+
}
|
|
709
|
+
const configuredGroups = existingBuzzConfig.groups ?? {};
|
|
710
|
+
const roomIds = await promptRooms({
|
|
711
|
+
rooms: discoveredRooms,
|
|
712
|
+
configuredRoomIds: Object.keys(configuredGroups),
|
|
713
|
+
prompter
|
|
714
|
+
});
|
|
715
|
+
const existingDefault = existingBuzzConfig.defaultTo;
|
|
716
|
+
const defaultTo = roomIds.length === 1 ? roomIds[0] : await prompter.select({
|
|
717
|
+
message: "Choose the default Buzz room target",
|
|
718
|
+
options: roomIds.map((roomId) => {
|
|
719
|
+
return {
|
|
720
|
+
value: roomId,
|
|
721
|
+
label: discoveredRooms.find((candidate) => candidate.id === roomId)?.name ?? roomId,
|
|
722
|
+
hint: roomId
|
|
723
|
+
};
|
|
724
|
+
}),
|
|
725
|
+
initialValue: existingDefault && roomIds.includes(existingDefault) ? existingDefault : roomIds[0]
|
|
726
|
+
});
|
|
727
|
+
next = patchBuzzAccountConfig({
|
|
728
|
+
cfg: next,
|
|
729
|
+
accountId,
|
|
730
|
+
patch: {
|
|
731
|
+
...useFreshAccessDefaults ? {
|
|
732
|
+
groupPolicy: "open",
|
|
733
|
+
groupAllowFrom: void 0
|
|
734
|
+
} : {},
|
|
735
|
+
groups: Object.fromEntries(roomIds.map((roomId) => [roomId, {
|
|
736
|
+
...configuredGroups[roomId],
|
|
737
|
+
enabled: configuredGroups[roomId]?.enabled ?? true,
|
|
738
|
+
requireMention: configuredGroups[roomId]?.requireMention ?? !useFreshAccessDefaults
|
|
739
|
+
}])),
|
|
740
|
+
defaultTo
|
|
741
|
+
}
|
|
742
|
+
});
|
|
743
|
+
options?.onPostWriteHook?.({
|
|
778
744
|
channel,
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
745
|
+
accountId,
|
|
746
|
+
run: async ({ runtime }) => await verifyBuzzAfterSetup({
|
|
747
|
+
accountId,
|
|
748
|
+
target: defaultTo,
|
|
749
|
+
runtime
|
|
750
|
+
})
|
|
751
|
+
});
|
|
752
|
+
return {
|
|
753
|
+
cfg: next,
|
|
754
|
+
accountId
|
|
755
|
+
};
|
|
756
|
+
},
|
|
757
|
+
disable: (cfg) => patchTopLevelChannelConfigSection({
|
|
758
|
+
cfg,
|
|
759
|
+
channel,
|
|
760
|
+
patch: { enabled: false }
|
|
761
|
+
})
|
|
762
|
+
};
|
|
784
763
|
//#endregion
|
|
785
764
|
export { startBuzzRoomMembershipNotifications as i, buzzSetupContract as n, discoverBuzzRooms as r, buzzSetupWizard as t };
|
package/dist/api.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { i as resolveBuzzAccount, r as listBuzzAccountIds, s as resolveDefaultBuzzAccountId } from "./.setup/types-DRUZMyTx.mjs";
|
|
2
|
-
import { n as getBuzzRuntime, r as setBuzzRuntime, t as buzzPlugin } from "./.setup/channel-
|
|
2
|
+
import { n as getBuzzRuntime, r as setBuzzRuntime, t as buzzPlugin } from "./.setup/channel-Ba25iqfd.mjs";
|
|
3
3
|
export { buzzPlugin, getBuzzRuntime, listBuzzAccountIds, resolveBuzzAccount, resolveDefaultBuzzAccountId, setBuzzRuntime };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as buzzPlugin } from "./.setup/channel-
|
|
1
|
+
import { t as buzzPlugin } from "./.setup/channel-Ba25iqfd.mjs";
|
|
2
2
|
export { buzzPlugin };
|
package/dist/qa-runner-api.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createLazyCliRuntimeLoader, createLiveTransportQaCliRegistration, runLiveTransportQaSuiteCommand } from "openclaw/plugin-sdk/qa-runner-runtime";
|
|
2
2
|
//#region extensions/buzz/src/qa/cli.ts
|
|
3
3
|
const DEFAULT_BUZZ_QA_SCENARIOS = ["channel-canary", "channel-mention-gating"];
|
|
4
|
-
const loadBuzzQaAdapterRuntime = createLazyCliRuntimeLoader(() => import("./.setup/adapter.runtime-
|
|
4
|
+
const loadBuzzQaAdapterRuntime = createLazyCliRuntimeLoader(() => import("./.setup/adapter.runtime-Diltpvcm.mjs"));
|
|
5
5
|
async function runQaBuzz(options) {
|
|
6
6
|
await runLiveTransportQaSuiteCommand({
|
|
7
7
|
channelId: "buzz",
|
package/dist/setup-entry.js
CHANGED
|
@@ -4,7 +4,7 @@ import { fileURLToPath } from "node:url";
|
|
|
4
4
|
var setup_entry_default = defineBundledChannelSetupEntry({
|
|
5
5
|
importMetaUrl: import.meta.url,
|
|
6
6
|
plugin: {
|
|
7
|
-
specifier: fileURLToPath(new URL(".setup/setup-plugin-api-
|
|
7
|
+
specifier: fileURLToPath(new URL(".setup/setup-plugin-api-DOqDYVDO.mjs", import.meta.url).href),
|
|
8
8
|
exportName: "buzzSetupPlugin"
|
|
9
9
|
},
|
|
10
10
|
secrets: {
|
package/dist/setup-plugin-api.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as buzzSetupPlugin } from "./.setup/setup-plugin-api-
|
|
1
|
+
import { t as buzzSetupPlugin } from "./.setup/setup-plugin-api-mJRSnC3g.mjs";
|
|
2
2
|
export { buzzSetupPlugin };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/buzz",
|
|
3
|
-
"version": "2026.10.
|
|
3
|
+
"version": "2026.10.5-beta.1",
|
|
4
4
|
"description": "Connect OpenClaw agents to Buzz rooms",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"zod": "4.6.5"
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
|
-
"openclaw": ">=2026.10.
|
|
15
|
+
"openclaw": ">=2026.10.5-beta.1"
|
|
16
16
|
},
|
|
17
17
|
"peerDependenciesMeta": {
|
|
18
18
|
"openclaw": {
|
|
@@ -84,10 +84,10 @@
|
|
|
84
84
|
"minHostVersion": ">=2026.7.2"
|
|
85
85
|
},
|
|
86
86
|
"compat": {
|
|
87
|
-
"pluginApi": ">=2026.10.
|
|
87
|
+
"pluginApi": ">=2026.10.5-beta.1"
|
|
88
88
|
},
|
|
89
89
|
"build": {
|
|
90
|
-
"openclawVersion": "2026.10.
|
|
90
|
+
"openclawVersion": "2026.10.5-beta.1"
|
|
91
91
|
},
|
|
92
92
|
"release": {
|
|
93
93
|
"publishToClawHub": true,
|