@clawos-dev/clawd 0.2.258 → 0.2.260

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.
Files changed (2) hide show
  1. package/dist/cli.cjs +18 -22
  2. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -46528,8 +46528,9 @@ var import_node_crypto4 = __toESM(require("crypto"), 1);
46528
46528
  init_runtime();
46529
46529
 
46530
46530
  // src/visitor/visitor-token.ts
46531
+ var DOMAIN_PREFIX = "clawd-visitor-v1|";
46531
46532
  function hmac(secret, body) {
46532
- return import_node_crypto4.default.createHmac("sha256", secret).update(body).digest("base64url");
46533
+ return import_node_crypto4.default.createHmac("sha256", secret).update(`${DOMAIN_PREFIX}${body}`).digest("base64url");
46533
46534
  }
46534
46535
  function signVisitorToken(secret, payload) {
46535
46536
  const body = Buffer.from(JSON.stringify(payload)).toString("base64url");
@@ -51966,8 +51967,9 @@ function encodeAbsPathForUrl(absPath) {
51966
51967
  function decodeAbsPathFromUrl(encoded) {
51967
51968
  return encoded.split("/").map(decodeURIComponent).join("/");
51968
51969
  }
51970
+ var DOMAIN_PREFIX2 = "clawd-attach-v1|";
51969
51971
  function computeSig(secret, absPath, e) {
51970
- const msg = e === null ? absPath : `${absPath}|${e}`;
51972
+ const msg = e === null ? `${DOMAIN_PREFIX2}${absPath}` : `${DOMAIN_PREFIX2}${absPath}|${e}`;
51971
51973
  return import_node_crypto7.default.createHmac(HMAC_ALGO, secret).update(msg).digest();
51972
51974
  }
51973
51975
  function signUrlParts(secret, absPath, ttlSeconds, now = Date.now) {
@@ -53667,23 +53669,19 @@ function loadOrCreateAuthFile(opts) {
53667
53669
  const genId = opts.genOwnerPrincipalId ?? defaultGenerateOwnerPrincipalId;
53668
53670
  const now = opts.now ?? (() => /* @__PURE__ */ new Date());
53669
53671
  const existing = readAuthFile(file);
53670
- if (existing && existing.token && existing.signSecret && existing.visitorTokenSecret && existing.ownerPrincipalId && existing.deviceId && existing.deviceId === existing.ownerPrincipalId) {
53672
+ if (existing && existing.token && existing.ownerPrincipalId && existing.deviceId && existing.deviceId === existing.ownerPrincipalId && !existing.hasLegacySecrets) {
53671
53673
  return {
53672
53674
  token: existing.token,
53673
- signSecret: existing.signSecret,
53674
- visitorTokenSecret: existing.visitorTokenSecret,
53675
53675
  ownerPrincipalId: existing.ownerPrincipalId,
53676
53676
  deviceId: existing.deviceId,
53677
53677
  createdAt: existing.createdAt ?? (/* @__PURE__ */ new Date(0)).toISOString()
53678
53678
  };
53679
53679
  }
53680
53680
  const token = existing?.token || generate();
53681
- const signSecret = existing?.signSecret || generate();
53682
- const visitorTokenSecret = existing?.visitorTokenSecret || generate();
53683
53681
  const ownerPrincipalId = existing?.ownerPrincipalId || genId();
53684
53682
  const deviceId = ownerPrincipalId;
53685
53683
  const createdAt = existing?.createdAt || now().toISOString();
53686
- const next = { token, signSecret, visitorTokenSecret, ownerPrincipalId, deviceId, createdAt };
53684
+ const next = { token, ownerPrincipalId, deviceId, createdAt };
53687
53685
  writeAuthFile(file, next);
53688
53686
  return next;
53689
53687
  }
@@ -53702,11 +53700,11 @@ function readAuthFile(file) {
53702
53700
  }
53703
53701
  return {
53704
53702
  token: parsed.token,
53705
- signSecret: typeof parsed.signSecret === "string" && parsed.signSecret.length > 0 ? parsed.signSecret : void 0,
53706
- visitorTokenSecret: typeof parsed.visitorTokenSecret === "string" && parsed.visitorTokenSecret.length > 0 ? parsed.visitorTokenSecret : void 0,
53707
53703
  ownerPrincipalId: typeof parsed.ownerPrincipalId === "string" && parsed.ownerPrincipalId.length > 0 ? parsed.ownerPrincipalId : void 0,
53708
53704
  deviceId: typeof parsed.deviceId === "string" && parsed.deviceId.length > 0 ? parsed.deviceId : void 0,
53709
- createdAt: typeof parsed.createdAt === "string" ? parsed.createdAt : void 0
53705
+ createdAt: typeof parsed.createdAt === "string" ? parsed.createdAt : void 0,
53706
+ // 单 secret 合并前的旧字段:出现即触发清理写回(值无所谓,硬切不再使用)
53707
+ hasLegacySecrets: "signSecret" in parsed || "visitorTokenSecret" in parsed
53710
53708
  };
53711
53709
  } catch (err) {
53712
53710
  const code = err?.code;
@@ -54787,7 +54785,7 @@ function buildHistoryHandlers(deps) {
54787
54785
  };
54788
54786
  const list = async (frame, _client, ctx) => {
54789
54787
  const args = HistoryListArgs.parse(frame);
54790
- assertGuestPath(ctx, path57.resolve(args.projectPath), personaRoot, "history:list");
54788
+ assertGuestPath(ctx, path57.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
54791
54789
  const sessions = await history.listSessions(args);
54792
54790
  return { response: { type: "history:list", sessions } };
54793
54791
  };
@@ -59056,7 +59054,7 @@ async function startDaemon(config) {
59056
59054
  // persona web 分享:访客 visitor token = daemon 自签 HMAC(无 aud),独立于飞书 connect token
59057
59055
  // 基建——secret 恒存在(auth-store backfill),故无条件注入。验签 ok → guest ctx(persona wildcard)。
59058
59056
  verifyVisitorToken: (t) => {
59059
- const r = verifyVisitorToken(authFile.visitorTokenSecret, t, Math.floor(Date.now() / 1e3));
59057
+ const r = verifyVisitorToken(authFile.token, t, Math.floor(Date.now() / 1e3));
59060
59058
  return r.ok ? { ok: true, payload: r.payload } : { ok: false };
59061
59059
  },
59062
59060
  ...feishuActive ? {
@@ -59543,7 +59541,7 @@ async function startDaemon(config) {
59543
59541
  });
59544
59542
  const visitorStore = createVisitorStore({ dir: config.dataDir });
59545
59543
  const exchangeVisitorToken = buildVisitorLogin({
59546
- getSecret: () => authFile.visitorTokenSecret,
59544
+ getSecret: () => authFile.token,
59547
59545
  fetchUserInfo: (ttcToken) => fetchTtcUserInfo({ apiBase: TTC_HOSTS.api, token: ttcToken }),
59548
59546
  visitorStore,
59549
59547
  now: () => Date.now(),
@@ -59599,9 +59597,8 @@ async function startDaemon(config) {
59599
59597
  groupFileStore,
59600
59598
  sessionStore: { read: (sid) => manager.findOwnedSession(sid) },
59601
59599
  getHttpBaseUrl,
59602
- // HMAC sign secret:~/.clawd/auth.json signSecret 字段(与 WS Bearer token 独立)。
59603
- // --auth-token CLI 模式 / noAuth 模式 authFile 为 null → handler 自己返 NOT_IMPLEMENTED。
59604
- getSignSecret: () => authFile?.signSecret ?? "",
59600
+ // HMAC sign secret = auth.json 唯一 token(authFile 恒非空,startDaemon 开头加载)。
59601
+ getSignSecret: () => authFile.token,
59605
59602
  // group RPC + sign 都用:根据 sessionId 反查 scope。owner-mode persona session 走
59606
59603
  // 'persona/<pid>/owner',default 走 'default'。
59607
59604
  getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
@@ -59888,11 +59885,10 @@ async function startDaemon(config) {
59888
59885
  // persona web 分享:访客换 token(POST /share/exchange)+ guest SPA serve(GET /s)
59889
59886
  visitorExchange: exchangeVisitorToken,
59890
59887
  ...shareUiAssetLoader ? { shareUiAssetLoader } : {},
59891
- // /files HMAC verify 用 auth.json signSecret 字段(与 attachment.signUrl 同源)。
59892
- // --auth-token CLI 模式没 signSecret → 路由返 501,sign URL 功能整体禁用。
59893
- getSignSecret: () => authFile?.signSecret ?? null,
59888
+ // /files HMAC verify 用 auth.json token(与 attachment.signUrl 同源)。
59889
+ getSignSecret: () => authFile.token,
59894
59890
  // chatinput 附件上传(POST /attachments/upload,spec §6.1)。upload pipeline
59895
- // 在 session.cwd 下的 .attachments/ 落盘;signSecret 与 /files HMAC 同源;
59891
+ // 在 session.cwd 下的 .attachments/ 落盘;签名 secret 与 /files HMAC 同源;
59896
59892
  // tunnel 未启时返 503 TUNNEL_NOT_READY 让前端显式提示。
59897
59893
  attachmentUpload: {
59898
59894
  groupFileStore,
@@ -59973,7 +59969,7 @@ async function startDaemon(config) {
59973
59969
  // (非 persona-web 场景静默 return null;tunnel 模式走 AuthGate 不经此路)。参数名
59974
59970
  // tryVerifyCapabilityToken 不再准确,跨 local-ws-server 改名属 followup 清理。
59975
59971
  tryVerifyCapabilityToken: (token) => {
59976
- const vis = verifyVisitorToken(authFile.visitorTokenSecret, token, Math.floor(Date.now() / 1e3));
59972
+ const vis = verifyVisitorToken(authFile.token, token, Math.floor(Date.now() / 1e3));
59977
59973
  if (vis.ok) return visitorGuestContext(vis.payload);
59978
59974
  return null;
59979
59975
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawos-dev/clawd",
3
- "version": "0.2.258",
3
+ "version": "0.2.260",
4
4
  "description": "Standalone clawd daemon — Claude Code (and future Codex) session server over WebSocket",
5
5
  "type": "module",
6
6
  "license": "MIT",