@clawos-dev/clawd 0.2.563 → 0.2.564

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
@@ -44543,7 +44543,7 @@ Env (advanced):
44543
44543
  var import_node_path78 = __toESM(require("path"), 1);
44544
44544
  var import_node_fs60 = __toESM(require("fs"), 1);
44545
44545
  var import_node_os28 = __toESM(require("os"), 1);
44546
- var import_node_crypto23 = require("crypto");
44546
+ var import_node_crypto24 = require("crypto");
44547
44547
  var import_node_url5 = require("url");
44548
44548
 
44549
44549
  // src/logger.ts
@@ -62600,6 +62600,7 @@ async function centralGithubAuthToken(opts) {
62600
62600
  }
62601
62601
 
62602
62602
  // src/cloud/gateway-client.ts
62603
+ var CLOUD_WORKSPACE_SLOT = "{{WORKSPACE}}";
62603
62604
  var GATEWAY_ROUTES = {
62604
62605
  healthz: () => "/healthz",
62605
62606
  session: (personaId2) => `/p/${encodeURIComponent(personaId2)}/session`,
@@ -62700,7 +62701,8 @@ var CloudGatewayClient = class {
62700
62701
  * 会话通道。返回的行流在 Pod 就绪前就能 write:写入先攒着,收到 `ready` 控制行后按序 POST 出去——
62701
62702
  * 编排那头一构造就发 initialize,不用知道 Pod 还在起。
62702
62703
  * `toolSessionId`:调用方预分配的引擎会话 id(pi 的 --session-id;codex 的 thread id 是协议内的、不传),进 open 的 body `engineSessionId`
62703
- * (契约 2026-09-18 §3.2)。
62704
+ * (契约 2026-09-18 §3.2)。`instructions`:会话级指令(pi-cloud 的连接 intro,工作目录写 CLOUD_WORKSPACE_SLOT),进 body `instructions`,
62705
+ * gateway 落成 Pod 里的 /run/agent/instructions.md(契约 §3.1);codex-cloud 不发(走协议内 developerInstructions)。
62704
62706
  */
62705
62707
  async openSession(personaId2, opts = {}) {
62706
62708
  const { apiKey, gatewayUrl } = await this.credentials();
@@ -62710,6 +62712,7 @@ var CloudGatewayClient = class {
62710
62712
  apiKey,
62711
62713
  personaId: personaId2,
62712
62714
  ...opts.toolSessionId ? { engineSessionId: opts.toolSessionId } : {},
62715
+ ...opts.instructions ? { instructions: opts.instructions } : {},
62713
62716
  logger: this.deps.logger
62714
62717
  });
62715
62718
  }
@@ -62754,7 +62757,7 @@ function parseControlLine(line) {
62754
62757
  }
62755
62758
  }
62756
62759
  function openHttpLineStream(opts) {
62757
- const { fetchImpl, gatewayUrl, apiKey, personaId: personaId2, engineSessionId, logger } = opts;
62760
+ const { fetchImpl, gatewayUrl, apiKey, personaId: personaId2, engineSessionId, instructions, logger } = opts;
62758
62761
  const headers = { authorization: `Bearer ${apiKey}`, "content-type": "application/json" };
62759
62762
  const ac = new AbortController();
62760
62763
  const lineCbs = [];
@@ -62811,7 +62814,7 @@ function openHttpLineStream(opts) {
62811
62814
  res = await fetchImpl(gatewayUrl + GATEWAY_ROUTES.session(personaId2), {
62812
62815
  method: "POST",
62813
62816
  headers,
62814
- body: JSON.stringify(engineSessionId ? { engineSessionId } : {}),
62817
+ body: JSON.stringify({ ...engineSessionId ? { engineSessionId } : {}, ...instructions ? { instructions } : {} }),
62815
62818
  signal: ac.signal
62816
62819
  });
62817
62820
  } catch (e) {
@@ -63168,6 +63171,9 @@ var CloudCodexAdapter = class {
63168
63171
  }
63169
63172
  };
63170
63173
 
63174
+ // src/tools/pi-cloud.ts
63175
+ init_protocol();
63176
+
63171
63177
  // src/tools/pi.ts
63172
63178
  var import_node_child_process11 = require("child_process");
63173
63179
  var import_node_fs37 = __toESM(require("fs"), 1);
@@ -63970,6 +63976,152 @@ var PiAdapter = class {
63970
63976
  }
63971
63977
  };
