@clawos-dev/clawd 0.2.525 → 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.
@@ -21929,13 +21929,7 @@ var AuthGetIdentityResponseSchema = external_exports.object({
21929
21929
  * 设备属性,与登录态无关、登录登出不变。UI"我的设备标识"用它拼
21930
21930
  * clawos://device/<deviceId>(替代旧的 unionId——不再向外暴露人的身份标识)。
21931
21931
  */
21932
- deviceId: external_exports.string().min(1),
21933
- /**
21934
- * TTC JWT 过期时间(unix ms)。null = 登录回调未携带 expires_at;字段缺省 = 老 daemon。
21935
- * 仅时间戳——token 本体永不出 ws(spec §9 不变)。UI 据此派生 过期/临期 提示
21936
- * (见 spec 2026-08-17-ttc-jwt-expiry-ux-design §2)。
21937
- */
21938
- ttcTokenExpiresAt: external_exports.number().nullable().optional()
21932
+ deviceId: external_exports.string().min(1)
21939
21933
  });
21940
21934
  var AuthLogoutResponseSchema = external_exports.object({
21941
21935
  type: external_exports.literal("auth:logout:ok")
@@ -24492,7 +24486,7 @@ var METHOD_DOCS = {
24492
24486
  args: NO_ARGS
24493
24487
  },
24494
24488
  "auth:getIdentity": {
24495
- 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 ttcToken",
24489
+ 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",
24496
24490
  args: NO_ARGS
24497
24491
  },
24498
24492
  "auth:logout": {
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 的 ttcJwt)
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 ttcToken",
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": {
@@ -62144,7 +62138,7 @@ async function centralRequest(opts, path101, init) {
62144
62138
  }
62145
62139
  clearTimeout(timer);
62146
62140
  if (res.status === 401) {
62147
- throw new CentralClientError("UNAUTHORIZED", "TTC JWT invalid or expired");
62141
+ throw new CentralClientError("UNAUTHORIZED", "login pass rejected by center");
62148
62142
  }
62149
62143
  if (!res.ok) {
62150
62144
  let detail = "";
@@ -62164,12 +62158,8 @@ async function centralRequest(opts, path101, init) {
62164
62158
  async function centralExchange(opts) {
62165
62159
  const body = await centralRequest(opts, "/api/clawd-identity/exchange", {
62166
62160
  method: "POST",
62167
- body: {
62168
- jwt: opts.jwt,
62169
- provider: opts.provider,
62170
- deviceId: opts.deviceId,
62171
- selfDeviceId: opts.selfDeviceId
62172
- }
62161
+ bearer: opts.loginPass,
62162
+ body: { deviceId: opts.deviceId }
62173
62163
  });
62174
62164
  if (typeof body.token !== "string" || body.token.length === 0 || typeof body.ownerId !== "string" || typeof body.provider !== "string" || typeof body.displayName !== "string") {
62175
62165
  throw new CentralClientError("BAD_RESPONSE", "exchange: missing token/ownerId/provider/displayName");
@@ -62189,10 +62179,8 @@ async function centralGetPublicKey(opts) {
62189
62179
  async function centralUpsertDevice(opts) {
62190
62180
  const body = await centralRequest(opts, "/api/clawd-identity/devices/self", {
62191
62181
  method: "PUT",
62192
- bearer: opts.ttcJwt,
62182
+ bearer: opts.loginPass,
62193
62183
  body: {
62194
- deviceId: opts.deviceId,
62195
- provider: opts.provider,
62196
62184
  ...opts.url ? { url: opts.url } : {},
62197
62185
  ...opts.name ? { name: opts.name } : {}
62198
62186
  }
@@ -62200,10 +62188,7 @@ async function centralUpsertDevice(opts) {
62200
62188
  if (body.ok !== true) {
62201
62189
  throw new CentralClientError("BAD_RESPONSE", "upsertDevice: server did not ack ok");
62202
62190
  }
62203
- return {
62204
- ok: true,
62205
- ...typeof body.loginPass === "string" && body.loginPass.length > 0 ? { loginPass: body.loginPass } : {}
62206
- };
62191
+ return { ok: true };
62207
62192
  }
62208
62193
  async function centralPrincipalStatus(opts) {
62209
62194
  const query = `provider=${encodeURIComponent(opts.provider)}&ownerId=${encodeURIComponent(opts.ownerId)}`;
@@ -62216,11 +62201,10 @@ async function centralPrincipalStatus(opts) {
62216
62201
  return { active: body.active };
62217
62202
  }
62218
62203
  async function centralGetApiKey(opts) {
62219
- const body = await centralRequest(
62220
- opts,
62221
- `/api/persona-cloud/api-key?provider=${encodeURIComponent(opts.provider)}`,
62222
- { method: "GET", bearer: opts.ttcJwt }
62223
- );
62204
+ const body = await centralRequest(opts, "/api/persona-cloud/api-key", {
62205
+ method: "GET",
62206
+ bearer: opts.loginPass
62207
+ });
62224
62208
  if (body.apiKey !== null && typeof body.apiKey !== "string") {
62225
62209
  throw new CentralClientError("BAD_RESPONSE", "api-key: apiKey must be string or null");
62226
62210
  }
@@ -62234,8 +62218,7 @@ async function centralGetApiKey(opts) {
62234
62218
  async function centralIssueApiKey(opts) {
62235
62219
  const body = await centralRequest(opts, "/api/persona-cloud/api-key", {
62236
62220
  method: "POST",
62237
- bearer: opts.ttcJwt,
62238
- body: { provider: opts.provider }
62221
+ bearer: opts.loginPass
62239
62222
  });
62240
62223
  if (typeof body.apiKey !== "string" || body.apiKey.length === 0) {
62241
62224
  throw new CentralClientError("BAD_RESPONSE", "api-key: missing apiKey");
@@ -62250,11 +62233,10 @@ async function centralIssueApiKey(opts) {
62250
62233
  };
62251
62234
  }
62252
62235
  async function centralListDevices(opts) {
62253
- const body = await centralRequest(
62254
- opts,
62255
- `/api/clawd-identity/devices?provider=${encodeURIComponent(opts.provider)}`,
62256
- { method: "GET", bearer: opts.ttcJwt }
62257
- );
62236
+ const body = await centralRequest(opts, "/api/clawd-identity/devices", {
62237
+ method: "GET",
62238
+ bearer: opts.loginPass
62239
+ });
62258
62240
  if (!Array.isArray(body.devices)) {
62259
62241
  throw new CentralClientError("BAD_RESPONSE", "devices: missing devices array");
62260
62242
  }
@@ -62271,8 +62253,8 @@ async function centralListDevices(opts) {
62271
62253
  async function centralConnectorsMine(opts) {
62272
62254
  const body = await centralRequest(opts, "/api/persona-cloud/connectors/mine", {
62273
62255
  method: "POST",
62274
- bearer: opts.ttcJwt,
62275
- body: { provider: opts.provider, personaId: opts.personaId, connectors: opts.connectors }
62256
+ bearer: opts.loginPass,
62257
+ body: { personaId: opts.personaId, connectors: opts.connectors }
62276
62258
  });
62277
62259
  if (!Array.isArray(body.connectors)) throw new CentralClientError("BAD_RESPONSE", "connectors/mine: missing connectors array");
62278
62260
  return { connectors: body.connectors };
@@ -62280,16 +62262,16 @@ async function centralConnectorsMine(opts) {
62280
62262
  async function centralConnectorFill(opts) {
62281
62263
  const body = await centralRequest(opts, "/api/persona-cloud/connectors/fields", {
62282
62264
  method: "PUT",
62283
- bearer: opts.ttcJwt,
62284
- body: { provider: opts.provider, connector: opts.connector, values: opts.values }
62265
+ bearer: opts.loginPass,
62266
+ body: { connector: opts.connector, values: opts.values }
62285
62267
  });
62286
62268
  if (body.ok !== true) throw new CentralClientError("BAD_RESPONSE", "connectors/fields: server did not ack ok");
62287
62269
  }
62288
62270
  async function centralGithubAuthOauthStart(opts) {
62289
62271
  const body = await centralRequest(opts, "/api/persona-cloud/github/oauth/start", {
62290
62272
  method: "POST",
62291
- bearer: opts.ttcJwt,
62292
- body: { provider: opts.provider, ...opts.returnTo ? { returnTo: opts.returnTo } : {} }
62273
+ bearer: opts.loginPass,
62274
+ body: { ...opts.returnTo ? { returnTo: opts.returnTo } : {} }
62293
62275
  });
62294
62276
  if (typeof body.authUrl !== "string" || !body.authUrl) throw new CentralClientError("BAD_RESPONSE", "github/oauth/start: missing authUrl");
62295
62277
  return { authUrl: body.authUrl };
@@ -62297,8 +62279,8 @@ async function centralGithubAuthOauthStart(opts) {
62297
62279
  async function centralGithubAuthToken(opts) {
62298
62280
  const body = await centralRequest(opts, "/api/persona-cloud/github/oauth/token", {
62299
62281
  method: "POST",
62300
- bearer: opts.ttcJwt,
62301
- body: { provider: opts.provider }
62282
+ bearer: opts.loginPass,
62283
+ body: {}
62302
62284
  });
62303
62285
  if (body.token === null || body.token === void 0) return void 0;
62304
62286
  if (typeof body.token !== "string" || !body.token) throw new CentralClientError("BAD_RESPONSE", "github/oauth/token: malformed token");
@@ -62337,10 +62319,10 @@ var CloudGatewayClient = class {
62337
62319
  deps;
62338
62320
  fetchImpl;
62339
62321
  async credentials() {
62340
- const rec5 = this.deps.readIdentity();
62341
- if (!rec5) throw new ClawdError(ERROR_CODES.FEISHU_LOGIN_REQUIRED, "\u8FD8\u6CA1\u767B\u5F55\u98DE\u4E66\uFF0C\u4E91\u4E0A persona \u7528\u4E0D\u4E86");
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");
62342
62324
  const get = this.deps.getApiKey ?? ((args) => centralGetApiKey({ api: this.deps.centralApi ?? "", fetchImpl: this.fetchImpl, ...args }));
62343
- const { apiKey, gatewayUrl } = await get({ ttcJwt: rec5.ttcToken, provider: rec5.provider });
62325
+ const { apiKey, gatewayUrl } = await get({ loginPass });
62344
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");
62345
62327
  if (!gatewayUrl) throw new Error("\u4E2D\u5FC3\u6CA1\u914D\u4E91 gateway \u5730\u5740\uFF08gatewayUrl \u4E3A\u7A7A\uFF09");
62346
62328
  return { apiKey, gatewayUrl: trimSlash(gatewayUrl) };
@@ -65896,8 +65878,7 @@ async function importZip(buf, root) {
65896
65878
  function parseLoginCallbackQuery(url) {
65897
65879
  return {
65898
65880
  token: url.searchParams.get("token") ?? "",
65899
- state: url.searchParams.get("state") ?? "",
65900
- expiresAt: url.searchParams.get("expires_at")
65881
+ state: url.searchParams.get("state") ?? ""
65901
65882
  };
65902
65883
  }
65903
65884
  function escapeHtml(s2) {
@@ -67558,7 +67539,7 @@ var OwnerIdentityStore = class {
67558
67539
  return null;
67559
67540
  }
67560
67541
  const r2 = parsed;
67561
- 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.ttcToken !== "string" || r2.ttcToken.length === 0) {
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) {
67562
67543
  return null;
67563
67544
  }
67564
67545
  return {
@@ -67569,10 +67550,8 @@ var OwnerIdentityStore = class {
67569
67550
  ...typeof r2.identity.avatarUrl === "string" ? { avatarUrl: r2.identity.avatarUrl } : {},
67570
67551
  ...typeof r2.identity.unionId === "string" ? { unionId: r2.identity.unionId } : {}
67571
67552
  },
67572
- ttcToken: r2.ttcToken,
67573
- ttcTokenExpiresAt: typeof r2.ttcTokenExpiresAt === "number" ? r2.ttcTokenExpiresAt : null,
67574
- loginAt: typeof r2.loginAt === "string" ? r2.loginAt : (/* @__PURE__ */ new Date(0)).toISOString(),
67575
- ...typeof r2.loginPass === "string" && r2.loginPass.length > 0 ? { loginPass: r2.loginPass } : {}
67553
+ loginPass: r2.loginPass,
67554
+ loginAt: typeof r2.loginAt === "string" ? r2.loginAt : (/* @__PURE__ */ new Date(0)).toISOString()
67576
67555
  };
67577
67556
  }
67578
67557
  write(record4) {
@@ -67649,13 +67628,10 @@ var LoginFlow = class {
67649
67628
  reason: `device_binding upsert failed: ${err.message}`
67650
67629
  };
67651
67630
  }
67652
- const expiresAtNum = params.expiresAt ? Number.parseInt(params.expiresAt, 10) : NaN;
67653
67631
  this.deps.store.write({
67654
67632
  identity,
67655
- ttcToken: params.token,
67656
- ttcTokenExpiresAt: Number.isFinite(expiresAtNum) ? expiresAtNum : null,
67657
- loginAt: new Date(now).toISOString(),
67658
- ...loginPass ? { loginPass } : {}
67633
+ loginPass,
67634
+ loginAt: new Date(now).toISOString()
67659
67635
  });
67660
67636
  return { ok: true, identity };
67661
67637
  }
@@ -67765,7 +67741,10 @@ async function upsertDeviceBinding(opts) {
67765
67741
  body = await res.json();
67766
67742
  } catch {
67767
67743
  }
67768
- return typeof body.loginPass === "string" && body.loginPass.length > 0 ? { loginPass: body.loginPass } : {};
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
@@ -67872,7 +67851,7 @@ function rethrowLoginExpired(e) {
67872
67851
  if (e instanceof CentralClientError && e.code === "UNAUTHORIZED") {
67873
67852
  throw new ClawdError(
67874
67853
  ERROR_CODES.VALIDATION_ERROR,
67875
- `${LOGIN_EXPIRED_ERROR_MARKER}: \u767B\u5F55\u51ED\u8BC1\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55`
67854
+ `${LOGIN_EXPIRED_ERROR_MARKER}: \u767B\u5F55\u7968\u5DF2\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55`
67876
67855
  );
67877
67856
  }
67878
67857
  throw e;
@@ -69974,9 +69953,7 @@ function buildFeishuAuthHandlers(deps) {
69974
69953
  type: "auth:getIdentity:ok",
69975
69954
  identity: record4 ? record4.identity : null,
69976
69955
  // 决策 #15:设备属性,与登录态无关——UI"分享我的 Hub 标识"用
69977
- deviceId: deps.deviceId,
69978
- // 过期时间戳(仅时间戳,token 本体永不出 ws)——UI 派生 过期/临期 提示
69979
- ttcTokenExpiresAt: record4 ? record4.ttcTokenExpiresAt : null
69956
+ deviceId: deps.deviceId
69980
69957
  }
69981
69958
  };
69982
69959
  };
@@ -69996,7 +69973,7 @@ function buildFeishuAuthHandlers(deps) {
69996
69973
  "\u8FD8\u6CA1\u767B\u5F55\u98DE\u4E66\uFF0C\u62FF\u4E0D\u5230\u4E91 persona \u7684\u8C03\u7528 key"
69997
69974
  );
69998
69975
  }
69999
- return { ttcJwt: record4.ttcToken, provider: record4.identity.provider };
69976
+ return { loginPass: record4.loginPass };
70000
69977
  }
70001
69978
  const apiKeyGet = async () => {
70002
69979
  const { apiKey, createdAt, gatewayUrl } = await deps.apiKeyClient.get(requireLogin());
@@ -70029,9 +70006,9 @@ function ensureOwner6(ctx) {
70029
70006
  var invalid2 = (msg) => new ClawdError(ERROR_CODES.VALIDATION_ERROR, `VALIDATION_ERROR: ${msg}`);
70030
70007
  function buildCloudConnectorsHandlers(deps) {
70031
70008
  function requireLogin() {
70032
- const rec5 = deps.readIdentity();
70033
- if (!rec5) 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");
70034
- return rec5;
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 };
70035
70012
  }
70036
70013
  async function personalConnectors(personaId2) {
70037
70014
  const persona = deps.getPersona(personaId2);
@@ -70317,7 +70294,7 @@ var METHOD_GRANT_MAP = {
70317
70294
  "auth:apiKey:get": ADMIN_ANY,
70318
70295
  "auth:apiKey:regenerate": ADMIN_ANY,
70319
70296
  // ---- device:* 设备目录 + 连接(决策 #15,owner-only) ----
70320
- // 设备目录 / 连接都是 owner 本机操作(用 owner 的 ttcJwt 找中心 server),guest 不可调
70297
+ // 设备目录 / 连接都是 owner 本机操作(用本机登录票找中心 server),guest 不可调
70321
70298
  "device:list": ADMIN_ANY,
70322
70299
  "device:connect": ADMIN_ANY,
70323
70300
  "device:connections": ADMIN_ANY
@@ -70371,7 +70348,7 @@ function computeMethodAccess(args) {
70371
70348
  }
70372
70349
 
70373
70350
  // src/version.ts
70374
- var version = "0.2.525".length > 0 ? "0.2.525" : "dev";
70351
+ var version = "0.2.526".length > 0 ? "0.2.526" : "dev";
70375
70352
 
70376
70353
  // src/cli-probe/probe.ts
70377
70354
  var fs77 = __toESM(require("fs"), 1);
@@ -73032,8 +73009,8 @@ async function startDaemon(config) {
73032
73009
  });
73033
73010
  },
73034
73011
  // 验票第二段(spec 2026-08-28):本地验签只证明"票是中心签的",这一步问中心
73035
- // "持票人还在职吗"。token 不再过期,撤销全靠它。端点无鉴权——不带本机 ttcJwt,
73036
- // 否则飞书过期又会牵连互联。
73012
+ // "持票人还在职吗"。token 不再过期,撤销全靠它。端点无鉴权——不带本机登录票,
73013
+ // 本机没登录也能验别人的票。
73037
73014
  checkPrincipalActive: async (provider, ownerId2) => {
73038
73015
  const r2 = await centralPrincipalStatus({
73039
73016
  api: config.clawosApi ?? DEFAULT_CLAWOS_API,
@@ -73183,7 +73160,7 @@ async function startDaemon(config) {
73183
73160
  const r2 = ownerIdentityStore.read();
73184
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");
73185
73162
  try {
73186
- return await centralGithubAuthOauthStart({ api: config.clawosApi ?? DEFAULT_CLAWOS_API, ttcJwt: r2.ttcToken, provider: r2.identity.provider, ...returnTo ? { returnTo } : {} });
73163
+ return await centralGithubAuthOauthStart({ api: config.clawosApi ?? DEFAULT_CLAWOS_API, loginPass: r2.loginPass, ...returnTo ? { returnTo } : {} });
73187
73164
  } catch (err) {
73188
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)}`);
73189
73166
  }
@@ -73191,7 +73168,7 @@ async function startDaemon(config) {
73191
73168
  token: async () => {
73192
73169
  const r2 = ownerIdentityStore.read();
73193
73170
  if (!r2) return void 0;
73194
- return centralGithubAuthToken({ api: config.clawosApi ?? DEFAULT_CLAWOS_API, ttcJwt: r2.ttcToken, provider: r2.identity.provider });
73171
+ return centralGithubAuthToken({ api: config.clawosApi ?? DEFAULT_CLAWOS_API, loginPass: r2.loginPass });
73195
73172
  }
73196
73173
  },
73197
73174
  now: () => Date.now(),
@@ -73593,10 +73570,7 @@ async function startDaemon(config) {
73593
73570
  screenIdleProbeLogger
73594
73571
  }) : new ClaudeAdapter({ logger, historyReader: new ClaudeHistoryReader() });
73595
73572
  const cloudGateway = new CloudGatewayClient({
73596
- readIdentity: () => {
73597
- const r2 = ownerIdentityStore.read();
73598
- return r2 ? { ttcToken: r2.ttcToken, provider: r2.identity.provider } : null;
73599
- },
73573
+ getLoginPass: () => ownerIdentityStore.read()?.loginPass ?? null,
73600
73574
  centralApi: config.clawosApi ?? DEFAULT_CLAWOS_API,
73601
73575
  logger
73602
73576
  });
@@ -73701,24 +73675,15 @@ async function startDaemon(config) {
73701
73675
  const record4 = ownerIdentityStore.read();
73702
73676
  if (!record4) return;
73703
73677
  try {
73704
- const r2 = await centralUpsertDevice({
73678
+ await centralUpsertDevice({
73705
73679
  api: config.clawosApi ?? DEFAULT_CLAWOS_API,
73706
- ttcJwt: record4.ttcToken,
73707
- provider: record4.identity.provider,
73708
- deviceId: authFile.deviceId,
73680
+ loginPass: record4.loginPass,
73709
73681
  url: currentTunnelUrl ?? void 0,
73710
73682
  name: ownerDisplayName
73711
73683
  });
73712
- if (r2.loginPass) {
73713
- const latest = ownerIdentityStore.read();
73714
- if (latest && latest.ttcToken === record4.ttcToken && latest.loginPass !== r2.loginPass) {
73715
- ownerIdentityStore.write({ ...latest, loginPass: r2.loginPass });
73716
- }
73717
- }
73718
73684
  logger.info("device registered to central server", {
73719
73685
  deviceId: authFile.deviceId,
73720
- url: currentTunnelUrl ?? "(none)",
73721
- loginPass: r2.loginPass ? "issued" : "absent"
73686
+ url: currentTunnelUrl ?? "(none)"
73722
73687
  });
73723
73688
  } catch (err) {
73724
73689
  logger.warn("device register failed (best-effort)", { err: err.message });
@@ -73728,7 +73693,7 @@ async function startDaemon(config) {
73728
73693
  const runOrgMesh = async () => {
73729
73694
  if (!feishuActive || orgMeshInFlight) return;
73730
73695
  const record4 = ownerIdentityStore.read();
73731
- if (!record4?.loginPass) return;
73696
+ if (!record4) return;
73732
73697
  const loginPass = record4.loginPass;
73733
73698
  orgMeshInFlight = true;
73734
73699
  try {
@@ -73776,10 +73741,8 @@ async function startDaemon(config) {
73776
73741
  }
73777
73742
  return centralExchange({
73778
73743
  api: config.clawosApi ?? DEFAULT_CLAWOS_API,
73779
- jwt: record4.ttcToken,
73780
- provider: record4.identity.provider,
73781
- deviceId,
73782
- selfDeviceId: authFile.deviceId
73744
+ loginPass: record4.loginPass,
73745
+ deviceId
73783
73746
  });
73784
73747
  },
73785
73748
  listDevices: async () => {
@@ -73789,8 +73752,7 @@ async function startDaemon(config) {
73789
73752
  }
73790
73753
  return centralListDevices({
73791
73754
  api: config.clawosApi ?? DEFAULT_CLAWOS_API,
73792
- ttcJwt: record4.ttcToken,
73793
- provider: record4.identity.provider
73755
+ loginPass: record4.loginPass
73794
73756
  });
73795
73757
  },
73796
73758
  connectRemote,
@@ -73821,8 +73783,7 @@ async function startDaemon(config) {
73821
73783
  });
73822
73784
  logger.info("device-binding upsert succeeded", {
73823
73785
  deviceId: opts.deviceId,
73824
- unionId: opts.identity.unionId,
73825
- loginPass: r2.loginPass ? "issued" : "absent"
73786
+ unionId: opts.identity.unionId
73826
73787
  });
73827
73788
  return r2;
73828
73789
  } catch (err) {
@@ -73964,8 +73925,8 @@ async function startDaemon(config) {
73964
73925
  // 联系人列表 store(device:connect 出站 / contact:handshake 入站落同一 store)
73965
73926
  contactStore,
73966
73927
  // contact:handshake 换票(spec 2026-07-22;2026-08-17 起硬失败,不再是回填):
73967
- // 用 owner 当前 jwt 换 aud=对方设备 的票,现读 ownerIdentityStore(热切换后用新身份)。
73968
- // 契约(ContactHandlerDeps.exchangeToken):null = 本机登录问题(未登录 / JWT 过期),
73928
+ // 用本机登录票换 aud=对方设备 的票,现读 ownerIdentityStore(热切换后用新身份)。
73929
+ // 契约(ContactHandlerDeps.exchangeToken):null = 本机登录问题(未登录),
73969
73930
  // 其他失败原样抛给 handler——两种都会让握手硬失败,只是给对端的错误文案不同。
73970
73931
  exchangeToken: async (targetDeviceId) => {
73971
73932
  const record4 = ownerIdentityStore.read();
@@ -73973,10 +73934,8 @@ async function startDaemon(config) {
73973
73934
  try {
73974
73935
  const r2 = await centralExchange({
73975
73936
  api: config.clawosApi ?? DEFAULT_CLAWOS_API,
73976
- jwt: record4.ttcToken,
73977
- provider: record4.identity.provider,
73937
+ loginPass: record4.loginPass,
73978
73938
  deviceId: targetDeviceId,
73979
- selfDeviceId: authFile.deviceId,
73980
73939
  // 换票在握手关键路径上(硬失败),对端 connect-remote RPC_TIMEOUT_MS=5s:
73981
73940
  // 必须在其内失败/成功,否则对端先超时不落库、本机后换票成功落库 → 反向半连,
73982
73941
  // 破坏「两侧都不落库」不变量。4s 留 1s 余量给 ws 往返
@@ -74029,21 +73988,18 @@ async function startDaemon(config) {
74029
73988
  }
74030
73989
  },
74031
73990
  // 云 persona 卡片上的连接器区(design 2026-09-11-mcp-connector §3.8):装了什么以 gateway 登记行为真源,
74032
- // 连没连上问中心。登录凭证只在 daemon 内部传给中心,与 apiKeyClient 同一条纪律。
73991
+ // 连没连上问中心。登录票只在 daemon 内部传给中心,与 apiKeyClient 同一条纪律。
74033
73992
  cloudConnectors: {
74034
73993
  getPersona: (personaId2) => personaRegistry.get(personaId2),
74035
73994
  gatewayConnectors: (gatewayPersonaId) => cloudGateway.personaConnectors(gatewayPersonaId),
74036
- readIdentity: () => {
74037
- const r2 = ownerIdentityStore.read();
74038
- return r2 ? { ttcJwt: r2.ttcToken, provider: r2.identity.provider } : null;
74039
- },
73995
+ getLoginPass: () => ownerIdentityStore.read()?.loginPass ?? null,
74040
73996
  central: {
74041
73997
  mine: (args) => centralConnectorsMine({ api: config.clawosApi ?? DEFAULT_CLAWOS_API, ...args }),
74042
73998
  fill: (args) => centralConnectorFill({ api: config.clawosApi ?? DEFAULT_CLAWOS_API, ...args })
74043
73999
  }
74044
74000
  },
74045
74001
  // 设备目录 + 连接(决策 #15:daemon 代理中心 server)。
74046
- // exchange/listDevices 包掉 owner ttcJwt(每次现读 store——热切换后立即用新身份);
74002
+ // exchange/listDevices 包掉本机登录票(每次现读 store——热切换后立即用新身份);
74047
74003
  // dispatcher 的 FEISHU_GATED_METHODS gate 已保证未登录时这些 RPC 到不了 handler,
74048
74004
  // 这里的 FEISHU_LOGIN_REQUIRED 抛错只是防御纵深。
74049
74005
  feishuDevice: feishuDeviceDeps,
@@ -21744,13 +21744,7 @@ var AuthGetIdentityResponseSchema = external_exports.object({
21744
21744
  * 设备属性,与登录态无关、登录登出不变。UI"我的设备标识"用它拼
21745
21745
  * clawos://device/<deviceId>(替代旧的 unionId——不再向外暴露人的身份标识)。
21746
21746
  */
21747
- deviceId: external_exports.string().min(1),
21748
- /**
21749
- * TTC JWT 过期时间(unix ms)。null = 登录回调未携带 expires_at;字段缺省 = 老 daemon。
21750
- * 仅时间戳——token 本体永不出 ws(spec §9 不变)。UI 据此派生 过期/临期 提示
21751
- * (见 spec 2026-08-17-ttc-jwt-expiry-ux-design §2)。
21752
- */
21753
- ttcTokenExpiresAt: external_exports.number().nullable().optional()
21747
+ deviceId: external_exports.string().min(1)
21754
21748
  });
21755
21749
  var AuthLogoutResponseSchema = external_exports.object({
21756
21750
  type: external_exports.literal("auth:logout:ok")
@@ -24307,7 +24301,7 @@ var METHOD_DOCS = {
24307
24301
  args: NO_ARGS
24308
24302
  },
24309
24303
  "auth:getIdentity": {
24310
- 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 ttcToken",
24304
+ 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",
24311
24305
  args: NO_ARGS
24312
24306
  },
24313
24307
  "auth:logout": {