@coolclaw/coolclaw 0.5.1 → 1.0.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/{chunk-FFEQQ4B4.js → chunk-D346LLBV.js} +137 -45
- package/dist/{chunk-KLWIUZCZ.js → chunk-TPXBPYZ2.js} +3 -5
- package/dist/cli-metadata.d.ts +1 -1
- package/dist/cli-metadata.js +2 -4
- package/dist/index.d.ts +2 -34
- package/dist/index.js +3 -8
- package/dist/setup-entry.d.ts +1 -1
- package/dist/setup-entry.js +1 -2
- package/dist/{types-DYTarCqf.d.ts → types-y7-Cr6xf.d.ts} +1 -1
- package/package.json +9 -9
- package/dist/chunk-FBTRQUNW.js +0 -346
- package/dist/chunk-Q3NF4NWE.js +0 -105
- package/dist/setup-OG74IIBU.js +0 -13
|
@@ -1,7 +1,45 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
// src/binding.ts
|
|
2
|
+
import { mkdir, readFile, rename, writeFile, chmod } from "fs/promises";
|
|
3
|
+
import { homedir } from "os";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import { fileURLToPath } from "url";
|
|
6
|
+
function defaultBindingFile(home = homedir()) {
|
|
7
|
+
return path.join(home, ".config", "coolclaw", "agent_binding.json");
|
|
8
|
+
}
|
|
9
|
+
async function readTokenRef(tokenRef) {
|
|
10
|
+
if (!tokenRef) return void 0;
|
|
11
|
+
if (tokenRef.startsWith("env:")) {
|
|
12
|
+
return process.env[tokenRef.slice("env:".length)] || void 0;
|
|
13
|
+
}
|
|
14
|
+
if (tokenRef.startsWith("file://")) {
|
|
15
|
+
const tokenPath = fileURLToPath(tokenRef);
|
|
16
|
+
return (await readFile(tokenPath, "utf8")).trim() || void 0;
|
|
17
|
+
}
|
|
18
|
+
return void 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// src/config.ts
|
|
22
|
+
import { z } from "zod";
|
|
23
|
+
var CoolclawConfigSchema = z.object({
|
|
24
|
+
gatewayUrl: z.string().url().optional().describe("Riddle gateway URL"),
|
|
25
|
+
agentId: z.string().optional().describe("Riddle agent ID"),
|
|
26
|
+
tokenSecretRef: z.string().optional().describe("Token secret reference (file:// or env:)"),
|
|
27
|
+
allowFrom: z.array(z.string()).optional().describe("Allowed sender IDs"),
|
|
28
|
+
dmPolicy: z.enum(["allowlist", "pairing", "open"]).optional().describe("DM access policy"),
|
|
29
|
+
enabled: z.boolean().optional().describe("Whether the account is enabled"),
|
|
30
|
+
name: z.string().optional().describe("Account display name")
|
|
31
|
+
});
|
|
32
|
+
function normalizeGatewayUrl(value) {
|
|
33
|
+
return value.trim().replace(/\/+$/, "");
|
|
34
|
+
}
|
|
35
|
+
function buildWsUrl(gatewayUrl, lastAckedSeq) {
|
|
36
|
+
const baseUrl = normalizeGatewayUrl(gatewayUrl).replace(/^https:\/\//, "wss://").replace(/^http:\/\//, "ws://");
|
|
37
|
+
return `${baseUrl}/ws/channel?lastAckedSeq=${lastAckedSeq}`;
|
|
38
|
+
}
|
|
39
|
+
async function resolveAccountToken(account) {
|
|
40
|
+
if (account.tokenSecret) return account.tokenSecret;
|
|
41
|
+
return readTokenRef(account.tokenSecretRef);
|
|
42
|
+
}
|
|
5
43
|
|
|
6
44
|
// src/runtime.ts
|
|
7
45
|
var _runtime;
|
|
@@ -15,7 +53,7 @@ function getCoolclawRuntime() {
|
|
|
15
53
|
// src/ack-store.ts
|
|
16
54
|
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
|
|
17
55
|
import { join } from "path";
|
|
18
|
-
import { homedir } from "os";
|
|
56
|
+
import { homedir as homedir2 } from "os";
|
|
19
57
|
var InMemoryAckStore = class {
|
|
20
58
|
cursors = /* @__PURE__ */ new Map();
|
|
21
59
|
async getLastAckedSeq(accountKey) {
|
|
@@ -37,7 +75,7 @@ var FileAckStore = class {
|
|
|
37
75
|
cursors = /* @__PURE__ */ new Map();
|
|
38
76
|
dir;
|
|
39
77
|
constructor(dir) {
|
|
40
|
-
this.dir = dir ?? join(
|
|
78
|
+
this.dir = dir ?? join(homedir2(), ".openclaw", "extensions", "coolclaw", ".ack-store");
|
|
41
79
|
if (!existsSync(this.dir)) {
|
|
42
80
|
mkdirSync(this.dir, { recursive: true });
|
|
43
81
|
}
|
|
@@ -171,13 +209,13 @@ function renderPlayerInfo(list, selfSeat) {
|
|
|
171
209
|
if (list.length === 0) return "\uFF08\u65E0\u5EA7\u4F4D\u4FE1\u606F\uFF09";
|
|
172
210
|
return list.map((p) => {
|
|
173
211
|
const seat = asNumberOrNull(p.seat);
|
|
174
|
-
const
|
|
212
|
+
const playerStatus = p.alive === true ? "\u5B58\u6D3B" : p.alive === false ? "\u5DF2\u6B7B\u4EA1" : "\u53C2\u8D5B";
|
|
175
213
|
if (seat != null && selfSeat != null && seat === selfSeat) {
|
|
176
214
|
const name = asString(p.name, "\u672A\u77E5");
|
|
177
215
|
const voice = asString(p.voiceDesc, "");
|
|
178
|
-
return `\u5EA7\u4F4D${seat}\uFF08\u4F60\u81EA\u5DF1\uFF0C${name}${voice ? `\uFF0C${voice}` : ""}\uFF0C${
|
|
216
|
+
return `\u5EA7\u4F4D${seat}\uFF08\u4F60\u81EA\u5DF1\uFF0C${name}${voice ? `\uFF0C${voice}` : ""}\uFF0C${playerStatus}\uFF09`;
|
|
179
217
|
}
|
|
180
|
-
return `\u5EA7\u4F4D${seat ?? "?"}\uFF08${
|
|
218
|
+
return `\u5EA7\u4F4D${seat ?? "?"}\uFF08${playerStatus}\uFF09`;
|
|
181
219
|
}).join("\uFF1B");
|
|
182
220
|
}
|
|
183
221
|
function stripAudioSuffix(line) {
|
|
@@ -190,20 +228,42 @@ function renderHistory(history) {
|
|
|
190
228
|
function renderAliveSeats(seats) {
|
|
191
229
|
return seats.length === 0 ? "\uFF08\u65E0\uFF09" : `[${seats.join(", ")}]`;
|
|
192
230
|
}
|
|
231
|
+
function asMvpCandidates(v) {
|
|
232
|
+
if (!Array.isArray(v)) return [];
|
|
233
|
+
return v.flatMap((item) => {
|
|
234
|
+
if (typeof item === "number" && Number.isFinite(item)) {
|
|
235
|
+
return [{ agentId: item, seatNumber: null }];
|
|
236
|
+
}
|
|
237
|
+
const record = asRecord(item);
|
|
238
|
+
const agentId = asNumberOrNull(record.agentId) ?? asNumberOrNull(record.targetAgentId);
|
|
239
|
+
if (agentId == null) return [];
|
|
240
|
+
const seatNumber = asNumberOrNull(record.seatNumber) ?? asNumberOrNull(record.seat);
|
|
241
|
+
return [{ agentId, seatNumber }];
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
function renderMvpCandidateList(candidates, selfAgentId) {
|
|
245
|
+
if (candidates.length === 0) return "\uFF08\u5019\u9009\u4FE1\u606F\u7F3A\u5931\uFF1B\u7B49\u5F85\u5E73\u53F0\u8D85\u65F6\u515C\u5E95\uFF09";
|
|
246
|
+
return candidates.map((candidate) => {
|
|
247
|
+
const seat = candidate.seatNumber == null ? "?" : candidate.seatNumber;
|
|
248
|
+
const selfMark = selfAgentId != null && candidate.agentId === selfAgentId ? "\uFF08\u4F60\u81EA\u5DF1\uFF0C\u4E0D\u80FD\u6295\u7ED9\u81EA\u5DF1\uFF09" : "";
|
|
249
|
+
return `- \u5EA7\u4F4D${seat} / Agent ${candidate.agentId}${selfMark}`;
|
|
250
|
+
}).join("\n");
|
|
251
|
+
}
|
|
193
252
|
function renderHeader(eventType, outer, payload) {
|
|
194
253
|
const round = asNumberOrNull(outer.round) ?? 1;
|
|
195
254
|
const selfSeat = asNumberOrNull(payload.selfSeat);
|
|
196
255
|
const selfRole = asString(payload.selfRole, "\u672A\u77E5");
|
|
197
256
|
const selfName = asString(payload.selfAgentName, "");
|
|
198
|
-
const phase = eventType.startsWith("DAY_") || eventType === "LAST_WORD_TURN" || eventType === "HUNTER_SKILL_TURN" ? "\u767D\u5929" : "\u591C\u665A";
|
|
257
|
+
const phase = eventType === "MVP_VOTE_REQUEST" ? "\u8D5B\u540E" : eventType.startsWith("DAY_") || eventType === "LAST_WORD_TURN" || eventType === "HUNTER_SKILL_TURN" ? "\u767D\u5929" : "\u591C\u665A";
|
|
199
258
|
const aliveSeats = asNumberArray(payload.aliveSeats);
|
|
259
|
+
const seatsLabel = eventType === "MVP_VOTE_REQUEST" ? "MVP \u5019\u9009\u5EA7\u4F4D" : "\u5F53\u524D\u5B58\u6D3B\u5EA7\u4F4D";
|
|
200
260
|
const playerInfo = renderPlayerInfo(asRecordArray(payload.playerInfoList), selfSeat);
|
|
201
261
|
const history = renderHistory(asStringArray(payload.scopedHistory));
|
|
202
262
|
return [
|
|
203
263
|
`[\u6E38\u620F] \u72FC\u4EBA\u6740 \xB7 \u7B2C ${round} \u8F6E \xB7 ${phase} \xB7 ${describeEventType(eventType)}`,
|
|
204
264
|
``,
|
|
205
265
|
`\u4F60\u662F\u5EA7\u4F4D ${selfSeat ?? "?"} \u7684 ${selfRole}${selfName ? `\uFF08${selfName}\uFF09` : ""}\u3002`,
|
|
206
|
-
|
|
266
|
+
`${seatsLabel}\uFF1A${renderAliveSeats(aliveSeats)}\u3002`,
|
|
207
267
|
`\u5168\u4F53\u73A9\u5BB6\uFF1A${playerInfo}`,
|
|
208
268
|
``,
|
|
209
269
|
`\u3010\u8FD1\u671F\u5386\u53F2\uFF08\u4EC5\u4F60\u53EF\u89C1\uFF09\u3011`,
|
|
@@ -227,6 +287,8 @@ function describeEventType(eventType) {
|
|
|
227
287
|
return "\u767D\u5929\u6295\u7968";
|
|
228
288
|
case "HUNTER_SKILL_TURN":
|
|
229
289
|
return "\u730E\u4EBA\u6280\u80FD";
|
|
290
|
+
case "MVP_VOTE_REQUEST":
|
|
291
|
+
return "MVP \u6295\u7968";
|
|
230
292
|
default:
|
|
231
293
|
return eventType;
|
|
232
294
|
}
|
|
@@ -247,6 +309,8 @@ function renderTask(eventType, payload) {
|
|
|
247
309
|
return renderDayVoteTurn(payload);
|
|
248
310
|
case "HUNTER_SKILL_TURN":
|
|
249
311
|
return renderHunterTurn(payload);
|
|
312
|
+
case "MVP_VOTE_REQUEST":
|
|
313
|
+
return renderMvpVoteRequest(payload);
|
|
250
314
|
default:
|
|
251
315
|
return renderUnknownTurn(eventType);
|
|
252
316
|
}
|
|
@@ -381,6 +445,23 @@ function renderHunterTurn(payload) {
|
|
|
381
445
|
`<ACTION>{"actionType":"HUNTER_PASS","actionData":{}}</ACTION>`
|
|
382
446
|
].join("\n");
|
|
383
447
|
}
|
|
448
|
+
function renderMvpVoteRequest(payload) {
|
|
449
|
+
const candidates = asMvpCandidates(payload.candidates);
|
|
450
|
+
const selfAgentId = asNumberOrNull(payload.selfAgentId);
|
|
451
|
+
const round = asNumberOrNull(payload.round) ?? 1;
|
|
452
|
+
const deadlineSeconds = asNumberOrNull(payload.deadlineSeconds);
|
|
453
|
+
return [
|
|
454
|
+
`\u3010\u4EFB\u52A1\u3011\u8D5B\u540E MVP \u6295\u7968\uFF08\u7B2C ${round} \u8F6E\uFF09`,
|
|
455
|
+
deadlineSeconds != null ? `\u8BF7\u5728 ${deadlineSeconds} \u79D2\u5185\u4ECE\u5019\u9009\u5BF9\u8C61\u91CC\u9009\u51FA\u4F60\u8BA4\u4E3A\u672C\u5C40\u8D21\u732E\u6700\u5927\u7684 Agent\u3002` : `\u8BF7\u4ECE\u5019\u9009\u5BF9\u8C61\u91CC\u9009\u51FA\u4F60\u8BA4\u4E3A\u672C\u5C40\u8D21\u732E\u6700\u5927\u7684 Agent\u3002`,
|
|
456
|
+
`\u5019\u9009\u5BF9\u8C61\uFF08targetAgentId \u5FC5\u987B\u4ECE\u8FD9\u91CC\u9009\uFF0C\u4E0D\u80FD\u6295\u7ED9\u81EA\u5DF1\uFF09\uFF1A`,
|
|
457
|
+
renderMvpCandidateList(candidates, selfAgentId),
|
|
458
|
+
``,
|
|
459
|
+
`\u8BF7\u7EFC\u5408\u53D1\u8A00\u3001\u6295\u7968\u3001\u5173\u952E\u884C\u52A8\u548C\u80DC\u8D1F\u8D21\u732E\uFF0C\u7B80\u77ED\u8BF4\u660E\u7406\u7531\uFF0C\u7136\u540E\u5728\u56DE\u590D\u6700\u540E\u4E25\u683C\u6309\u4EE5\u4E0B\u683C\u5F0F\u58F0\u660E\u52A8\u4F5C\uFF1A`,
|
|
460
|
+
`<ACTION>`,
|
|
461
|
+
`{"actionType":"MVP_VOTE","actionData":{"targetAgentId":<number>,"round":${round},"reason":"<\u7B80\u8FF0>"}}`,
|
|
462
|
+
`</ACTION>`
|
|
463
|
+
].join("\n");
|
|
464
|
+
}
|
|
384
465
|
function renderUnknownTurn(eventType) {
|
|
385
466
|
return [
|
|
386
467
|
`\u3010\u63D0\u793A\u3011\u672A\u8BC6\u522B\u7684\u6E38\u620F\u4E8B\u4EF6\u7C7B\u578B\uFF1A${eventType}`,
|
|
@@ -389,7 +470,8 @@ function renderUnknownTurn(eventType) {
|
|
|
389
470
|
}
|
|
390
471
|
function buildGameEventPrompt(eventType, eventData) {
|
|
391
472
|
const outer = asRecord(eventData);
|
|
392
|
-
const
|
|
473
|
+
const nestedPayload = asRecord(outer.payload);
|
|
474
|
+
const payload = Object.keys(nestedPayload).length > 0 ? nestedPayload : outer;
|
|
393
475
|
const header = renderHeader(eventType, outer, payload);
|
|
394
476
|
const task = renderTask(eventType, payload);
|
|
395
477
|
const footer = `
|
|
@@ -809,16 +891,38 @@ function parseAgentAction(text) {
|
|
|
809
891
|
function asNumberArray2(v) {
|
|
810
892
|
return Array.isArray(v) ? v.filter((x) => typeof x === "number") : [];
|
|
811
893
|
}
|
|
894
|
+
function asNumberOrNull2(v) {
|
|
895
|
+
return typeof v === "number" && Number.isFinite(v) ? v : null;
|
|
896
|
+
}
|
|
812
897
|
function asRecord2(v) {
|
|
813
898
|
return typeof v === "object" && v !== null ? v : {};
|
|
814
899
|
}
|
|
900
|
+
function hasKeys(record) {
|
|
901
|
+
return Object.keys(record).length > 0;
|
|
902
|
+
}
|
|
903
|
+
function candidateAgentIds(v) {
|
|
904
|
+
if (!Array.isArray(v)) return [];
|
|
905
|
+
return v.flatMap((item) => {
|
|
906
|
+
if (typeof item === "number" && Number.isFinite(item)) return [item];
|
|
907
|
+
const record = asRecord2(item);
|
|
908
|
+
const agentId = asNumberOrNull2(record.agentId) ?? asNumberOrNull2(record.targetAgentId);
|
|
909
|
+
return agentId == null ? [] : [agentId];
|
|
910
|
+
});
|
|
911
|
+
}
|
|
815
912
|
function pickRandomAlive(aliveSeats, excludeSeat) {
|
|
816
913
|
const candidates = excludeSeat != null ? aliveSeats.filter((s) => s !== excludeSeat) : aliveSeats;
|
|
817
914
|
if (candidates.length === 0) return null;
|
|
818
915
|
return candidates[Math.floor(Math.random() * candidates.length)];
|
|
819
916
|
}
|
|
917
|
+
function pickRandomAgent(candidates, excludeAgentId) {
|
|
918
|
+
const eligible = excludeAgentId == null ? candidates : candidates.filter((candidate) => candidate !== excludeAgentId);
|
|
919
|
+
if (eligible.length === 0) return candidates[0] ?? null;
|
|
920
|
+
return eligible[Math.floor(Math.random() * eligible.length)];
|
|
921
|
+
}
|
|
820
922
|
function fallbackActionFor(eventType, eventData) {
|
|
821
|
-
const
|
|
923
|
+
const outer = asRecord2(eventData);
|
|
924
|
+
const nestedPayload = asRecord2(outer.payload);
|
|
925
|
+
const payload = hasKeys(nestedPayload) ? nestedPayload : outer;
|
|
822
926
|
const aliveSeats = asNumberArray2(payload.aliveSeats);
|
|
823
927
|
const selfSeat = typeof payload.selfSeat === "number" ? payload.selfSeat : void 0;
|
|
824
928
|
switch (eventType) {
|
|
@@ -863,6 +967,22 @@ function fallbackActionFor(eventType, eventData) {
|
|
|
863
967
|
};
|
|
864
968
|
case "HUNTER_SKILL_TURN":
|
|
865
969
|
return { actionType: "HUNTER_PASS", actionData: {} };
|
|
970
|
+
case "MVP_VOTE_REQUEST": {
|
|
971
|
+
const selfAgentId = asNumberOrNull2(payload.selfAgentId);
|
|
972
|
+
const candidates = candidateAgentIds(payload.candidates);
|
|
973
|
+
const targetAgentId = pickRandomAgent(candidates, selfAgentId);
|
|
974
|
+
if (targetAgentId == null) {
|
|
975
|
+
return { actionType: "UNKNOWN", actionData: {} };
|
|
976
|
+
}
|
|
977
|
+
return {
|
|
978
|
+
actionType: "MVP_VOTE",
|
|
979
|
+
actionData: {
|
|
980
|
+
targetAgentId,
|
|
981
|
+
round: asNumberOrNull2(payload.round) ?? asNumberOrNull2(outer.round) ?? 1,
|
|
982
|
+
reason: "\uFF08\u6258\u7BA1\uFF1ALLM \u672A\u7ED9\u51FA\u5408\u6CD5 MVP \u6295\u7968\uFF09"
|
|
983
|
+
}
|
|
984
|
+
};
|
|
985
|
+
}
|
|
866
986
|
default:
|
|
867
987
|
return { actionType: "UNKNOWN", actionData: {} };
|
|
868
988
|
}
|
|
@@ -1098,12 +1218,12 @@ function isRecord3(value) {
|
|
|
1098
1218
|
// src/version.ts
|
|
1099
1219
|
import { readFileSync as readFileSync2 } from "fs";
|
|
1100
1220
|
import { join as join2, dirname } from "path";
|
|
1101
|
-
import { fileURLToPath } from "url";
|
|
1221
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1102
1222
|
var _version;
|
|
1103
1223
|
function getPluginVersion() {
|
|
1104
1224
|
if (_version) return _version;
|
|
1105
1225
|
try {
|
|
1106
|
-
const pkgPath = join2(dirname(
|
|
1226
|
+
const pkgPath = join2(dirname(fileURLToPath2(import.meta.url)), "..", "package.json");
|
|
1107
1227
|
const pkg = JSON.parse(readFileSync2(pkgPath, "utf-8"));
|
|
1108
1228
|
_version = pkg.version ?? "0.0.0";
|
|
1109
1229
|
} catch {
|
|
@@ -1524,36 +1644,6 @@ var coolclawChannelPlugin = createChatChannelPlugin({
|
|
|
1524
1644
|
ctx.log?.info(`[${ctx.accountId}] CoolClaw client stopped via stopAccount`);
|
|
1525
1645
|
}
|
|
1526
1646
|
}
|
|
1527
|
-
},
|
|
1528
|
-
/** auth 适配器 — 支持 openclaw channels login --channel coolclaw 原生命令 */
|
|
1529
|
-
auth: {
|
|
1530
|
-
async login({ cfg, accountId, verbose }) {
|
|
1531
|
-
const resolvedAccountId = accountId?.trim() || "default";
|
|
1532
|
-
const account = coolclawChannelPlugin.config.resolveAccount(cfg, resolvedAccountId);
|
|
1533
|
-
const { validateAgentToken, runCoolclawSetup } = await import("./setup-OG74IIBU.js");
|
|
1534
|
-
const existingToken = account.tokenSecretRef ? await resolveAccountToken(account) : void 0;
|
|
1535
|
-
if (existingToken) {
|
|
1536
|
-
const gatewayUrl = account.gatewayUrl ?? "https://agits-xa.baidu.com/riddle";
|
|
1537
|
-
const valid = await validateAgentToken(gatewayUrl, existingToken);
|
|
1538
|
-
if (valid) {
|
|
1539
|
-
if (verbose) console.log("[coolclaw] Already authenticated.");
|
|
1540
|
-
return;
|
|
1541
|
-
}
|
|
1542
|
-
}
|
|
1543
|
-
if (verbose) console.log("[coolclaw] Running setup...");
|
|
1544
|
-
const result = await runCoolclawSetup({
|
|
1545
|
-
gatewayUrl: account.gatewayUrl,
|
|
1546
|
-
accountId: resolvedAccountId,
|
|
1547
|
-
autoRestart: false
|
|
1548
|
-
// login 场景不需要重启网关
|
|
1549
|
-
});
|
|
1550
|
-
console.log(`[coolclaw] Agent ID: ${result.agentId}`);
|
|
1551
|
-
if (result.mode === "register") {
|
|
1552
|
-
console.log("[coolclaw] New agent registered. Please claim this agent on Riddle platform to start chatting.");
|
|
1553
|
-
} else {
|
|
1554
|
-
console.log("[coolclaw] Reusing existing agent binding.");
|
|
1555
|
-
}
|
|
1556
|
-
}
|
|
1557
1647
|
}
|
|
1558
1648
|
},
|
|
1559
1649
|
security: {
|
|
@@ -1663,6 +1753,8 @@ var coolclawChannelPlugin = createChatChannelPlugin({
|
|
|
1663
1753
|
});
|
|
1664
1754
|
|
|
1665
1755
|
export {
|
|
1756
|
+
defaultBindingFile,
|
|
1757
|
+
CoolclawConfigSchema,
|
|
1666
1758
|
setCoolclawRuntime,
|
|
1667
1759
|
coolclawChannelPlugin
|
|
1668
1760
|
};
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
|
+
CoolclawConfigSchema,
|
|
2
3
|
coolclawChannelPlugin,
|
|
4
|
+
defaultBindingFile,
|
|
3
5
|
setCoolclawRuntime
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import {
|
|
6
|
-
CoolclawConfigSchema,
|
|
7
|
-
defaultBindingFile
|
|
8
|
-
} from "./chunk-Q3NF4NWE.js";
|
|
6
|
+
} from "./chunk-D346LLBV.js";
|
|
9
7
|
|
|
10
8
|
// index.ts
|
|
11
9
|
import { defineChannelPluginEntry, buildChannelConfigSchema } from "openclaw/plugin-sdk/core";
|
package/dist/cli-metadata.d.ts
CHANGED
package/dist/cli-metadata.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
index_default
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-FBTRQUNW.js";
|
|
6
|
-
import "./chunk-Q3NF4NWE.js";
|
|
3
|
+
} from "./chunk-TPXBPYZ2.js";
|
|
4
|
+
import "./chunk-D346LLBV.js";
|
|
7
5
|
|
|
8
6
|
// cli-metadata.ts
|
|
9
7
|
var cli_metadata_default = index_default;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,37 +1,5 @@
|
|
|
1
1
|
import { OpenClawPluginApi, ChannelPlugin, PluginRuntime } from 'openclaw/plugin-sdk/core';
|
|
2
|
-
import { C as
|
|
3
|
-
|
|
4
|
-
type AgentRegistrationInput = {
|
|
5
|
-
name: string;
|
|
6
|
-
bio: string;
|
|
7
|
-
tags: string;
|
|
8
|
-
/** 邀请码(平台处于邀请制阶段时必填,由主人提供) */
|
|
9
|
-
inviteCode?: string;
|
|
10
|
-
};
|
|
11
|
-
type CoolclawSetupOptions = {
|
|
12
|
-
gatewayUrl?: string;
|
|
13
|
-
bindingFile?: string;
|
|
14
|
-
openclawConfigPath?: string;
|
|
15
|
-
workspaceDir?: string;
|
|
16
|
-
registration?: AgentRegistrationInput;
|
|
17
|
-
allowFrom?: string[];
|
|
18
|
-
dmPolicy?: CoolclawDmPolicy;
|
|
19
|
-
dryRun?: boolean;
|
|
20
|
-
forceRegister?: boolean;
|
|
21
|
-
/** @deprecated 网关重启已移至 CLI 安装器处理,此选项不再使用 */
|
|
22
|
-
autoRestart?: boolean;
|
|
23
|
-
/** 账户 ID,默认 "default" */
|
|
24
|
-
accountId?: string;
|
|
25
|
-
};
|
|
26
|
-
type CoolclawSetupResult = {
|
|
27
|
-
mode: "reuse" | "register" | "dry-run";
|
|
28
|
-
gatewayUrl: string;
|
|
29
|
-
agentId: string;
|
|
30
|
-
bindingFile: string;
|
|
31
|
-
openclawConfigPath: string;
|
|
32
|
-
tokenSavedTo: string;
|
|
33
|
-
};
|
|
34
|
-
declare function runCoolclawSetup(options?: CoolclawSetupOptions): Promise<CoolclawSetupResult>;
|
|
2
|
+
import { C as CoolclawAccount } from './types-y7-Cr6xf.js';
|
|
35
3
|
|
|
36
4
|
declare const entry: {
|
|
37
5
|
id: string;
|
|
@@ -43,4 +11,4 @@ declare const entry: {
|
|
|
43
11
|
setChannelRuntime?: (runtime: PluginRuntime) => void;
|
|
44
12
|
};
|
|
45
13
|
|
|
46
|
-
export {
|
|
14
|
+
export { entry as default };
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
index_default
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import {
|
|
6
|
-
runCoolclawSetup
|
|
7
|
-
} from "./chunk-FBTRQUNW.js";
|
|
8
|
-
import "./chunk-Q3NF4NWE.js";
|
|
3
|
+
} from "./chunk-TPXBPYZ2.js";
|
|
4
|
+
import "./chunk-D346LLBV.js";
|
|
9
5
|
export {
|
|
10
|
-
index_default as default
|
|
11
|
-
runCoolclawSetup
|
|
6
|
+
index_default as default
|
|
12
7
|
};
|
package/dist/setup-entry.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as openclaw_plugin_sdk_core from 'openclaw/plugin-sdk/core';
|
|
2
|
-
import {
|
|
2
|
+
import { C as CoolclawAccount } from './types-y7-Cr6xf.js';
|
|
3
3
|
|
|
4
4
|
declare const _default: {
|
|
5
5
|
plugin: openclaw_plugin_sdk_core.ChannelPlugin<CoolclawAccount, unknown, unknown>;
|
package/dist/setup-entry.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coolclaw/coolclaw",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "OpenClaw native channel plugin for Riddle/CoolClaw chat.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -41,16 +41,16 @@
|
|
|
41
41
|
"lint": "tsc --noEmit"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"ws": "
|
|
45
|
-
"zod": "
|
|
44
|
+
"ws": "^8.20.1",
|
|
45
|
+
"zod": "^4.4.3"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@types/node": "
|
|
49
|
-
"@types/ws": "
|
|
48
|
+
"@types/node": "^25.8.0",
|
|
49
|
+
"@types/ws": "^8.18.1",
|
|
50
50
|
"openclaw": "^2026.4.27",
|
|
51
|
-
"tsup": "
|
|
52
|
-
"typescript": "
|
|
53
|
-
"vitest": "
|
|
51
|
+
"tsup": "^8.5.1",
|
|
52
|
+
"typescript": "^6.0.3",
|
|
53
|
+
"vitest": "^4.1.6"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
56
|
"openclaw": ">=2026.3.22 <2027"
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"runtimeSetupEntry": "./dist/setup-entry.js",
|
|
72
72
|
"install": {
|
|
73
73
|
"npmSpec": "@coolclaw/coolclaw",
|
|
74
|
-
"expectedIntegrity": "sha512-
|
|
74
|
+
"expectedIntegrity": "sha512-k3P69ef3+p51LIu6gbIVG4Y48e0wev2sJHPf8EqUd7RvQk8S6HNiVKLNnna6Izg767DYT5gN3GaG6fMUfngsWg==",
|
|
75
75
|
"defaultChoice": "npm",
|
|
76
76
|
"minHostVersion": ">=2026.3.22"
|
|
77
77
|
},
|
package/dist/chunk-FBTRQUNW.js
DELETED
|
@@ -1,346 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
defaultBindingFile,
|
|
3
|
-
defaultOpenClawConfigFile,
|
|
4
|
-
defaultTokenFile,
|
|
5
|
-
loadBinding,
|
|
6
|
-
normalizeGatewayUrl,
|
|
7
|
-
readTokenRef,
|
|
8
|
-
saveAgentToken,
|
|
9
|
-
saveBinding,
|
|
10
|
-
touchBinding
|
|
11
|
-
} from "./chunk-Q3NF4NWE.js";
|
|
12
|
-
|
|
13
|
-
// src/setup.ts
|
|
14
|
-
import { access } from "fs/promises";
|
|
15
|
-
import { readFile as readFile3 } from "fs/promises";
|
|
16
|
-
import path3 from "path";
|
|
17
|
-
import { homedir } from "os";
|
|
18
|
-
|
|
19
|
-
// src/identity.ts
|
|
20
|
-
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
21
|
-
import path from "path";
|
|
22
|
-
var BEGIN_MARKER = "<!-- BEGIN_RIDDLE_IDENTITY -->";
|
|
23
|
-
var END_MARKER = "<!-- END_RIDDLE_IDENTITY -->";
|
|
24
|
-
async function updateRiddleIdentitySummary(summary) {
|
|
25
|
-
await mkdir(summary.workspaceDir, { recursive: true });
|
|
26
|
-
const identityFile = path.join(summary.workspaceDir, "IDENTITY.md");
|
|
27
|
-
const existing = await readExisting(identityFile);
|
|
28
|
-
const block = [
|
|
29
|
-
BEGIN_MARKER,
|
|
30
|
-
"## Riddle Platform",
|
|
31
|
-
"",
|
|
32
|
-
`Riddle Agent ID: ${summary.agentId}`,
|
|
33
|
-
`Riddle Gateway: ${normalizeGatewayUrl(summary.gatewayUrl)}`,
|
|
34
|
-
`Riddle Binding: ${summary.bindingFile}`,
|
|
35
|
-
"Messaging: handled by the CoolClaw OpenClaw channel.",
|
|
36
|
-
"Non-message platform actions: handled by the Riddle skill.",
|
|
37
|
-
END_MARKER
|
|
38
|
-
].join("\n");
|
|
39
|
-
const next = replaceBlock(existing, block);
|
|
40
|
-
await writeFile(identityFile, next.endsWith("\n") ? next : `${next}
|
|
41
|
-
`);
|
|
42
|
-
}
|
|
43
|
-
async function readExisting(identityFile) {
|
|
44
|
-
try {
|
|
45
|
-
return await readFile(identityFile, "utf8");
|
|
46
|
-
} catch {
|
|
47
|
-
return "";
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
function replaceBlock(existing, block) {
|
|
51
|
-
const start = existing.indexOf(BEGIN_MARKER);
|
|
52
|
-
const end = existing.indexOf(END_MARKER);
|
|
53
|
-
if (start >= 0 && end >= start) {
|
|
54
|
-
return `${existing.slice(0, start).trimEnd()}
|
|
55
|
-
|
|
56
|
-
${block}
|
|
57
|
-
${existing.slice(end + END_MARKER.length).trimStart()}`;
|
|
58
|
-
}
|
|
59
|
-
return existing.trim() ? `${existing.trimEnd()}
|
|
60
|
-
|
|
61
|
-
${block}
|
|
62
|
-
` : `${block}
|
|
63
|
-
`;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// src/openclaw-config.ts
|
|
67
|
-
import { mkdir as mkdir2, readFile as readFile2, rename, writeFile as writeFile2 } from "fs/promises";
|
|
68
|
-
import path2 from "path";
|
|
69
|
-
async function patchCoolclawAccountConfig(patch) {
|
|
70
|
-
const config = await readOpenClawConfig(patch.configPath);
|
|
71
|
-
const channels = ensureRecord(config, "channels");
|
|
72
|
-
const coolclaw = ensureRecord(channels, "coolclaw");
|
|
73
|
-
const accounts = ensureRecord(coolclaw, "accounts");
|
|
74
|
-
const account = {
|
|
75
|
-
name: `Riddle Agent ${patch.agentId}`,
|
|
76
|
-
enabled: true,
|
|
77
|
-
gatewayUrl: normalizeGatewayUrl(patch.gatewayUrl),
|
|
78
|
-
agentId: patch.agentId,
|
|
79
|
-
tokenSecretRef: patch.tokenSecretRef,
|
|
80
|
-
dmPolicy: patch.dmPolicy ?? "open"
|
|
81
|
-
};
|
|
82
|
-
const effectiveDmPolicy = account.dmPolicy;
|
|
83
|
-
if (patch.allowFrom && patch.allowFrom.length > 0) {
|
|
84
|
-
account.allowFrom = patch.allowFrom;
|
|
85
|
-
} else if (effectiveDmPolicy === "open") {
|
|
86
|
-
account.allowFrom = ["*"];
|
|
87
|
-
}
|
|
88
|
-
accounts.default = account;
|
|
89
|
-
await writeOpenClawConfig(patch.configPath, config);
|
|
90
|
-
}
|
|
91
|
-
async function readOpenClawConfig(configPath) {
|
|
92
|
-
try {
|
|
93
|
-
const parsed = JSON.parse(await readFile2(configPath, "utf8"));
|
|
94
|
-
return isRecord(parsed) ? parsed : {};
|
|
95
|
-
} catch {
|
|
96
|
-
return {};
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
async function writeOpenClawConfig(configPath, config) {
|
|
100
|
-
await mkdir2(path2.dirname(configPath), { recursive: true });
|
|
101
|
-
const tmpFile = `${configPath}.${process.pid}.tmp`;
|
|
102
|
-
await writeFile2(tmpFile, `${JSON.stringify(config, null, 2)}
|
|
103
|
-
`);
|
|
104
|
-
await rename(tmpFile, configPath);
|
|
105
|
-
}
|
|
106
|
-
function ensureRecord(parent, key) {
|
|
107
|
-
const existing = parent[key];
|
|
108
|
-
if (isRecord(existing)) return existing;
|
|
109
|
-
const created = {};
|
|
110
|
-
parent[key] = created;
|
|
111
|
-
return created;
|
|
112
|
-
}
|
|
113
|
-
function isRecord(value) {
|
|
114
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// src/setup.ts
|
|
118
|
-
async function registerAgent(baseUrl, input) {
|
|
119
|
-
const res = await fetch(`${normalizeGatewayUrl(baseUrl)}/api/agent/register`, {
|
|
120
|
-
method: "POST",
|
|
121
|
-
headers: { "Content-Type": "application/json" },
|
|
122
|
-
body: JSON.stringify(input)
|
|
123
|
-
});
|
|
124
|
-
const body = await res.json();
|
|
125
|
-
if (!res.ok || body.code !== 200) {
|
|
126
|
-
throw new Error(body.message ?? `Agent register failed: ${res.status}`);
|
|
127
|
-
}
|
|
128
|
-
if (!body.data?.agentId || !body.data.token) {
|
|
129
|
-
throw new Error("Agent register response missing agentId or token");
|
|
130
|
-
}
|
|
131
|
-
return {
|
|
132
|
-
agentId: String(body.data.agentId),
|
|
133
|
-
token: String(body.data.token)
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
async function resolveSetupBinding(input) {
|
|
137
|
-
const gatewayUrl = normalizeGatewayUrl(input.gatewayUrl);
|
|
138
|
-
const existingAgentId = input.existingAgentId?.trim();
|
|
139
|
-
const existingTokenSecretRef = input.existingTokenSecretRef?.trim();
|
|
140
|
-
if (existingAgentId && existingTokenSecretRef) {
|
|
141
|
-
return {
|
|
142
|
-
mode: "reuse",
|
|
143
|
-
gatewayUrl,
|
|
144
|
-
agentId: existingAgentId,
|
|
145
|
-
tokenSecretRef: existingTokenSecretRef
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
if (!input.registration) {
|
|
149
|
-
throw new Error("CoolClaw setup requires an existing binding or registration input");
|
|
150
|
-
}
|
|
151
|
-
const registered = await registerAgent(gatewayUrl, input.registration);
|
|
152
|
-
return {
|
|
153
|
-
mode: "register",
|
|
154
|
-
gatewayUrl,
|
|
155
|
-
agentId: registered.agentId,
|
|
156
|
-
token: registered.token
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
async function validateAgentToken(baseUrl, token) {
|
|
160
|
-
const res = await fetch(`${normalizeGatewayUrl(baseUrl)}/api/users/me`, {
|
|
161
|
-
headers: { Authorization: `Bearer ${token}` }
|
|
162
|
-
});
|
|
163
|
-
if (!res.ok) return false;
|
|
164
|
-
const body = await res.json();
|
|
165
|
-
return body.code === 200 && body.data?.identityType === "AGENT";
|
|
166
|
-
}
|
|
167
|
-
async function runCoolclawSetup(options = {}) {
|
|
168
|
-
const gatewayUrl = normalizeGatewayUrl(options.gatewayUrl ?? "https://agits-xa.baidu.com/riddle");
|
|
169
|
-
const bindingFile = options.bindingFile ?? defaultBindingFile();
|
|
170
|
-
const openclawConfigPath = options.openclawConfigPath ?? defaultOpenClawConfigFile();
|
|
171
|
-
const existingBinding = await loadBinding(bindingFile);
|
|
172
|
-
const existingToken = await readTokenRef(existingBinding.tokenRef);
|
|
173
|
-
const canReuse = !options.forceRegister && existingBinding.agentId.length > 0 && Boolean(existingToken) && await validateAgentToken(gatewayUrl, existingToken);
|
|
174
|
-
if (options.dryRun) {
|
|
175
|
-
return {
|
|
176
|
-
mode: canReuse ? "reuse" : "dry-run",
|
|
177
|
-
gatewayUrl,
|
|
178
|
-
agentId: canReuse ? existingBinding.agentId : "",
|
|
179
|
-
bindingFile,
|
|
180
|
-
openclawConfigPath,
|
|
181
|
-
tokenSavedTo: tokenFileFromBinding(existingBinding, bindingFile)
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
const binding = canReuse ? existingBinding : await registerAndPersistBinding({
|
|
185
|
-
gatewayUrl,
|
|
186
|
-
bindingFile,
|
|
187
|
-
registration: await resolveRegistrationInput(
|
|
188
|
-
options.registration,
|
|
189
|
-
options.workspaceDir,
|
|
190
|
-
openclawConfigPath
|
|
191
|
-
)
|
|
192
|
-
});
|
|
193
|
-
const tokenFile = tokenFileFromBinding(binding, bindingFile);
|
|
194
|
-
if (!options.dryRun) {
|
|
195
|
-
await patchCoolclawAccountConfig({
|
|
196
|
-
configPath: openclawConfigPath,
|
|
197
|
-
gatewayUrl,
|
|
198
|
-
agentId: binding.agentId,
|
|
199
|
-
tokenSecretRef: binding.tokenRef ?? `file://${tokenFile}`,
|
|
200
|
-
allowFrom: options.allowFrom,
|
|
201
|
-
dmPolicy: options.dmPolicy
|
|
202
|
-
});
|
|
203
|
-
if (options.workspaceDir) {
|
|
204
|
-
await updateRiddleIdentitySummary({
|
|
205
|
-
workspaceDir: options.workspaceDir,
|
|
206
|
-
agentId: binding.agentId,
|
|
207
|
-
gatewayUrl,
|
|
208
|
-
bindingFile,
|
|
209
|
-
tokenRef: binding.tokenRef ?? void 0
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
console.log("[coolclaw] Setup complete. Restart the gateway to apply changes: openclaw gateway restart");
|
|
213
|
-
}
|
|
214
|
-
return {
|
|
215
|
-
mode: options.dryRun ? "dry-run" : canReuse ? "reuse" : "register",
|
|
216
|
-
gatewayUrl,
|
|
217
|
-
agentId: binding.agentId,
|
|
218
|
-
bindingFile,
|
|
219
|
-
openclawConfigPath,
|
|
220
|
-
tokenSavedTo: tokenFile
|
|
221
|
-
};
|
|
222
|
-
}
|
|
223
|
-
async function registerAndPersistBinding(input) {
|
|
224
|
-
const registered = await registerAgent(input.gatewayUrl, input.registration);
|
|
225
|
-
const valid = await validateAgentToken(input.gatewayUrl, registered.token);
|
|
226
|
-
if (!valid) {
|
|
227
|
-
throw new Error("Newly registered Riddle token did not validate as an AGENT token");
|
|
228
|
-
}
|
|
229
|
-
const tokenFile = defaultTokenFile(input.bindingFile, registered.agentId);
|
|
230
|
-
await saveAgentToken(tokenFile, registered.token);
|
|
231
|
-
const binding = touchBinding({
|
|
232
|
-
agentId: registered.agentId,
|
|
233
|
-
tokenRef: `file://${tokenFile}`,
|
|
234
|
-
runtimeType: "openclaw",
|
|
235
|
-
lastAckedSeq: 0
|
|
236
|
-
});
|
|
237
|
-
await saveBinding(input.bindingFile, binding);
|
|
238
|
-
return binding;
|
|
239
|
-
}
|
|
240
|
-
function tokenFileFromBinding(binding, bindingFile) {
|
|
241
|
-
if (binding.tokenRef?.startsWith("file://")) {
|
|
242
|
-
return binding.tokenRef.slice("file://".length);
|
|
243
|
-
}
|
|
244
|
-
return defaultTokenFile(bindingFile, binding.agentId);
|
|
245
|
-
}
|
|
246
|
-
var IDENTITY_PLACEHOLDERS = /* @__PURE__ */ new Set([
|
|
247
|
-
"pick something you like",
|
|
248
|
-
"ai? robot? familiar? ghost in the machine? something weirder?",
|
|
249
|
-
"how do you come across? sharp? warm? chaotic? calm?",
|
|
250
|
-
"your signature - pick one that feels right",
|
|
251
|
-
"workspace-relative path, http(s) url, or data uri"
|
|
252
|
-
]);
|
|
253
|
-
function parseIdentityMarkdown(content) {
|
|
254
|
-
const result = {};
|
|
255
|
-
for (const line of content.split(/\r?\n/)) {
|
|
256
|
-
const cleaned = line.trim().replace(/^\s*-\s*/, "");
|
|
257
|
-
const colonIdx = cleaned.indexOf(":");
|
|
258
|
-
if (colonIdx === -1) continue;
|
|
259
|
-
const label = cleaned.slice(0, colonIdx).replace(/[*_]/g, "").trim().toLowerCase();
|
|
260
|
-
const value = cleaned.slice(colonIdx + 1).replace(/^[*_]+|[*_]+$/g, "").trim();
|
|
261
|
-
if (!value || IDENTITY_PLACEHOLDERS.has(value.toLowerCase().replace(/[()]/g, "").trim())) continue;
|
|
262
|
-
if (label === "name") result.name = value;
|
|
263
|
-
if (label === "creature") result.creature = value;
|
|
264
|
-
if (label === "vibe") result.vibe = value;
|
|
265
|
-
if (label === "theme") result.theme = value;
|
|
266
|
-
}
|
|
267
|
-
return result;
|
|
268
|
-
}
|
|
269
|
-
async function readWorkspaceDirFromOpenclawConfig(configPath) {
|
|
270
|
-
try {
|
|
271
|
-
const content = await readFile3(configPath, "utf-8");
|
|
272
|
-
const config = JSON.parse(content);
|
|
273
|
-
const workspace = config.agents?.defaults?.workspace;
|
|
274
|
-
if (typeof workspace === "string" && workspace.trim()) {
|
|
275
|
-
return workspace.trim();
|
|
276
|
-
}
|
|
277
|
-
} catch {
|
|
278
|
-
}
|
|
279
|
-
const defaultWorkspace = path3.join(homedir(), ".openclaw", "workspace");
|
|
280
|
-
try {
|
|
281
|
-
await access(defaultWorkspace);
|
|
282
|
-
return defaultWorkspace;
|
|
283
|
-
} catch {
|
|
284
|
-
return void 0;
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
async function readIdentityFromWorkspace(workspaceDir) {
|
|
288
|
-
try {
|
|
289
|
-
const content = await readFile3(path3.join(workspaceDir, "IDENTITY.md"), "utf-8");
|
|
290
|
-
return parseIdentityMarkdown(content);
|
|
291
|
-
} catch {
|
|
292
|
-
return {};
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
async function readIdentityFromOpenclawConfig(configPath) {
|
|
296
|
-
try {
|
|
297
|
-
const content = await readFile3(configPath, "utf-8");
|
|
298
|
-
const config = JSON.parse(content);
|
|
299
|
-
const defaultsName = config.agents?.defaults?.identity?.name || config.agents?.defaults?.name;
|
|
300
|
-
if (defaultsName) return { name: defaultsName };
|
|
301
|
-
const mainAgent = config.agents?.list?.find((a) => a.id === "main") || config.agents?.list?.[0];
|
|
302
|
-
if (mainAgent?.identity?.name || mainAgent?.name) {
|
|
303
|
-
return { name: mainAgent.identity?.name || mainAgent.name };
|
|
304
|
-
}
|
|
305
|
-
return {};
|
|
306
|
-
} catch {
|
|
307
|
-
return {};
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
async function resolveRegistrationInput(explicitRegistration, workspaceDir, openclawConfigPath) {
|
|
311
|
-
if (explicitRegistration?.name && explicitRegistration?.bio && explicitRegistration.name !== "CoolClaw Agent" && explicitRegistration.bio !== "OpenClaw agent connected through CoolClaw channel.") {
|
|
312
|
-
return explicitRegistration;
|
|
313
|
-
}
|
|
314
|
-
let identityName;
|
|
315
|
-
let identityBio;
|
|
316
|
-
const resolvedWorkspaceDir = workspaceDir ?? await readWorkspaceDirFromOpenclawConfig(openclawConfigPath);
|
|
317
|
-
if (resolvedWorkspaceDir) {
|
|
318
|
-
const identity = await readIdentityFromWorkspace(resolvedWorkspaceDir);
|
|
319
|
-
if (identity.name) {
|
|
320
|
-
identityName = identity.name;
|
|
321
|
-
}
|
|
322
|
-
const bioParts = [identity.creature, identity.vibe, identity.theme].filter(Boolean);
|
|
323
|
-
if (bioParts.length > 0) {
|
|
324
|
-
identityBio = bioParts.join(". ") + ".";
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
if (!identityName) {
|
|
328
|
-
const configIdentity = await readIdentityFromOpenclawConfig(openclawConfigPath);
|
|
329
|
-
identityName = configIdentity.name;
|
|
330
|
-
}
|
|
331
|
-
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[-:T]/g, "").slice(4, 12);
|
|
332
|
-
return {
|
|
333
|
-
name: explicitRegistration?.name && explicitRegistration.name !== "CoolClaw Agent" ? explicitRegistration.name : identityName ?? `RiddleAgent-${stamp}`,
|
|
334
|
-
bio: explicitRegistration?.bio && explicitRegistration.bio !== "OpenClaw agent connected through CoolClaw channel." ? explicitRegistration.bio : identityBio ?? "OpenClaw agent connected through CoolClaw channel.",
|
|
335
|
-
tags: explicitRegistration?.tags ?? JSON.stringify(["assistant", "openclaw", "coolclaw"]),
|
|
336
|
-
// 邀请码:CLI 参数 > 环境变量 RIDDLE_INVITE_CODE
|
|
337
|
-
inviteCode: explicitRegistration?.inviteCode ?? process.env.RIDDLE_INVITE_CODE?.trim() ?? void 0
|
|
338
|
-
};
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
export {
|
|
342
|
-
registerAgent,
|
|
343
|
-
resolveSetupBinding,
|
|
344
|
-
validateAgentToken,
|
|
345
|
-
runCoolclawSetup
|
|
346
|
-
};
|
package/dist/chunk-Q3NF4NWE.js
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
// src/binding.ts
|
|
2
|
-
import { mkdir, readFile, rename, writeFile, chmod } from "fs/promises";
|
|
3
|
-
import { homedir } from "os";
|
|
4
|
-
import path from "path";
|
|
5
|
-
import { fileURLToPath } from "url";
|
|
6
|
-
var RIDDLE_BINDING_VERSION = 1;
|
|
7
|
-
function defaultBindingFile(home = homedir()) {
|
|
8
|
-
return path.join(home, ".config", "coolclaw", "agent_binding.json");
|
|
9
|
-
}
|
|
10
|
-
function defaultOpenClawConfigFile(home = homedir()) {
|
|
11
|
-
return path.join(home, ".openclaw", "openclaw.json");
|
|
12
|
-
}
|
|
13
|
-
function defaultTokenFile(bindingFile, agentId) {
|
|
14
|
-
return path.join(path.dirname(bindingFile), `agent_token_${agentId}.txt`);
|
|
15
|
-
}
|
|
16
|
-
async function loadBinding(bindingFile) {
|
|
17
|
-
try {
|
|
18
|
-
const raw = JSON.parse(await readFile(bindingFile, "utf8"));
|
|
19
|
-
return {
|
|
20
|
-
agentId: String(raw.agentId ?? ""),
|
|
21
|
-
tokenRef: typeof raw.tokenRef === "string" ? raw.tokenRef : null,
|
|
22
|
-
runtimeType: String(raw.runtimeType ?? "unknown"),
|
|
23
|
-
lastAckedSeq: Number(raw.lastAckedSeq ?? 0),
|
|
24
|
-
bindingVersion: Number(raw.bindingVersion ?? RIDDLE_BINDING_VERSION),
|
|
25
|
-
updatedAt: typeof raw.updatedAt === "string" ? raw.updatedAt : void 0
|
|
26
|
-
};
|
|
27
|
-
} catch {
|
|
28
|
-
return {
|
|
29
|
-
agentId: "",
|
|
30
|
-
tokenRef: null,
|
|
31
|
-
runtimeType: "unknown",
|
|
32
|
-
lastAckedSeq: 0,
|
|
33
|
-
bindingVersion: RIDDLE_BINDING_VERSION
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
function touchBinding(binding) {
|
|
38
|
-
return {
|
|
39
|
-
...binding,
|
|
40
|
-
bindingVersion: RIDDLE_BINDING_VERSION,
|
|
41
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z")
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
async function saveBinding(bindingFile, binding) {
|
|
45
|
-
await mkdir(path.dirname(bindingFile), { recursive: true });
|
|
46
|
-
const tmpFile = `${bindingFile}.${process.pid}.tmp`;
|
|
47
|
-
await writeFile(tmpFile, `${JSON.stringify(touchBinding(binding), null, 2)}
|
|
48
|
-
`, { mode: 384 });
|
|
49
|
-
await chmod(tmpFile, 384);
|
|
50
|
-
await rename(tmpFile, bindingFile);
|
|
51
|
-
}
|
|
52
|
-
async function saveAgentToken(tokenFile, token) {
|
|
53
|
-
await mkdir(path.dirname(tokenFile), { recursive: true });
|
|
54
|
-
await writeFile(tokenFile, token, { mode: 384 });
|
|
55
|
-
await chmod(tokenFile, 384);
|
|
56
|
-
}
|
|
57
|
-
async function readTokenRef(tokenRef) {
|
|
58
|
-
if (!tokenRef) return void 0;
|
|
59
|
-
if (tokenRef.startsWith("env:")) {
|
|
60
|
-
return process.env[tokenRef.slice("env:".length)] || void 0;
|
|
61
|
-
}
|
|
62
|
-
if (tokenRef.startsWith("file://")) {
|
|
63
|
-
const tokenPath = fileURLToPath(tokenRef);
|
|
64
|
-
return (await readFile(tokenPath, "utf8")).trim() || void 0;
|
|
65
|
-
}
|
|
66
|
-
return void 0;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// src/config.ts
|
|
70
|
-
import { z } from "zod";
|
|
71
|
-
var CoolclawConfigSchema = z.object({
|
|
72
|
-
gatewayUrl: z.string().url().optional().describe("Riddle gateway URL"),
|
|
73
|
-
agentId: z.string().optional().describe("Riddle agent ID"),
|
|
74
|
-
tokenSecretRef: z.string().optional().describe("Token secret reference (file:// or env:)"),
|
|
75
|
-
allowFrom: z.array(z.string()).optional().describe("Allowed sender IDs"),
|
|
76
|
-
dmPolicy: z.enum(["allowlist", "pairing", "open"]).optional().describe("DM access policy"),
|
|
77
|
-
enabled: z.boolean().optional().describe("Whether the account is enabled"),
|
|
78
|
-
name: z.string().optional().describe("Account display name")
|
|
79
|
-
});
|
|
80
|
-
function normalizeGatewayUrl(value) {
|
|
81
|
-
return value.trim().replace(/\/+$/, "");
|
|
82
|
-
}
|
|
83
|
-
function buildWsUrl(gatewayUrl, lastAckedSeq) {
|
|
84
|
-
const baseUrl = normalizeGatewayUrl(gatewayUrl).replace(/^https:\/\//, "wss://").replace(/^http:\/\//, "ws://");
|
|
85
|
-
return `${baseUrl}/ws/channel?lastAckedSeq=${lastAckedSeq}`;
|
|
86
|
-
}
|
|
87
|
-
async function resolveAccountToken(account) {
|
|
88
|
-
if (account.tokenSecret) return account.tokenSecret;
|
|
89
|
-
return readTokenRef(account.tokenSecretRef);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export {
|
|
93
|
-
defaultBindingFile,
|
|
94
|
-
defaultOpenClawConfigFile,
|
|
95
|
-
defaultTokenFile,
|
|
96
|
-
loadBinding,
|
|
97
|
-
touchBinding,
|
|
98
|
-
saveBinding,
|
|
99
|
-
saveAgentToken,
|
|
100
|
-
readTokenRef,
|
|
101
|
-
CoolclawConfigSchema,
|
|
102
|
-
normalizeGatewayUrl,
|
|
103
|
-
buildWsUrl,
|
|
104
|
-
resolveAccountToken
|
|
105
|
-
};
|
package/dist/setup-OG74IIBU.js
DELETED