@openclaw/buzz 2026.9.1-beta.1 → 2026.9.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/{adapter.runtime-DA6guOQ_.js → adapter.runtime-CaDdxQ2C.js} +4 -4
- package/dist/api.js +2 -2
- package/dist/{channel-BulZqShF.js → channel-Czma0_CC.js} +200 -66
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{directory-config-BesCse0q.js → directory-config-B0shiBa4.js} +1 -1
- package/dist/directory-contract-api.js +1 -1
- package/dist/{message-event-CFw7gGLi.js → message-event-X_aBiM1X.js} +5 -8
- package/dist/qa-runner-api.js +1 -1
- package/dist/{room-membership-DSAkyE0a.js → room-membership-a8IHfdgL.js} +7 -5
- package/dist/secret-contract-DNuqbK64.js +50 -0
- package/dist/secret-contract-api.js +1 -1
- package/dist/setup-plugin-api.js +6 -3
- package/dist/{setup-surface-BvQgEJ7O.js → setup-surface-DDUmAluL.js} +197 -170
- package/dist/types-CeupBG0P.js +160 -0
- package/node_modules/nostr-tools/lib/cjs/index.js +21 -5
- package/node_modules/nostr-tools/lib/cjs/index.js.map +2 -2
- package/node_modules/nostr-tools/lib/cjs/nip17.js +19 -3
- package/node_modules/nostr-tools/lib/cjs/nip17.js.map +2 -2
- package/node_modules/nostr-tools/lib/cjs/nip46.js +7 -3
- package/node_modules/nostr-tools/lib/cjs/nip46.js.map +2 -2
- package/node_modules/nostr-tools/lib/cjs/nip59.js +19 -3
- package/node_modules/nostr-tools/lib/cjs/nip59.js.map +2 -2
- package/node_modules/nostr-tools/lib/cjs/nip98.js +1 -1
- package/node_modules/nostr-tools/lib/cjs/nip98.js.map +2 -2
- package/node_modules/nostr-tools/lib/cjs/nipad.js +55 -0
- package/node_modules/nostr-tools/lib/cjs/nipad.js.map +7 -0
- package/node_modules/nostr-tools/lib/cjs/nipb7.js +1003 -98
- package/node_modules/nostr-tools/lib/cjs/nipb7.js.map +4 -4
- package/node_modules/nostr-tools/lib/cjs/relay.js +1 -1
- package/node_modules/nostr-tools/lib/cjs/relay.js.map +2 -2
- package/node_modules/nostr-tools/lib/esm/index.js +21 -5
- package/node_modules/nostr-tools/lib/esm/index.js.map +2 -2
- package/node_modules/nostr-tools/lib/esm/nip17.js +19 -3
- package/node_modules/nostr-tools/lib/esm/nip17.js.map +2 -2
- package/node_modules/nostr-tools/lib/esm/nip46.js +7 -3
- package/node_modules/nostr-tools/lib/esm/nip46.js.map +2 -2
- package/node_modules/nostr-tools/lib/esm/nip59.js +19 -3
- package/node_modules/nostr-tools/lib/esm/nip59.js.map +2 -2
- package/node_modules/nostr-tools/lib/esm/nip98.js +1 -1
- package/node_modules/nostr-tools/lib/esm/nip98.js.map +2 -2
- package/node_modules/nostr-tools/lib/esm/nipad.js +34 -0
- package/node_modules/nostr-tools/lib/esm/nipad.js.map +7 -0
- package/node_modules/nostr-tools/lib/esm/nipb7.js +1009 -98
- package/node_modules/nostr-tools/lib/esm/nipb7.js.map +4 -4
- package/node_modules/nostr-tools/lib/esm/relay.js +1 -1
- package/node_modules/nostr-tools/lib/esm/relay.js.map +2 -2
- package/node_modules/nostr-tools/lib/nostr.bundle.js +21 -5
- package/node_modules/nostr-tools/lib/nostr.bundle.js.map +2 -2
- package/node_modules/nostr-tools/lib/types/nip98.d.ts +1 -1
- package/node_modules/nostr-tools/lib/types/nipad.d.ts +16 -0
- package/node_modules/nostr-tools/lib/types/nipb7.d.ts +112 -5
- package/node_modules/nostr-tools/lib/types/relay.d.ts +1 -1
- package/node_modules/nostr-tools/package.json +7 -7
- package/openclaw.plugin.json +346 -0
- package/package.json +8 -5
- package/dist/secret-contract-D19RiJv_.js +0 -12
- package/dist/types-BN_HOsnq.js +0 -101
- package/node_modules/nostr-tools/lib/cjs/nipb0.js +0 -1087
- package/node_modules/nostr-tools/lib/cjs/nipb0.js.map +0 -7
- package/node_modules/nostr-tools/lib/esm/nipb0.js +0 -1072
- package/node_modules/nostr-tools/lib/esm/nipb0.js.map +0 -7
- package/node_modules/nostr-tools/lib/types/nipb0.d.ts +0 -128
- /package/node_modules/nostr-tools/lib/types/{nipb0.test.d.ts → nip46.test.d.ts} +0 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { a as resolveBuzzAccountConfig } from "./types-CeupBG0P.js";
|
|
2
|
+
import { collectSecretInputAssignment, createChannelSecretTargetRegistryEntries, getChannelRecord, isRecord } from "openclaw/plugin-sdk/channel-secret-basic-runtime";
|
|
3
|
+
//#region extensions/buzz/src/secret-contract.ts
|
|
4
|
+
const fields = ["privateKey", "authTag"];
|
|
5
|
+
const secretTargetRegistryEntries = createChannelSecretTargetRegistryEntries({
|
|
6
|
+
channelKey: "buzz",
|
|
7
|
+
account: fields,
|
|
8
|
+
channel: fields
|
|
9
|
+
});
|
|
10
|
+
function collectRuntimeConfigAssignments(params) {
|
|
11
|
+
const root = getChannelRecord(params.config, "buzz");
|
|
12
|
+
if (!root) return;
|
|
13
|
+
const collect = (accountId, account, rootIdentity = false) => {
|
|
14
|
+
const resolved = resolveBuzzAccountConfig({
|
|
15
|
+
cfg: params.config,
|
|
16
|
+
accountId
|
|
17
|
+
});
|
|
18
|
+
const active = resolved.config.enabled !== false && (!rootIdentity || resolved.allowEnv);
|
|
19
|
+
const configPath = rootIdentity ? "channels.buzz" : resolved.configPath;
|
|
20
|
+
for (const field of fields) collectSecretInputAssignment({
|
|
21
|
+
value: account[field],
|
|
22
|
+
path: `${configPath}.${field}`,
|
|
23
|
+
expected: "string",
|
|
24
|
+
defaults: params.defaults,
|
|
25
|
+
context: params.context,
|
|
26
|
+
active,
|
|
27
|
+
inactiveReason: "Buzz identity is disabled or replaced by accounts.default.",
|
|
28
|
+
owner: {
|
|
29
|
+
ownerKind: "account",
|
|
30
|
+
ownerId: `buzz:${accountId}`,
|
|
31
|
+
requiredForGateway: false,
|
|
32
|
+
disposition: "isolate",
|
|
33
|
+
contract: resolved.config
|
|
34
|
+
},
|
|
35
|
+
apply: (value) => {
|
|
36
|
+
account[field] = value;
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
collect("default", root, true);
|
|
41
|
+
if (isRecord(root.accounts)) {
|
|
42
|
+
for (const [accountId, account] of Object.entries(root.accounts).toSorted(([a], [b]) => a.localeCompare(b))) if (isRecord(account)) collect(accountId, account);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const channelSecrets = {
|
|
46
|
+
secretTargetRegistryEntries,
|
|
47
|
+
collectRuntimeConfigAssignments
|
|
48
|
+
};
|
|
49
|
+
//#endregion
|
|
50
|
+
export { collectRuntimeConfigAssignments as n, secretTargetRegistryEntries as r, channelSecrets as t };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries, t as channelSecrets } from "./secret-contract-
|
|
1
|
+
import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries, t as channelSecrets } from "./secret-contract-DNuqbK64.js";
|
|
2
2
|
export { channelSecrets, collectRuntimeConfigAssignments, secretTargetRegistryEntries };
|
package/dist/setup-plugin-api.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { c as BuzzConfigSchema, i as resolveBuzzAccount, r as listBuzzAccountIds, s as resolveDefaultBuzzAccountId } from "./types-CeupBG0P.js";
|
|
2
|
+
import { n as buzzSetupContract, t as buzzSetupWizard } from "./setup-surface-DDUmAluL.js";
|
|
3
3
|
import { describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
|
|
4
4
|
//#region extensions/buzz/src/channel.setup.ts
|
|
5
5
|
const buzzSetupPlugin = {
|
|
@@ -18,7 +18,10 @@ const buzzSetupPlugin = {
|
|
|
18
18
|
chatTypes: ["group"],
|
|
19
19
|
threads: true
|
|
20
20
|
},
|
|
21
|
-
reload: {
|
|
21
|
+
reload: {
|
|
22
|
+
configPrefixes: ["channels.buzz"],
|
|
23
|
+
accountScopedRestart: true
|
|
24
|
+
},
|
|
22
25
|
configSchema: BuzzConfigSchema,
|
|
23
26
|
setupContract: buzzSetupContract,
|
|
24
27
|
setupWizard: buzzSetupWizard,
|
|
@@ -1,36 +1,10 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
import {
|
|
3
|
-
import { GroupPolicySchema, MarkdownConfigSchema, buildChannelConfigSchema } from "openclaw/plugin-sdk/channel-config-schema";
|
|
4
|
-
import { buildSecretInputSchema } from "openclaw/plugin-sdk/secret-input";
|
|
5
|
-
import { z } from "zod";
|
|
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-CeupBG0P.js";
|
|
2
|
+
import { c as openBuzzRelaySubscription, i as parseBuzzRoomMembershipEvent, l as queryBuzzRelaySnapshot, o as connectAuthenticatedBuzzRelaySession, s as parseBuzzAuthTag, t as BUZZ_ROOM_MEMBERSHIP_KIND, u as isNewerBuzzRevision } from "./room-membership-a8IHfdgL.js";
|
|
6
3
|
import { generateSecretKey, nip19 } from "nostr-tools";
|
|
7
4
|
import { sleep } from "openclaw/plugin-sdk/runtime-env";
|
|
8
5
|
import { defineChannelSetupContract } from "openclaw/plugin-sdk/channel-setup";
|
|
9
|
-
import {
|
|
10
|
-
import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$1 } from "openclaw/plugin-sdk/setup-runtime";
|
|
6
|
+
import { patchScopedAccountConfig, patchTopLevelChannelConfigSection, promptAccountId, runSingleChannelSecretStep } from "openclaw/plugin-sdk/setup";
|
|
11
7
|
import { isIP } from "node:net";
|
|
12
|
-
//#region extensions/buzz/src/config-schema.ts
|
|
13
|
-
const BuzzGroupConfigSchema = z.object({
|
|
14
|
-
enabled: z.boolean().optional(),
|
|
15
|
-
requireMention: z.boolean().optional(),
|
|
16
|
-
groupPolicy: GroupPolicySchema.optional(),
|
|
17
|
-
groupAllowFrom: z.array(z.union([z.string(), z.number()])).optional()
|
|
18
|
-
}).strict();
|
|
19
|
-
const BuzzConfigSchema = buildChannelConfigSchema(z.object({
|
|
20
|
-
name: z.string().optional(),
|
|
21
|
-
enabled: z.boolean().optional(),
|
|
22
|
-
configWrites: z.boolean().optional(),
|
|
23
|
-
responsePrefix: z.string().optional(),
|
|
24
|
-
markdown: MarkdownConfigSchema,
|
|
25
|
-
relayUrl: z.string().url().and(z.string().regex(/^[wW][sS][sS]?:\/\//, "Buzz relay URL must use ws:// or wss://")).optional(),
|
|
26
|
-
privateKey: buildSecretInputSchema().optional(),
|
|
27
|
-
authTag: buildSecretInputSchema().optional(),
|
|
28
|
-
groupPolicy: GroupPolicySchema.optional().default("allowlist"),
|
|
29
|
-
groupAllowFrom: z.array(z.union([z.string(), z.number()])).optional(),
|
|
30
|
-
groups: z.record(z.string().regex(BUZZ_CHANNEL_ID_PATTERN, "Buzz group key must be a channel UUID"), BuzzGroupConfigSchema).optional(),
|
|
31
|
-
defaultTo: z.string().optional()
|
|
32
|
-
}).strict());
|
|
33
|
-
//#endregion
|
|
34
8
|
//#region extensions/buzz/src/room-membership-notification.ts
|
|
35
9
|
const BUZZ_MEMBER_ADDED_NOTIFICATION_KIND = 44100;
|
|
36
10
|
const BUZZ_MEMBER_REMOVED_NOTIFICATION_KIND = 44101;
|
|
@@ -126,7 +100,13 @@ async function discoverBuzzRoomsOnRelay(params) {
|
|
|
126
100
|
for (const event of metadataEvents) {
|
|
127
101
|
const roomId = tagValue(event, "d")?.toLowerCase();
|
|
128
102
|
const current = roomId ? latestMetadata.get(roomId) : void 0;
|
|
129
|
-
if (event.kind !== METADATA_KIND || event.pubkey.toLowerCase() !== params.relayPublicKey || !roomId || !roomIds.includes(roomId) ||
|
|
103
|
+
if (event.kind !== METADATA_KIND || event.pubkey.toLowerCase() !== params.relayPublicKey || !roomId || !roomIds.includes(roomId) || !isNewerBuzzRevision({
|
|
104
|
+
createdAt: event.created_at,
|
|
105
|
+
eventId: event.id
|
|
106
|
+
}, current ? {
|
|
107
|
+
createdAt: current.created_at,
|
|
108
|
+
eventId: current.id
|
|
109
|
+
} : void 0)) continue;
|
|
130
110
|
latestMetadata.set(roomId, event);
|
|
131
111
|
}
|
|
132
112
|
return roomIds.flatMap((id) => {
|
|
@@ -176,10 +156,25 @@ function validRelayUrl(value) {
|
|
|
176
156
|
return false;
|
|
177
157
|
}
|
|
178
158
|
}
|
|
179
|
-
function
|
|
180
|
-
const
|
|
159
|
+
function patchBuzzAccountConfig(params) {
|
|
160
|
+
const { accountId, allowEnv } = resolveBuzzAccountConfig(params);
|
|
161
|
+
return patchScopedAccountConfig({
|
|
162
|
+
...params,
|
|
163
|
+
accountId,
|
|
164
|
+
channelKey: "buzz",
|
|
165
|
+
scopeDefaultToAccounts: !allowEnv,
|
|
166
|
+
ensureChannelEnabled: false,
|
|
167
|
+
ensureAccountEnabled: false
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
function resolveComparableCurrentKey(cfg, accountId) {
|
|
171
|
+
const { config, allowEnv } = resolveBuzzAccountConfig({
|
|
172
|
+
cfg,
|
|
173
|
+
accountId
|
|
174
|
+
});
|
|
175
|
+
const configured = config.privateKey;
|
|
181
176
|
if (configured !== void 0) return typeof configured === "string" ? configured.trim() || void 0 : void 0;
|
|
182
|
-
return process.env.BUZZ_PRIVATE_KEY?.trim() || void 0;
|
|
177
|
+
return allowEnv ? process.env.BUZZ_PRIVATE_KEY?.trim() || void 0 : void 0;
|
|
183
178
|
}
|
|
184
179
|
function isSameBuzzIdentity(currentKey, nextKey) {
|
|
185
180
|
if (!currentKey || !nextKey) return false;
|
|
@@ -216,16 +211,22 @@ const buzzSetupContract = defineChannelSetupContract({
|
|
|
216
211
|
}
|
|
217
212
|
},
|
|
218
213
|
adapter: {
|
|
219
|
-
|
|
214
|
+
configPromotion: "preserve-root",
|
|
215
|
+
resolveAccountId: ({ cfg, accountId }) => resolveBuzzAccountConfig({
|
|
216
|
+
cfg,
|
|
217
|
+
accountId
|
|
218
|
+
}).accountId,
|
|
219
|
+
applyAccountName: ({ cfg, accountId, name }) => name?.trim() ? patchBuzzAccountConfig({
|
|
220
220
|
cfg,
|
|
221
|
-
channelKey: "buzz",
|
|
222
221
|
accountId,
|
|
223
|
-
name
|
|
224
|
-
}),
|
|
225
|
-
validateInput: ({ accountId, input }) => {
|
|
226
|
-
if (accountId !== DEFAULT_ACCOUNT_ID$1) return "Buzz currently supports only the default account.";
|
|
222
|
+
patch: { name: name.trim() }
|
|
223
|
+
}) : cfg,
|
|
224
|
+
validateInput: ({ cfg, accountId, input }) => {
|
|
227
225
|
if (!validRelayUrl(input.relayUrl)) return "Buzz requires --relay-url with a ws:// or wss:// URL.";
|
|
228
|
-
if (input.useEnv) return
|
|
226
|
+
if (input.useEnv) return resolveBuzzAccountConfig({
|
|
227
|
+
cfg,
|
|
228
|
+
accountId
|
|
229
|
+
}).allowEnv ? null : "Buzz --use-env is only supported for the root default identity; use an explicit private key or SecretRef for this account.";
|
|
229
230
|
const privateKey = input.privateKey?.trim();
|
|
230
231
|
if (!privateKey) return "Buzz requires --private-key or --use-env.";
|
|
231
232
|
try {
|
|
@@ -235,22 +236,18 @@ const buzzSetupContract = defineChannelSetupContract({
|
|
|
235
236
|
}
|
|
236
237
|
return null;
|
|
237
238
|
},
|
|
238
|
-
applyAccountConfig: ({ cfg, input }) => {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
...cfg,
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
relayUrl: input.relayUrl?.trim(),
|
|
249
|
-
...keepAuthTag && authTag !== void 0 ? { authTag } : {},
|
|
250
|
-
...input.useEnv ? {} : { privateKey: input.privateKey?.trim() }
|
|
251
|
-
}
|
|
239
|
+
applyAccountConfig: ({ cfg, accountId, input }) => {
|
|
240
|
+
return patchBuzzAccountConfig({
|
|
241
|
+
cfg,
|
|
242
|
+
accountId,
|
|
243
|
+
clearFields: ["privateKey", ...isSameBuzzIdentity(resolveComparableCurrentKey(cfg, accountId), input.useEnv ? process.env.BUZZ_PRIVATE_KEY?.trim() : input.privateKey?.trim()) ? [] : ["authTag"]],
|
|
244
|
+
patch: {
|
|
245
|
+
enabled: true,
|
|
246
|
+
...input.name?.trim() ? { name: input.name.trim() } : {},
|
|
247
|
+
relayUrl: input.relayUrl?.trim(),
|
|
248
|
+
...input.useEnv ? {} : { privateKey: input.privateKey?.trim() }
|
|
252
249
|
}
|
|
253
|
-
};
|
|
250
|
+
});
|
|
254
251
|
}
|
|
255
252
|
}
|
|
256
253
|
});
|
|
@@ -454,13 +451,6 @@ async function verifyBuzzAfterSetup(params) {
|
|
|
454
451
|
//#endregion
|
|
455
452
|
//#region extensions/buzz/src/setup-surface.ts
|
|
456
453
|
const channel = "buzz";
|
|
457
|
-
function patchBuzzConfig(cfg, patch) {
|
|
458
|
-
return patchTopLevelChannelConfigSection({
|
|
459
|
-
cfg,
|
|
460
|
-
channel,
|
|
461
|
-
patch
|
|
462
|
-
});
|
|
463
|
-
}
|
|
464
454
|
function validateRelayUrl(value) {
|
|
465
455
|
try {
|
|
466
456
|
const url = new URL(value.trim());
|
|
@@ -476,10 +466,6 @@ function isRemoteInsecureRelayUrl(value) {
|
|
|
476
466
|
const isLoopback = hostname === "localhost" || hostname.endsWith(".localhost") || hostname === "::1" || isIpv4Loopback;
|
|
477
467
|
return url.protocol === "ws:" && !isLoopback;
|
|
478
468
|
}
|
|
479
|
-
function isBuzzSetupConfigured(cfg) {
|
|
480
|
-
const buzzConfig = cfg.channels?.buzz;
|
|
481
|
-
return Boolean((buzzConfig?.relayUrl?.trim() || process.env.BUZZ_RELAY_URL?.trim()) && (hasConfiguredSecretInput$1(buzzConfig?.privateKey, cfg.secrets?.defaults) || process.env.BUZZ_PRIVATE_KEY?.trim()));
|
|
482
|
-
}
|
|
483
469
|
async function promptRelayUrl(params) {
|
|
484
470
|
while (true) {
|
|
485
471
|
const relayUrl = (await params.prompter.text({
|
|
@@ -509,35 +495,53 @@ async function resolveRelayUrl(params) {
|
|
|
509
495
|
prompter: params.prompter
|
|
510
496
|
});
|
|
511
497
|
}
|
|
512
|
-
function
|
|
513
|
-
const
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
498
|
+
async function resolveSetupCredential(params) {
|
|
499
|
+
const { config, configPath, allowEnv } = resolveBuzzAccountConfig(params);
|
|
500
|
+
const { resolveConfiguredSecretInputWithFallback } = await import("openclaw/plugin-sdk/secret-input-runtime");
|
|
501
|
+
const resolved = await resolveConfiguredSecretInputWithFallback({
|
|
502
|
+
config: params.cfg,
|
|
503
|
+
env: process.env,
|
|
504
|
+
value: config[params.field],
|
|
505
|
+
path: `${configPath}.${params.field}`,
|
|
506
|
+
unresolvedReasonStyle: "detailed",
|
|
507
|
+
readFallback: allowEnv ? () => params.field === "privateKey" ? process.env.BUZZ_PRIVATE_KEY : process.env.BUZZ_AUTH_TAG : void 0
|
|
508
|
+
});
|
|
509
|
+
if (resolved.unresolvedRefReason) throw new Error(`${resolved.unresolvedRefReason} Make the secret available and rerun Buzz setup.`);
|
|
510
|
+
return resolved.value;
|
|
518
511
|
}
|
|
519
512
|
async function resolvePrivateKey(params) {
|
|
520
|
-
const
|
|
521
|
-
const currentPrivateKey =
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
513
|
+
const { allowEnv } = resolveBuzzAccountConfig(params);
|
|
514
|
+
const currentPrivateKey = await resolveSetupCredential({
|
|
515
|
+
...params,
|
|
516
|
+
field: "privateKey"
|
|
517
|
+
});
|
|
518
|
+
if (currentPrivateKey) {
|
|
519
|
+
decodeBuzzPrivateKey(currentPrivateKey);
|
|
525
520
|
return {
|
|
526
521
|
cfg: params.cfg,
|
|
527
|
-
resolvedPrivateKey
|
|
522
|
+
resolvedPrivateKey: currentPrivateKey
|
|
528
523
|
};
|
|
529
524
|
}
|
|
530
525
|
if (params.secretInputMode !== "ref") {
|
|
531
|
-
let
|
|
526
|
+
let accountKeys = params.generatedPrivateKeys.get(params.prompter);
|
|
527
|
+
if (!accountKeys) {
|
|
528
|
+
accountKeys = /* @__PURE__ */ new Map();
|
|
529
|
+
params.generatedPrivateKeys.set(params.prompter, accountKeys);
|
|
530
|
+
}
|
|
531
|
+
let privateKey = accountKeys.get(params.accountId);
|
|
532
532
|
if (!privateKey) {
|
|
533
533
|
privateKey = nip19.nsecEncode(params.generate());
|
|
534
|
-
|
|
534
|
+
accountKeys.set(params.accountId, privateKey);
|
|
535
535
|
}
|
|
536
536
|
return {
|
|
537
|
-
cfg:
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
537
|
+
cfg: patchBuzzAccountConfig({
|
|
538
|
+
cfg: params.cfg,
|
|
539
|
+
accountId: params.accountId,
|
|
540
|
+
patch: {
|
|
541
|
+
enabled: true,
|
|
542
|
+
privateKey
|
|
543
|
+
},
|
|
544
|
+
clearFields: ["authTag"]
|
|
541
545
|
}),
|
|
542
546
|
resolvedPrivateKey: privateKey
|
|
543
547
|
};
|
|
@@ -550,36 +554,31 @@ async function resolvePrivateKey(params) {
|
|
|
550
554
|
secretInputMode: params.secretInputMode,
|
|
551
555
|
accountConfigured: false,
|
|
552
556
|
hasConfigToken: false,
|
|
553
|
-
allowEnv
|
|
554
|
-
envValue: process.env.BUZZ_PRIVATE_KEY,
|
|
557
|
+
allowEnv,
|
|
558
|
+
envValue: allowEnv ? process.env.BUZZ_PRIVATE_KEY : void 0,
|
|
555
559
|
envPrompt: "Use BUZZ_PRIVATE_KEY?",
|
|
556
560
|
keepPrompt: "Keep the existing Buzz bot private key?",
|
|
557
561
|
inputPrompt: "Buzz bot private key (nsec or 64-character hex)",
|
|
558
|
-
preferredEnvVar: "BUZZ_PRIVATE_KEY",
|
|
559
|
-
applyUseEnv: (cfg) => {
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
};
|
|
574
|
-
},
|
|
575
|
-
applySet: (cfg, value, resolvedValue) => patchBuzzConfig(cfg, {
|
|
576
|
-
enabled: true,
|
|
577
|
-
privateKey: value,
|
|
578
|
-
...isSameBuzzIdentity(currentPrivateKey, resolvedValue) ? {} : { authTag: void 0 }
|
|
562
|
+
...allowEnv ? { preferredEnvVar: "BUZZ_PRIVATE_KEY" } : {},
|
|
563
|
+
applyUseEnv: (cfg) => patchBuzzAccountConfig({
|
|
564
|
+
cfg,
|
|
565
|
+
accountId: params.accountId,
|
|
566
|
+
patch: { enabled: true },
|
|
567
|
+
clearFields: ["privateKey", "authTag"]
|
|
568
|
+
}),
|
|
569
|
+
applySet: (cfg, value) => patchBuzzAccountConfig({
|
|
570
|
+
cfg,
|
|
571
|
+
accountId: params.accountId,
|
|
572
|
+
patch: {
|
|
573
|
+
enabled: true,
|
|
574
|
+
privateKey: value
|
|
575
|
+
},
|
|
576
|
+
clearFields: ["authTag"]
|
|
579
577
|
})
|
|
580
578
|
});
|
|
581
|
-
const resolvedPrivateKey = secretStep.resolvedValue
|
|
582
|
-
if (resolvedPrivateKey)
|
|
579
|
+
const resolvedPrivateKey = secretStep.resolvedValue;
|
|
580
|
+
if (!resolvedPrivateKey) throw new Error("Buzz bot private key could not be resolved. Make the secret available and rerun setup.");
|
|
581
|
+
decodeBuzzPrivateKey(resolvedPrivateKey);
|
|
583
582
|
return {
|
|
584
583
|
cfg: secretStep.cfg,
|
|
585
584
|
resolvedPrivateKey
|
|
@@ -589,37 +588,34 @@ async function promptRooms(params) {
|
|
|
589
588
|
if (params.rooms.length === 1) return [params.rooms[0].id];
|
|
590
589
|
const configuredRooms = new Set(params.configuredRoomIds);
|
|
591
590
|
const preservedRoomIds = params.rooms.map((room) => room.id).filter((roomId) => configuredRooms.has(roomId));
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
completion: "paused"
|
|
606
|
-
};
|
|
591
|
+
while (true) {
|
|
592
|
+
const roomIds = await params.prompter.multiselect({
|
|
593
|
+
message: "Select authorized Buzz rooms",
|
|
594
|
+
options: params.rooms.map((room) => ({
|
|
595
|
+
value: room.id,
|
|
596
|
+
label: room.name,
|
|
597
|
+
hint: room.about ?? room.id
|
|
598
|
+
})),
|
|
599
|
+
initialValues: preservedRoomIds.length > 0 ? preservedRoomIds : params.rooms.map((room) => room.id)
|
|
600
|
+
});
|
|
601
|
+
if (roomIds.length > 0) return roomIds;
|
|
602
|
+
await params.prompter.note("Select at least one authorized room, or go back to leave setup.", "Buzz room selection required");
|
|
603
|
+
}
|
|
607
604
|
}
|
|
608
605
|
async function noteBuzzAccessInstructions(params) {
|
|
609
|
-
const npub =
|
|
610
|
-
const hex = params.publicKey ?? "<64_CHAR_BOT_PUBLIC_KEY>";
|
|
606
|
+
const npub = nip19.npubEncode(params.publicKey);
|
|
611
607
|
await params.prompter.note([
|
|
612
608
|
...params.discoveryError ? [`Status: ${params.discoveryError}`, ""] : [],
|
|
613
609
|
`Relay: ${params.relayUrl}`,
|
|
614
610
|
`Bot npub: ${npub}`,
|
|
615
|
-
`Bot hex public key: ${
|
|
611
|
+
`Bot hex public key: ${params.publicKey}`,
|
|
616
612
|
"",
|
|
617
613
|
"Run as the existing human room owner/admin:",
|
|
618
|
-
`buzz channels add-member --channel <ROOM_UUID> --pubkey ${
|
|
614
|
+
`buzz channels add-member --channel <ROOM_UUID> --pubkey ${params.publicKey} --role bot`,
|
|
619
615
|
"",
|
|
620
616
|
"OpenClaw is waiting for Buzz to confirm the Bot role automatically.",
|
|
621
617
|
"Local `just dev` needs no separate community-member step.",
|
|
622
|
-
`Closed relay only: first run buzz-admin add-member --pubkey ${
|
|
618
|
+
`Closed relay only: first run buzz-admin add-member --pubkey ${params.publicKey} --role member.`,
|
|
623
619
|
"Never paste that human private key into OpenClaw."
|
|
624
620
|
].join("\n"), "Buzz room access required");
|
|
625
621
|
}
|
|
@@ -632,10 +628,11 @@ function createBuzzSetupWizard(dependencies = {}) {
|
|
|
632
628
|
const generatedPrivateKeys = /* @__PURE__ */ new WeakMap();
|
|
633
629
|
return {
|
|
634
630
|
channel,
|
|
635
|
-
getStatus: async ({ cfg }) => {
|
|
636
|
-
const
|
|
637
|
-
|
|
638
|
-
|
|
631
|
+
getStatus: async ({ cfg, accountOverrides }) => {
|
|
632
|
+
const { configured, enabled } = resolveBuzzAccount({
|
|
633
|
+
cfg,
|
|
634
|
+
accountId: accountOverrides.buzz
|
|
635
|
+
});
|
|
639
636
|
const status = !configured ? "needs relay URL and bot identity" : enabled ? "configured" : "configured but disabled";
|
|
640
637
|
return {
|
|
641
638
|
channel,
|
|
@@ -644,20 +641,47 @@ function createBuzzSetupWizard(dependencies = {}) {
|
|
|
644
641
|
selectionHint: status
|
|
645
642
|
};
|
|
646
643
|
},
|
|
647
|
-
configure: async ({ cfg, prompter, options }) => {
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
644
|
+
configure: async ({ cfg, prompter, options, accountOverrides, shouldPromptAccountIds }) => {
|
|
645
|
+
let accountId = resolveBuzzAccountConfig({
|
|
646
|
+
cfg,
|
|
647
|
+
accountId: accountOverrides.buzz
|
|
648
|
+
}).accountId;
|
|
649
|
+
if (shouldPromptAccountIds && !accountOverrides.buzz?.trim()) accountId = await promptAccountId({
|
|
650
|
+
cfg,
|
|
651
|
+
prompter,
|
|
652
|
+
label: "Buzz",
|
|
653
|
+
currentId: accountId,
|
|
654
|
+
listAccountIds: listBuzzAccountIds,
|
|
655
|
+
defaultAccountId: accountId
|
|
656
|
+
});
|
|
657
|
+
const { config: existingBuzzConfig } = resolveBuzzAccountConfig({
|
|
658
|
+
cfg,
|
|
659
|
+
accountId
|
|
660
|
+
});
|
|
661
|
+
const rootPolicy = cfg.channels?.buzz;
|
|
662
|
+
const rawAccount = rootPolicy?.accounts?.[accountId];
|
|
663
|
+
const hasExistingAccessConfig = rootPolicy?.groupPolicy !== void 0 || rootPolicy?.groupAllowFrom !== void 0 || rawAccount?.groupPolicy !== void 0 || rawAccount?.groupAllowFrom !== void 0 || existingBuzzConfig.groups !== void 0;
|
|
664
|
+
const existingAccount = resolveBuzzAccount({
|
|
665
|
+
cfg,
|
|
666
|
+
accountId
|
|
667
|
+
});
|
|
668
|
+
const useFreshAccessDefaults = !existingAccount.configured && !hasExistingAccessConfig;
|
|
669
|
+
const configuredRelayUrl = existingAccount.relayUrl;
|
|
651
670
|
const relayUrl = await resolveRelayUrl({
|
|
652
|
-
configuredValue:
|
|
671
|
+
configuredValue: configuredRelayUrl,
|
|
653
672
|
prompter
|
|
654
673
|
});
|
|
655
|
-
let next =
|
|
656
|
-
|
|
657
|
-
|
|
674
|
+
let next = patchBuzzAccountConfig({
|
|
675
|
+
cfg,
|
|
676
|
+
accountId,
|
|
677
|
+
patch: {
|
|
678
|
+
enabled: true,
|
|
679
|
+
relayUrl
|
|
680
|
+
}
|
|
658
681
|
});
|
|
659
682
|
const identity = await resolvePrivateKey({
|
|
660
683
|
cfg: next,
|
|
684
|
+
accountId,
|
|
661
685
|
prompter,
|
|
662
686
|
secretInputMode: options?.secretInputMode,
|
|
663
687
|
generate,
|
|
@@ -666,15 +690,14 @@ function createBuzzSetupWizard(dependencies = {}) {
|
|
|
666
690
|
});
|
|
667
691
|
next = identity.cfg;
|
|
668
692
|
const privateKey = identity.resolvedPrivateKey;
|
|
669
|
-
|
|
670
|
-
if (privateKey) publicKey = resolveBuzzPublicKey(privateKey);
|
|
671
|
-
if (!privateKey) {
|
|
672
|
-
await prompter.note("OpenClaw cannot resolve the configured private-key reference during setup, so room access cannot be verified. The relay URL and identity reference will be saved with Buzz disabled. Make the secret available and rerun setup.", "Buzz setup paused");
|
|
673
|
-
return pauseBuzzSetup(next);
|
|
674
|
-
}
|
|
693
|
+
const publicKey = resolveBuzzPublicKey(privateKey);
|
|
675
694
|
let discoveredRooms = [];
|
|
676
695
|
let discoveryError;
|
|
677
|
-
const authTag =
|
|
696
|
+
const authTag = await resolveSetupCredential({
|
|
697
|
+
cfg: next,
|
|
698
|
+
accountId,
|
|
699
|
+
field: "authTag"
|
|
700
|
+
});
|
|
678
701
|
const discoverAuthorizedRooms = async () => {
|
|
679
702
|
try {
|
|
680
703
|
const rooms = await discoverRooms({
|
|
@@ -725,17 +748,13 @@ function createBuzzSetupWizard(dependencies = {}) {
|
|
|
725
748
|
progress.stop(discoveredRooms.length > 0 ? "Buzz room access confirmed" : "Buzz room access not found");
|
|
726
749
|
if (discoveredRooms.length === 0 && discoveryError) await prompter.note(discoveryError, "Buzz room access not ready");
|
|
727
750
|
}
|
|
728
|
-
const configuredGroups =
|
|
751
|
+
const configuredGroups = existingBuzzConfig.groups ?? {};
|
|
729
752
|
const roomIds = await promptRooms({
|
|
730
753
|
rooms: discoveredRooms,
|
|
731
754
|
configuredRoomIds: Object.keys(configuredGroups),
|
|
732
755
|
prompter
|
|
733
756
|
});
|
|
734
|
-
|
|
735
|
-
await prompter.note("No rooms were selected. Relay URL and bot identity will be saved with Buzz disabled.", "Buzz setup paused");
|
|
736
|
-
return pauseBuzzSetup(next);
|
|
737
|
-
}
|
|
738
|
-
const existingDefault = cfg.channels?.buzz?.defaultTo;
|
|
757
|
+
const existingDefault = existingBuzzConfig.defaultTo;
|
|
739
758
|
const defaultTo = roomIds.length === 1 ? roomIds[0] : await prompter.select({
|
|
740
759
|
message: "Choose the default Buzz room target",
|
|
741
760
|
options: roomIds.map((roomId) => {
|
|
@@ -747,35 +766,43 @@ function createBuzzSetupWizard(dependencies = {}) {
|
|
|
747
766
|
}),
|
|
748
767
|
initialValue: existingDefault && roomIds.includes(existingDefault) ? existingDefault : roomIds[0]
|
|
749
768
|
});
|
|
750
|
-
next =
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
769
|
+
next = patchBuzzAccountConfig({
|
|
770
|
+
cfg: next,
|
|
771
|
+
accountId,
|
|
772
|
+
patch: {
|
|
773
|
+
...useFreshAccessDefaults ? {
|
|
774
|
+
groupPolicy: "open",
|
|
775
|
+
groupAllowFrom: void 0
|
|
776
|
+
} : {},
|
|
777
|
+
groups: Object.fromEntries(roomIds.map((roomId) => [roomId, {
|
|
778
|
+
...configuredGroups[roomId],
|
|
779
|
+
enabled: configuredGroups[roomId]?.enabled ?? true,
|
|
780
|
+
requireMention: configuredGroups[roomId]?.requireMention ?? !useFreshAccessDefaults
|
|
781
|
+
}])),
|
|
782
|
+
defaultTo
|
|
783
|
+
}
|
|
761
784
|
});
|
|
762
785
|
options?.onPostWriteHook?.({
|
|
763
786
|
channel,
|
|
764
|
-
accountId
|
|
787
|
+
accountId,
|
|
765
788
|
run: async ({ runtime }) => await verifyAfterWrite({
|
|
766
|
-
accountId
|
|
789
|
+
accountId,
|
|
767
790
|
target: defaultTo,
|
|
768
791
|
runtime
|
|
769
792
|
})
|
|
770
793
|
});
|
|
771
794
|
return {
|
|
772
795
|
cfg: next,
|
|
773
|
-
accountId
|
|
796
|
+
accountId
|
|
774
797
|
};
|
|
775
798
|
},
|
|
776
|
-
disable: (cfg) =>
|
|
799
|
+
disable: (cfg) => patchTopLevelChannelConfigSection({
|
|
800
|
+
cfg,
|
|
801
|
+
channel,
|
|
802
|
+
patch: { enabled: false }
|
|
803
|
+
})
|
|
777
804
|
};
|
|
778
805
|
}
|
|
779
806
|
const buzzSetupWizard = createBuzzSetupWizard();
|
|
780
807
|
//#endregion
|
|
781
|
-
export {
|
|
808
|
+
export { startBuzzRoomMembershipNotifications as i, buzzSetupContract as n, discoverBuzzRooms as r, buzzSetupWizard as t };
|