@clawos-dev/clawd 0.2.530 → 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/app-builder-plugin/mcp-server.cjs +9 -0
- package/dist/cli.cjs +105 -16
- package/dist/dispatch/mcp-server.cjs +9 -0
- package/dist/share-md-viewer-error.html +1 -1
- package/dist/share-md-viewer.html +1 -1
- package/dist/share-ui/assets/{guest-DcCzHdsq.js → guest-BmFDorIL.js} +1 -1
- package/dist/share-ui/assets/guest-DdY1ARl4.css +32 -0
- package/dist/share-ui/guest.html +2 -2
- package/package.json +1 -1
- package/dist/share-ui/assets/guest-CnDyufxk.css +0 -32
|
@@ -21947,6 +21947,11 @@ var AuthApiKeyRegenerateResponseSchema = external_exports.object({
|
|
|
21947
21947
|
createdAt: external_exports.string().min(1),
|
|
21948
21948
|
gatewayUrl: GatewayUrl
|
|
21949
21949
|
});
|
|
21950
|
+
var AuthApiKeyRevokeResponseSchema = external_exports.object({
|
|
21951
|
+
type: external_exports.literal("auth:apiKey:revoke:ok"),
|
|
21952
|
+
/** 之前有没有那把——没发过也算成功(幂等) */
|
|
21953
|
+
revoked: external_exports.boolean()
|
|
21954
|
+
});
|
|
21950
21955
|
var AuthLoginDoneEventSchema = external_exports.object({
|
|
21951
21956
|
type: external_exports.literal("auth:login:done"),
|
|
21952
21957
|
identity: FeishuIdentitySchema
|
|
@@ -24494,6 +24499,10 @@ var METHOD_DOCS = {
|
|
|
24494
24499
|
summary: "\u6362\u4E00\u628A\u65B0\u7684\u4E91 persona \u8C03\u7528 key\uFF0C**\u65E7\u7684\u5F53\u573A\u5931\u6548**\uFF08\u4E00\u4EBA\u4E00\u628A\uFF0C\u4E2D\u5FC3\u6309 union_id \u8986\u76D6\uFF09\u3002owner-only",
|
|
24495
24500
|
args: NO_ARGS
|
|
24496
24501
|
},
|
|
24502
|
+
"auth:apiKey:revoke": {
|
|
24503
|
+
summary: "\u64A4\u9500\u81EA\u5DF1\u7684\u4E91 persona \u8C03\u7528 key\uFF1A\u4E2D\u5FC3\u5220\u6389\u90A3\u4E00\u884C\u3001**\u4E0D\u53D1\u65B0\u7684**\u3002gateway \u53EA\u5728\u5F00\u4F1A\u8BDD\u548C\u6BCF\u6B21\u4E0A\u884C\u65F6\u9A8C key\uFF0C\u6240\u4EE5\u5F00\u7740\u7684\u4E91\u4F1A\u8BDD\u4E0B\u4E00\u6761\u6D88\u606F\u624D\u53D1\u4E0D\u51FA\u53BB\u3001\u6B63\u5728\u8DD1\u7684\u90A3\u4E00\u8F6E\u4F1A\u8DD1\u5B8C\u3002\u6CA1\u53D1\u8FC7\u4E5F\u56DE ok\uFF08revoked:false\uFF09\u3002owner-only",
|
|
24504
|
+
args: NO_ARGS
|
|
24505
|
+
},
|
|
24497
24506
|
"device:list": {
|
|
24498
24507
|
summary: "\u5217\u51FA\u516C\u5171\u8BBE\u5907\u76EE\u5F55\u91CC\u53EF\u8FDE\u63A5\u7684\u8BBE\u5907\uFF08daemon \u4EE3\u7406\u4E2D\u5FC3 server\uFF09\u3002owner-only",
|
|
24499
24508
|
args: NO_ARGS
|
package/dist/cli.cjs
CHANGED
|
@@ -6431,7 +6431,7 @@ var init_contact = __esm({
|
|
|
6431
6431
|
});
|
|
6432
6432
|
|
|
6433
6433
|
// ../protocol/src/feishu-auth.ts
|
|
6434
|
-
var FEISHU_GATED_METHODS, LOGIN_EXPIRED_ERROR_MARKER, DeviceEntrySchema, DeviceListResponseSchema, DeviceConnectArgsSchema, DeviceConnectResponseSchema, FeishuIdentitySchema, AuthLoginStartResponseSchema, AuthGetIdentityResponseSchema, AuthLogoutResponseSchema, GatewayUrl, AuthApiKeyGetResponseSchema, AuthApiKeyRegenerateResponseSchema, AuthLoginDoneEventSchema, AuthLoginFailedEventSchema;
|
|
6434
|
+
var FEISHU_GATED_METHODS, LOGIN_EXPIRED_ERROR_MARKER, DeviceEntrySchema, DeviceListResponseSchema, DeviceConnectArgsSchema, DeviceConnectResponseSchema, FeishuIdentitySchema, AuthLoginStartResponseSchema, AuthGetIdentityResponseSchema, AuthLogoutResponseSchema, GatewayUrl, AuthApiKeyGetResponseSchema, AuthApiKeyRegenerateResponseSchema, AuthApiKeyRevokeResponseSchema, AuthLoginDoneEventSchema, AuthLoginFailedEventSchema;
|
|
6435
6435
|
var init_feishu_auth = __esm({
|
|
6436
6436
|
"../protocol/src/feishu-auth.ts"() {
|
|
6437
6437
|
"use strict";
|
|
@@ -6538,6 +6538,11 @@ var init_feishu_auth = __esm({
|
|
|
6538
6538
|
createdAt: external_exports.string().min(1),
|
|
6539
6539
|
gatewayUrl: GatewayUrl
|
|
6540
6540
|
});
|
|
6541
|
+
AuthApiKeyRevokeResponseSchema = external_exports.object({
|
|
6542
|
+
type: external_exports.literal("auth:apiKey:revoke:ok"),
|
|
6543
|
+
/** 之前有没有那把——没发过也算成功(幂等) */
|
|
6544
|
+
revoked: external_exports.boolean()
|
|
6545
|
+
});
|
|
6541
6546
|
AuthLoginDoneEventSchema = external_exports.object({
|
|
6542
6547
|
type: external_exports.literal("auth:login:done"),
|
|
6543
6548
|
identity: FeishuIdentitySchema
|
|
@@ -9311,6 +9316,10 @@ var init_methods = __esm({
|
|
|
9311
9316
|
summary: "\u6362\u4E00\u628A\u65B0\u7684\u4E91 persona \u8C03\u7528 key\uFF0C**\u65E7\u7684\u5F53\u573A\u5931\u6548**\uFF08\u4E00\u4EBA\u4E00\u628A\uFF0C\u4E2D\u5FC3\u6309 union_id \u8986\u76D6\uFF09\u3002owner-only",
|
|
9312
9317
|
args: NO_ARGS
|
|
9313
9318
|
},
|
|
9319
|
+
"auth:apiKey:revoke": {
|
|
9320
|
+
summary: "\u64A4\u9500\u81EA\u5DF1\u7684\u4E91 persona \u8C03\u7528 key\uFF1A\u4E2D\u5FC3\u5220\u6389\u90A3\u4E00\u884C\u3001**\u4E0D\u53D1\u65B0\u7684**\u3002gateway \u53EA\u5728\u5F00\u4F1A\u8BDD\u548C\u6BCF\u6B21\u4E0A\u884C\u65F6\u9A8C key\uFF0C\u6240\u4EE5\u5F00\u7740\u7684\u4E91\u4F1A\u8BDD\u4E0B\u4E00\u6761\u6D88\u606F\u624D\u53D1\u4E0D\u51FA\u53BB\u3001\u6B63\u5728\u8DD1\u7684\u90A3\u4E00\u8F6E\u4F1A\u8DD1\u5B8C\u3002\u6CA1\u53D1\u8FC7\u4E5F\u56DE ok\uFF08revoked:false\uFF09\u3002owner-only",
|
|
9321
|
+
args: NO_ARGS
|
|
9322
|
+
},
|
|
9314
9323
|
"device:list": {
|
|
9315
9324
|
summary: "\u5217\u51FA\u516C\u5171\u8BBE\u5907\u76EE\u5F55\u91CC\u53EF\u8FDE\u63A5\u7684\u8BBE\u5907\uFF08daemon \u4EE3\u7406\u4E2D\u5FC3 server\uFF09\u3002owner-only",
|
|
9316
9325
|
args: NO_ARGS
|
|
@@ -62214,6 +62223,16 @@ async function centralIssueApiKey(opts) {
|
|
|
62214
62223
|
gatewayUrl: typeof body.gatewayUrl === "string" ? body.gatewayUrl : null
|
|
62215
62224
|
};
|
|
62216
62225
|
}
|
|
62226
|
+
async function centralRevokeApiKey(opts) {
|
|
62227
|
+
const body = await centralRequest(opts, "/api/persona-cloud/api-key", {
|
|
62228
|
+
method: "DELETE",
|
|
62229
|
+
bearer: opts.loginPass
|
|
62230
|
+
});
|
|
62231
|
+
if (typeof body.revoked !== "boolean") {
|
|
62232
|
+
throw new CentralClientError("BAD_RESPONSE", "api-key: revoked must be boolean");
|
|
62233
|
+
}
|
|
62234
|
+
return { revoked: body.revoked };
|
|
62235
|
+
}
|
|
62217
62236
|
async function centralListDevices(opts) {
|
|
62218
62237
|
const body = await centralRequest(opts, "/api/clawd-identity/devices", {
|
|
62219
62238
|
method: "GET",
|
|
@@ -62278,6 +62297,12 @@ var GATEWAY_ROUTES = {
|
|
|
62278
62297
|
thread: (threadId) => `/threads/${encodeURIComponent(threadId)}`
|
|
62279
62298
|
};
|
|
62280
62299
|
var trimSlash = (u2) => u2.replace(/\/+$/, "");
|
|
62300
|
+
var CloudApiKeyRequiredError = class extends Error {
|
|
62301
|
+
constructor() {
|
|
62302
|
+
super("\u8FD8\u6CA1\u751F\u6210\u4E91 persona \u7684\u8C03\u7528 key\u3002\u5230\u300C\u8BBE\u7F6E \u2192 \u8D26\u53F7\u300D\u6216\u8FD9\u4E2A persona \u7684\u5361\u7247\u4E0A\u751F\u6210\u4E00\u628A\uFF0C\u518D\u5F00\u4F1A\u8BDD");
|
|
62303
|
+
this.name = "CloudApiKeyRequiredError";
|
|
62304
|
+
}
|
|
62305
|
+
};
|
|
62281
62306
|
var CLOUD_PERSONA_ID_SUFFIX = "-cloud";
|
|
62282
62307
|
function cloudPersonaToFile(p3) {
|
|
62283
62308
|
const at3 = p3.registeredAt ?? 0;
|
|
@@ -62315,7 +62340,7 @@ var CloudGatewayClient = class {
|
|
|
62315
62340
|
}
|
|
62316
62341
|
async credentials() {
|
|
62317
62342
|
const { apiKey, gatewayUrl } = await this.locate();
|
|
62318
|
-
if (!apiKey) throw new
|
|
62343
|
+
if (!apiKey) throw new CloudApiKeyRequiredError();
|
|
62319
62344
|
return { apiKey, gatewayUrl };
|
|
62320
62345
|
}
|
|
62321
62346
|
async listPersonas() {
|
|
@@ -62435,7 +62460,9 @@ function openHttpLineStream(opts) {
|
|
|
62435
62460
|
}
|
|
62436
62461
|
if (!res.ok) {
|
|
62437
62462
|
logger?.warn("cloud session send failed", { status: res.status });
|
|
62438
|
-
fail(
|
|
62463
|
+
fail(
|
|
62464
|
+
res.status === 401 ? "\u8C03\u7528 key \u5DF2\u5931\u6548\uFF08\u64A4\u9500\u6216\u91CD\u65B0\u751F\u6210\u8FC7\uFF09\uFF0C\u8FD9\u6761\u4F1A\u8BDD\u65AD\u4E86\u3002\u5230\u300C\u8BBE\u7F6E \u2192 \u8D26\u53F7\u300D\u6216\u8FD9\u4E2A persona \u7684\u5361\u7247\u4E0A\u751F\u6210\u4E00\u628A\uFF0C\u518D\u5F00\u65B0\u4F1A\u8BDD" : `\u4E0A\u884C\u53D1\u4E0D\u51FA\u53BB\uFF08gateway \u56DE ${res.status}\uFF09\uFF0C\u8FD9\u6761\u4F1A\u8BDD\u65AD\u4E86`
|
|
62465
|
+
);
|
|
62439
62466
|
}
|
|
62440
62467
|
}).catch((e) => {
|
|
62441
62468
|
if (closed) return;
|
|
@@ -62726,7 +62753,7 @@ function createCloudCodexSession(ctx, sink, deps) {
|
|
|
62726
62753
|
stream.attach(channel);
|
|
62727
62754
|
},
|
|
62728
62755
|
(e) => {
|
|
62729
|
-
sink.onError(`\u8FDE\u4E0D\u4E0A\u4E91 gateway\uFF1A${e.message}`);
|
|
62756
|
+
sink.onError(e instanceof CloudApiKeyRequiredError ? e.message : `\u8FDE\u4E0D\u4E0A\u4E91 gateway\uFF1A${e.message}`);
|
|
62730
62757
|
stream.close();
|
|
62731
62758
|
}
|
|
62732
62759
|
);
|
|
@@ -67416,7 +67443,8 @@ function loadOrCreateAuthFile(opts) {
|
|
|
67416
67443
|
token: existing.token,
|
|
67417
67444
|
ownerPrincipalId: existing.ownerPrincipalId,
|
|
67418
67445
|
deviceId: existing.deviceId,
|
|
67419
|
-
createdAt: existing.createdAt ?? (/* @__PURE__ */ new Date(0)).toISOString()
|
|
67446
|
+
createdAt: existing.createdAt ?? (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
67447
|
+
...existing.tunnelDeviceKey ? { tunnelDeviceKey: existing.tunnelDeviceKey } : {}
|
|
67420
67448
|
};
|
|
67421
67449
|
}
|
|
67422
67450
|
const token = existing?.token || generate();
|
|
@@ -67424,9 +67452,17 @@ function loadOrCreateAuthFile(opts) {
|
|
|
67424
67452
|
const deviceId = ownerPrincipalId;
|
|
67425
67453
|
const createdAt = existing?.createdAt || now().toISOString();
|
|
67426
67454
|
const next = { token, ownerPrincipalId, deviceId, createdAt };
|
|
67455
|
+
if (existing?.tunnelDeviceKey) next.tunnelDeviceKey = existing.tunnelDeviceKey;
|
|
67427
67456
|
writeAuthFile(file, next);
|
|
67428
67457
|
return next;
|
|
67429
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
|
+
}
|
|
67430
67466
|
function defaultGenerateToken() {
|
|
67431
67467
|
return import_node_crypto15.default.randomBytes(32).toString("base64url");
|
|
67432
67468
|
}
|
|
@@ -67445,6 +67481,7 @@ function readAuthFile(file) {
|
|
|
67445
67481
|
ownerPrincipalId: typeof parsed.ownerPrincipalId === "string" && parsed.ownerPrincipalId.length > 0 ? parsed.ownerPrincipalId : void 0,
|
|
67446
67482
|
deviceId: typeof parsed.deviceId === "string" && parsed.deviceId.length > 0 ? parsed.deviceId : void 0,
|
|
67447
67483
|
createdAt: typeof parsed.createdAt === "string" ? parsed.createdAt : void 0,
|
|
67484
|
+
tunnelDeviceKey: typeof parsed.tunnelDeviceKey === "string" && parsed.tunnelDeviceKey.length > 0 ? parsed.tunnelDeviceKey : void 0,
|
|
67448
67485
|
// 单 secret 合并前的旧字段:出现即触发清理写回(值无所谓,硬切不再使用)
|
|
67449
67486
|
hasLegacySecrets: "signSecret" in parsed || "visitorTokenSecret" in parsed
|
|
67450
67487
|
};
|
|
@@ -67779,22 +67816,51 @@ var lastPeers = [];
|
|
|
67779
67816
|
function getCachedOrgPeers() {
|
|
67780
67817
|
return lastPeers;
|
|
67781
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
|
+
}
|
|
67782
67833
|
async function syncOrgMesh(deps) {
|
|
67783
67834
|
const peers = await deps.fetchPeers();
|
|
67784
67835
|
lastPeers = peers;
|
|
67785
67836
|
if (peers.length === 0) {
|
|
67786
67837
|
deps.log("org-mesh: \u4E0D\u5728\u4EFB\u4F55\u7EC4\u7EC7\uFF08\u6216\u7EC4\u91CC\u53EA\u6709\u81EA\u5DF1\uFF09\uFF0C\u8DF3\u8FC7");
|
|
67787
67838
|
deps.onProgress?.({ total: 0, done: 0, connected: 0, failed: 0, active: false });
|
|
67788
|
-
return { peers: 0, attempted: 0, connected: 0, failed: 0 };
|
|
67839
|
+
return { peers: 0, attempted: 0, connected: 0, failed: 0, refreshed: 0 };
|
|
67789
67840
|
}
|
|
67790
67841
|
const targets = [];
|
|
67842
|
+
let refreshed = 0;
|
|
67791
67843
|
for (const p3 of peers) {
|
|
67792
67844
|
for (const d2 of p3.devices) {
|
|
67793
|
-
|
|
67794
|
-
|
|
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);
|
|
67795
67861
|
}
|
|
67796
67862
|
}
|
|
67797
|
-
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 });
|
|
67798
67864
|
let connected = 0;
|
|
67799
67865
|
let failed = 0;
|
|
67800
67866
|
deps.onProgress?.({
|
|
@@ -67825,8 +67891,14 @@ async function syncOrgMesh(deps) {
|
|
|
67825
67891
|
active: connected + failed < targets.length
|
|
67826
67892
|
});
|
|
67827
67893
|
}
|
|
67828
|
-
deps.log("org-mesh: \u540C\u6B65\u5B8C\u6210", {
|
|
67829
|
-
|
|
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 };
|
|
67830
67902
|
}
|
|
67831
67903
|
|
|
67832
67904
|
// src/handlers/device.ts
|
|
@@ -69976,12 +70048,19 @@ function buildFeishuAuthHandlers(deps) {
|
|
|
69976
70048
|
response: { type: "auth:apiKey:regenerate:ok", apiKey, createdAt, gatewayUrl }
|
|
69977
70049
|
};
|
|
69978
70050
|
};
|
|
70051
|
+
const apiKeyRevoke = async () => {
|
|
70052
|
+
const { revoked } = await deps.apiKeyClient.revoke(requireLogin());
|
|
70053
|
+
return {
|
|
70054
|
+
response: { type: "auth:apiKey:revoke:ok", revoked }
|
|
70055
|
+
};
|
|
70056
|
+
};
|
|
69979
70057
|
return {
|
|
69980
70058
|
"auth:login:start": loginStart,
|
|
69981
70059
|
"auth:getIdentity": getIdentity,
|
|
69982
70060
|
"auth:logout": logout,
|
|
69983
70061
|
"auth:apiKey:get": apiKeyGet,
|
|
69984
|
-
"auth:apiKey:regenerate": apiKeyRegenerate
|
|
70062
|
+
"auth:apiKey:regenerate": apiKeyRegenerate,
|
|
70063
|
+
"auth:apiKey:revoke": apiKeyRevoke
|
|
69985
70064
|
};
|
|
69986
70065
|
}
|
|
69987
70066
|
|
|
@@ -70281,6 +70360,7 @@ var METHOD_GRANT_MAP = {
|
|
|
70281
70360
|
// 云 persona 调用 key:本机主人自己的东西,guest 一律够不着
|
|
70282
70361
|
"auth:apiKey:get": ADMIN_ANY,
|
|
70283
70362
|
"auth:apiKey:regenerate": ADMIN_ANY,
|
|
70363
|
+
"auth:apiKey:revoke": ADMIN_ANY,
|
|
70284
70364
|
// ---- device:* 设备目录 + 连接(决策 #15,owner-only) ----
|
|
70285
70365
|
// 设备目录 / 连接都是 owner 本机操作(用本机登录票找中心 server),guest 不可调
|
|
70286
70366
|
"device:list": ADMIN_ANY,
|
|
@@ -70335,7 +70415,7 @@ function computeMethodAccess(args) {
|
|
|
70335
70415
|
}
|
|
70336
70416
|
|
|
70337
70417
|
// src/version.ts
|
|
70338
|
-
var version = "0.2.
|
|
70418
|
+
var version = "0.2.532".length > 0 ? "0.2.532" : "dev";
|
|
70339
70419
|
|
|
70340
70420
|
// src/cli-probe/probe.ts
|
|
70341
70421
|
var fs77 = __toESM(require("fs"), 1);
|
|
@@ -73693,7 +73773,10 @@ async function startDaemon(config) {
|
|
|
73693
73773
|
connectToDevice: createConnectToDevice(feishuDeviceDeps),
|
|
73694
73774
|
log: (msg, meta) => logger.info(msg, meta),
|
|
73695
73775
|
// 进度上报:串行建联 20+ 台要几十秒,UI 靠这个帧渲染进度条
|
|
73696
|
-
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 })
|
|
73697
73780
|
});
|
|
73698
73781
|
} catch (err) {
|
|
73699
73782
|
logger.warn("org-mesh sync failed (best-effort)", { err: err.message });
|
|
@@ -73971,7 +74054,8 @@ async function startDaemon(config) {
|
|
|
73971
74054
|
// 凭证不出 ws —— UI 只拿到 key 本身,跟 exchange / listDevices 同一条纪律。
|
|
73972
74055
|
apiKeyClient: {
|
|
73973
74056
|
get: (args) => centralGetApiKey({ api: config.clawosApi ?? DEFAULT_CLAWOS_API, ...args }),
|
|
73974
|
-
issue: (args) => centralIssueApiKey({ api: config.clawosApi ?? DEFAULT_CLAWOS_API, ...args })
|
|
74057
|
+
issue: (args) => centralIssueApiKey({ api: config.clawosApi ?? DEFAULT_CLAWOS_API, ...args }),
|
|
74058
|
+
revoke: (args) => centralRevokeApiKey({ api: config.clawosApi ?? DEFAULT_CLAWOS_API, ...args })
|
|
73975
74059
|
}
|
|
73976
74060
|
},
|
|
73977
74061
|
// 云 persona 卡片上的连接器区(design 2026-09-11-mcp-connector §3.8):装了什么以 gateway 登记行为真源,
|
|
@@ -74443,7 +74527,12 @@ async function startDaemon(config) {
|
|
|
74443
74527
|
tunnelMgr = new TunnelManager({
|
|
74444
74528
|
dataDir: config.dataDir,
|
|
74445
74529
|
clawosApi: config.clawosApi,
|
|
74446
|
-
|
|
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
|
+
}),
|
|
74447
74536
|
frpcBinaryOverride: config.frpcBinary,
|
|
74448
74537
|
noPersist: config.noTunnelPersist,
|
|
74449
74538
|
logger,
|
|
@@ -21762,6 +21762,11 @@ var AuthApiKeyRegenerateResponseSchema = external_exports.object({
|
|
|
21762
21762
|
createdAt: external_exports.string().min(1),
|
|
21763
21763
|
gatewayUrl: GatewayUrl
|
|
21764
21764
|
});
|
|
21765
|
+
var AuthApiKeyRevokeResponseSchema = external_exports.object({
|
|
21766
|
+
type: external_exports.literal("auth:apiKey:revoke:ok"),
|
|
21767
|
+
/** 之前有没有那把——没发过也算成功(幂等) */
|
|
21768
|
+
revoked: external_exports.boolean()
|
|
21769
|
+
});
|
|
21765
21770
|
var AuthLoginDoneEventSchema = external_exports.object({
|
|
21766
21771
|
type: external_exports.literal("auth:login:done"),
|
|
21767
21772
|
identity: FeishuIdentitySchema
|
|
@@ -24309,6 +24314,10 @@ var METHOD_DOCS = {
|
|
|
24309
24314
|
summary: "\u6362\u4E00\u628A\u65B0\u7684\u4E91 persona \u8C03\u7528 key\uFF0C**\u65E7\u7684\u5F53\u573A\u5931\u6548**\uFF08\u4E00\u4EBA\u4E00\u628A\uFF0C\u4E2D\u5FC3\u6309 union_id \u8986\u76D6\uFF09\u3002owner-only",
|
|
24310
24315
|
args: NO_ARGS
|
|
24311
24316
|
},
|
|
24317
|
+
"auth:apiKey:revoke": {
|
|
24318
|
+
summary: "\u64A4\u9500\u81EA\u5DF1\u7684\u4E91 persona \u8C03\u7528 key\uFF1A\u4E2D\u5FC3\u5220\u6389\u90A3\u4E00\u884C\u3001**\u4E0D\u53D1\u65B0\u7684**\u3002gateway \u53EA\u5728\u5F00\u4F1A\u8BDD\u548C\u6BCF\u6B21\u4E0A\u884C\u65F6\u9A8C key\uFF0C\u6240\u4EE5\u5F00\u7740\u7684\u4E91\u4F1A\u8BDD\u4E0B\u4E00\u6761\u6D88\u606F\u624D\u53D1\u4E0D\u51FA\u53BB\u3001\u6B63\u5728\u8DD1\u7684\u90A3\u4E00\u8F6E\u4F1A\u8DD1\u5B8C\u3002\u6CA1\u53D1\u8FC7\u4E5F\u56DE ok\uFF08revoked:false\uFF09\u3002owner-only",
|
|
24319
|
+
args: NO_ARGS
|
|
24320
|
+
},
|
|
24312
24321
|
"device:list": {
|
|
24313
24322
|
summary: "\u5217\u51FA\u516C\u5171\u8BBE\u5907\u76EE\u5F55\u91CC\u53EF\u8FDE\u63A5\u7684\u8BBE\u5907\uFF08daemon \u4EE3\u7406\u4E2D\u5FC3 server\uFF09\u3002owner-only",
|
|
24314
24323
|
args: NO_ARGS
|