@clawos-dev/clawd 0.2.275 → 0.2.276
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/cli.cjs +57 -59
- package/dist/dispatch/mcp-server.cjs +6 -1
- package/dist/share-md-viewer-error.html +1 -1
- package/dist/share-md-viewer.html +1 -1
- package/dist/share-ui/assets/{guest-DB_Gozzs.css → guest-BKKB9cOG.css} +1 -1
- package/dist/share-ui/assets/{guest-BKO48Nz8.js → guest-XaN4r7jJ.js} +1 -1
- package/dist/share-ui/guest.html +2 -2
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -6651,6 +6651,11 @@ var init_persona_schemas = __esm({
|
|
|
6651
6651
|
sandboxSettings: PersonaSandboxSettingsSchema.nullable().optional()
|
|
6652
6652
|
});
|
|
6653
6653
|
PersonaCreateArgsSchema = external_exports.object({
|
|
6654
|
+
// persona 身份。daemon 拼成 personaId = `persona-<slug>`——前缀由 daemon 拥有,调用方只给后半段,
|
|
6655
|
+
// 「所有 persona id 带该前缀」的约定由构造保证。与 label(显示名,可中文、可随时改)是两个概念:
|
|
6656
|
+
// 曾经只有 label、id 从 label 推,导致中文 label 被剥空后一律降级成 persona-persona。
|
|
6657
|
+
// 正则即安全边界——该值直接落进 ~/.clawd/personas/<id>/,此处排除 . / 空格后路径穿越无从构造。
|
|
6658
|
+
slug: external_exports.string().regex(/^[a-z0-9]+(-[a-z0-9]+)*$/).max(32),
|
|
6654
6659
|
label: external_exports.string().min(1),
|
|
6655
6660
|
personality: external_exports.string(),
|
|
6656
6661
|
model: external_exports.string().optional(),
|
|
@@ -7981,7 +7986,7 @@ var init_methods = __esm({
|
|
|
7981
7986
|
args: CapabilitiesGetArgs
|
|
7982
7987
|
},
|
|
7983
7988
|
"persona:create": {
|
|
7984
|
-
summary: "\u65B0\u5EFA persona\uFF08\u5199 PersonaFile + CLAUDE.md \u9AA8\u67B6\uFF09\u3002owner-only",
|
|
7989
|
+
summary: "\u65B0\u5EFA persona\uFF08\u5199 PersonaFile + CLAUDE.md \u9AA8\u67B6\uFF09\u3002owner-only\u3002slug \u53EA\u6536\u5C0F\u5199\u5B57\u6BCD\u6570\u5B57\u4E0E\u5355\u8FDE\u5B57\u7B26\uFF08^[a-z0-9]+(-[a-z0-9]+)*$\uFF0C\u226432\uFF09\uFF0Cdaemon \u62FC\u6210 personaId=persona-<slug>\uFF1B\u8BE5 id \u5DF2\u5B58\u5728\u5219\u62A5\u9519\uFF0C\u4E0D\u81EA\u52A8\u6539\u540D\u3002label \u662F\u663E\u793A\u540D\uFF0C\u4E0D\u53C2\u4E0E id \u63A8\u5BFC\uFF0C\u53EF\u7528\u4E2D\u6587",
|
|
7985
7990
|
args: PersonaCreateArgsSchema
|
|
7986
7991
|
},
|
|
7987
7992
|
"persona:list": {
|
|
@@ -47622,9 +47627,6 @@ var PersonaRegistry = class {
|
|
|
47622
47627
|
}
|
|
47623
47628
|
};
|
|
47624
47629
|
|
|
47625
|
-
// src/persona/manager.ts
|
|
47626
|
-
var import_node_crypto3 = __toESM(require("crypto"), 1);
|
|
47627
|
-
|
|
47628
47630
|
// src/skills/scanner.ts
|
|
47629
47631
|
var import_node_fs10 = __toESM(require("fs"), 1);
|
|
47630
47632
|
var import_node_os6 = __toESM(require("os"), 1);
|
|
@@ -47904,8 +47906,19 @@ var PersonaManager = class {
|
|
|
47904
47906
|
this.deps = deps;
|
|
47905
47907
|
}
|
|
47906
47908
|
deps;
|
|
47909
|
+
/**
|
|
47910
|
+
* slug 是 persona 的身份,label 只是显示名——两者刻意分开:id 落进文件路径 /
|
|
47911
|
+
* 分享链接且创建后不可改,label 可中文、可随时改。此前 id 从 label 推导,
|
|
47912
|
+
* 非 ascii 被剥空后一律 fallback 成 `persona-persona`。
|
|
47913
|
+
*
|
|
47914
|
+
* 撞名直接抛错而非改名:id 由调用方显式指定,静默换成带后缀的 id 等于把
|
|
47915
|
+
* 用户的选择偷偷改掉。字符集校验在 PersonaCreateArgsSchema(路径穿越边界)。
|
|
47916
|
+
*/
|
|
47907
47917
|
create(args) {
|
|
47908
|
-
const personaId2 =
|
|
47918
|
+
const personaId2 = `persona-${args.slug}`;
|
|
47919
|
+
if (this.deps.store.has(personaId2)) {
|
|
47920
|
+
throw new Error(`personaId already exists: ${personaId2}`);
|
|
47921
|
+
}
|
|
47909
47922
|
const now = Date.now();
|
|
47910
47923
|
const persona = {
|
|
47911
47924
|
personaId: personaId2,
|
|
@@ -47971,21 +47984,6 @@ var PersonaManager = class {
|
|
|
47971
47984
|
this.deps.store.remove(personaId2);
|
|
47972
47985
|
this.deps.registry.remove(personaId2);
|
|
47973
47986
|
}
|
|
47974
|
-
/**
|
|
47975
|
-
* label 转 4-16 char slug。优先用 `persona-<slug>`;若 slug 已被占用,追加 4 char
|
|
47976
|
-
* base64url 随机后缀直到不撞为止(最多 5 次,理论冲突 ≈ 2^-24,留个 panic 上限)。
|
|
47977
|
-
*/
|
|
47978
|
-
generatePersonaId(label) {
|
|
47979
|
-
const slug = label.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 16) || "persona";
|
|
47980
|
-
const base = `persona-${slug}`;
|
|
47981
|
-
if (!this.deps.store.has(base)) return base;
|
|
47982
|
-
for (let i = 0; i < 5; i++) {
|
|
47983
|
-
const rand = import_node_crypto3.default.randomBytes(3).toString("base64url").slice(0, 4);
|
|
47984
|
-
const candidate = `${base}-${rand}`;
|
|
47985
|
-
if (!this.deps.store.has(candidate)) return candidate;
|
|
47986
|
-
}
|
|
47987
|
-
throw new Error(`failed to generate unique personaId for label=${label}`);
|
|
47988
|
-
}
|
|
47989
47987
|
};
|
|
47990
47988
|
|
|
47991
47989
|
// src/persona/seed.ts
|
|
@@ -48545,7 +48543,7 @@ function tryLoadShareUi(logger) {
|
|
|
48545
48543
|
}
|
|
48546
48544
|
|
|
48547
48545
|
// src/visitor/visitor-token.ts
|
|
48548
|
-
var
|
|
48546
|
+
var import_node_crypto3 = __toESM(require("crypto"), 1);
|
|
48549
48547
|
|
|
48550
48548
|
// ../protocol/src/index.ts
|
|
48551
48549
|
init_runtime();
|
|
@@ -48553,7 +48551,7 @@ init_runtime();
|
|
|
48553
48551
|
// src/visitor/visitor-token.ts
|
|
48554
48552
|
var DOMAIN_PREFIX = "clawd-visitor-v1|";
|
|
48555
48553
|
function hmac(secret, body) {
|
|
48556
|
-
return
|
|
48554
|
+
return import_node_crypto3.default.createHmac("sha256", secret).update(`${DOMAIN_PREFIX}${body}`).digest("base64url");
|
|
48557
48555
|
}
|
|
48558
48556
|
function signVisitorToken(secret, payload) {
|
|
48559
48557
|
const body = Buffer.from(JSON.stringify(payload)).toString("base64url");
|
|
@@ -48566,7 +48564,7 @@ function verifyVisitorToken(secret, token, now) {
|
|
|
48566
48564
|
const sig = token.slice(dot + 1);
|
|
48567
48565
|
const expected = hmac(secret, body);
|
|
48568
48566
|
if (sig.length !== expected.length) return { ok: false, reason: "BAD_SIGNATURE" };
|
|
48569
|
-
if (!
|
|
48567
|
+
if (!import_node_crypto3.default.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
|
|
48570
48568
|
return { ok: false, reason: "BAD_SIGNATURE" };
|
|
48571
48569
|
}
|
|
48572
48570
|
let payload;
|
|
@@ -49268,7 +49266,7 @@ var CodexAdapter = class {
|
|
|
49268
49266
|
};
|
|
49269
49267
|
|
|
49270
49268
|
// src/tools/claude-tui.ts
|
|
49271
|
-
var
|
|
49269
|
+
var import_node_crypto4 = require("crypto");
|
|
49272
49270
|
var import_node_fs19 = __toESM(require("fs"), 1);
|
|
49273
49271
|
var import_node_os7 = __toESM(require("os"), 1);
|
|
49274
49272
|
var import_node_path17 = __toESM(require("path"), 1);
|
|
@@ -50156,7 +50154,7 @@ function observeScreenIdle(surface, opts) {
|
|
|
50156
50154
|
};
|
|
50157
50155
|
}
|
|
50158
50156
|
function shortHash(s) {
|
|
50159
|
-
return (0,
|
|
50157
|
+
return (0, import_node_crypto4.createHash)("sha1").update(s).digest("hex").slice(0, 8);
|
|
50160
50158
|
}
|
|
50161
50159
|
function firstLineDiff(prev, next) {
|
|
50162
50160
|
const p2 = prev.split("\n");
|
|
@@ -50870,7 +50868,7 @@ function resolveSourceJsonlPath(sourceFile, home) {
|
|
|
50870
50868
|
// src/shift/store.ts
|
|
50871
50869
|
var import_promises2 = __toESM(require("fs/promises"), 1);
|
|
50872
50870
|
var import_node_path26 = __toESM(require("path"), 1);
|
|
50873
|
-
var
|
|
50871
|
+
var import_node_crypto5 = require("crypto");
|
|
50874
50872
|
|
|
50875
50873
|
// src/shift/schedule.ts
|
|
50876
50874
|
var import_cron_parser = __toESM(require_dist(), 1);
|
|
@@ -50974,7 +50972,7 @@ function createShiftStore(deps) {
|
|
|
50974
50972
|
const shift = {
|
|
50975
50973
|
...input,
|
|
50976
50974
|
schedule,
|
|
50977
|
-
id: (0,
|
|
50975
|
+
id: (0, import_node_crypto5.randomUUID)(),
|
|
50978
50976
|
createdAtMs: now,
|
|
50979
50977
|
updatedAtMs: now,
|
|
50980
50978
|
state: { nextRunAtMs },
|
|
@@ -53678,7 +53676,7 @@ var ContactStore = class {
|
|
|
53678
53676
|
};
|
|
53679
53677
|
|
|
53680
53678
|
// src/contact/connect-remote.ts
|
|
53681
|
-
var
|
|
53679
|
+
var crypto4 = __toESM(require("crypto"), 1);
|
|
53682
53680
|
init_protocol();
|
|
53683
53681
|
var HANDSHAKE_TIMEOUT_MS = 5e3;
|
|
53684
53682
|
var RPC_TIMEOUT_MS = 5e3;
|
|
@@ -53733,7 +53731,7 @@ async function connectRemote(args) {
|
|
|
53733
53731
|
ws.once("close", onClose);
|
|
53734
53732
|
});
|
|
53735
53733
|
function call(method, payload) {
|
|
53736
|
-
const requestId =
|
|
53734
|
+
const requestId = crypto4.randomUUID();
|
|
53737
53735
|
return new Promise((resolve6, reject) => {
|
|
53738
53736
|
const onMessage = (raw) => {
|
|
53739
53737
|
let f;
|
|
@@ -53990,7 +53988,7 @@ function lookupMime(filePathOrName) {
|
|
|
53990
53988
|
}
|
|
53991
53989
|
|
|
53992
53990
|
// src/attachment/sign-url.ts
|
|
53993
|
-
var
|
|
53991
|
+
var import_node_crypto6 = __toESM(require("crypto"), 1);
|
|
53994
53992
|
var HMAC_ALGO = "sha256";
|
|
53995
53993
|
function base64urlEncode(buf) {
|
|
53996
53994
|
const b2 = typeof buf === "string" ? Buffer.from(buf, "utf8") : buf;
|
|
@@ -54008,7 +54006,7 @@ function decodeAbsPathFromUrl(encoded) {
|
|
|
54008
54006
|
var DOMAIN_PREFIX2 = "clawd-attach-v1|";
|
|
54009
54007
|
function computeSig(secret, absPath, e) {
|
|
54010
54008
|
const msg = e === null ? `${DOMAIN_PREFIX2}${absPath}` : `${DOMAIN_PREFIX2}${absPath}|${e}`;
|
|
54011
|
-
return
|
|
54009
|
+
return import_node_crypto6.default.createHmac(HMAC_ALGO, secret).update(msg).digest();
|
|
54012
54010
|
}
|
|
54013
54011
|
function signUrlParts(secret, absPath, ttlSeconds, now = Date.now) {
|
|
54014
54012
|
const e = ttlSeconds === null ? null : Math.floor(now() / 1e3) + ttlSeconds;
|
|
@@ -54043,7 +54041,7 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
|
|
|
54043
54041
|
if (provided.length !== expected.length) {
|
|
54044
54042
|
return { ok: false, code: "BAD_SIG" };
|
|
54045
54043
|
}
|
|
54046
|
-
if (!
|
|
54044
|
+
if (!import_node_crypto6.default.timingSafeEqual(provided, expected)) {
|
|
54047
54045
|
return { ok: false, code: "BAD_SIG" };
|
|
54048
54046
|
}
|
|
54049
54047
|
if (e !== null && now() / 1e3 > e) {
|
|
@@ -54055,7 +54053,7 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
|
|
|
54055
54053
|
// src/attachment/upload.ts
|
|
54056
54054
|
var import_node_fs30 = __toESM(require("fs"), 1);
|
|
54057
54055
|
var import_node_path33 = __toESM(require("path"), 1);
|
|
54058
|
-
var
|
|
54056
|
+
var import_node_crypto7 = __toESM(require("crypto"), 1);
|
|
54059
54057
|
var import_promises3 = require("stream/promises");
|
|
54060
54058
|
var UploadError = class extends Error {
|
|
54061
54059
|
constructor(code, message) {
|
|
@@ -54079,11 +54077,11 @@ async function writeUploadedAttachment(args) {
|
|
|
54079
54077
|
} catch (err) {
|
|
54080
54078
|
throw new UploadError("STORAGE_ERROR", `mkdir failed: ${err.message}`);
|
|
54081
54079
|
}
|
|
54082
|
-
const hasher =
|
|
54080
|
+
const hasher = import_node_crypto7.default.createHash("sha256");
|
|
54083
54081
|
let actualSize = 0;
|
|
54084
54082
|
const tmpPath = import_node_path33.default.join(
|
|
54085
54083
|
attachmentsRoot,
|
|
54086
|
-
`.upload-${process.pid}-${Date.now()}-${
|
|
54084
|
+
`.upload-${process.pid}-${Date.now()}-${import_node_crypto7.default.randomBytes(4).toString("hex")}`
|
|
54087
54085
|
);
|
|
54088
54086
|
try {
|
|
54089
54087
|
await (0, import_promises3.pipeline)(
|
|
@@ -54873,7 +54871,7 @@ function runAttachmentGc(args) {
|
|
|
54873
54871
|
// src/attachment/group.ts
|
|
54874
54872
|
var import_node_fs33 = __toESM(require("fs"), 1);
|
|
54875
54873
|
var import_node_path37 = __toESM(require("path"), 1);
|
|
54876
|
-
var
|
|
54874
|
+
var import_node_crypto8 = __toESM(require("crypto"), 1);
|
|
54877
54875
|
init_protocol();
|
|
54878
54876
|
var GroupFileStore = class {
|
|
54879
54877
|
dataDir;
|
|
@@ -54962,7 +54960,7 @@ var GroupFileStore = class {
|
|
|
54962
54960
|
entries[idx] = next;
|
|
54963
54961
|
} else {
|
|
54964
54962
|
next = {
|
|
54965
|
-
id: `gf-${
|
|
54963
|
+
id: `gf-${import_node_crypto8.default.randomBytes(6).toString("base64url")}`,
|
|
54966
54964
|
relPath: input.relPath,
|
|
54967
54965
|
from: input.from,
|
|
54968
54966
|
label: input.label,
|
|
@@ -55080,7 +55078,7 @@ function readSpawnedByDesktopFromEnv(env = process.env) {
|
|
|
55080
55078
|
// src/tunnel/tunnel-manager.ts
|
|
55081
55079
|
var import_node_fs38 = __toESM(require("fs"), 1);
|
|
55082
55080
|
var import_node_path42 = __toESM(require("path"), 1);
|
|
55083
|
-
var
|
|
55081
|
+
var import_node_crypto9 = __toESM(require("crypto"), 1);
|
|
55084
55082
|
var import_node_child_process10 = require("child_process");
|
|
55085
55083
|
|
|
55086
55084
|
// src/tunnel/tunnel-store.ts
|
|
@@ -55579,7 +55577,7 @@ var TunnelManager = class {
|
|
|
55579
55577
|
override: this.deps.frpcBinaryOverride ?? void 0
|
|
55580
55578
|
});
|
|
55581
55579
|
const tomlPath = import_node_path42.default.join(this.deps.dataDir, "frpc.toml");
|
|
55582
|
-
const proxyName = `clawd-${t.subdomain}-${localPort}-${
|
|
55580
|
+
const proxyName = `clawd-${t.subdomain}-${localPort}-${import_node_crypto9.default.randomBytes(3).toString("hex")}`;
|
|
55583
55581
|
const toml = buildFrpcToml({
|
|
55584
55582
|
serverAddr: t.frpsHost,
|
|
55585
55583
|
serverPort: t.frpsPort,
|
|
@@ -55680,7 +55678,7 @@ async function waitForFrpcReady(proc, timeoutMs) {
|
|
|
55680
55678
|
// src/tunnel/device-key.ts
|
|
55681
55679
|
var import_node_os14 = __toESM(require("os"), 1);
|
|
55682
55680
|
var import_node_path43 = __toESM(require("path"), 1);
|
|
55683
|
-
var
|
|
55681
|
+
var import_node_crypto10 = __toESM(require("crypto"), 1);
|
|
55684
55682
|
var DERIVE_SALT = "clawd-tunnel-device-v1";
|
|
55685
55683
|
function deriveStableDeviceKey(opts = {}) {
|
|
55686
55684
|
const hostname = opts.hostname ?? import_node_os14.default.hostname();
|
|
@@ -55690,13 +55688,13 @@ function deriveStableDeviceKey(opts = {}) {
|
|
|
55690
55688
|
const normalizedDataDir = opts.dataDir ? import_node_path43.default.resolve(opts.dataDir) : null;
|
|
55691
55689
|
const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
|
|
55692
55690
|
const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
|
|
55693
|
-
return
|
|
55691
|
+
return import_node_crypto10.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
|
|
55694
55692
|
}
|
|
55695
55693
|
|
|
55696
55694
|
// src/auth-store.ts
|
|
55697
55695
|
var import_node_fs39 = __toESM(require("fs"), 1);
|
|
55698
55696
|
var import_node_path44 = __toESM(require("path"), 1);
|
|
55699
|
-
var
|
|
55697
|
+
var import_node_crypto11 = __toESM(require("crypto"), 1);
|
|
55700
55698
|
var AUTH_FILE_NAME = "auth.json";
|
|
55701
55699
|
function authFilePath(dataDir) {
|
|
55702
55700
|
return import_node_path44.default.join(dataDir, AUTH_FILE_NAME);
|
|
@@ -55724,10 +55722,10 @@ function loadOrCreateAuthFile(opts) {
|
|
|
55724
55722
|
return next;
|
|
55725
55723
|
}
|
|
55726
55724
|
function defaultGenerateToken() {
|
|
55727
|
-
return
|
|
55725
|
+
return import_node_crypto11.default.randomBytes(32).toString("base64url");
|
|
55728
55726
|
}
|
|
55729
55727
|
function defaultGenerateOwnerPrincipalId() {
|
|
55730
|
-
return `owner-${
|
|
55728
|
+
return `owner-${import_node_crypto11.default.randomUUID()}`;
|
|
55731
55729
|
}
|
|
55732
55730
|
function readAuthFile(file) {
|
|
55733
55731
|
try {
|
|
@@ -55849,7 +55847,7 @@ var OwnerIdentityStore = class {
|
|
|
55849
55847
|
};
|
|
55850
55848
|
|
|
55851
55849
|
// src/feishu-auth/login-flow.ts
|
|
55852
|
-
var
|
|
55850
|
+
var import_node_crypto12 = __toESM(require("crypto"), 1);
|
|
55853
55851
|
var STATE_TTL_MS = 5 * 60 * 1e3;
|
|
55854
55852
|
var LoginFlow = class {
|
|
55855
55853
|
constructor(deps) {
|
|
@@ -55858,7 +55856,7 @@ var LoginFlow = class {
|
|
|
55858
55856
|
deps;
|
|
55859
55857
|
pendingStates = /* @__PURE__ */ new Map();
|
|
55860
55858
|
start() {
|
|
55861
|
-
const state =
|
|
55859
|
+
const state = import_node_crypto12.default.randomBytes(16).toString("base64url");
|
|
55862
55860
|
const now = (this.deps.now ?? Date.now)();
|
|
55863
55861
|
this.pendingStates.set(state, now);
|
|
55864
55862
|
this.gcExpired(now);
|
|
@@ -56124,7 +56122,7 @@ async function upsertDeviceBinding(opts) {
|
|
|
56124
56122
|
}
|
|
56125
56123
|
|
|
56126
56124
|
// src/feishu-auth/verify-token.ts
|
|
56127
|
-
var
|
|
56125
|
+
var crypto12 = __toESM(require("crypto"), 1);
|
|
56128
56126
|
var CONNECT_TOKEN_PREFIX = "clawdtk1";
|
|
56129
56127
|
function verifyConnectToken(args) {
|
|
56130
56128
|
const now = args.nowSeconds ?? Math.floor(Date.now() / 1e3);
|
|
@@ -56136,7 +56134,7 @@ function verifyConnectToken(args) {
|
|
|
56136
56134
|
const data = `${prefix}.${payloadB64}`;
|
|
56137
56135
|
let signatureValid = false;
|
|
56138
56136
|
try {
|
|
56139
|
-
signatureValid =
|
|
56137
|
+
signatureValid = crypto12.verify(
|
|
56140
56138
|
null,
|
|
56141
56139
|
Buffer.from(data, "utf8"),
|
|
56142
56140
|
args.publicKeyPem,
|
|
@@ -57931,7 +57929,7 @@ function computeMethodAccess(args) {
|
|
|
57931
57929
|
}
|
|
57932
57930
|
|
|
57933
57931
|
// src/version.ts
|
|
57934
|
-
var version = "0.2.
|
|
57932
|
+
var version = "0.2.276".length > 0 ? "0.2.276" : "dev";
|
|
57935
57933
|
|
|
57936
57934
|
// src/cli-probe/probe.ts
|
|
57937
57935
|
var fs54 = __toESM(require("fs"), 1);
|
|
@@ -58312,7 +58310,7 @@ init_protocol();
|
|
|
58312
58310
|
// src/extension/bundle-zip.ts
|
|
58313
58311
|
var import_promises6 = __toESM(require("fs/promises"), 1);
|
|
58314
58312
|
var import_node_path50 = __toESM(require("path"), 1);
|
|
58315
|
-
var
|
|
58313
|
+
var import_node_crypto13 = __toESM(require("crypto"), 1);
|
|
58316
58314
|
var import_jszip2 = __toESM(require_lib3(), 1);
|
|
58317
58315
|
async function bundleExtensionDir(dir) {
|
|
58318
58316
|
const entries = await listFilesSorted(dir);
|
|
@@ -58327,7 +58325,7 @@ async function bundleExtensionDir(dir) {
|
|
|
58327
58325
|
compression: "DEFLATE",
|
|
58328
58326
|
compressionOptions: { level: 6 }
|
|
58329
58327
|
});
|
|
58330
|
-
const sha256 =
|
|
58328
|
+
const sha256 = import_node_crypto13.default.createHash("sha256").update(buffer).digest("hex");
|
|
58331
58329
|
return { buffer, sha256 };
|
|
58332
58330
|
}
|
|
58333
58331
|
var FIXED_DATE = /* @__PURE__ */ new Date("2020-01-01T00:00:00.000Z");
|
|
@@ -58395,7 +58393,7 @@ function computePublishCheck(args) {
|
|
|
58395
58393
|
var import_promises7 = __toESM(require("fs/promises"), 1);
|
|
58396
58394
|
var import_node_path52 = __toESM(require("path"), 1);
|
|
58397
58395
|
var import_node_os19 = __toESM(require("os"), 1);
|
|
58398
|
-
var
|
|
58396
|
+
var import_node_crypto14 = __toESM(require("crypto"), 1);
|
|
58399
58397
|
var import_jszip3 = __toESM(require_lib3(), 1);
|
|
58400
58398
|
|
|
58401
58399
|
// src/extension/paths.ts
|
|
@@ -58424,7 +58422,7 @@ var InstallError = class extends Error {
|
|
|
58424
58422
|
};
|
|
58425
58423
|
async function installFromChannel(args, deps) {
|
|
58426
58424
|
const { channelRef, snapshotHash, bundleZip } = args;
|
|
58427
|
-
const computed =
|
|
58425
|
+
const computed = import_node_crypto14.default.createHash("sha256").update(bundleZip).digest("hex");
|
|
58428
58426
|
if (computed !== snapshotHash) {
|
|
58429
58427
|
throw new InstallError(
|
|
58430
58428
|
"HASH_MISMATCH",
|
|
@@ -58516,7 +58514,7 @@ async function installFromChannel(args, deps) {
|
|
|
58516
58514
|
var import_promises8 = __toESM(require("fs/promises"), 1);
|
|
58517
58515
|
var import_node_path53 = __toESM(require("path"), 1);
|
|
58518
58516
|
var import_node_os20 = __toESM(require("os"), 1);
|
|
58519
|
-
var
|
|
58517
|
+
var import_node_crypto15 = __toESM(require("crypto"), 1);
|
|
58520
58518
|
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
58521
58519
|
var UpdateError = class extends Error {
|
|
58522
58520
|
constructor(code, message) {
|
|
@@ -58554,7 +58552,7 @@ async function updateFromChannel(args, deps) {
|
|
|
58554
58552
|
if (e instanceof UpdateError) throw e;
|
|
58555
58553
|
throw e;
|
|
58556
58554
|
}
|
|
58557
|
-
const computed =
|
|
58555
|
+
const computed = import_node_crypto15.default.createHash("sha256").update(bundleZip).digest("hex");
|
|
58558
58556
|
if (computed !== snapshotHash) {
|
|
58559
58557
|
throw new UpdateError(
|
|
58560
58558
|
"HASH_MISMATCH",
|
|
@@ -59220,7 +59218,7 @@ function listPidsOnPort(port) {
|
|
|
59220
59218
|
}
|
|
59221
59219
|
|
|
59222
59220
|
// src/app-builder/publish-registry.ts
|
|
59223
|
-
var
|
|
59221
|
+
var import_node_crypto16 = require("crypto");
|
|
59224
59222
|
var PublishJobRegistry = class {
|
|
59225
59223
|
jobs = /* @__PURE__ */ new Map();
|
|
59226
59224
|
has(name) {
|
|
@@ -59237,7 +59235,7 @@ var PublishJobRegistry = class {
|
|
|
59237
59235
|
if (this.jobs.has(args.name)) {
|
|
59238
59236
|
throw new Error(`already publishing: ${args.name}`);
|
|
59239
59237
|
}
|
|
59240
|
-
const jobId = args.jobId ?? `job-${(0,
|
|
59238
|
+
const jobId = args.jobId ?? `job-${(0, import_node_crypto16.randomUUID)()}`;
|
|
59241
59239
|
this.jobs.set(args.name, {
|
|
59242
59240
|
jobId,
|
|
59243
59241
|
name: args.name,
|
|
@@ -60180,7 +60178,7 @@ async function uninstall(deps) {
|
|
|
60180
60178
|
}
|
|
60181
60179
|
|
|
60182
60180
|
// src/handlers/index.ts
|
|
60183
|
-
var
|
|
60181
|
+
var import_node_crypto17 = require("crypto");
|
|
60184
60182
|
|
|
60185
60183
|
// src/handlers/peer-exec.ts
|
|
60186
60184
|
init_protocol();
|
|
@@ -60335,7 +60333,7 @@ function buildMethodHandlers(deps) {
|
|
|
60335
60333
|
const c = deps.contactStore.get(deviceId);
|
|
60336
60334
|
return c ? { deviceId: c.deviceId, remoteUrl: c.remoteUrl, connectToken: c.connectToken } : null;
|
|
60337
60335
|
},
|
|
60338
|
-
genId: () => (0,
|
|
60336
|
+
genId: () => (0, import_node_crypto17.randomUUID)(),
|
|
60339
60337
|
now: () => Date.now(),
|
|
60340
60338
|
forwardInboxPostToPeer,
|
|
60341
60339
|
logger: deps.logger
|
|
@@ -21852,6 +21852,11 @@ var PersonaInfoResponseSchema = PersonaFileSchema.extend({
|
|
|
21852
21852
|
sandboxSettings: PersonaSandboxSettingsSchema.nullable().optional()
|
|
21853
21853
|
});
|
|
21854
21854
|
var PersonaCreateArgsSchema = external_exports.object({
|
|
21855
|
+
// persona 身份。daemon 拼成 personaId = `persona-<slug>`——前缀由 daemon 拥有,调用方只给后半段,
|
|
21856
|
+
// 「所有 persona id 带该前缀」的约定由构造保证。与 label(显示名,可中文、可随时改)是两个概念:
|
|
21857
|
+
// 曾经只有 label、id 从 label 推,导致中文 label 被剥空后一律降级成 persona-persona。
|
|
21858
|
+
// 正则即安全边界——该值直接落进 ~/.clawd/personas/<id>/,此处排除 . / 空格后路径穿越无从构造。
|
|
21859
|
+
slug: external_exports.string().regex(/^[a-z0-9]+(-[a-z0-9]+)*$/).max(32),
|
|
21855
21860
|
label: external_exports.string().min(1),
|
|
21856
21861
|
personality: external_exports.string(),
|
|
21857
21862
|
model: external_exports.string().optional(),
|
|
@@ -23095,7 +23100,7 @@ var METHOD_DOCS = {
|
|
|
23095
23100
|
args: CapabilitiesGetArgs
|
|
23096
23101
|
},
|
|
23097
23102
|
"persona:create": {
|
|
23098
|
-
summary: "\u65B0\u5EFA persona\uFF08\u5199 PersonaFile + CLAUDE.md \u9AA8\u67B6\uFF09\u3002owner-only",
|
|
23103
|
+
summary: "\u65B0\u5EFA persona\uFF08\u5199 PersonaFile + CLAUDE.md \u9AA8\u67B6\uFF09\u3002owner-only\u3002slug \u53EA\u6536\u5C0F\u5199\u5B57\u6BCD\u6570\u5B57\u4E0E\u5355\u8FDE\u5B57\u7B26\uFF08^[a-z0-9]+(-[a-z0-9]+)*$\uFF0C\u226432\uFF09\uFF0Cdaemon \u62FC\u6210 personaId=persona-<slug>\uFF1B\u8BE5 id \u5DF2\u5B58\u5728\u5219\u62A5\u9519\uFF0C\u4E0D\u81EA\u52A8\u6539\u540D\u3002label \u662F\u663E\u793A\u540D\uFF0C\u4E0D\u53C2\u4E0E id \u63A8\u5BFC\uFF0C\u53EF\u7528\u4E2D\u6587",
|
|
23099
23104
|
args: PersonaCreateArgsSchema
|
|
23100
23105
|
},
|
|
23101
23106
|
"persona:list": {
|