@clawos-dev/clawd 0.2.531 → 0.2.532
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 +63 -10
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -67443,7 +67443,8 @@ function loadOrCreateAuthFile(opts) {
|
|
|
67443
67443
|
token: existing.token,
|
|
67444
67444
|
ownerPrincipalId: existing.ownerPrincipalId,
|
|
67445
67445
|
deviceId: existing.deviceId,
|
|
67446
|
-
createdAt: existing.createdAt ?? (/* @__PURE__ */ new Date(0)).toISOString()
|
|
67446
|
+
createdAt: existing.createdAt ?? (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
67447
|
+
...existing.tunnelDeviceKey ? { tunnelDeviceKey: existing.tunnelDeviceKey } : {}
|
|
67447
67448
|
};
|
|
67448
67449
|
}
|
|
67449
67450
|
const token = existing?.token || generate();
|
|
@@ -67451,9 +67452,17 @@ function loadOrCreateAuthFile(opts) {
|
|
|
67451
67452
|
const deviceId = ownerPrincipalId;
|
|
67452
67453
|
const createdAt = existing?.createdAt || now().toISOString();
|
|
67453
67454
|
const next = { token, ownerPrincipalId, deviceId, createdAt };
|
|
67455
|
+
if (existing?.tunnelDeviceKey) next.tunnelDeviceKey = existing.tunnelDeviceKey;
|
|
67454
67456
|
writeAuthFile(file, next);
|
|
67455
67457
|
return next;
|
|
67456
67458
|
}
|
|
67459
|
+
function loadOrCreateTunnelDeviceKey(opts) {
|
|
67460
|
+
const current = loadOrCreateAuthFile(opts);
|
|
67461
|
+
if (current.tunnelDeviceKey) return current.tunnelDeviceKey;
|
|
67462
|
+
const tunnelDeviceKey = opts.derive();
|
|
67463
|
+
writeAuthFile(authFilePath(opts.dataDir), { ...current, tunnelDeviceKey });
|
|
67464
|
+
return tunnelDeviceKey;
|
|
67465
|
+
}
|
|
67457
67466
|
function defaultGenerateToken() {
|
|
67458
67467
|
return import_node_crypto15.default.randomBytes(32).toString("base64url");
|
|
67459
67468
|
}
|
|
@@ -67472,6 +67481,7 @@ function readAuthFile(file) {
|
|
|
67472
67481
|
ownerPrincipalId: typeof parsed.ownerPrincipalId === "string" && parsed.ownerPrincipalId.length > 0 ? parsed.ownerPrincipalId : void 0,
|
|
67473
67482
|
deviceId: typeof parsed.deviceId === "string" && parsed.deviceId.length > 0 ? parsed.deviceId : void 0,
|
|
67474
67483
|
createdAt: typeof parsed.createdAt === "string" ? parsed.createdAt : void 0,
|
|
67484
|
+
tunnelDeviceKey: typeof parsed.tunnelDeviceKey === "string" && parsed.tunnelDeviceKey.length > 0 ? parsed.tunnelDeviceKey : void 0,
|
|
67475
67485
|
// 单 secret 合并前的旧字段:出现即触发清理写回(值无所谓,硬切不再使用)
|
|
67476
67486
|
hasLegacySecrets: "signSecret" in parsed || "visitorTokenSecret" in parsed
|
|
67477
67487
|
};
|
|
@@ -67806,22 +67816,51 @@ var lastPeers = [];
|
|
|
67806
67816
|
function getCachedOrgPeers() {
|
|
67807
67817
|
return lastPeers;
|
|
67808
67818
|
}
|
|
67819
|
+
function sameOrigin(a2, b3) {
|
|
67820
|
+
const oa2 = toOrigin(a2);
|
|
67821
|
+
const ob = toOrigin(b3);
|
|
67822
|
+
return oa2 != null && ob != null ? oa2 === ob : a2 === b3;
|
|
67823
|
+
}
|
|
67824
|
+
function toOrigin(raw) {
|
|
67825
|
+
const http2 = raw.replace(/^wss:\/\//i, "https://").replace(/^ws:\/\//i, "http://");
|
|
67826
|
+
try {
|
|
67827
|
+
const origin = new URL(http2).origin;
|
|
67828
|
+
return origin === "null" ? null : origin;
|
|
67829
|
+
} catch {
|
|
67830
|
+
return null;
|
|
67831
|
+
}
|
|
67832
|
+
}
|
|
67809
67833
|
async function syncOrgMesh(deps) {
|
|
67810
67834
|
const peers = await deps.fetchPeers();
|
|
67811
67835
|
lastPeers = peers;
|
|
67812
67836
|
if (peers.length === 0) {
|
|
67813
67837
|
deps.log("org-mesh: \u4E0D\u5728\u4EFB\u4F55\u7EC4\u7EC7\uFF08\u6216\u7EC4\u91CC\u53EA\u6709\u81EA\u5DF1\uFF09\uFF0C\u8DF3\u8FC7");
|
|
67814
67838
|
deps.onProgress?.({ total: 0, done: 0, connected: 0, failed: 0, active: false });
|
|
67815
|
-
return { peers: 0, attempted: 0, connected: 0, failed: 0 };
|
|
67839
|
+
return { peers: 0, attempted: 0, connected: 0, failed: 0, refreshed: 0 };
|
|
67816
67840
|
}
|
|
67817
67841
|
const targets = [];
|
|
67842
|
+
let refreshed = 0;
|
|
67818
67843
|
for (const p3 of peers) {
|
|
67819
67844
|
for (const d2 of p3.devices) {
|
|
67820
|
-
|
|
67821
|
-
|
|
67845
|
+
const existing = deps.store.get(d2.deviceId);
|
|
67846
|
+
if (!existing) {
|
|
67847
|
+
targets.push({ deviceId: d2.deviceId, displayName: p3.displayName });
|
|
67848
|
+
continue;
|
|
67849
|
+
}
|
|
67850
|
+
if (d2.url == null || sameOrigin(existing.remoteUrl, d2.url)) continue;
|
|
67851
|
+
const updated = { ...existing, remoteUrl: d2.url };
|
|
67852
|
+
deps.store.upsert(updated);
|
|
67853
|
+
refreshed += 1;
|
|
67854
|
+
deps.log("org-mesh: \u8054\u7CFB\u4EBA\u5730\u5740\u5DF2\u5237\u65B0", {
|
|
67855
|
+
deviceId: d2.deviceId,
|
|
67856
|
+
name: p3.displayName,
|
|
67857
|
+
from: existing.remoteUrl,
|
|
67858
|
+
to: d2.url
|
|
67859
|
+
});
|
|
67860
|
+
deps.onContactUpdated?.(updated);
|
|
67822
67861
|
}
|
|
67823
67862
|
}
|
|
67824
|
-
deps.log("org-mesh: \u5F00\u59CB\u540C\u6B65", { peers: peers.length, targets: targets.length });
|
|
67863
|
+
deps.log("org-mesh: \u5F00\u59CB\u540C\u6B65", { peers: peers.length, targets: targets.length, refreshed });
|
|
67825
67864
|
let connected = 0;
|
|
67826
67865
|
let failed = 0;
|
|
67827
67866
|
deps.onProgress?.({
|
|
@@ -67852,8 +67891,14 @@ async function syncOrgMesh(deps) {
|
|
|
67852
67891
|
active: connected + failed < targets.length
|
|
67853
67892
|
});
|
|
67854
67893
|
}
|
|
67855
|
-
deps.log("org-mesh: \u540C\u6B65\u5B8C\u6210", {
|
|
67856
|
-
|
|
67894
|
+
deps.log("org-mesh: \u540C\u6B65\u5B8C\u6210", {
|
|
67895
|
+
peers: peers.length,
|
|
67896
|
+
attempted: targets.length,
|
|
67897
|
+
connected,
|
|
67898
|
+
failed,
|
|
67899
|
+
refreshed
|
|
67900
|
+
});
|
|
67901
|
+
return { peers: peers.length, attempted: targets.length, connected, failed, refreshed };
|
|
67857
67902
|
}
|
|
67858
67903
|
|
|
67859
67904
|
// src/handlers/device.ts
|
|
@@ -70370,7 +70415,7 @@ function computeMethodAccess(args) {
|
|
|
70370
70415
|
}
|
|
70371
70416
|
|
|
70372
70417
|
// src/version.ts
|
|
70373
|
-
var version = "0.2.
|
|
70418
|
+
var version = "0.2.532".length > 0 ? "0.2.532" : "dev";
|
|
70374
70419
|
|
|
70375
70420
|
// src/cli-probe/probe.ts
|
|
70376
70421
|
var fs77 = __toESM(require("fs"), 1);
|
|
@@ -73728,7 +73773,10 @@ async function startDaemon(config) {
|
|
|
73728
73773
|
connectToDevice: createConnectToDevice(feishuDeviceDeps),
|
|
73729
73774
|
log: (msg, meta) => logger.info(msg, meta),
|
|
73730
73775
|
// 进度上报:串行建联 20+ 台要几十秒,UI 靠这个帧渲染进度条
|
|
73731
|
-
onProgress: (progress) => wsServer?.broadcastToOwners({ type: "org-mesh:progress", ...progress })
|
|
73776
|
+
onProgress: (progress) => wsServer?.broadcastToOwners({ type: "org-mesh:progress", ...progress }),
|
|
73777
|
+
// 已有联系人的地址被中心最新 url 刷新 → 复用 contact:added(UI reducer 按 deviceId upsert,
|
|
73778
|
+
// auto-reverse 重握手也发这一帧),不新增帧
|
|
73779
|
+
onContactUpdated: (contact) => wsServer?.broadcastToOwners({ type: "contact:added", contact })
|
|
73732
73780
|
});
|
|
73733
73781
|
} catch (err) {
|
|
73734
73782
|
logger.warn("org-mesh sync failed (best-effort)", { err: err.message });
|
|
@@ -74479,7 +74527,12 @@ async function startDaemon(config) {
|
|
|
74479
74527
|
tunnelMgr = new TunnelManager({
|
|
74480
74528
|
dataDir: config.dataDir,
|
|
74481
74529
|
clawosApi: config.clawosApi,
|
|
74482
|
-
|
|
74530
|
+
// 子域指纹落盘于 auth.json,首次缺失才由 hostname+uid 算初值——改电脑名不再换对外地址
|
|
74531
|
+
// (design 2026-09-16-tunnel-address-stability §3.1)
|
|
74532
|
+
deviceKey: loadOrCreateTunnelDeviceKey({
|
|
74533
|
+
dataDir: config.dataDir,
|
|
74534
|
+
derive: () => deriveStableDeviceKey({ dataDir: config.dataDir })
|
|
74535
|
+
}),
|
|
74483
74536
|
frpcBinaryOverride: config.frpcBinary,
|
|
74484
74537
|
noPersist: config.noTunnelPersist,
|
|
74485
74538
|
logger,
|