@clawos-dev/clawd 0.2.610 → 0.2.612

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
@@ -8759,6 +8759,8 @@ var init_schemas = __esm({
8759
8759
  limit: external_exports.number().int().positive().max(5e3).optional(),
8760
8760
  /** 不传时走 tail 语义:daemon 返回最后 limit 条(offset = max(0, total - limit)) */
8761
8761
  offset: external_exports.number().int().nonnegative().optional(),
8762
+ /** 云历史分页快照标识;续页原样带回,避免多条链交错时混读。 */
8763
+ snapshotId: external_exports.string().uuid().optional(),
8762
8764
  /**
8763
8765
  * 瘦身投影(2026-07-18 android-tasks-tab 迭代,v2 语义):true = daemon 裁掉窄消费面客户端
8764
8766
  * (mobile)不渲染的大字段(input / output / raw / toolResultExtra / memories /
@@ -33103,7 +33105,7 @@ var require_websocket = __commonJS({
33103
33105
  var http2 = require("http");
33104
33106
  var net2 = require("net");
33105
33107
  var tls = require("tls");
33106
- var { randomBytes: randomBytes2, createHash: createHash3 } = require("crypto");
33108
+ var { randomBytes: randomBytes2, createHash: createHash4 } = require("crypto");
33107
33109
  var { Duplex, Readable: Readable4 } = require("stream");
33108
33110
  var { URL: URL2 } = require("url");
33109
33111
  var PerMessageDeflate2 = require_permessage_deflate();
@@ -33763,7 +33765,7 @@ var require_websocket = __commonJS({
33763
33765
  abortHandshake(websocket, socket, "Invalid Upgrade header");
33764
33766
  return;
33765
33767
  }
33766
- const digest = createHash3("sha1").update(key + GUID).digest("base64");
33768
+ const digest = createHash4("sha1").update(key + GUID).digest("base64");
33767
33769
  if (res.headers["sec-websocket-accept"] !== digest) {
33768
33770
  abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
33769
33771
  return;
@@ -34130,7 +34132,7 @@ var require_websocket_server = __commonJS({
34130
34132
  var EventEmitter2 = require("events");
34131
34133
  var http2 = require("http");
34132
34134
  var { Duplex } = require("stream");
34133
- var { createHash: createHash3 } = require("crypto");
34135
+ var { createHash: createHash4 } = require("crypto");
34134
34136
  var extension2 = require_extension();
34135
34137
  var PerMessageDeflate2 = require_permessage_deflate();
34136
34138
  var subprotocol2 = require_subprotocol();
@@ -34431,7 +34433,7 @@ var require_websocket_server = __commonJS({
34431
34433
  );
34432
34434
  }
34433
34435
  if (this._state > RUNNING) return abortHandshake(socket, 503);
34434
- const digest = createHash3("sha1").update(key + GUID).digest("base64");
34436
+ const digest = createHash4("sha1").update(key + GUID).digest("base64");
34435
34437
  const headers = [
34436
34438
  "HTTP/1.1 101 Switching Protocols",
34437
34439
  "Upgrade: websocket",
@@ -44796,7 +44798,7 @@ Env (advanced):
44796
44798
  var import_node_path84 = __toESM(require("path"), 1);
44797
44799
  var import_node_fs65 = __toESM(require("fs"), 1);
44798
44800
  var import_node_os31 = __toESM(require("os"), 1);
44799
- var import_node_crypto26 = require("crypto");
44801
+ var import_node_crypto27 = require("crypto");
44800
44802
  var import_node_url6 = require("url");
44801
44803
 
44802
44804
  // src/logger.ts
@@ -51726,10 +51728,10 @@ var DashboardDataError = class extends Error {
51726
51728
  code;
51727
51729
  };
51728
51730
  var SUBROUTES = {
51729
- "cloud-persona-metrics": ["personas", "data"],
51731
+ "cloud-persona-metrics": ["personas", "data", "issues"],
51730
51732
  "cloud-persona-conversations": ["personas", "threads", "thread"]
51731
51733
  };
51732
- var UPSTREAM_DOWN = { personas: "UPSTREAM_UNREACHABLE", data: "GATEWAY_UNREACHABLE", threads: "CENTER_UNREACHABLE", thread: "CENTER_UNREACHABLE" };
51734
+ var UPSTREAM_DOWN = { personas: "UPSTREAM_UNREACHABLE", data: "GATEWAY_UNREACHABLE", issues: "GATEWAY_UNREACHABLE", threads: "CENTER_UNREACHABLE", thread: "CENTER_UNREACHABLE" };
51733
51735
  var NO_STORE = { "cache-control": "no-store" };
51734
51736
  function send(res, status, contentType, body) {
51735
51737
  res.writeHead(status, { "content-type": contentType, ...NO_STORE });
@@ -51787,6 +51789,17 @@ function createDashboardRoutes(deps) {
51787
51789
  sendPassthrough(res, await deps.data.metrics({ personaId: personaId2, window: q3.get("window"), entry: q3.get("entry") }));
51788
51790
  return true;
51789
51791
  }
51792
+ if (sub === "issues") {
51793
+ const threadId2 = q3.get("threadId") ?? "";
51794
+ const cursor = q3.get("cursor");
51795
+ const rawSnapshot = q3.get("snapshotTo");
51796
+ if (!ID_RE.test(threadId2) || cursor !== null && !/^[A-Za-z0-9_-]{1,256}$/.test(cursor) || rawSnapshot !== null && (!/^[1-9]\d*$/.test(rawSnapshot) || !Number.isSafeInteger(Number(rawSnapshot))) || cursor === null !== (rawSnapshot === null)) {
51797
+ sendJson(res, 400, { code: "INVALID_PARAM", message: "threadId / cursor / snapshotTo \u65E0\u6548" });
51798
+ return true;
51799
+ }
51800
+ sendPassthrough(res, await deps.data.issues({ personaId: personaId2, threadId: threadId2, window: q3.get("window"), entry: q3.get("entry"), cursor, snapshotTo: rawSnapshot === null ? null : Number(rawSnapshot) }));
51801
+ return true;
51802
+ }
51790
51803
  if (sub === "threads") {
51791
51804
  const limit = q3.get("limit");
51792
51805
  if (limit !== null && !/^\d{1,3}$/.test(limit)) {
@@ -52144,7 +52157,7 @@ function walkRollouts(dir, visit) {
52144
52157
  }
52145
52158
  return true;
52146
52159
  }
52147
- async function withSubagentResults(parent, parentThreadId, loadChild, logger) {
52160
+ async function withSubagentResults(parent, parentThreadId, loadChild, logger, rethrowLoadError = false) {
52148
52161
  const messages = [];
52149
52162
  const started = new Map(parent.subagents.map((s2) => [s2.toolUseId, s2]));
52150
52163
  for (const m3 of parent.messages) {
@@ -52155,6 +52168,7 @@ async function withSubagentResults(parent, parentThreadId, loadChild, logger) {
52155
52168
  try {
52156
52169
  text = await loadChild(sub.agentId);
52157
52170
  } catch (error) {
52171
+ if (rethrowLoadError) throw error;
52158
52172
  logger?.warn("codex subagent rollout unreadable", { childThreadId: sub.agentId, message: error.message });
52159
52173
  continue;
52160
52174
  }
@@ -52334,6 +52348,73 @@ var CodexHistoryReader = class {
52334
52348
  }
52335
52349
  };
52336
52350
 
52351
+ // src/tools/cloud-history-pages.ts
52352
+ var import_node_crypto6 = require("crypto");
52353
+ var CloudHistoryPages = class _CloudHistoryPages {
52354
+ constructor(log) {
52355
+ this.log = log;
52356
+ }
52357
+ log;
52358
+ snapshots = [];
52359
+ firstReads = /* @__PURE__ */ new Map();
52360
+ static IDLE_MS = 5 * 6e4;
52361
+ async read(args, load) {
52362
+ const key = `${args.cwd}\0${args.toolSessionId}`;
52363
+ const now = Date.now();
52364
+ for (let i2 = this.snapshots.length - 1; i2 >= 0; i2--) {
52365
+ if (now - this.snapshots[i2].lastUsedAt > _CloudHistoryPages.IDLE_MS) this.snapshots.splice(i2, 1);
52366
+ }
52367
+ let first = args.offset === void 0;
52368
+ let cached;
52369
+ if (!first) {
52370
+ for (let i2 = this.snapshots.length - 1; i2 >= 0; i2--) {
52371
+ const candidate = this.snapshots[i2];
52372
+ if (candidate.key === key && (args.snapshotId ? candidate.id === args.snapshotId : candidate.nextOffset === args.offset)) {
52373
+ cached = candidate;
52374
+ break;
52375
+ }
52376
+ }
52377
+ }
52378
+ if (args.snapshotId && !cached) first = true;
52379
+ const pageArgs = first ? { limit: args.limit } : args;
52380
+ const threadHash = (0, import_node_crypto6.createHash)("sha256").update(key).digest("hex").slice(0, 12);
52381
+ let source = "central";
52382
+ let messages;
52383
+ try {
52384
+ if (cached) {
52385
+ source = "snapshot";
52386
+ messages = cached.messages;
52387
+ } else if (first) {
52388
+ let pending = this.firstReads.get(key);
52389
+ if (!pending) {
52390
+ pending = load();
52391
+ this.firstReads.set(key, pending);
52392
+ void pending.finally(() => {
52393
+ if (this.firstReads.get(key) === pending) this.firstReads.delete(key);
52394
+ }).catch(() => {
52395
+ });
52396
+ } else {
52397
+ source = "shared";
52398
+ }
52399
+ messages = await pending;
52400
+ } else {
52401
+ messages = await load();
52402
+ }
52403
+ } catch (error) {
52404
+ this.log?.({ threadHash, source, outcome: error.status === 429 ? "429" : "error" });
52405
+ throw error;
52406
+ }
52407
+ this.log?.({ threadHash, source, outcome: "success" });
52408
+ const page = pageMessages(messages, pageArgs);
52409
+ const snapshotId = cached?.id ?? (0, import_node_crypto6.randomUUID)();
52410
+ if (cached) this.snapshots.splice(this.snapshots.indexOf(cached), 1);
52411
+ if (page.offset > 0 && args.limit !== void 0) {
52412
+ this.snapshots.push({ key, id: snapshotId, messages, nextOffset: Math.max(0, page.offset - args.limit), lastUsedAt: now });
52413
+ }
52414
+ return { ...page, snapshotId };
52415
+ }
52416
+ };
52417
+
52337
52418
  // src/tools/codex-cloud-history.ts
52338
52419
  function personaIdFromCloudCwd(cwd) {
52339
52420
  const m3 = /\/p\/([^/?#]+)(?:[/?#]|$)/.exec(cwd);
@@ -52348,9 +52429,11 @@ var CloudCodexHistoryReader = class {
52348
52429
  constructor(client, logger) {
52349
52430
  this.client = client;
52350
52431
  this.logger = logger;
52432
+ this.pages = new CloudHistoryPages((meta) => logger?.info?.("cloud history page", meta));
52351
52433
  }
52352
52434
  client;
52353
52435
  logger;
52436
+ pages;
52354
52437
  async listProjects() {
52355
52438
  return [];
52356
52439
  }
@@ -52359,14 +52442,16 @@ var CloudCodexHistoryReader = class {
52359
52442
  return [];
52360
52443
  }
52361
52444
  async read(args) {
52362
- const parent = await this.fetchThread(args.toolSessionId);
52363
- const messages = await withSubagentResults(
52364
- parent,
52365
- args.toolSessionId,
52366
- (agentId) => this.client.fetchRollout(agentId),
52367
- this.logger
52368
- );
52369
- return pageMessages(messages, args);
52445
+ return this.pages.read(args, async () => {
52446
+ const parent = await this.fetchThread(args.toolSessionId);
52447
+ return withSubagentResults(
52448
+ parent,
52449
+ args.toolSessionId,
52450
+ (agentId) => this.client.fetchRollout(agentId),
52451
+ this.logger,
52452
+ true
52453
+ );
52454
+ });
52370
52455
  }
52371
52456
  async listSubagents(args) {
52372
52457
  return subagentSummaries(await this.fetchThread(args.toolSessionId));
@@ -52619,9 +52704,11 @@ var CloudPiHistoryReader = class {
52619
52704
  constructor(client, logger) {
52620
52705
  this.client = client;
52621
52706
  this.logger = logger;
52707
+ this.pages = new CloudHistoryPages((meta) => logger?.info?.("cloud history page", meta));
52622
52708
  }
52623
52709
  client;
52624
52710
  logger;
52711
+ pages;
52625
52712
  async listProjects() {
52626
52713
  return [];
52627
52714
  }
@@ -52630,11 +52717,13 @@ var CloudPiHistoryReader = class {
52630
52717
  return [];
52631
52718
  }
52632
52719
  async read(args) {
52633
- const text = await this.client.fetchRollout(args.toolSessionId);
52634
- if (text === null) throw new Error(`pi session not found for ${args.toolSessionId}`);
52635
- const parsed = parsePiSession(text);
52636
- if (!parsed.meta) this.logger?.warn("cloud pi session has no header line", { toolSessionId: args.toolSessionId });
52637
- return pageMessages(parsed.messages, args);
52720
+ return this.pages.read(args, async () => {
52721
+ const text = await this.client.fetchRollout(args.toolSessionId);
52722
+ if (text === null) throw new Error(`pi session not found for ${args.toolSessionId}`);
52723
+ const parsed = parsePiSession(text);
52724
+ if (!parsed.meta) this.logger?.warn("cloud pi session has no header line", { toolSessionId: args.toolSessionId });
52725
+ return parsed.messages;
52726
+ });
52638
52727
  }
52639
52728
  async listSubagents(_args) {
52640
52729
  return [];
@@ -52784,7 +52873,7 @@ async function centralGetThread(opts) {
52784
52873
  if (typeof body?.message === "string" && body.message) detail = `: ${body.message}`;
52785
52874
  } catch {
52786
52875
  }
52787
- throw new CentralClientError("API_ERROR", `central server HTTP ${res.status}${detail}`);
52876
+ throw new CentralClientError("API_ERROR", `central server HTTP ${res.status}${detail}`, void 0, res.status);
52788
52877
  }
52789
52878
  return await res.text();
52790
52879
  }
@@ -52974,6 +53063,7 @@ function createDashboardData(deps) {
52974
53063
  return visiblePersonaIds(registered, visible);
52975
53064
  },
52976
53065
  metrics: (q3) => deps.metrics(q3),
53066
+ issues: (q3) => deps.issues(q3),
52977
53067
  async threads(q3) {
52978
53068
  return deps.threads(mustLoginPass(), q3);
52979
53069
  },
@@ -53062,7 +53152,7 @@ function tryLoadShareUi(logger) {
53062
53152
  }
53063
53153
 
53064
53154
  // src/visitor/visitor-token.ts
53065
- var import_node_crypto6 = __toESM(require("crypto"), 1);
53155
+ var import_node_crypto7 = __toESM(require("crypto"), 1);
53066
53156
 
53067
53157
  // ../protocol/src/index.ts
53068
53158
  init_runtime();
@@ -53070,7 +53160,7 @@ init_runtime();
53070
53160
  // src/visitor/visitor-token.ts
53071
53161
  var DOMAIN_PREFIX3 = "clawd-visitor-v1|";
53072
53162
  function hmac(secret, body) {
53073
- return import_node_crypto6.default.createHmac("sha256", secret).update(`${DOMAIN_PREFIX3}${body}`).digest("base64url");
53163
+ return import_node_crypto7.default.createHmac("sha256", secret).update(`${DOMAIN_PREFIX3}${body}`).digest("base64url");
53074
53164
  }
53075
53165
  function signVisitorToken(secret, payload) {
53076
53166
  const body = Buffer.from(JSON.stringify(payload)).toString("base64url");
@@ -53083,7 +53173,7 @@ function verifyVisitorToken(secret, token, now) {
53083
53173
  const sig = token.slice(dot + 1);
53084
53174
  const expected = hmac(secret, body);
53085
53175
  if (sig.length !== expected.length) return { ok: false, reason: "BAD_SIGNATURE" };
53086
- if (!import_node_crypto6.default.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
53176
+ if (!import_node_crypto7.default.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
53087
53177
  return { ok: false, reason: "BAD_SIGNATURE" };
53088
53178
  }
53089
53179
  let payload;
@@ -54606,7 +54696,7 @@ var CodexAdapter = class {
54606
54696
  };
54607
54697
 
54608
54698
  // src/tools/claude-tui.ts
54609
- var import_node_crypto7 = require("crypto");
54699
+ var import_node_crypto8 = require("crypto");
54610
54700
  var import_node_fs25 = __toESM(require("fs"), 1);
54611
54701
  var import_node_os10 = __toESM(require("os"), 1);
54612
54702
  var import_node_path24 = __toESM(require("path"), 1);
@@ -55494,7 +55584,7 @@ function observeScreenIdle(surface, opts) {
55494
55584
  };
55495
55585
  }
55496
55586
  function shortHash(s2) {
55497
- return (0, import_node_crypto7.createHash)("sha1").update(s2).digest("hex").slice(0, 8);
55587
+ return (0, import_node_crypto8.createHash)("sha1").update(s2).digest("hex").slice(0, 8);
55498
55588
  }
55499
55589
  function firstLineDiff(prev, next) {
55500
55590
  const p3 = prev.split("\n");
@@ -56625,7 +56715,7 @@ function resolveSourceJsonlPath(sourceFile, home) {
56625
56715
  // src/shift/store.ts
56626
56716
  var import_promises3 = __toESM(require("fs/promises"), 1);
56627
56717
  var import_node_path35 = __toESM(require("path"), 1);
56628
- var import_node_crypto8 = require("crypto");
56718
+ var import_node_crypto9 = require("crypto");
56629
56719
 
56630
56720
  // src/shift/schedule.ts
56631
56721
  var import_cron_parser = __toESM(require_dist(), 1);
@@ -56729,7 +56819,7 @@ function createShiftStore(deps) {
56729
56819
  const shift = {
56730
56820
  ...input,
56731
56821
  schedule,
56732
- id: (0, import_node_crypto8.randomUUID)(),
56822
+ id: (0, import_node_crypto9.randomUUID)(),
56733
56823
  createdAtMs: now,
56734
56824
  updatedAtMs: now,
56735
56825
  state: { nextRunAtMs },
@@ -57160,7 +57250,7 @@ function redactEvidence(evidence) {
57160
57250
  // src/deploy/deploy-file.ts
57161
57251
  var import_promises4 = __toESM(require("fs/promises"), 1);
57162
57252
  var import_node_path37 = __toESM(require("path"), 1);
57163
- var import_node_crypto9 = require("crypto");
57253
+ var import_node_crypto10 = require("crypto");
57164
57254
  init_zod();
57165
57255
  init_protocol();
57166
57256
 
@@ -57366,7 +57456,7 @@ async function restoreDeployFileRaw(dir, raw) {
57366
57456
  }
57367
57457
  var emptyScanFile = () => ({ version: 3, scans: [], releases: [] });
57368
57458
  var LEGACY_SCAN_ID = "legacy";
57369
- var newScanId = () => (0, import_node_crypto9.randomBytes)(4).toString("hex");
57459
+ var newScanId = () => (0, import_node_crypto10.randomBytes)(4).toString("hex");
57370
57460
  var z1 = DeployScanSchema.omit({ id: true, manifest: true }).extend({ releasedHead: DeployScanSchema.shape.head }).strict();
57371
57461
  function migrateV1(v1, manifest) {
57372
57462
  const { releasedHead, ...rest } = v1;
@@ -57504,7 +57594,7 @@ function requiredEnvNames(manifest) {
57504
57594
  }
57505
57595
 
57506
57596
  // src/deploy/artifact.ts
57507
- var import_node_crypto10 = require("crypto");
57597
+ var import_node_crypto11 = require("crypto");
57508
57598
  var import_node_fs34 = __toESM(require("fs"), 1);
57509
57599
  var import_node_os11 = __toESM(require("os"), 1);
57510
57600
  var import_node_path38 = __toESM(require("path"), 1);
@@ -57543,7 +57633,7 @@ function downloadArtifact(exec) {
57543
57633
  if (declared > ARTIFACT_MAX_BYTES) throw new Error(`\u8D44\u4EA7 ${declared} \u5B57\u8282\uFF0C\u8D85\u8FC7\u4E0A\u9650 ${ARTIFACT_MAX_BYTES}\uFF1A${url}`);
57544
57634
  const dir = await import_node_fs34.default.promises.mkdtemp(import_node_path38.default.join(import_node_os11.default.tmpdir(), "clawd-artifact-"));
57545
57635
  const file = import_node_path38.default.join(dir, "pkg");
57546
- const hash = (0, import_node_crypto10.createHash)("sha256");
57636
+ const hash = (0, import_node_crypto11.createHash)("sha256");
57547
57637
  let size = 0;
57548
57638
  const meter = new import_node_stream3.Transform({
57549
57639
  transform(chunk, _enc, cb) {
@@ -63892,7 +63982,7 @@ ${formatLarkSpeakerReminder(speaker)}`
63892
63982
  }
63893
63983
 
63894
63984
  // src/lark-bot-connector/envelope.ts
63895
- var import_node_crypto11 = require("crypto");
63985
+ var import_node_crypto12 = require("crypto");
63896
63986
  var LARK_ENVELOPE_PREFIX = "clawdlbe1";
63897
63987
  function verifyLarkEventEnvelope(args) {
63898
63988
  const { token, publicKeyPem } = args;
@@ -63911,7 +64001,7 @@ function verifyLarkEventEnvelope(args) {
63911
64001
  const data = Buffer.from(`${prefix}.${payloadB64}`, "utf8");
63912
64002
  let sigOk = false;
63913
64003
  try {
63914
- sigOk = (0, import_node_crypto11.verify)(null, data, publicKeyPem, Buffer.from(sigB64, "base64url"));
64004
+ sigOk = (0, import_node_crypto12.verify)(null, data, publicKeyPem, Buffer.from(sigB64, "base64url"));
63915
64005
  } catch {
63916
64006
  sigOk = false;
63917
64007
  }
@@ -64672,6 +64762,24 @@ var CloudGatewayClient = class {
64672
64762
  throw e;
64673
64763
  }
64674
64764
  }
64765
+ async fetchThreadIssues(q3) {
64766
+ const { apiKey, gatewayUrl } = await this.credentials();
64767
+ const qs = new URLSearchParams({ threadId: q3.threadId });
64768
+ if (q3.window) qs.set("window", q3.window);
64769
+ if (q3.entry) qs.set("entry", q3.entry);
64770
+ if (q3.cursor) qs.set("cursor", q3.cursor);
64771
+ if (q3.snapshotTo !== null) qs.set("snapshotTo", String(q3.snapshotTo));
64772
+ try {
64773
+ const res = await this.fetchImpl(`${gatewayUrl}${GATEWAY_ROUTES.metrics(q3.personaId)}/issues?${qs}`, {
64774
+ headers: { authorization: `Bearer ${apiKey}` },
64775
+ signal: AbortSignal.timeout(METRICS_TIMEOUT_MS)
64776
+ });
64777
+ return { status: res.status, body: await res.text() };
64778
+ } catch (e) {
64779
+ if (e.name === "TimeoutError") throw new Error(`\u4E91\u4E0A\u670D\u52A1 ${METRICS_TIMEOUT_MS / 1e3} \u79D2\u6CA1\u56DE`);
64780
+ throw e;
64781
+ }
64782
+ }
64675
64783
  /**
64676
64784
  * 这个人云盘上一轮末的用量(design 2026-09-19-cloud-volume-usage §3.3)。gateway 回 `volume: null` = 还没跑过任务(没有盘)。
64677
64785
  * 没登录 / 没 key 走 credentials() 的抛法,调用方(cloud:volume:get 的 handler)把它们和网络错一并折成 null——角标不该弹错。
@@ -65336,7 +65444,7 @@ var PiRpcClient = class {
65336
65444
 
65337
65445
  // src/tools/pi-session.ts
65338
65446
  var import_node_child_process11 = require("child_process");
65339
- var import_node_crypto12 = require("crypto");
65447
+ var import_node_crypto13 = require("crypto");
65340
65448
  var import_node_fs40 = __toESM(require("fs"), 1);
65341
65449
  var import_node_path44 = __toESM(require("path"), 1);
65342
65450
 
@@ -65609,7 +65717,7 @@ ${dirs.map((d2) => `- ${d2}`).join("\n")}`;
65609
65717
  }
65610
65718
  function createPiSession(ctx, sink, deps = {}) {
65611
65719
  const cmd = process.env.PI_BIN ?? "pi";
65612
- const sessionId = ctx.toolSessionId ?? (0, import_node_crypto12.randomUUID)();
65720
+ const sessionId = ctx.toolSessionId ?? (0, import_node_crypto13.randomUUID)();
65613
65721
  const skillsDir = import_node_path44.default.join(ctx.cwd, ".claude", "skills");
65614
65722
  const exists = deps.skillsDirExists ?? ((d2) => import_node_fs40.default.existsSync(d2));
65615
65723
  const args = buildPiArgs(ctx, {
@@ -65846,13 +65954,13 @@ var PiAdapter = class {
65846
65954
  };
65847
65955
 
65848
65956
  // src/tools/pi-cloud-session.ts
65849
- var import_node_crypto13 = require("crypto");
65957
+ var import_node_crypto14 = require("crypto");
65850
65958
  function cloudPiInstructions(ctx) {
65851
65959
  return [ctx.extraSystemPrompt, workDirPrompt(CLOUD_WORKSPACE_SLOT, ctx.personaMode ?? "owner")].filter((x2) => Boolean(x2)).join("\n\n");
65852
65960
  }
65853
65961
  function createCloudPiSession(ctx, sink, deps) {
65854
65962
  const personaId2 = personaIdFromCloudCwd(ctx.cwd);
65855
- const sessionId = ctx.toolSessionId ?? (0, import_node_crypto13.randomUUID)();
65963
+ const sessionId = ctx.toolSessionId ?? (0, import_node_crypto14.randomUUID)();
65856
65964
  let channel = null;
65857
65965
  let closed = false;
65858
65966
  let exited = false;
@@ -67009,7 +67117,7 @@ var wrapper_default = import_websocket.default;
67009
67117
 
67010
67118
  // src/transport/local-ws-server.ts
67011
67119
  var import_node_http = __toESM(require("http"), 1);
67012
- var import_node_crypto14 = require("crypto");
67120
+ var import_node_crypto15 = require("crypto");
67013
67121
  var LocalWsServer = class {
67014
67122
  constructor(opts) {
67015
67123
  this.opts = opts;
@@ -67226,7 +67334,7 @@ var LocalWsServer = class {
67226
67334
  }
67227
67335
  }
67228
67336
  onConnection(socket, remoteAddress) {
67229
- const id = (0, import_node_crypto14.randomUUID)();
67337
+ const id = (0, import_node_crypto15.randomUUID)();
67230
67338
  const subscribedSessions = /* @__PURE__ */ new Map();
67231
67339
  const handle = {
67232
67340
  id,
@@ -68191,7 +68299,7 @@ var import_node_path53 = __toESM(require("path"), 1);
68191
68299
  // src/attachment/upload.ts
68192
68300
  var import_node_fs47 = __toESM(require("fs"), 1);
68193
68301
  var import_node_path51 = __toESM(require("path"), 1);
68194
- var import_node_crypto15 = __toESM(require("crypto"), 1);
68302
+ var import_node_crypto16 = __toESM(require("crypto"), 1);
68195
68303
  var import_promises8 = require("stream/promises");
68196
68304
  var UploadError = class extends Error {
68197
68305
  constructor(code, message) {
@@ -68215,11 +68323,11 @@ async function writeUploadedAttachment(args) {
68215
68323
  } catch (err) {
68216
68324
  throw new UploadError("STORAGE_ERROR", `mkdir failed: ${err.message}`);
68217
68325
  }
68218
- const hasher = import_node_crypto15.default.createHash("sha256");
68326
+ const hasher = import_node_crypto16.default.createHash("sha256");
68219
68327
  let actualSize = 0;
68220
68328
  const tmpPath = import_node_path51.default.join(
68221
68329
  attachmentsRoot,
68222
- `.upload-${process.pid}-${Date.now()}-${import_node_crypto15.default.randomBytes(4).toString("hex")}`
68330
+ `.upload-${process.pid}-${Date.now()}-${import_node_crypto16.default.randomBytes(4).toString("hex")}`
68223
68331
  );
68224
68332
  try {
68225
68333
  await (0, import_promises8.pipeline)(
@@ -69070,7 +69178,7 @@ function runAttachmentGc(args) {
69070
69178
  // src/attachment/group.ts
69071
69179
  var import_node_fs50 = __toESM(require("fs"), 1);
69072
69180
  var import_node_path55 = __toESM(require("path"), 1);
69073
- var import_node_crypto16 = __toESM(require("crypto"), 1);
69181
+ var import_node_crypto17 = __toESM(require("crypto"), 1);
69074
69182
  init_protocol();
69075
69183
  var GroupFileStore = class {
69076
69184
  dataDir;
@@ -69159,7 +69267,7 @@ var GroupFileStore = class {
69159
69267
  entries[idx] = next;
69160
69268
  } else {
69161
69269
  next = {
69162
- id: `gf-${import_node_crypto16.default.randomBytes(6).toString("base64url")}`,
69270
+ id: `gf-${import_node_crypto17.default.randomBytes(6).toString("base64url")}`,
69163
69271
  relPath: input.relPath,
69164
69272
  from: input.from,
69165
69273
  label: input.label,
@@ -69305,7 +69413,7 @@ function readSpawnedByDesktopFromEnv(env = process.env) {
69305
69413
  // src/tunnel/tunnel-manager.ts
69306
69414
  var import_node_fs55 = __toESM(require("fs"), 1);
69307
69415
  var import_node_path60 = __toESM(require("path"), 1);
69308
- var import_node_crypto17 = __toESM(require("crypto"), 1);
69416
+ var import_node_crypto18 = __toESM(require("crypto"), 1);
69309
69417
  var import_node_child_process16 = require("child_process");
69310
69418
 
69311
69419
  // src/tunnel/tunnel-store.ts
@@ -69804,7 +69912,7 @@ var TunnelManager = class {
69804
69912
  override: this.deps.frpcBinaryOverride ?? void 0
69805
69913
  });
69806
69914
  const tomlPath = import_node_path60.default.join(this.deps.dataDir, "frpc.toml");
69807
- const proxyName = `clawd-${t2.subdomain}-${localPort}-${import_node_crypto17.default.randomBytes(3).toString("hex")}`;
69915
+ const proxyName = `clawd-${t2.subdomain}-${localPort}-${import_node_crypto18.default.randomBytes(3).toString("hex")}`;
69808
69916
  const toml = buildFrpcToml({
69809
69917
  serverAddr: t2.frpsHost,
69810
69918
  serverPort: t2.frpsPort,
@@ -69905,7 +70013,7 @@ async function waitForFrpcReady(proc, timeoutMs) {
69905
70013
  // src/tunnel/device-key.ts
69906
70014
  var import_node_os22 = __toESM(require("os"), 1);
69907
70015
  var import_node_path61 = __toESM(require("path"), 1);
69908
- var import_node_crypto18 = __toESM(require("crypto"), 1);
70016
+ var import_node_crypto19 = __toESM(require("crypto"), 1);
69909
70017
  var DERIVE_SALT = "clawd-tunnel-device-v1";
69910
70018
  function deriveStableDeviceKey(opts = {}) {
69911
70019
  const hostname = opts.hostname ?? import_node_os22.default.hostname();
@@ -69915,13 +70023,13 @@ function deriveStableDeviceKey(opts = {}) {
69915
70023
  const normalizedDataDir = opts.dataDir ? import_node_path61.default.resolve(opts.dataDir) : null;
69916
70024
  const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
69917
70025
  const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
69918
- return import_node_crypto18.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
70026
+ return import_node_crypto19.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
69919
70027
  }
69920
70028
 
69921
70029
  // src/auth-store.ts
69922
70030
  var import_node_fs56 = __toESM(require("fs"), 1);
69923
70031
  var import_node_path62 = __toESM(require("path"), 1);
69924
- var import_node_crypto19 = __toESM(require("crypto"), 1);
70032
+ var import_node_crypto20 = __toESM(require("crypto"), 1);
69925
70033
  var AUTH_FILE_NAME = "auth.json";
69926
70034
  function authFilePath(dataDir) {
69927
70035
  return import_node_path62.default.join(dataDir, AUTH_FILE_NAME);
@@ -69958,10 +70066,10 @@ function loadOrCreateTunnelDeviceKey(opts) {
69958
70066
  return tunnelDeviceKey;
69959
70067
  }
69960
70068
  function defaultGenerateToken() {
69961
- return import_node_crypto19.default.randomBytes(32).toString("base64url");
70069
+ return import_node_crypto20.default.randomBytes(32).toString("base64url");
69962
70070
  }
69963
70071
  function defaultGenerateOwnerPrincipalId() {
69964
- return `owner-${import_node_crypto19.default.randomUUID()}`;
70072
+ return `owner-${import_node_crypto20.default.randomUUID()}`;
69965
70073
  }
69966
70074
  function readAuthFile(file) {
69967
70075
  try {
@@ -70093,7 +70201,7 @@ var OwnerIdentityStore = class {
70093
70201
  };
70094
70202
 
70095
70203
  // src/feishu-auth/login-flow.ts
70096
- var import_node_crypto20 = __toESM(require("crypto"), 1);
70204
+ var import_node_crypto21 = __toESM(require("crypto"), 1);
70097
70205
  var STATE_TTL_MS = 5 * 60 * 1e3;
70098
70206
  var LoginFlow = class {
70099
70207
  constructor(deps) {
@@ -70102,7 +70210,7 @@ var LoginFlow = class {
70102
70210
  deps;
70103
70211
  pendingStates = /* @__PURE__ */ new Map();
70104
70212
  start() {
70105
- const state = import_node_crypto20.default.randomBytes(16).toString("base64url");
70213
+ const state = import_node_crypto21.default.randomBytes(16).toString("base64url");
70106
70214
  const now = (this.deps.now ?? Date.now)();
70107
70215
  this.pendingStates.set(state, now);
70108
70216
  this.gcExpired(now);
@@ -70633,7 +70741,7 @@ init_protocol();
70633
70741
  var import_node_fs59 = __toESM(require("fs"), 1);
70634
70742
  var import_node_os24 = __toESM(require("os"), 1);
70635
70743
  var import_node_path65 = __toESM(require("path"), 1);
70636
- var import_node_crypto21 = require("crypto");
70744
+ var import_node_crypto22 = require("crypto");
70637
70745
  init_claude_history();
70638
70746
  function readJsonlEntries(file) {
70639
70747
  const raw = import_node_fs59.default.readFileSync(file, "utf8");
@@ -70670,7 +70778,7 @@ function forkSession(input) {
70670
70778
  throw new Error(`fork: messageUuid not found in transcript: ${input.messageUuid}`);
70671
70779
  }
70672
70780
  const sliced = mainEntries.slice(0, targetIdx + 1);
70673
- const forkedToolSessionId = (0, import_node_crypto21.randomUUID)();
70781
+ const forkedToolSessionId = (0, import_node_crypto22.randomUUID)();
70674
70782
  let parentUuid = null;
70675
70783
  const forkedLines = [];
70676
70784
  for (const entry of sliced) {
@@ -71757,7 +71865,8 @@ function buildHistoryHandlers(deps) {
71757
71865
  cwd: f2.cwd,
71758
71866
  toolSessionId: f2.toolSessionId,
71759
71867
  limit: args.limit,
71760
- offset: args.offset
71868
+ offset: args.offset,
71869
+ snapshotId: args.snapshotId
71761
71870
  });
71762
71871
  } catch (err) {
71763
71872
  logger?.warn("chatflow.history.daemon.error", {
@@ -73457,7 +73566,7 @@ function computeMethodAccess(args) {
73457
73566
  }
73458
73567
 
73459
73568
  // src/version.ts
73460
- var version = "0.2.610".length > 0 ? "0.2.610" : "dev";
73569
+ var version = "0.2.612".length > 0 ? "0.2.612" : "dev";
73461
73570
 
73462
73571
  // src/cli-probe/probe.ts
73463
73572
  var fs83 = __toESM(require("fs"), 1);
@@ -73854,7 +73963,7 @@ init_protocol();
73854
73963
  // src/extension/bundle-zip.ts
73855
73964
  var import_promises12 = __toESM(require("fs/promises"), 1);
73856
73965
  var import_node_path73 = __toESM(require("path"), 1);
73857
- var import_node_crypto22 = __toESM(require("crypto"), 1);
73966
+ var import_node_crypto23 = __toESM(require("crypto"), 1);
73858
73967
  var import_jszip2 = __toESM(require_lib3(), 1);
73859
73968
  async function bundleExtensionDir(dir) {
73860
73969
  const entries = await listFilesSorted(dir);
@@ -73869,7 +73978,7 @@ async function bundleExtensionDir(dir) {
73869
73978
  compression: "DEFLATE",
73870
73979
  compressionOptions: { level: 6 }
73871
73980
  });
73872
- const sha256 = import_node_crypto22.default.createHash("sha256").update(buffer).digest("hex");
73981
+ const sha256 = import_node_crypto23.default.createHash("sha256").update(buffer).digest("hex");
73873
73982
  return { buffer, sha256 };
73874
73983
  }
73875
73984
  var FIXED_DATE = /* @__PURE__ */ new Date("2020-01-01T00:00:00.000Z");
@@ -73937,7 +74046,7 @@ function computePublishCheck(args) {
73937
74046
  var import_promises13 = __toESM(require("fs/promises"), 1);
73938
74047
  var import_node_path75 = __toESM(require("path"), 1);
73939
74048
  var import_node_os28 = __toESM(require("os"), 1);
73940
- var import_node_crypto23 = __toESM(require("crypto"), 1);
74049
+ var import_node_crypto24 = __toESM(require("crypto"), 1);
73941
74050
  var import_jszip3 = __toESM(require_lib3(), 1);
73942
74051
 
73943
74052
  // src/extension/paths.ts
@@ -73966,7 +74075,7 @@ var InstallError = class extends Error {
73966
74075
  };
73967
74076
  async function installFromChannel(args, deps) {
73968
74077
  const { channelRef, snapshotHash, bundleZip } = args;
73969
- const computed = import_node_crypto23.default.createHash("sha256").update(bundleZip).digest("hex");
74078
+ const computed = import_node_crypto24.default.createHash("sha256").update(bundleZip).digest("hex");
73970
74079
  if (computed !== snapshotHash) {
73971
74080
  throw new InstallError(
73972
74081
  "HASH_MISMATCH",
@@ -74058,7 +74167,7 @@ async function installFromChannel(args, deps) {
74058
74167
  var import_promises14 = __toESM(require("fs/promises"), 1);
74059
74168
  var import_node_path76 = __toESM(require("path"), 1);
74060
74169
  var import_node_os29 = __toESM(require("os"), 1);
74061
- var import_node_crypto24 = __toESM(require("crypto"), 1);
74170
+ var import_node_crypto25 = __toESM(require("crypto"), 1);
74062
74171
  var import_jszip4 = __toESM(require_lib3(), 1);
74063
74172
  var UpdateError = class extends Error {
74064
74173
  constructor(code, message) {
@@ -74096,7 +74205,7 @@ async function updateFromChannel(args, deps) {
74096
74205
  if (e instanceof UpdateError) throw e;
74097
74206
  throw e;
74098
74207
  }
74099
- const computed = import_node_crypto24.default.createHash("sha256").update(bundleZip).digest("hex");
74208
+ const computed = import_node_crypto25.default.createHash("sha256").update(bundleZip).digest("hex");
74100
74209
  if (computed !== snapshotHash) {
74101
74210
  throw new UpdateError(
74102
74211
  "HASH_MISMATCH",
@@ -75225,7 +75334,7 @@ async function uninstall(deps) {
75225
75334
  }
75226
75335
 
75227
75336
  // src/handlers/index.ts
75228
- var import_node_crypto25 = require("crypto");
75337
+ var import_node_crypto26 = require("crypto");
75229
75338
 
75230
75339
  // src/handlers/peer-exec.ts
75231
75340
  init_protocol();
@@ -75382,7 +75491,7 @@ function buildMethodHandlers(deps) {
75382
75491
  const c2 = deps.contactStore.get(deviceId);
75383
75492
  return c2 ? { deviceId: c2.deviceId, remoteUrl: c2.remoteUrl, connectToken: c2.connectToken } : null;
75384
75493
  },
75385
- genId: () => (0, import_node_crypto25.randomUUID)(),
75494
+ genId: () => (0, import_node_crypto26.randomUUID)(),
75386
75495
  now: () => Date.now(),
75387
75496
  forwardInboxPostToPeer,
75388
75497
  logger: deps.logger
@@ -76115,7 +76224,7 @@ async function startDaemon(config) {
76115
76224
  const channelStore = createChannelStore({
76116
76225
  filePath: import_node_path84.default.join(config.dataDir, "channels.json"),
76117
76226
  now: () => Date.now(),
76118
- genId: () => `ch-${(0, import_node_crypto26.randomUUID)().slice(0, 8)}`,
76227
+ genId: () => `ch-${(0, import_node_crypto27.randomUUID)().slice(0, 8)}`,
76119
76228
  onFlushError: (err) => logger.error("channel store flush failed", {
76120
76229
  reason: err instanceof Error ? err.message : String(err)
76121
76230
  })
@@ -76124,7 +76233,7 @@ async function startDaemon(config) {
76124
76233
  const topicStore = createTopicStore({
76125
76234
  filePath: import_node_path84.default.join(config.dataDir, "topics.json"),
76126
76235
  now: () => Date.now(),
76127
- genId: () => `tp-${(0, import_node_crypto26.randomUUID)().slice(0, 8)}`,
76236
+ genId: () => `tp-${(0, import_node_crypto27.randomUUID)().slice(0, 8)}`,
76128
76237
  onFlushError: (err) => logger.error("topic store flush failed", {
76129
76238
  reason: err instanceof Error ? err.message : String(err)
76130
76239
  })
@@ -76132,7 +76241,7 @@ async function startDaemon(config) {
76132
76241
  await topicStore.load();
76133
76242
  let deliverPendingRef;
76134
76243
  const personaDispatchManager = new PersonaDispatchManager({
76135
- genId: () => (0, import_node_crypto26.randomUUID)(),
76244
+ genId: () => (0, import_node_crypto27.randomUUID)(),
76136
76245
  store: dispatchStore,
76137
76246
  now: () => Date.now(),
76138
76247
  onCompleted: (sid) => deliverPendingRef?.(sid),
@@ -77330,6 +77439,7 @@ async function startDaemon(config) {
77330
77439
  registeredPersonas: async () => (await cloudGateway.listPersonas()).map((p3) => p3.personaId),
77331
77440
  visiblePersonas: (loginPass) => centralVisiblePersonas({ api: dashboardApi(), loginPass }),
77332
77441
  metrics: (q3) => cloudGateway.fetchMetrics(q3),
77442
+ issues: (q3) => cloudGateway.fetchThreadIssues(q3),
77333
77443
  threads: (loginPass, q3) => centralPersonaThreads({ api: dashboardApi(), loginPass, ...q3 }),
77334
77444
  thread: (loginPass, q3) => centralPersonaThread({ api: dashboardApi(), loginPass, ...q3 }),
77335
77445
  logger