@clawos-dev/clawd 0.2.524 → 0.2.526
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
CHANGED
|
@@ -6450,7 +6450,7 @@ var init_feishu_auth = __esm({
|
|
|
6450
6450
|
// mirror peer sessions(远端会话镜像)
|
|
6451
6451
|
"peerSession:upsert",
|
|
6452
6452
|
"peerSession:remove",
|
|
6453
|
-
// 设备目录 + 连接(决策 #15:daemon 代理中心 server,需要 owner
|
|
6453
|
+
// 设备目录 + 连接(决策 #15:daemon 代理中心 server,需要 owner 的登录票)
|
|
6454
6454
|
"device:list",
|
|
6455
6455
|
"device:connect",
|
|
6456
6456
|
// iOS TestFlight 意向登记(需要 owner unionId 上报中心 server)
|
|
@@ -6520,13 +6520,7 @@ var init_feishu_auth = __esm({
|
|
|
6520
6520
|
* 设备属性,与登录态无关、登录登出不变。UI"我的设备标识"用它拼
|
|
6521
6521
|
* clawos://device/<deviceId>(替代旧的 unionId——不再向外暴露人的身份标识)。
|
|
6522
6522
|
*/
|
|
6523
|
-
deviceId: external_exports.string().min(1)
|
|
6524
|
-
/**
|
|
6525
|
-
* TTC JWT 过期时间(unix ms)。null = 登录回调未携带 expires_at;字段缺省 = 老 daemon。
|
|
6526
|
-
* 仅时间戳——token 本体永不出 ws(spec §9 不变)。UI 据此派生 过期/临期 提示
|
|
6527
|
-
* (见 spec 2026-08-17-ttc-jwt-expiry-ux-design §2)。
|
|
6528
|
-
*/
|
|
6529
|
-
ttcTokenExpiresAt: external_exports.number().nullable().optional()
|
|
6523
|
+
deviceId: external_exports.string().min(1)
|
|
6530
6524
|
});
|
|
6531
6525
|
AuthLogoutResponseSchema = external_exports.object({
|
|
6532
6526
|
type: external_exports.literal("auth:logout:ok")
|
|
@@ -9309,7 +9303,7 @@ var init_methods = __esm({
|
|
|
9309
9303
|
args: NO_ARGS
|
|
9310
9304
|
},
|
|
9311
9305
|
"auth:getIdentity": {
|
|
9312
|
-
summary: "\u53D6\u672C\u673A owner \u7684\u98DE\u4E66\u8EAB\u4EFD\uFF08ownerId / provider / displayName / unionId\uFF09+ **\u672C\u673A deviceId**\uFF08\u8BBE\u5907\u5C5E\u6027\uFF0C\u4E0E\u767B\u5F55\u6001\u65E0\u5173\uFF1Bdevice:connect / contact:* / inbox:* \u7684\u4E3B\u952E\u90FD\u662F\u5B83\uFF09\uFF1B\u7EDD\u4E0D\u8FD4\u56DE
|
|
9306
|
+
summary: "\u53D6\u672C\u673A owner \u7684\u98DE\u4E66\u8EAB\u4EFD\uFF08ownerId / provider / displayName / unionId\uFF09+ **\u672C\u673A deviceId**\uFF08\u8BBE\u5907\u5C5E\u6027\uFF0C\u4E0E\u767B\u5F55\u6001\u65E0\u5173\uFF1Bdevice:connect / contact:* / inbox:* \u7684\u4E3B\u952E\u90FD\u662F\u5B83\uFF09\uFF1B\u7EDD\u4E0D\u8FD4\u56DE\u767B\u5F55\u7968",
|
|
9313
9307
|
args: NO_ARGS
|
|
9314
9308
|
},
|
|
9315
9309
|
"auth:logout": {
|
|
@@ -60156,8 +60150,7 @@ function buildLarkBotHandlers(deps) {
|
|
|
60156
60150
|
const { personaId: personaId2 } = parseArgs2(LarkBotProvisionArgs, frame, "larkBot:provision");
|
|
60157
60151
|
const tunnelUrl = deps.getTunnelUrl();
|
|
60158
60152
|
if (!tunnelUrl) throw new Error("larkBot provision requires tunnel to be up");
|
|
60159
|
-
|
|
60160
|
-
if (!ownerId) throw new Error("larkBot provision requires feishu login (owner identity)");
|
|
60153
|
+
if (!deps.getOwnerId()) throw new Error("larkBot provision requires feishu login (owner identity)");
|
|
60161
60154
|
if (deps.store.read(personaId2)) throw new Error(`larkBot already bound: ${personaId2}`);
|
|
60162
60155
|
if (inFlight.has(personaId2)) throw new Error(`larkBot provision already in flight: ${personaId2}`);
|
|
60163
60156
|
const botName = deps.getPersonaName(personaId2) ?? personaId2;
|
|
@@ -60166,12 +60159,7 @@ function buildLarkBotHandlers(deps) {
|
|
|
60166
60159
|
let qrUrl;
|
|
60167
60160
|
try {
|
|
60168
60161
|
;
|
|
60169
|
-
({ provisionId, qrUrl } = await deps.cloud.provisionBegin({
|
|
60170
|
-
personaId: personaId2,
|
|
60171
|
-
botName,
|
|
60172
|
-
tunnelUrl,
|
|
60173
|
-
ownerId
|
|
60174
|
-
}));
|
|
60162
|
+
({ provisionId, qrUrl } = await deps.cloud.provisionBegin({ personaId: personaId2, botName, tunnelUrl }));
|
|
60175
60163
|
} catch (err) {
|
|
60176
60164
|
inFlight.delete(personaId2);
|
|
60177
60165
|
throw err;
|
|
@@ -60340,11 +60328,10 @@ function buildLarkBotHandlers(deps) {
|
|
|
60340
60328
|
if (inFlight.has(personaId2)) throw new Error(`larkBot provision already in flight: ${personaId2}`);
|
|
60341
60329
|
const tunnelUrl = deps.getTunnelUrl();
|
|
60342
60330
|
if (!tunnelUrl) throw new Error("larkBot bind requires tunnel to be up");
|
|
60343
|
-
|
|
60344
|
-
if (!ownerId) throw new Error("larkBot bind requires feishu login (owner identity)");
|
|
60331
|
+
if (!deps.getOwnerId()) throw new Error("larkBot bind requires feishu login (owner identity)");
|
|
60345
60332
|
const name = botName ?? deps.getPersonaName(personaId2) ?? personaId2;
|
|
60346
60333
|
upgradeInFlight.delete(personaId2);
|
|
60347
|
-
await deps.cloud.bind({ personaId: personaId2, appId, appSecret, botName: name, tunnelUrl
|
|
60334
|
+
await deps.cloud.bind({ personaId: personaId2, appId, appSecret, botName: name, tunnelUrl });
|
|
60348
60335
|
deps.store.write(personaId2, { appId, botName: name, boundAt: now() });
|
|
60349
60336
|
emit(personaId2, { state: "bound", appId, botName: name, groups: groupsOf(personaId2) });
|
|
60350
60337
|
return { response: { type: "larkBot:bindManual:ok" } };
|
|
@@ -60510,21 +60497,22 @@ function createLarkBotCloudClient(opts) {
|
|
|
60510
60497
|
const f2 = opts.fetchImpl ?? globalThis.fetch;
|
|
60511
60498
|
if (!f2) throw new Error("fetch is not available (Node >= 18 required)");
|
|
60512
60499
|
const base = opts.api.replace(/\/+$/, "");
|
|
60500
|
+
function authHeaders() {
|
|
60501
|
+
const pass = opts.getLoginPass();
|
|
60502
|
+
if (!pass) throw new LarkBotCloudError("lark-bot cloud: no login pass (login / restart to obtain one)", 401);
|
|
60503
|
+
return { authorization: `Bearer ${pass}` };
|
|
60504
|
+
}
|
|
60513
60505
|
async function request(method, pathname, body) {
|
|
60506
|
+
const headers = authHeaders();
|
|
60507
|
+
const url = `${base}${pathname}`;
|
|
60514
60508
|
const ac = new AbortController();
|
|
60515
60509
|
const timer = setTimeout(() => ac.abort(), opts.timeoutMs ?? 15e3);
|
|
60516
60510
|
let res;
|
|
60517
60511
|
try {
|
|
60518
|
-
res = await f2(
|
|
60512
|
+
res = await f2(url, {
|
|
60519
60513
|
method,
|
|
60520
60514
|
signal: ac.signal,
|
|
60521
|
-
headers: {
|
|
60522
|
-
authorization: `Bearer ${opts.apiKey}`,
|
|
60523
|
-
"x-did": encodeURIComponent(opts.deviceId),
|
|
60524
|
-
"x-name": encodeURIComponent(opts.displayName),
|
|
60525
|
-
"x-scene": "daemon",
|
|
60526
|
-
"content-type": "application/json"
|
|
60527
|
-
},
|
|
60515
|
+
headers: { ...headers, "content-type": "application/json" },
|
|
60528
60516
|
body: body ? JSON.stringify(body) : void 0
|
|
60529
60517
|
});
|
|
60530
60518
|
} catch (err) {
|
|
@@ -60606,8 +60594,6 @@ function createLarkBotCloudClient(opts) {
|
|
|
60606
60594
|
});
|
|
60607
60595
|
},
|
|
60608
60596
|
async fetchResource(appId, messageId, fileKey, maxBytes, type) {
|
|
60609
|
-
const ac = new AbortController();
|
|
60610
|
-
const timer = setTimeout(() => ac.abort(), opts.timeoutMs ?? 15e3);
|
|
60611
60597
|
const qs = new URLSearchParams({
|
|
60612
60598
|
appId,
|
|
60613
60599
|
messageId,
|
|
@@ -60615,18 +60601,13 @@ function createLarkBotCloudClient(opts) {
|
|
|
60615
60601
|
...maxBytes ? { maxBytes: String(maxBytes) } : {},
|
|
60616
60602
|
...type ? { type } : {}
|
|
60617
60603
|
}).toString();
|
|
60604
|
+
const headers = authHeaders();
|
|
60605
|
+
const url = `${base}/api/lark-bot/resource?${qs}`;
|
|
60606
|
+
const ac = new AbortController();
|
|
60607
|
+
const timer = setTimeout(() => ac.abort(), opts.timeoutMs ?? 15e3);
|
|
60618
60608
|
let res;
|
|
60619
60609
|
try {
|
|
60620
|
-
res = await f2(
|
|
60621
|
-
method: "GET",
|
|
60622
|
-
signal: ac.signal,
|
|
60623
|
-
headers: {
|
|
60624
|
-
authorization: `Bearer ${opts.apiKey}`,
|
|
60625
|
-
"x-did": encodeURIComponent(opts.deviceId),
|
|
60626
|
-
"x-name": encodeURIComponent(opts.displayName),
|
|
60627
|
-
"x-scene": "daemon"
|
|
60628
|
-
}
|
|
60629
|
-
});
|
|
60610
|
+
res = await f2(url, { method: "GET", signal: ac.signal, headers });
|
|
60630
60611
|
} catch (err) {
|
|
60631
60612
|
throw new LarkBotCloudError(`lark-bot cloud resource fetch failed: ${err.message}`);
|
|
60632
60613
|
} finally {
|
|
@@ -62157,7 +62138,7 @@ async function centralRequest(opts, path101, init) {
|
|
|
62157
62138
|
}
|
|
62158
62139
|
clearTimeout(timer);
|
|
62159
62140
|
if (res.status === 401) {
|
|
62160
|
-
throw new CentralClientError("UNAUTHORIZED", "
|
|
62141
|
+
throw new CentralClientError("UNAUTHORIZED", "login pass rejected by center");
|
|
62161
62142
|
}
|
|
62162
62143
|
if (!res.ok) {
|
|
62163
62144
|
let detail = "";
|
|
@@ -62177,12 +62158,8 @@ async function centralRequest(opts, path101, init) {
|
|
|
62177
62158
|
async function centralExchange(opts) {
|
|
62178
62159
|
const body = await centralRequest(opts, "/api/clawd-identity/exchange", {
|
|
62179
62160
|
method: "POST",
|
|
62180
|
-
|
|
62181
|
-
|
|
62182
|
-
provider: opts.provider,
|
|
62183
|
-
deviceId: opts.deviceId,
|
|
62184
|
-
selfDeviceId: opts.selfDeviceId
|
|
62185
|
-
}
|
|
62161
|
+
bearer: opts.loginPass,
|
|
62162
|
+
body: { deviceId: opts.deviceId }
|
|
62186
62163
|
});
|
|
62187
62164
|
if (typeof body.token !== "string" || body.token.length === 0 || typeof body.ownerId !== "string" || typeof body.provider !== "string" || typeof body.displayName !== "string") {
|
|
62188
62165
|
throw new CentralClientError("BAD_RESPONSE", "exchange: missing token/ownerId/provider/displayName");
|
|
@@ -62202,10 +62179,8 @@ async function centralGetPublicKey(opts) {
|
|
|
62202
62179
|
async function centralUpsertDevice(opts) {
|
|
62203
62180
|
const body = await centralRequest(opts, "/api/clawd-identity/devices/self", {
|
|
62204
62181
|
method: "PUT",
|
|
62205
|
-
bearer: opts.
|
|
62182
|
+
bearer: opts.loginPass,
|
|
62206
62183
|
body: {
|
|
62207
|
-
deviceId: opts.deviceId,
|
|
62208
|
-
provider: opts.provider,
|
|
62209
62184
|
...opts.url ? { url: opts.url } : {},
|
|
62210
62185
|
...opts.name ? { name: opts.name } : {}
|
|
62211
62186
|
}
|
|
@@ -62226,11 +62201,10 @@ async function centralPrincipalStatus(opts) {
|
|
|
62226
62201
|
return { active: body.active };
|
|
62227
62202
|
}
|
|
62228
62203
|
async function centralGetApiKey(opts) {
|
|
62229
|
-
const body = await centralRequest(
|
|
62230
|
-
|
|
62231
|
-
|
|
62232
|
-
|
|
62233
|
-
);
|
|
62204
|
+
const body = await centralRequest(opts, "/api/persona-cloud/api-key", {
|
|
62205
|
+
method: "GET",
|
|
62206
|
+
bearer: opts.loginPass
|
|
62207
|
+
});
|
|
62234
62208
|
if (body.apiKey !== null && typeof body.apiKey !== "string") {
|
|
62235
62209
|
throw new CentralClientError("BAD_RESPONSE", "api-key: apiKey must be string or null");
|
|
62236
62210
|
}
|
|
@@ -62244,8 +62218,7 @@ async function centralGetApiKey(opts) {
|
|
|
62244
62218
|
async function centralIssueApiKey(opts) {
|
|
62245
62219
|
const body = await centralRequest(opts, "/api/persona-cloud/api-key", {
|
|
62246
62220
|
method: "POST",
|
|
62247
|
-
bearer: opts.
|
|
62248
|
-
body: { provider: opts.provider }
|
|
62221
|
+
bearer: opts.loginPass
|
|
62249
62222
|
});
|
|
62250
62223
|
if (typeof body.apiKey !== "string" || body.apiKey.length === 0) {
|
|
62251
62224
|
throw new CentralClientError("BAD_RESPONSE", "api-key: missing apiKey");
|
|
@@ -62260,11 +62233,10 @@ async function centralIssueApiKey(opts) {
|
|
|
62260
62233
|
};
|
|
62261
62234
|
}
|
|
62262
62235
|
async function centralListDevices(opts) {
|
|
62263
|
-
const body = await centralRequest(
|
|
62264
|
-
|
|
62265
|
-
|
|
62266
|
-
|
|
62267
|
-
);
|
|
62236
|
+
const body = await centralRequest(opts, "/api/clawd-identity/devices", {
|
|
62237
|
+
method: "GET",
|
|
62238
|
+
bearer: opts.loginPass
|
|
62239
|
+
});
|
|
62268
62240
|
if (!Array.isArray(body.devices)) {
|
|
62269
62241
|
throw new CentralClientError("BAD_RESPONSE", "devices: missing devices array");
|
|
62270
62242
|
}
|
|
@@ -62281,8 +62253,8 @@ async function centralListDevices(opts) {
|
|
|
62281
62253
|
async function centralConnectorsMine(opts) {
|
|
62282
62254
|
const body = await centralRequest(opts, "/api/persona-cloud/connectors/mine", {
|
|
62283
62255
|
method: "POST",
|
|
62284
|
-
bearer: opts.
|
|
62285
|
-
body: {
|
|
62256
|
+
bearer: opts.loginPass,
|
|
62257
|
+
body: { personaId: opts.personaId, connectors: opts.connectors }
|
|
62286
62258
|
});
|
|
62287
62259
|
if (!Array.isArray(body.connectors)) throw new CentralClientError("BAD_RESPONSE", "connectors/mine: missing connectors array");
|
|
62288
62260
|
return { connectors: body.connectors };
|
|
@@ -62290,16 +62262,16 @@ async function centralConnectorsMine(opts) {
|
|
|
62290
62262
|
async function centralConnectorFill(opts) {
|
|
62291
62263
|
const body = await centralRequest(opts, "/api/persona-cloud/connectors/fields", {
|
|
62292
62264
|
method: "PUT",
|
|
62293
|
-
bearer: opts.
|
|
62294
|
-
body: {
|
|
62265
|
+
bearer: opts.loginPass,
|
|
62266
|
+
body: { connector: opts.connector, values: opts.values }
|
|
62295
62267
|
});
|
|
62296
62268
|
if (body.ok !== true) throw new CentralClientError("BAD_RESPONSE", "connectors/fields: server did not ack ok");
|
|
62297
62269
|
}
|
|
62298
62270
|
async function centralGithubAuthOauthStart(opts) {
|
|
62299
62271
|
const body = await centralRequest(opts, "/api/persona-cloud/github/oauth/start", {
|
|
62300
62272
|
method: "POST",
|
|
62301
|
-
bearer: opts.
|
|
62302
|
-
body: {
|
|
62273
|
+
bearer: opts.loginPass,
|
|
62274
|
+
body: { ...opts.returnTo ? { returnTo: opts.returnTo } : {} }
|
|
62303
62275
|
});
|
|
62304
62276
|
if (typeof body.authUrl !== "string" || !body.authUrl) throw new CentralClientError("BAD_RESPONSE", "github/oauth/start: missing authUrl");
|
|
62305
62277
|
return { authUrl: body.authUrl };
|
|
@@ -62307,8 +62279,8 @@ async function centralGithubAuthOauthStart(opts) {
|
|
|
62307
62279
|
async function centralGithubAuthToken(opts) {
|
|
62308
62280
|
const body = await centralRequest(opts, "/api/persona-cloud/github/oauth/token", {
|
|
62309
62281
|
method: "POST",
|
|
62310
|
-
bearer: opts.
|
|
62311
|
-
body: {
|
|
62282
|
+
bearer: opts.loginPass,
|
|
62283
|
+
body: {}
|
|
62312
62284
|
});
|
|
62313
62285
|
if (body.token === null || body.token === void 0) return void 0;
|
|
62314
62286
|
if (typeof body.token !== "string" || !body.token) throw new CentralClientError("BAD_RESPONSE", "github/oauth/token: malformed token");
|
|
@@ -62347,10 +62319,10 @@ var CloudGatewayClient = class {
|
|
|
62347
62319
|
deps;
|
|
62348
62320
|
fetchImpl;
|
|
62349
62321
|
async credentials() {
|
|
62350
|
-
const
|
|
62351
|
-
if (!
|
|
62322
|
+
const loginPass = this.deps.getLoginPass();
|
|
62323
|
+
if (!loginPass) throw new ClawdError(ERROR_CODES.FEISHU_LOGIN_REQUIRED, "\u8FD8\u6CA1\u767B\u5F55\u98DE\u4E66\uFF0C\u4E91\u4E0A persona \u7528\u4E0D\u4E86");
|
|
62352
62324
|
const get = this.deps.getApiKey ?? ((args) => centralGetApiKey({ api: this.deps.centralApi ?? "", fetchImpl: this.fetchImpl, ...args }));
|
|
62353
|
-
const { apiKey, gatewayUrl } = await get({
|
|
62325
|
+
const { apiKey, gatewayUrl } = await get({ loginPass });
|
|
62354
62326
|
if (!apiKey) throw new Error("\u8FD8\u6CA1\u751F\u6210\u4E91 persona \u7684\u8C03\u7528 key\uFF0C\u53BB\u300C\u8BBE\u7F6E \u2192 \u4E91\u4E0A persona\u300D\u751F\u6210\u4E00\u628A");
|
|
62355
62327
|
if (!gatewayUrl) throw new Error("\u4E2D\u5FC3\u6CA1\u914D\u4E91 gateway \u5730\u5740\uFF08gatewayUrl \u4E3A\u7A7A\uFF09");
|
|
62356
62328
|
return { apiKey, gatewayUrl: trimSlash(gatewayUrl) };
|
|
@@ -65906,8 +65878,7 @@ async function importZip(buf, root) {
|
|
|
65906
65878
|
function parseLoginCallbackQuery(url) {
|
|
65907
65879
|
return {
|
|
65908
65880
|
token: url.searchParams.get("token") ?? "",
|
|
65909
|
-
state: url.searchParams.get("state") ?? ""
|
|
65910
|
-
expiresAt: url.searchParams.get("expires_at")
|
|
65881
|
+
state: url.searchParams.get("state") ?? ""
|
|
65911
65882
|
};
|
|
65912
65883
|
}
|
|
65913
65884
|
function escapeHtml(s2) {
|
|
@@ -67568,7 +67539,7 @@ var OwnerIdentityStore = class {
|
|
|
67568
67539
|
return null;
|
|
67569
67540
|
}
|
|
67570
67541
|
const r2 = parsed;
|
|
67571
|
-
if (!r2.identity || typeof r2.identity.ownerId !== "string" || r2.identity.ownerId.length === 0 || typeof r2.identity.provider !== "string" || r2.identity.provider.length === 0 || typeof r2.identity.displayName !== "string" || r2.identity.displayName.length === 0 || typeof r2.
|
|
67542
|
+
if (!r2.identity || typeof r2.identity.ownerId !== "string" || r2.identity.ownerId.length === 0 || typeof r2.identity.provider !== "string" || r2.identity.provider.length === 0 || typeof r2.identity.displayName !== "string" || r2.identity.displayName.length === 0 || typeof r2.loginPass !== "string" || r2.loginPass.length === 0) {
|
|
67572
67543
|
return null;
|
|
67573
67544
|
}
|
|
67574
67545
|
return {
|
|
@@ -67579,8 +67550,7 @@ var OwnerIdentityStore = class {
|
|
|
67579
67550
|
...typeof r2.identity.avatarUrl === "string" ? { avatarUrl: r2.identity.avatarUrl } : {},
|
|
67580
67551
|
...typeof r2.identity.unionId === "string" ? { unionId: r2.identity.unionId } : {}
|
|
67581
67552
|
},
|
|
67582
|
-
|
|
67583
|
-
ttcTokenExpiresAt: typeof r2.ttcTokenExpiresAt === "number" ? r2.ttcTokenExpiresAt : null,
|
|
67553
|
+
loginPass: r2.loginPass,
|
|
67584
67554
|
loginAt: typeof r2.loginAt === "string" ? r2.loginAt : (/* @__PURE__ */ new Date(0)).toISOString()
|
|
67585
67555
|
};
|
|
67586
67556
|
}
|
|
@@ -67644,23 +67614,23 @@ var LoginFlow = class {
|
|
|
67644
67614
|
if (!identity.unionId) {
|
|
67645
67615
|
return { ok: false, reason: "union_id missing from TTC user_info" };
|
|
67646
67616
|
}
|
|
67617
|
+
let loginPass;
|
|
67647
67618
|
try {
|
|
67648
|
-
|
|
67619
|
+
;
|
|
67620
|
+
({ loginPass } = await this.deps.upsertBinding({
|
|
67649
67621
|
deviceId: this.deps.getDeviceId(),
|
|
67650
67622
|
ttcToken: params.token,
|
|
67651
67623
|
identity
|
|
67652
|
-
});
|
|
67624
|
+
}));
|
|
67653
67625
|
} catch (err) {
|
|
67654
67626
|
return {
|
|
67655
67627
|
ok: false,
|
|
67656
67628
|
reason: `device_binding upsert failed: ${err.message}`
|
|
67657
67629
|
};
|
|
67658
67630
|
}
|
|
67659
|
-
const expiresAtNum = params.expiresAt ? Number.parseInt(params.expiresAt, 10) : NaN;
|
|
67660
67631
|
this.deps.store.write({
|
|
67661
67632
|
identity,
|
|
67662
|
-
|
|
67663
|
-
ttcTokenExpiresAt: Number.isFinite(expiresAtNum) ? expiresAtNum : null,
|
|
67633
|
+
loginPass,
|
|
67664
67634
|
loginAt: new Date(now).toISOString()
|
|
67665
67635
|
});
|
|
67666
67636
|
return { ok: true, identity };
|
|
@@ -67766,6 +67736,15 @@ async function upsertDeviceBinding(opts) {
|
|
|
67766
67736
|
}
|
|
67767
67737
|
throw new DeviceBindingClientError("API_ERROR", `HTTP ${res.status}: ${detail}`);
|
|
67768
67738
|
}
|
|
67739
|
+
let body = {};
|
|
67740
|
+
try {
|
|
67741
|
+
body = await res.json();
|
|
67742
|
+
} catch {
|
|
67743
|
+
}
|
|
67744
|
+
if (typeof body.loginPass !== "string" || body.loginPass.length === 0) {
|
|
67745
|
+
throw new DeviceBindingClientError("BAD_RESPONSE", "center did not issue a login pass (api too old?)");
|
|
67746
|
+
}
|
|
67747
|
+
return { loginPass: body.loginPass };
|
|
67769
67748
|
}
|
|
67770
67749
|
|
|
67771
67750
|
// src/contact/org-mesh.ts
|
|
@@ -67789,12 +67768,7 @@ async function fetchOrgPeers(opts) {
|
|
|
67789
67768
|
res = await doFetch(`${opts.apiUrl}/api/device-bindings/org-peers`, {
|
|
67790
67769
|
method: "GET",
|
|
67791
67770
|
signal: ac.signal,
|
|
67792
|
-
headers: {
|
|
67793
|
-
authorization: `Bearer ${opts.apiKey}`,
|
|
67794
|
-
"x-did": encodeURIComponent(opts.deviceId),
|
|
67795
|
-
"x-name": encodeURIComponent(opts.displayName),
|
|
67796
|
-
"x-scene": "daemon"
|
|
67797
|
-
}
|
|
67771
|
+
headers: { authorization: `Bearer ${opts.loginPass}` }
|
|
67798
67772
|
});
|
|
67799
67773
|
} catch (err) {
|
|
67800
67774
|
throw new OrgMeshClientError("NETWORK", `network error: ${err.message}`, err);
|
|
@@ -67877,7 +67851,7 @@ function rethrowLoginExpired(e) {
|
|
|
67877
67851
|
if (e instanceof CentralClientError && e.code === "UNAUTHORIZED") {
|
|
67878
67852
|
throw new ClawdError(
|
|
67879
67853
|
ERROR_CODES.VALIDATION_ERROR,
|
|
67880
|
-
`${LOGIN_EXPIRED_ERROR_MARKER}: \u767B\u5F55\
|
|
67854
|
+
`${LOGIN_EXPIRED_ERROR_MARKER}: \u767B\u5F55\u7968\u5DF2\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55`
|
|
67881
67855
|
);
|
|
67882
67856
|
}
|
|
67883
67857
|
throw e;
|
|
@@ -69979,9 +69953,7 @@ function buildFeishuAuthHandlers(deps) {
|
|
|
69979
69953
|
type: "auth:getIdentity:ok",
|
|
69980
69954
|
identity: record4 ? record4.identity : null,
|
|
69981
69955
|
// 决策 #15:设备属性,与登录态无关——UI"分享我的 Hub 标识"用
|
|
69982
|
-
deviceId: deps.deviceId
|
|
69983
|
-
// 过期时间戳(仅时间戳,token 本体永不出 ws)——UI 派生 过期/临期 提示
|
|
69984
|
-
ttcTokenExpiresAt: record4 ? record4.ttcTokenExpiresAt : null
|
|
69956
|
+
deviceId: deps.deviceId
|
|
69985
69957
|
}
|
|
69986
69958
|
};
|
|
69987
69959
|
};
|
|
@@ -70001,7 +69973,7 @@ function buildFeishuAuthHandlers(deps) {
|
|
|
70001
69973
|
"\u8FD8\u6CA1\u767B\u5F55\u98DE\u4E66\uFF0C\u62FF\u4E0D\u5230\u4E91 persona \u7684\u8C03\u7528 key"
|
|
70002
69974
|
);
|
|
70003
69975
|
}
|
|
70004
|
-
return {
|
|
69976
|
+
return { loginPass: record4.loginPass };
|
|
70005
69977
|
}
|
|
70006
69978
|
const apiKeyGet = async () => {
|
|
70007
69979
|
const { apiKey, createdAt, gatewayUrl } = await deps.apiKeyClient.get(requireLogin());
|
|
@@ -70034,9 +70006,9 @@ function ensureOwner6(ctx) {
|
|
|
70034
70006
|
var invalid2 = (msg) => new ClawdError(ERROR_CODES.VALIDATION_ERROR, `VALIDATION_ERROR: ${msg}`);
|
|
70035
70007
|
function buildCloudConnectorsHandlers(deps) {
|
|
70036
70008
|
function requireLogin() {
|
|
70037
|
-
const
|
|
70038
|
-
if (!
|
|
70039
|
-
return
|
|
70009
|
+
const loginPass = deps.getLoginPass();
|
|
70010
|
+
if (!loginPass) throw new ClawdError(ERROR_CODES.FEISHU_LOGIN_REQUIRED, "FEISHU_LOGIN_REQUIRED: \u8FD8\u6CA1\u767B\u5F55\u98DE\u4E66\uFF0C\u4E91\u4E0A persona \u7684\u8FDE\u63A5\u5668\u7528\u4E0D\u4E86");
|
|
70011
|
+
return { loginPass };
|
|
70040
70012
|
}
|
|
70041
70013
|
async function personalConnectors(personaId2) {
|
|
70042
70014
|
const persona = deps.getPersona(personaId2);
|
|
@@ -70322,7 +70294,7 @@ var METHOD_GRANT_MAP = {
|
|
|
70322
70294
|
"auth:apiKey:get": ADMIN_ANY,
|
|
70323
70295
|
"auth:apiKey:regenerate": ADMIN_ANY,
|
|
70324
70296
|
// ---- device:* 设备目录 + 连接(决策 #15,owner-only) ----
|
|
70325
|
-
// 设备目录 / 连接都是 owner
|
|
70297
|
+
// 设备目录 / 连接都是 owner 本机操作(用本机登录票找中心 server),guest 不可调
|
|
70326
70298
|
"device:list": ADMIN_ANY,
|
|
70327
70299
|
"device:connect": ADMIN_ANY,
|
|
70328
70300
|
"device:connections": ADMIN_ANY
|
|
@@ -70376,7 +70348,7 @@ function computeMethodAccess(args) {
|
|
|
70376
70348
|
}
|
|
70377
70349
|
|
|
70378
70350
|
// src/version.ts
|
|
70379
|
-
var version = "0.2.
|
|
70351
|
+
var version = "0.2.526".length > 0 ? "0.2.526" : "dev";
|
|
70380
70352
|
|
|
70381
70353
|
// src/cli-probe/probe.ts
|
|
70382
70354
|
var fs77 = __toESM(require("fs"), 1);
|
|
@@ -72458,14 +72430,7 @@ async function submitIosInterest(opts) {
|
|
|
72458
72430
|
res = await doFetch(`${opts.apiUrl}/api/ios-interest`, {
|
|
72459
72431
|
method: "POST",
|
|
72460
72432
|
signal: ac.signal,
|
|
72461
|
-
headers: {
|
|
72462
|
-
authorization: `Bearer ${opts.apiKey}`,
|
|
72463
|
-
"x-did": encodeURIComponent(opts.deviceId),
|
|
72464
|
-
"x-name": encodeURIComponent(opts.displayName),
|
|
72465
|
-
"x-scene": "daemon",
|
|
72466
|
-
"content-type": "application/json"
|
|
72467
|
-
},
|
|
72468
|
-
body: JSON.stringify({ unionId: opts.unionId, displayName: opts.displayName })
|
|
72433
|
+
headers: { authorization: `Bearer ${opts.loginPass}` }
|
|
72469
72434
|
});
|
|
72470
72435
|
} catch (err) {
|
|
72471
72436
|
clearTimeout(timer);
|
|
@@ -72500,16 +72465,13 @@ function buildOnboardingHandlers(deps) {
|
|
|
72500
72465
|
};
|
|
72501
72466
|
const iosInterest = async (frame) => {
|
|
72502
72467
|
parseArgs2(OnboardingIosInterestArgs, frame, "onboarding:iosInterest args");
|
|
72503
|
-
const
|
|
72504
|
-
if (!
|
|
72505
|
-
throw new ClawdError(ERROR_CODES.FEISHU_LOGIN_REQUIRED, "onboarding:iosInterest \u9700\u8981\u98DE\u4E66\u767B\u5F55");
|
|
72468
|
+
const loginPass = deps.getLoginPass();
|
|
72469
|
+
if (!loginPass) {
|
|
72470
|
+
throw new ClawdError(ERROR_CODES.FEISHU_LOGIN_REQUIRED, "onboarding:iosInterest \u9700\u8981\u98DE\u4E66\u767B\u5F55\uFF08\u5DF2\u767B\u5F55\u7684\u8BDD\u91CD\u542F\u4E00\u6B21 clawd \u9886\u767B\u5F55\u7968\uFF09");
|
|
72506
72471
|
}
|
|
72507
72472
|
await submitIosInterest({
|
|
72508
72473
|
apiUrl: deps.apiUrl,
|
|
72509
|
-
|
|
72510
|
-
deviceId: deps.deviceId,
|
|
72511
|
-
unionId: identity.unionId,
|
|
72512
|
-
displayName: identity.displayName,
|
|
72474
|
+
loginPass,
|
|
72513
72475
|
...deps.fetchImpl ? { fetchImpl: deps.fetchImpl } : {}
|
|
72514
72476
|
});
|
|
72515
72477
|
return { response: { registered: true } };
|
|
@@ -73047,8 +73009,8 @@ async function startDaemon(config) {
|
|
|
73047
73009
|
});
|
|
73048
73010
|
},
|
|
73049
73011
|
// 验票第二段(spec 2026-08-28):本地验签只证明"票是中心签的",这一步问中心
|
|
73050
|
-
// "持票人还在职吗"。token
|
|
73051
|
-
//
|
|
73012
|
+
// "持票人还在职吗"。token 不再过期,撤销全靠它。端点无鉴权——不带本机登录票,
|
|
73013
|
+
// 本机没登录也能验别人的票。
|
|
73052
73014
|
checkPrincipalActive: async (provider, ownerId2) => {
|
|
73053
73015
|
const r2 = await centralPrincipalStatus({
|
|
73054
73016
|
api: config.clawosApi ?? DEFAULT_CLAWOS_API,
|
|
@@ -73198,7 +73160,7 @@ async function startDaemon(config) {
|
|
|
73198
73160
|
const r2 = ownerIdentityStore.read();
|
|
73199
73161
|
if (!r2) throw new ClawdError(ERROR_CODES.FEISHU_LOGIN_REQUIRED, "FEISHU_LOGIN_REQUIRED: \u8FD8\u6CA1\u767B\u5F55\u98DE\u4E66\uFF0C\u5173\u8054 GitHub \u8981\u7ECF\u4E2D\u5FC3\uFF1B\u5148\u767B\u5F55\uFF0C\u6216\u5728\u5361\u7247\u4E0A\u624B\u52A8\u7C98 token");
|
|
73200
73162
|
try {
|
|
73201
|
-
return await centralGithubAuthOauthStart({ api: config.clawosApi ?? DEFAULT_CLAWOS_API,
|
|
73163
|
+
return await centralGithubAuthOauthStart({ api: config.clawosApi ?? DEFAULT_CLAWOS_API, loginPass: r2.loginPass, ...returnTo ? { returnTo } : {} });
|
|
73202
73164
|
} catch (err) {
|
|
73203
73165
|
throw new ClawdError(ERROR_CODES.INTERNAL, `\u5411\u4E2D\u5FC3\u8981 GitHub \u6388\u6743\u94FE\u63A5\u6CA1\u6210\uFF1A${err instanceof Error ? err.message : String(err)}`);
|
|
73204
73166
|
}
|
|
@@ -73206,7 +73168,7 @@ async function startDaemon(config) {
|
|
|
73206
73168
|
token: async () => {
|
|
73207
73169
|
const r2 = ownerIdentityStore.read();
|
|
73208
73170
|
if (!r2) return void 0;
|
|
73209
|
-
return centralGithubAuthToken({ api: config.clawosApi ?? DEFAULT_CLAWOS_API,
|
|
73171
|
+
return centralGithubAuthToken({ api: config.clawosApi ?? DEFAULT_CLAWOS_API, loginPass: r2.loginPass });
|
|
73210
73172
|
}
|
|
73211
73173
|
},
|
|
73212
73174
|
now: () => Date.now(),
|
|
@@ -73608,10 +73570,7 @@ async function startDaemon(config) {
|
|
|
73608
73570
|
screenIdleProbeLogger
|
|
73609
73571
|
}) : new ClaudeAdapter({ logger, historyReader: new ClaudeHistoryReader() });
|
|
73610
73572
|
const cloudGateway = new CloudGatewayClient({
|
|
73611
|
-
|
|
73612
|
-
const r2 = ownerIdentityStore.read();
|
|
73613
|
-
return r2 ? { ttcToken: r2.ttcToken, provider: r2.identity.provider } : null;
|
|
73614
|
-
},
|
|
73573
|
+
getLoginPass: () => ownerIdentityStore.read()?.loginPass ?? null,
|
|
73615
73574
|
centralApi: config.clawosApi ?? DEFAULT_CLAWOS_API,
|
|
73616
73575
|
logger
|
|
73617
73576
|
});
|
|
@@ -73718,9 +73677,7 @@ async function startDaemon(config) {
|
|
|
73718
73677
|
try {
|
|
73719
73678
|
await centralUpsertDevice({
|
|
73720
73679
|
api: config.clawosApi ?? DEFAULT_CLAWOS_API,
|
|
73721
|
-
|
|
73722
|
-
provider: record4.identity.provider,
|
|
73723
|
-
deviceId: authFile.deviceId,
|
|
73680
|
+
loginPass: record4.loginPass,
|
|
73724
73681
|
url: currentTunnelUrl ?? void 0,
|
|
73725
73682
|
name: ownerDisplayName
|
|
73726
73683
|
});
|
|
@@ -73737,15 +73694,14 @@ async function startDaemon(config) {
|
|
|
73737
73694
|
if (!feishuActive || orgMeshInFlight) return;
|
|
73738
73695
|
const record4 = ownerIdentityStore.read();
|
|
73739
73696
|
if (!record4) return;
|
|
73697
|
+
const loginPass = record4.loginPass;
|
|
73740
73698
|
orgMeshInFlight = true;
|
|
73741
73699
|
try {
|
|
73742
73700
|
await syncOrgMesh({
|
|
73743
73701
|
store: contactStore,
|
|
73744
73702
|
fetchPeers: () => fetchOrgPeers({
|
|
73745
73703
|
apiUrl: config.clawosApi ?? DEFAULT_CLAWOS_API,
|
|
73746
|
-
|
|
73747
|
-
deviceId: authFile.deviceId,
|
|
73748
|
-
displayName: record4.identity.displayName || authFile.deviceId
|
|
73704
|
+
loginPass
|
|
73749
73705
|
}),
|
|
73750
73706
|
connectToDevice: createConnectToDevice(feishuDeviceDeps),
|
|
73751
73707
|
log: (msg, meta) => logger.info(msg, meta),
|
|
@@ -73785,10 +73741,8 @@ async function startDaemon(config) {
|
|
|
73785
73741
|
}
|
|
73786
73742
|
return centralExchange({
|
|
73787
73743
|
api: config.clawosApi ?? DEFAULT_CLAWOS_API,
|
|
73788
|
-
|
|
73789
|
-
|
|
73790
|
-
deviceId,
|
|
73791
|
-
selfDeviceId: authFile.deviceId
|
|
73744
|
+
loginPass: record4.loginPass,
|
|
73745
|
+
deviceId
|
|
73792
73746
|
});
|
|
73793
73747
|
},
|
|
73794
73748
|
listDevices: async () => {
|
|
@@ -73798,8 +73752,7 @@ async function startDaemon(config) {
|
|
|
73798
73752
|
}
|
|
73799
73753
|
return centralListDevices({
|
|
73800
73754
|
api: config.clawosApi ?? DEFAULT_CLAWOS_API,
|
|
73801
|
-
|
|
73802
|
-
provider: record4.identity.provider
|
|
73755
|
+
loginPass: record4.loginPass
|
|
73803
73756
|
});
|
|
73804
73757
|
},
|
|
73805
73758
|
connectRemote,
|
|
@@ -73816,13 +73769,13 @@ async function startDaemon(config) {
|
|
|
73816
73769
|
fetchUserInfo: (ttcToken) => fetchTtcUserInfo({ apiBase: TTC_HOSTS.api, token: ttcToken }),
|
|
73817
73770
|
ttcAuthBase: TTC_HOSTS.auth,
|
|
73818
73771
|
getCallbackUrl: () => `http://127.0.0.1:${config.port}/auth/callback`,
|
|
73819
|
-
// device_bindings upsert(did ↔ 飞书 unionId
|
|
73820
|
-
// deviceId 从 auth.json 稳定读;apiUrl 走同一份 clawosApi;鉴权 = 刚登录拿到的 TTC JWT。
|
|
73772
|
+
// 登录换票(design 2026-09-15-api-auth-tiers §2):device_bindings upsert(did ↔ 飞书 unionId 映射)
|
|
73773
|
+
// + 领登录票。deviceId 从 auth.json 稳定读;apiUrl 走同一份 clawosApi;鉴权 = 刚登录拿到的 TTC JWT。
|
|
73821
73774
|
// 失败即登录失败(fail-hard,login-flow.spec §upsert 失败)。
|
|
73822
73775
|
getDeviceId: () => authFile.deviceId,
|
|
73823
73776
|
upsertBinding: async (opts) => {
|
|
73824
73777
|
try {
|
|
73825
|
-
await upsertDeviceBinding({
|
|
73778
|
+
const r2 = await upsertDeviceBinding({
|
|
73826
73779
|
apiUrl: config.clawosApi ?? DEFAULT_CLAWOS_API,
|
|
73827
73780
|
ttcToken: opts.ttcToken,
|
|
73828
73781
|
provider: opts.identity.provider,
|
|
@@ -73832,6 +73785,7 @@ async function startDaemon(config) {
|
|
|
73832
73785
|
deviceId: opts.deviceId,
|
|
73833
73786
|
unionId: opts.identity.unionId
|
|
73834
73787
|
});
|
|
73788
|
+
return r2;
|
|
73835
73789
|
} catch (err) {
|
|
73836
73790
|
logger.warn("device-binding upsert failed", {
|
|
73837
73791
|
deviceId: opts.deviceId,
|
|
@@ -73971,8 +73925,8 @@ async function startDaemon(config) {
|
|
|
73971
73925
|
// 联系人列表 store(device:connect 出站 / contact:handshake 入站落同一 store)
|
|
73972
73926
|
contactStore,
|
|
73973
73927
|
// contact:handshake 换票(spec 2026-07-22;2026-08-17 起硬失败,不再是回填):
|
|
73974
|
-
//
|
|
73975
|
-
// 契约(ContactHandlerDeps.exchangeToken):null =
|
|
73928
|
+
// 用本机登录票换 aud=对方设备 的票,现读 ownerIdentityStore(热切换后用新身份)。
|
|
73929
|
+
// 契约(ContactHandlerDeps.exchangeToken):null = 本机登录问题(未登录),
|
|
73976
73930
|
// 其他失败原样抛给 handler——两种都会让握手硬失败,只是给对端的错误文案不同。
|
|
73977
73931
|
exchangeToken: async (targetDeviceId) => {
|
|
73978
73932
|
const record4 = ownerIdentityStore.read();
|
|
@@ -73980,10 +73934,8 @@ async function startDaemon(config) {
|
|
|
73980
73934
|
try {
|
|
73981
73935
|
const r2 = await centralExchange({
|
|
73982
73936
|
api: config.clawosApi ?? DEFAULT_CLAWOS_API,
|
|
73983
|
-
|
|
73984
|
-
provider: record4.identity.provider,
|
|
73937
|
+
loginPass: record4.loginPass,
|
|
73985
73938
|
deviceId: targetDeviceId,
|
|
73986
|
-
selfDeviceId: authFile.deviceId,
|
|
73987
73939
|
// 换票在握手关键路径上(硬失败),对端 connect-remote RPC_TIMEOUT_MS=5s:
|
|
73988
73940
|
// 必须在其内失败/成功,否则对端先超时不落库、本机后换票成功落库 → 反向半连,
|
|
73989
73941
|
// 破坏「两侧都不落库」不变量。4s 留 1s 余量给 ws 往返
|
|
@@ -74036,21 +73988,18 @@ async function startDaemon(config) {
|
|
|
74036
73988
|
}
|
|
74037
73989
|
},
|
|
74038
73990
|
// 云 persona 卡片上的连接器区(design 2026-09-11-mcp-connector §3.8):装了什么以 gateway 登记行为真源,
|
|
74039
|
-
//
|
|
73991
|
+
// 连没连上问中心。登录票只在 daemon 内部传给中心,与 apiKeyClient 同一条纪律。
|
|
74040
73992
|
cloudConnectors: {
|
|
74041
73993
|
getPersona: (personaId2) => personaRegistry.get(personaId2),
|
|
74042
73994
|
gatewayConnectors: (gatewayPersonaId) => cloudGateway.personaConnectors(gatewayPersonaId),
|
|
74043
|
-
|
|
74044
|
-
const r2 = ownerIdentityStore.read();
|
|
74045
|
-
return r2 ? { ttcJwt: r2.ttcToken, provider: r2.identity.provider } : null;
|
|
74046
|
-
},
|
|
73995
|
+
getLoginPass: () => ownerIdentityStore.read()?.loginPass ?? null,
|
|
74047
73996
|
central: {
|
|
74048
73997
|
mine: (args) => centralConnectorsMine({ api: config.clawosApi ?? DEFAULT_CLAWOS_API, ...args }),
|
|
74049
73998
|
fill: (args) => centralConnectorFill({ api: config.clawosApi ?? DEFAULT_CLAWOS_API, ...args })
|
|
74050
73999
|
}
|
|
74051
74000
|
},
|
|
74052
74001
|
// 设备目录 + 连接(决策 #15:daemon 代理中心 server)。
|
|
74053
|
-
// exchange/listDevices
|
|
74002
|
+
// exchange/listDevices 包掉本机登录票(每次现读 store——热切换后立即用新身份);
|
|
74054
74003
|
// dispatcher 的 FEISHU_GATED_METHODS gate 已保证未登录时这些 RPC 到不了 handler,
|
|
74055
74004
|
// 这里的 FEISHU_LOGIN_REQUIRED 抛错只是防御纵深。
|
|
74056
74005
|
feishuDevice: feishuDeviceDeps,
|
|
@@ -74238,9 +74187,7 @@ async function startDaemon(config) {
|
|
|
74238
74187
|
const larkBotStore = createLarkBotBindingStore(import_node_path79.default.join(config.dataDir, "personas"));
|
|
74239
74188
|
const larkBotCloud = createLarkBotCloudClient({
|
|
74240
74189
|
api: config.clawosApi ?? DEFAULT_CLAWOS_API,
|
|
74241
|
-
|
|
74242
|
-
deviceId: authFile.deviceId,
|
|
74243
|
-
displayName: ownerDisplayName
|
|
74190
|
+
getLoginPass: () => ownerIdentityStore.read()?.loginPass ?? null
|
|
74244
74191
|
});
|
|
74245
74192
|
let larkDraining = false;
|
|
74246
74193
|
const larkChatRouter = createLarkChatRouter({
|
|
@@ -74280,17 +74227,8 @@ async function startDaemon(config) {
|
|
|
74280
74227
|
buildOnboardingHandlers({
|
|
74281
74228
|
dataDir: config.dataDir,
|
|
74282
74229
|
// 现读(登录/登出热切换);unionId 缺失时回落 ownerId(老登录记录无 unionId)
|
|
74283
|
-
|
|
74284
|
-
|
|
74285
|
-
if (!rec5) return null;
|
|
74286
|
-
return {
|
|
74287
|
-
unionId: rec5.identity.unionId ?? rec5.identity.ownerId,
|
|
74288
|
-
displayName: rec5.identity.displayName
|
|
74289
|
-
};
|
|
74290
|
-
},
|
|
74291
|
-
apiUrl: config.clawosApi ?? DEFAULT_CLAWOS_API,
|
|
74292
|
-
apiKey: resolveClawdTicketsApiKey(),
|
|
74293
|
-
deviceId: authFile.deviceId
|
|
74230
|
+
getLoginPass: () => ownerIdentityStore.read()?.loginPass ?? null,
|
|
74231
|
+
apiUrl: config.clawosApi ?? DEFAULT_CLAWOS_API
|
|
74294
74232
|
})
|
|
74295
74233
|
);
|
|
74296
74234
|
const authResolver = new AuthContextResolver({
|
|
@@ -74533,21 +74471,6 @@ async function startDaemon(config) {
|
|
|
74533
74471
|
stateMgr.write(stateSnapshot);
|
|
74534
74472
|
currentTunnelUrl = r2.url;
|
|
74535
74473
|
wss.broadcastAll({ type: "tunnel:ready", url: r2.url, subdomain: r2.subdomain });
|
|
74536
|
-
void refreshTunnelUrlOnStartup(larkBotDeps);
|
|
74537
|
-
void (async () => {
|
|
74538
|
-
if (larkBotDeps.listBoundPersonaIds().length === 0) return;
|
|
74539
|
-
try {
|
|
74540
|
-
const items = await larkBotCloud.claimEvents();
|
|
74541
|
-
routeClaimedEvents(items, {
|
|
74542
|
-
router: larkChatRouter,
|
|
74543
|
-
dedupe: larkEventDedupe,
|
|
74544
|
-
nowSec: Math.floor(Date.now() / 1e3)
|
|
74545
|
-
});
|
|
74546
|
-
if (items.length > 0) logger.info("larkBot pending events claimed", { count: items.length });
|
|
74547
|
-
} catch (err) {
|
|
74548
|
-
logger.warn("larkBot pending events claim failed", { err: err.message });
|
|
74549
|
-
}
|
|
74550
|
-
})();
|
|
74551
74474
|
const connectUrl = resolvedAuthToken ? `${r2.url}#token=${resolvedAuthToken}` : r2.url;
|
|
74552
74475
|
const lines = [
|
|
74553
74476
|
`Tunnel: ${r2.url}`,
|
|
@@ -74592,9 +74515,23 @@ ${bar}
|
|
|
74592
74515
|
logger.warn("tunnel unavailable, degraded to local mode", { reason: tunnelError });
|
|
74593
74516
|
}
|
|
74594
74517
|
}
|
|
74595
|
-
void reportDevice()
|
|
74518
|
+
void reportDevice().then(async () => {
|
|
74519
|
+
void runOrgMesh();
|
|
74520
|
+
if (!currentTunnelUrl || larkBotDeps.listBoundPersonaIds().length === 0) return;
|
|
74521
|
+
void refreshTunnelUrlOnStartup(larkBotDeps);
|
|
74522
|
+
try {
|
|
74523
|
+
const items = await larkBotCloud.claimEvents();
|
|
74524
|
+
routeClaimedEvents(items, {
|
|
74525
|
+
router: larkChatRouter,
|
|
74526
|
+
dedupe: larkEventDedupe,
|
|
74527
|
+
nowSec: Math.floor(Date.now() / 1e3)
|
|
74528
|
+
});
|
|
74529
|
+
if (items.length > 0) logger.info("larkBot pending events claimed", { count: items.length });
|
|
74530
|
+
} catch (err) {
|
|
74531
|
+
logger.warn("larkBot pending events claim failed", { err: err.message });
|
|
74532
|
+
}
|
|
74533
|
+
});
|
|
74596
74534
|
void fetchServerKey();
|
|
74597
|
-
void runOrgMesh();
|
|
74598
74535
|
const tickAttachmentGc = () => {
|
|
74599
74536
|
try {
|
|
74600
74537
|
runAttachmentGc({
|