63972
63978
 
63979
+ // src/tools/pi-cloud-session.ts
63980
+ var import_node_crypto11 = require("crypto");
63981
+ function cloudPiInstructions(ctx) {
63982
+ return [ctx.extraSystemPrompt, workDirPrompt(CLOUD_WORKSPACE_SLOT, ctx.personaMode ?? "owner")].filter((x2) => Boolean(x2)).join("\n\n");
63983
+ }
63984
+ function createCloudPiSession(ctx, sink, deps) {
63985
+ const personaId2 = personaIdFromCloudCwd(ctx.cwd);
63986
+ const sessionId = ctx.toolSessionId ?? (0, import_node_crypto11.randomUUID)();
63987
+ const stream = deferredLineStream();
63988
+ let channel = null;
63989
+ const driver = drivePiSession({
63990
+ sink,
63991
+ stream,
63992
+ sessionId,
63993
+ logger: deps.logger,
63994
+ fetchImage: deps.fetchImage ?? makeImageFetcher(),
63995
+ // 「让对端走人」= 断开下行流,gateway 收到就删 Pod;信号对 Pod 没有意义
63996
+ kill: () => stream.close(),
63997
+ onTurnCompleted: () => void channel?.mirror()
63998
+ });
63999
+ if (!personaId2) {
64000
+ queueMicrotask(() => {
64001
+ sink.onError(`cloud session has no persona id (cwd=${ctx.cwd})`);
64002
+ stream.close();
64003
+ });
64004
+ return driver.session;
64005
+ }
64006
+ void deps.client.openSession(personaId2, { toolSessionId: sessionId, instructions: cloudPiInstructions(ctx) }).then(
64007
+ (opened) => {
64008
+ channel = opened;
64009
+ channel.onControl((c2) => {
64010
+ if (c2.kind === "queued") {
64011
+ sink.pushEvents([{ kind: "meta-text", text: `\u4E91\u4E0A\u673A\u5668\u6709 ${c2.running} \u4E2A\u4EFB\u52A1\u5728\u8DD1\uFF0C\u7B49\u4E00\u4E2A\u7ED3\u675F\u5C31\u8F6E\u5230\u4F60` }]);
64012
+ } else if (c2.kind === "error") {
64013
+ sink.onError(`\u4E91\u4E0A persona \u8D77\u4E0D\u6765\uFF1A${c2.message}`);
64014
+ }
64015
+ });
64016
+ stream.attach(channel);
64017
+ },
64018
+ (e) => {
64019
+ sink.onError(e instanceof CloudApiKeyRequiredError ? e.message : `\u8FDE\u4E0D\u4E0A\u4E91 gateway\uFF1A${e.message}`);
64020
+ stream.close();
64021
+ }
64022
+ );
64023
+ return driver.session;
64024
+ }
64025
+
64026
+ // src/tools/pi-cloud-history.ts
64027
+ var CloudPiHistoryReader = class {
64028
+ constructor(client, logger) {
64029
+ this.client = client;
64030
+ this.logger = logger;
64031
+ }
64032
+ client;
64033
+ logger;
64034
+ async listProjects() {
64035
+ return [];
64036
+ }
64037
+ /** 云 persona 没有「关联已有会话」的动线:会话列表就是本机的会话记录 */
64038
+ async listSessions() {
64039
+ return [];
64040
+ }
64041
+ async read(args) {
64042
+ const text = await this.client.fetchRollout(args.toolSessionId);
64043
+ if (text === null) throw new Error(`pi session not found for ${args.toolSessionId}`);
64044
+ const parsed = parsePiSession(text);
64045
+ if (!parsed.meta) this.logger?.warn("cloud pi session has no header line", { toolSessionId: args.toolSessionId });
64046
+ return pageMessages(parsed.messages, args);
64047
+ }
64048
+ async listSubagents(_args) {
64049
+ return [];
64050
+ }
64051
+ async readSubagent(args) {
64052
+ throw new Error(`pi has no subagent threads (${args.subagentId})`);
64053
+ }
64054
+ computeRewindDiff() {
64055
+ return { canRewind: false, files: [], totalInsertions: 0, totalDeletions: 0 };
64056
+ }
64057
+ listRewindableUserMessageIds() {
64058
+ return [];
64059
+ }
64060
+ };
64061
+
64062
+ // src/tools/pi-cloud.ts
64063
+ var CLOUD_APPROVAL2 = { id: "never", label: "Full Access", description: "\u4E91\u4E0A\u65E0\u4EBA\u503C\u5B88\uFF1A\u4ECE\u4E0D\u8BE2\u95EE\uFF0C\u81EA\u4E3B\u6267\u884C" };
64064
+ var CLOUD_PI_CAPABILITIES = {
64065
+ tool: PI_CLOUD_TOOL_ID,
64066
+ toolSessionIdLabel: "pi Session ID",
64067
+ models: [],
64068
+ permissionModes: [CLOUD_APPROVAL2],
64069
+ // 无 rewind / 无子 agent(pi 核心没有)/ 无 pty / observer 是 CC jsonl 解析器 / 无文件分享 / fork 是 claude jsonl 专用
64070
+ features: { rewind: false, subagents: false, tui: false, observe: false, fileSharing: false, fork: false },
64071
+ configSchema: [
64072
+ {
64073
+ name: "permissionMode",
64074
+ type: "select",
64075
+ label: "Approval",
64076
+ scope: "core",
64077
+ options: [{ value: CLOUD_APPROVAL2.id, label: CLOUD_APPROVAL2.label, description: CLOUD_APPROVAL2.description }],
64078
+ default: "never"
64079
+ }
64080
+ ]
64081
+ };
64082
+ var CloudPiAdapter = class {
64083
+ id = PI_CLOUD_TOOL_ID;
64084
+ /** manager 据此跳过「cwd 是本机目录」的校验(cwd 是 gateway 上的地址) */
64085
+ remote = true;
64086
+ historyReader;
64087
+ client;
64088
+ logger;
64089
+ constructor(opts) {
64090
+ this.client = opts.client;
64091
+ this.logger = opts.logger;
64092
+ this.historyReader = new CloudPiHistoryReader(opts.history, opts.logger);
64093
+ }
64094
+ /** 可用 = 能拿到凭据(登了飞书、生成过 key、中心配了 gateway),与本机装没装 pi 无关 */
64095
+ async probe() {
64096
+ try {
64097
+ const { gatewayUrl } = await this.client.credentials();
64098
+ return { available: true, path: gatewayUrl };
64099
+ } catch (err) {
64100
+ this.logger?.debug?.("pi-cloud probe: unavailable", { reason: err.message });
64101
+ return { available: false };
64102
+ }
64103
+ }
64104
+ async capabilities() {
64105
+ return CLOUD_PI_CAPABILITIES;
64106
+ }
64107
+ // 模型由登记行定、本机不知道它的窗口:给 pi 的缺省,运行时 get_state 的 meta_update 会补真值
64108
+ resolveContextWindow(_modelId) {
64109
+ return PI_DEFAULT_CONTEXT_WINDOW;
64110
+ }
64111
+ createSession(ctx, sink) {
64112
+ return createCloudPiSession(ctx, sink, { client: this.client, logger: this.logger });
64113
+ }
64114
+ spawn(_ctx) {
64115
+ throw new Error("CloudPiAdapter uses createSession, not spawn");
64116
+ }
64117
+ parseLine(_line) {
64118
+ return [];
64119
+ }
64120
+ encodeStdin(text, _ctx) {
64121
+ return text;
64122
+ }
64123
+ };
64124
+
63973
64125
  // src/index.ts
63974
64126
  init_protocol();
63975
64127
 
@@ -64914,7 +65066,7 @@ var wrapper_default = import_websocket.default;
64914
65066
 
64915
65067
  // src/transport/local-ws-server.ts
64916
65068
  var import_node_http = __toESM(require("http"), 1);
64917
- var import_node_crypto11 = require("crypto");
65069
+ var import_node_crypto12 = require("crypto");
64918
65070
  var LocalWsServer = class {
64919
65071
  constructor(opts) {
64920
65072
  this.opts = opts;
@@ -65131,7 +65283,7 @@ var LocalWsServer = class {
65131
65283
  }
65132
65284
  }
65133
65285
  onConnection(socket, remoteAddress) {
65134
- const id = (0, import_node_crypto11.randomUUID)();
65286
+ const id = (0, import_node_crypto12.randomUUID)();
65135
65287
  const subscribedSessions = /* @__PURE__ */ new Map();
65136
65288
  const handle = {
65137
65289
  id,
@@ -66096,7 +66248,7 @@ var import_node_path49 = __toESM(require("path"), 1);
66096
66248
  // src/attachment/upload.ts
66097
66249
  var import_node_fs43 = __toESM(require("fs"), 1);
66098
66250
  var import_node_path47 = __toESM(require("path"), 1);
66099
- var import_node_crypto12 = __toESM(require("crypto"), 1);
66251
+ var import_node_crypto13 = __toESM(require("crypto"), 1);
66100
66252
  var import_promises7 = require("stream/promises");
66101
66253
  var UploadError = class extends Error {
66102
66254
  constructor(code, message) {
@@ -66120,11 +66272,11 @@ async function writeUploadedAttachment(args) {
66120
66272
  } catch (err) {
66121
66273
  throw new UploadError("STORAGE_ERROR", `mkdir failed: ${err.message}`);
66122
66274
  }
66123
- const hasher = import_node_crypto12.default.createHash("sha256");
66275
+ const hasher = import_node_crypto13.default.createHash("sha256");
66124
66276
  let actualSize = 0;
66125
66277
  const tmpPath = import_node_path47.default.join(
66126
66278
  attachmentsRoot,
66127
- `.upload-${process.pid}-${Date.now()}-${import_node_crypto12.default.randomBytes(4).toString("hex")}`
66279
+ `.upload-${process.pid}-${Date.now()}-${import_node_crypto13.default.randomBytes(4).toString("hex")}`
66128
66280
  );
66129
66281
  try {
66130
66282
  await (0, import_promises7.pipeline)(
@@ -66968,7 +67120,7 @@ function runAttachmentGc(args) {
66968
67120
  // src/attachment/group.ts
66969
67121
  var import_node_fs46 = __toESM(require("fs"), 1);
66970
67122
  var import_node_path51 = __toESM(require("path"), 1);
66971
- var import_node_crypto13 = __toESM(require("crypto"), 1);
67123
+ var import_node_crypto14 = __toESM(require("crypto"), 1);
66972
67124
  init_protocol();
66973
67125
  var GroupFileStore = class {
66974
67126
  dataDir;
@@ -67057,7 +67209,7 @@ var GroupFileStore = class {
67057
67209
  entries[idx] = next;
67058
67210
  } else {
67059
67211
  next = {
67060
- id: `gf-${import_node_crypto13.default.randomBytes(6).toString("base64url")}`,
67212
+ id: `gf-${import_node_crypto14.default.randomBytes(6).toString("base64url")}`,
67061
67213
  relPath: input.relPath,
67062
67214
  from: input.from,
67063
67215
  label: input.label,
@@ -67203,7 +67355,7 @@ function readSpawnedByDesktopFromEnv(env = process.env) {
67203
67355
  // src/tunnel/tunnel-manager.ts
67204
67356
  var import_node_fs51 = __toESM(require("fs"), 1);
67205
67357
  var import_node_path56 = __toESM(require("path"), 1);
67206
- var import_node_crypto14 = __toESM(require("crypto"), 1);
67358
+ var import_node_crypto15 = __toESM(require("crypto"), 1);
67207
67359
  var import_node_child_process15 = require("child_process");
67208
67360
 
67209
67361
  // src/tunnel/tunnel-store.ts
@@ -67702,7 +67854,7 @@ var TunnelManager = class {
67702
67854
  override: this.deps.frpcBinaryOverride ?? void 0
67703
67855
  });
67704
67856
  const tomlPath = import_node_path56.default.join(this.deps.dataDir, "frpc.toml");
67705
- const proxyName = `clawd-${t2.subdomain}-${localPort}-${import_node_crypto14.default.randomBytes(3).toString("hex")}`;
67857
+ const proxyName = `clawd-${t2.subdomain}-${localPort}-${import_node_crypto15.default.randomBytes(3).toString("hex")}`;
67706
67858
  const toml = buildFrpcToml({
67707
67859
  serverAddr: t2.frpsHost,
67708
67860
  serverPort: t2.frpsPort,
@@ -67803,7 +67955,7 @@ async function waitForFrpcReady(proc, timeoutMs) {
67803
67955
  // src/tunnel/device-key.ts
67804
67956
  var import_node_os18 = __toESM(require("os"), 1);
67805
67957
  var import_node_path57 = __toESM(require("path"), 1);
67806
- var import_node_crypto15 = __toESM(require("crypto"), 1);
67958
+ var import_node_crypto16 = __toESM(require("crypto"), 1);
67807
67959
  var DERIVE_SALT = "clawd-tunnel-device-v1";
67808
67960
  function deriveStableDeviceKey(opts = {}) {
67809
67961
  const hostname = opts.hostname ?? import_node_os18.default.hostname();
@@ -67813,13 +67965,13 @@ function deriveStableDeviceKey(opts = {}) {
67813
67965
  const normalizedDataDir = opts.dataDir ? import_node_path57.default.resolve(opts.dataDir) : null;
67814
67966
  const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
67815
67967
  const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
67816
- return import_node_crypto15.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
67968
+ return import_node_crypto16.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
67817
67969
  }
67818
67970
 
67819
67971
  // src/auth-store.ts
67820
67972
  var import_node_fs52 = __toESM(require("fs"), 1);
67821
67973
  var import_node_path58 = __toESM(require("path"), 1);
67822
- var import_node_crypto16 = __toESM(require("crypto"), 1);
67974
+ var import_node_crypto17 = __toESM(require("crypto"), 1);
67823
67975
  var AUTH_FILE_NAME = "auth.json";
67824
67976
  function authFilePath(dataDir) {
67825
67977
  return import_node_path58.default.join(dataDir, AUTH_FILE_NAME);
@@ -67856,10 +68008,10 @@ function loadOrCreateTunnelDeviceKey(opts) {
67856
68008
  return tunnelDeviceKey;
67857
68009
  }
67858
68010
  function defaultGenerateToken() {
67859
- return import_node_crypto16.default.randomBytes(32).toString("base64url");
68011
+ return import_node_crypto17.default.randomBytes(32).toString("base64url");
67860
68012
  }
67861
68013
  function defaultGenerateOwnerPrincipalId() {
67862
- return `owner-${import_node_crypto16.default.randomUUID()}`;
68014
+ return `owner-${import_node_crypto17.default.randomUUID()}`;
67863
68015
  }
67864
68016
  function readAuthFile(file) {
67865
68017
  try {
@@ -67991,7 +68143,7 @@ var OwnerIdentityStore = class {
67991
68143
  };
67992
68144
 
67993
68145
  // src/feishu-auth/login-flow.ts
67994
- var import_node_crypto17 = __toESM(require("crypto"), 1);
68146
+ var import_node_crypto18 = __toESM(require("crypto"), 1);
67995
68147
  var STATE_TTL_MS = 5 * 60 * 1e3;
67996
68148
  var LoginFlow = class {
67997
68149
  constructor(deps) {
@@ -68000,7 +68152,7 @@ var LoginFlow = class {
68000
68152
  deps;
68001
68153
  pendingStates = /* @__PURE__ */ new Map();
68002
68154
  start() {
68003
- const state = import_node_crypto17.default.randomBytes(16).toString("base64url");
68155
+ const state = import_node_crypto18.default.randomBytes(16).toString("base64url");
68004
68156
  const now = (this.deps.now ?? Date.now)();
68005
68157
  this.pendingStates.set(state, now);
68006
68158
  this.gcExpired(now);
@@ -68531,7 +68683,7 @@ init_protocol();
68531
68683
  var import_node_fs55 = __toESM(require("fs"), 1);
68532
68684
  var import_node_os20 = __toESM(require("os"), 1);
68533
68685
  var import_node_path61 = __toESM(require("path"), 1);
68534
- var import_node_crypto18 = require("crypto");
68686
+ var import_node_crypto19 = require("crypto");
68535
68687
  init_claude_history();
68536
68688
  function readJsonlEntries(file) {
68537
68689
  const raw = import_node_fs55.default.readFileSync(file, "utf8");
@@ -68568,7 +68720,7 @@ function forkSession(input) {
68568
68720
  throw new Error(`fork: messageUuid not found in transcript: ${input.messageUuid}`);
68569
68721
  }
68570
68722
  const sliced = mainEntries.slice(0, targetIdx + 1);
68571
- const forkedToolSessionId = (0, import_node_crypto18.randomUUID)();
68723
+ const forkedToolSessionId = (0, import_node_crypto19.randomUUID)();
68572
68724
  let parentUuid = null;
68573
68725
  const forkedLines = [];
68574
68726
  for (const entry of sliced) {
@@ -69775,7 +69927,7 @@ function buildWorkspaceHandlers(deps) {
69775
69927
  const args = AgentsListArgs.parse(frame);
69776
69928
  const cwdAbs = path80.resolve(args.cwd);
69777
69929
  assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
69778
- if (isCodexFamily(args.tool) || args.tool === PI_TOOL_ID) {
69930
+ if (isCodexFamily(args.tool) || isPiFamily(args.tool)) {
69779
69931
  return { response: { type: "agents:list", agents: [] } };
69780
69932
  }
69781
69933
  const list2 = agents.list(args);
@@ -71156,7 +71308,7 @@ function computeMethodAccess(args) {
71156
71308
  }
71157
71309
 
71158
71310
  // src/version.ts
71159
- var version = "0.2.563".length > 0 ? "0.2.563" : "dev";
71311
+ var version = "0.2.564".length > 0 ? "0.2.564" : "dev";
71160
71312
 
71161
71313
  // src/cli-probe/probe.ts
71162
71314
  var fs78 = __toESM(require("fs"), 1);
@@ -71553,7 +71705,7 @@ init_protocol();
71553
71705
  // src/extension/bundle-zip.ts
71554
71706
  var import_promises11 = __toESM(require("fs/promises"), 1);
71555
71707
  var import_node_path67 = __toESM(require("path"), 1);
71556
- var import_node_crypto19 = __toESM(require("crypto"), 1);
71708
+ var import_node_crypto20 = __toESM(require("crypto"), 1);
71557
71709
  var import_jszip2 = __toESM(require_lib3(), 1);
71558
71710
  async function bundleExtensionDir(dir) {
71559
71711
  const entries = await listFilesSorted(dir);
@@ -71568,7 +71720,7 @@ async function bundleExtensionDir(dir) {
71568
71720
  compression: "DEFLATE",
71569
71721
  compressionOptions: { level: 6 }
71570
71722
  });
71571
- const sha256 = import_node_crypto19.default.createHash("sha256").update(buffer).digest("hex");
71723
+ const sha256 = import_node_crypto20.default.createHash("sha256").update(buffer).digest("hex");
71572
71724
  return { buffer, sha256 };
71573
71725
  }
71574
71726
  var FIXED_DATE = /* @__PURE__ */ new Date("2020-01-01T00:00:00.000Z");
@@ -71636,7 +71788,7 @@ function computePublishCheck(args) {
71636
71788
  var import_promises12 = __toESM(require("fs/promises"), 1);
71637
71789
  var import_node_path69 = __toESM(require("path"), 1);
71638
71790
  var import_node_os25 = __toESM(require("os"), 1);
71639
- var import_node_crypto20 = __toESM(require("crypto"), 1);
71791
+ var import_node_crypto21 = __toESM(require("crypto"), 1);
71640
71792
  var import_jszip3 = __toESM(require_lib3(), 1);
71641
71793
 
71642
71794
  // src/extension/paths.ts
@@ -71665,7 +71817,7 @@ var InstallError = class extends Error {
71665
71817
  };
71666
71818
  async function installFromChannel(args, deps) {
71667
71819
  const { channelRef, snapshotHash, bundleZip } = args;
71668
- const computed = import_node_crypto20.default.createHash("sha256").update(bundleZip).digest("hex");
71820
+ const computed = import_node_crypto21.default.createHash("sha256").update(bundleZip).digest("hex");
71669
71821
  if (computed !== snapshotHash) {
71670
71822
  throw new InstallError(
71671
71823
  "HASH_MISMATCH",
@@ -71757,7 +71909,7 @@ async function installFromChannel(args, deps) {
71757
71909
  var import_promises13 = __toESM(require("fs/promises"), 1);
71758
71910
  var import_node_path70 = __toESM(require("path"), 1);
71759
71911
  var import_node_os26 = __toESM(require("os"), 1);
71760
- var import_node_crypto21 = __toESM(require("crypto"), 1);
71912
+ var import_node_crypto22 = __toESM(require("crypto"), 1);
71761
71913
  var import_jszip4 = __toESM(require_lib3(), 1);
71762
71914
  var UpdateError = class extends Error {
71763
71915
  constructor(code, message) {
@@ -71795,7 +71947,7 @@ async function updateFromChannel(args, deps) {
71795
71947
  if (e instanceof UpdateError) throw e;
71796
71948
  throw e;
71797
71949
  }
71798
- const computed = import_node_crypto21.default.createHash("sha256").update(bundleZip).digest("hex");
71950
+ const computed = import_node_crypto22.default.createHash("sha256").update(bundleZip).digest("hex");
71799
71951
  if (computed !== snapshotHash) {
71800
71952
  throw new UpdateError(
71801
71953
  "HASH_MISMATCH",
@@ -72924,7 +73076,7 @@ async function uninstall(deps) {
72924
73076
  }
72925
73077
 
72926
73078
  // src/handlers/index.ts
72927
- var import_node_crypto22 = require("crypto");
73079
+ var import_node_crypto23 = require("crypto");
72928
73080
 
72929
73081
  // src/handlers/peer-exec.ts
72930
73082
  init_protocol();
@@ -73079,7 +73231,7 @@ function buildMethodHandlers(deps) {
73079
73231
  const c2 = deps.contactStore.get(deviceId);
73080
73232
  return c2 ? { deviceId: c2.deviceId, remoteUrl: c2.remoteUrl, connectToken: c2.connectToken } : null;
73081
73233
  },
73082
- genId: () => (0, import_node_crypto22.randomUUID)(),
73234
+ genId: () => (0, import_node_crypto23.randomUUID)(),
73083
73235
  now: () => Date.now(),
73084
73236
  forwardInboxPostToPeer,
73085
73237
  logger: deps.logger
@@ -73808,7 +73960,7 @@ async function startDaemon(config) {
73808
73960
  const channelStore = createChannelStore({
73809
73961
  filePath: import_node_path78.default.join(config.dataDir, "channels.json"),
73810
73962
  now: () => Date.now(),
73811
- genId: () => `ch-${(0, import_node_crypto23.randomUUID)().slice(0, 8)}`,
73963
+ genId: () => `ch-${(0, import_node_crypto24.randomUUID)().slice(0, 8)}`,
73812
73964
  onFlushError: (err) => logger.error("channel store flush failed", {
73813
73965
  reason: err instanceof Error ? err.message : String(err)
73814
73966
  })
@@ -73817,7 +73969,7 @@ async function startDaemon(config) {
73817
73969
  const topicStore = createTopicStore({
73818
73970
  filePath: import_node_path78.default.join(config.dataDir, "topics.json"),
73819
73971
  now: () => Date.now(),
73820
- genId: () => `tp-${(0, import_node_crypto23.randomUUID)().slice(0, 8)}`,
73972
+ genId: () => `tp-${(0, import_node_crypto24.randomUUID)().slice(0, 8)}`,
73821
73973
  onFlushError: (err) => logger.error("topic store flush failed", {
73822
73974
  reason: err instanceof Error ? err.message : String(err)
73823
73975
  })
@@ -73825,7 +73977,7 @@ async function startDaemon(config) {
73825
73977
  await topicStore.load();
73826
73978
  let deliverPendingRef;
73827
73979
  const personaDispatchManager = new PersonaDispatchManager({
73828
- genId: () => (0, import_node_crypto23.randomUUID)(),
73980
+ genId: () => (0, import_node_crypto24.randomUUID)(),
73829
73981
  store: dispatchStore,
73830
73982
  now: () => Date.now(),
73831
73983
  onCompleted: (sid) => deliverPendingRef?.(sid),
@@ -74272,22 +74424,23 @@ async function startDaemon(config) {
74272
74424
  getSignSecret: () => authFile.token
74273
74425
  })
74274
74426
  );
74427
+ const cloudHistorySource = {
74428
+ fetchRollout: (threadId) => {
74429
+ const loginPass = ownerIdentityStore.read()?.loginPass;
74430
+ if (!loginPass) return Promise.resolve(null);
74431
+ return centralGetThread({ api: config.clawosApi ?? DEFAULT_CLAWOS_API, loginPass, threadId });
74432
+ }
74433
+ };
74275
74434
  registerAdapter(
74276
74435
  CODEX_CLOUD_TOOL_ID,
74277
74436
  new CloudCodexAdapter({
74278
74437
  client: cloudGateway,
74279
- // 历史副本从中心拉(design 2026-09-19-cloud-session-oss §3.4):没登录就没有历史,不抛
74280
- history: {
74281
- fetchRollout: (threadId) => {
74282
- const loginPass = ownerIdentityStore.read()?.loginPass;
74283
- if (!loginPass) return Promise.resolve(null);
74284
- return centralGetThread({ api: config.clawosApi ?? DEFAULT_CLAWOS_API, loginPass, threadId });
74285
- }
74286
- },
74438
+ history: cloudHistorySource,
74287
74439
  logger,
74288
74440
  getSignSecret: () => authFile.token
74289
74441
  })
74290
74442
  );
74443
+ registerAdapter(PI_CLOUD_TOOL_ID, new CloudPiAdapter({ client: cloudGateway, history: cloudHistorySource, logger }));
74291
74444
  const piMcpBridgeCandidates = [
74292
74445
  import_node_path78.default.join(here, "pi-mcp-bridge", "extension.cjs"),
74293
74446
  import_node_path78.default.join(here, "..", "dist", "pi-mcp-bridge", "extension.cjs")