@clawos-dev/clawd 0.2.574 → 0.2.576

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
@@ -450,8 +450,8 @@ var init_parseUtil = __esm({
450
450
  init_errors();
451
451
  init_en();
452
452
  makeIssue = (params) => {
453
- const { data, path: path100, errorMaps, issueData } = params;
454
- const fullPath = [...path100, ...issueData.path || []];
453
+ const { data, path: path101, errorMaps, issueData } = params;
454
+ const fullPath = [...path101, ...issueData.path || []];
455
455
  const fullIssue = {
456
456
  ...issueData,
457
457
  path: fullPath
@@ -762,11 +762,11 @@ var init_types = __esm({
762
762
  init_parseUtil();
763
763
  init_util();
764
764
  ParseInputLazyPath = class {
765
- constructor(parent, value, path100, key) {
765
+ constructor(parent, value, path101, key) {
766
766
  this._cachedPath = [];
767
767
  this.parent = parent;
768
768
  this.data = value;
769
- this._path = path100;
769
+ this._path = path101;
770
770
  this._key = key;
771
771
  }
772
772
  get path() {
@@ -5989,7 +5989,7 @@ function sharedConnectorSecrets(m3) {
5989
5989
  function requiredSecretEnvNames(m3) {
5990
5990
  return [.../* @__PURE__ */ new Set([...m3.secrets.flatMap((s2) => s2.env), ...sharedConnectorSecrets(m3).flatMap((s2) => s2.env)])];
5991
5991
  }
5992
- var EnvArtifactSchema, EnvPackageSchema, EnvSecretSchema, ConnectorNameSchema, CONNECTOR_KINDS, CONNECTOR_RUNNERS, CONNECTOR_PROTOCOLS, CREDENTIAL_SOURCES, CONNECTOR_AUTHS, ConnectorFieldSchema, EnvConnectorSchema, normalizeLegacyManifest, MANIFEST_BODY, EnvManifestBodySchema, EnvironmentManifestSchema, EnvEvidenceSchema;
5992
+ var EnvArtifactSchema, CLOUD_ROOT_PROVIDES, EnvPackageSchema, EnvSecretSchema, ConnectorNameSchema, CONNECTOR_KINDS, CONNECTOR_RUNNERS, CONNECTOR_PROTOCOLS, CREDENTIAL_SOURCES, CONNECTOR_AUTHS, ConnectorFieldSchema, EnvConnectorSchema, normalizeLegacyManifest, MANIFEST_BODY, EnvManifestBodySchema, EnvironmentManifestSchema, EnvEvidenceSchema;
5993
5993
  var init_environment_schemas = __esm({
5994
5994
  "../protocol/src/environment-schemas.ts"() {
5995
5995
  "use strict";
@@ -5998,9 +5998,10 @@ var init_environment_schemas = __esm({
5998
5998
  url: external_exports.string().url(),
5999
5999
  // 包内可执行文件的路径(`hbi` / `dist/bin/x`);空串 = 裸二进制
6000
6000
  bin: external_exports.string(),
6001
- sha256: external_exports.string().regex(/^[0-9a-f]{64}$/).optional(),
6002
- size: external_exports.number().int().positive().optional()
6001
+ sha256: external_exports.string().regex(/^[0-9a-f]{64}$/),
6002
+ size: external_exports.number().int().positive()
6003
6003
  });
6004
+ CLOUD_ROOT_PROVIDES = ["node", "npm"];
6004
6005
  EnvPackageSchema = external_exports.object({
6005
6006
  // 装完后在 PATH 里能直接调到的名字('aliyun' / 's' / 'pnpm' / 'python3');npm 包报 bin 名,包名进 from
6006
6007
  name: external_exports.string().min(1),
@@ -6039,7 +6040,18 @@ var init_environment_schemas = __esm({
6039
6040
  */
6040
6041
  localVersion: external_exports.string().optional(),
6041
6042
  /** `github:` 专用——那个版本是哪个文件。见 EnvArtifactSchema */
6042
- artifact: EnvArtifactSchema.optional()
6043
+ artifact: EnvArtifactSchema.optional(),
6044
+ /**
6045
+ * `apt:` 专用——daemon 上报时查过 Debian 12(bookworm)仓库,**没有**这个包。云上装不了,怎么办由老板在页面上定(换源 / 去掉 / 接受);
6046
+ * 不打回 butler(它也不见得找得到对的 npm / github 源)。有这个包时不写此字段,`version` 就是 Debian 12 会装的那一版(不是本机的)。
6047
+ */
6048
+ aptMissing: external_exports.literal(true).optional(),
6049
+ /**
6050
+ * `apt:` 专用——daemon 查到的 Debian 12 里这个包的版本(上游号,如 `3.11.2`;元包抠不出上游号时是 Debian 的版本串原样)。
6051
+ * 是**事实**不是要求:`version` 才是构建期要验的那个——Debian 版本满足 `min`(或没 `min`)时 `version` = 它;不满足时只记这里、不钉 `version`,
6052
+ * 页面把「Debian 12 只有 x,要求 ≥ min」摆出来让老板定。查不到(出网失败)时两者都不写,页面显示「没查到」。
6053
+ */
6054
+ aptVersion: external_exports.string().optional()
6043
6055
  });
6044
6056
  EnvSecretSchema = external_exports.object({
6045
6057
  // 凭据的命名引用('aliyun-ak' / 'supabase-shared')。部署时按这个名字去解析实际的值。
@@ -10109,8 +10121,8 @@ var require_req = __commonJS({
10109
10121
  if (req.originalUrl) {
10110
10122
  _req.url = req.originalUrl;
10111
10123
  } else {
10112
- const path100 = req.path;
10113
- _req.url = typeof path100 === "string" ? path100 : req.url ? req.url.path || req.url : void 0;
10124
+ const path101 = req.path;
10125
+ _req.url = typeof path101 === "string" ? path101 : req.url ? req.url.path || req.url : void 0;
10114
10126
  }
10115
10127
  if (req.query) {
10116
10128
  _req.query = req.query;
@@ -10275,14 +10287,14 @@ var require_redact = __commonJS({
10275
10287
  }
10276
10288
  return obj;
10277
10289
  }
10278
- function parsePath(path100) {
10290
+ function parsePath(path101) {
10279
10291
  const parts = [];
10280
10292
  let current = "";
10281
10293
  let inBrackets = false;
10282
10294
  let inQuotes = false;
10283
10295
  let quoteChar = "";
10284
- for (let i2 = 0; i2 < path100.length; i2++) {
10285
- const char = path100[i2];
10296
+ for (let i2 = 0; i2 < path101.length; i2++) {
10297
+ const char = path101[i2];
10286
10298
  if (!inBrackets && char === ".") {
10287
10299
  if (current) {
10288
10300
  parts.push(current);
@@ -10413,10 +10425,10 @@ var require_redact = __commonJS({
10413
10425
  return current;
10414
10426
  }
10415
10427
  function redactPaths(obj, paths, censor, remove = false) {
10416
- for (const path100 of paths) {
10417
- const parts = parsePath(path100);
10428
+ for (const path101 of paths) {
10429
+ const parts = parsePath(path101);
10418
10430
  if (parts.includes("*")) {
10419
- redactWildcardPath(obj, parts, censor, path100, remove);
10431
+ redactWildcardPath(obj, parts, censor, path101, remove);
10420
10432
  } else {
10421
10433
  if (remove) {
10422
10434
  removeKey(obj, parts);
@@ -10501,8 +10513,8 @@ var require_redact = __commonJS({
10501
10513
  }
10502
10514
  } else {
10503
10515
  if (afterWildcard.includes("*")) {
10504
- const wrappedCensor = typeof censor === "function" ? (value, path100) => {
10505
- const fullPath = [...pathArray.slice(0, pathLength), ...path100];
10516
+ const wrappedCensor = typeof censor === "function" ? (value, path101) => {
10517
+ const fullPath = [...pathArray.slice(0, pathLength), ...path101];
10506
10518
  return censor(value, fullPath);
10507
10519
  } : censor;
10508
10520
  redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
@@ -10537,8 +10549,8 @@ var require_redact = __commonJS({
10537
10549
  return null;
10538
10550
  }
10539
10551
  const pathStructure = /* @__PURE__ */ new Map();
10540
- for (const path100 of pathsToClone) {
10541
- const parts = parsePath(path100);
10552
+ for (const path101 of pathsToClone) {
10553
+ const parts = parsePath(path101);
10542
10554
  let current = pathStructure;
10543
10555
  for (let i2 = 0; i2 < parts.length; i2++) {
10544
10556
  const part = parts[i2];
@@ -10590,24 +10602,24 @@ var require_redact = __commonJS({
10590
10602
  }
10591
10603
  return cloneSelectively(obj, pathStructure);
10592
10604
  }
10593
- function validatePath(path100) {
10594
- if (typeof path100 !== "string") {
10605
+ function validatePath(path101) {
10606
+ if (typeof path101 !== "string") {
10595
10607
  throw new Error("Paths must be (non-empty) strings");
10596
10608
  }
10597
- if (path100 === "") {
10609
+ if (path101 === "") {
10598
10610
  throw new Error("Invalid redaction path ()");
10599
10611
  }
10600
- if (path100.includes("..")) {
10601
- throw new Error(`Invalid redaction path (${path100})`);
10612
+ if (path101.includes("..")) {
10613
+ throw new Error(`Invalid redaction path (${path101})`);
10602
10614
  }
10603
- if (path100.includes(",")) {
10604
- throw new Error(`Invalid redaction path (${path100})`);
10615
+ if (path101.includes(",")) {
10616
+ throw new Error(`Invalid redaction path (${path101})`);
10605
10617
  }
10606
10618
  let bracketCount = 0;
10607
10619
  let inQuotes = false;
10608
10620
  let quoteChar = "";
10609
- for (let i2 = 0; i2 < path100.length; i2++) {
10610
- const char = path100[i2];
10621
+ for (let i2 = 0; i2 < path101.length; i2++) {
10622
+ const char = path101[i2];
10611
10623
  if ((char === '"' || char === "'") && bracketCount > 0) {
10612
10624
  if (!inQuotes) {
10613
10625
  inQuotes = true;
@@ -10621,20 +10633,20 @@ var require_redact = __commonJS({
10621
10633
  } else if (char === "]" && !inQuotes) {
10622
10634
  bracketCount--;
10623
10635
  if (bracketCount < 0) {
10624
- throw new Error(`Invalid redaction path (${path100})`);
10636
+ throw new Error(`Invalid redaction path (${path101})`);
10625
10637
  }
10626
10638
  }
10627
10639
  }
10628
10640
  if (bracketCount !== 0) {
10629
- throw new Error(`Invalid redaction path (${path100})`);
10641
+ throw new Error(`Invalid redaction path (${path101})`);
10630
10642
  }
10631
10643
  }
10632
10644
  function validatePaths(paths) {
10633
10645
  if (!Array.isArray(paths)) {
10634
10646
  throw new TypeError("paths must be an array");
10635
10647
  }
10636
- for (const path100 of paths) {
10637
- validatePath(path100);
10648
+ for (const path101 of paths) {
10649
+ validatePath(path101);
10638
10650
  }
10639
10651
  }
10640
10652
  function slowRedact(options = {}) {
@@ -10802,8 +10814,8 @@ var require_redaction = __commonJS({
10802
10814
  if (shape[k3] === null) {
10803
10815
  o2[k3] = (value) => topCensor(value, [k3]);
10804
10816
  } else {
10805
- const wrappedCensor = typeof censor === "function" ? (value, path100) => {
10806
- return censor(value, [k3, ...path100]);
10817
+ const wrappedCensor = typeof censor === "function" ? (value, path101) => {
10818
+ return censor(value, [k3, ...path101]);
10807
10819
  } : censor;
10808
10820
  o2[k3] = Redact({
10809
10821
  paths: shape[k3],
@@ -11021,10 +11033,10 @@ var require_atomic_sleep = __commonJS({
11021
11033
  var require_sonic_boom = __commonJS({
11022
11034
  "../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
11023
11035
  "use strict";
11024
- var fs90 = require("fs");
11036
+ var fs91 = require("fs");
11025
11037
  var EventEmitter2 = require("events");
11026
11038
  var inherits = require("util").inherits;
11027
- var path100 = require("path");
11039
+ var path101 = require("path");
11028
11040
  var sleep2 = require_atomic_sleep();
11029
11041
  var assert = require("assert");
11030
11042
  var BUSY_WRITE_TIMEOUT = 100;
@@ -11078,20 +11090,20 @@ var require_sonic_boom = __commonJS({
11078
11090
  const mode = sonic.mode;
11079
11091
  if (sonic.sync) {
11080
11092
  try {
11081
- if (sonic.mkdir) fs90.mkdirSync(path100.dirname(file), { recursive: true });
11082
- const fd = fs90.openSync(file, flags, mode);
11093
+ if (sonic.mkdir) fs91.mkdirSync(path101.dirname(file), { recursive: true });
11094
+ const fd = fs91.openSync(file, flags, mode);
11083
11095
  fileOpened(null, fd);
11084
11096
  } catch (err) {
11085
11097
  fileOpened(err);
11086
11098
  throw err;
11087
11099
  }
11088
11100
  } else if (sonic.mkdir) {
11089
- fs90.mkdir(path100.dirname(file), { recursive: true }, (err) => {
11101
+ fs91.mkdir(path101.dirname(file), { recursive: true }, (err) => {
11090
11102
  if (err) return fileOpened(err);
11091
- fs90.open(file, flags, mode, fileOpened);
11103
+ fs91.open(file, flags, mode, fileOpened);
11092
11104
  });
11093
11105
  } else {
11094
- fs90.open(file, flags, mode, fileOpened);
11106
+ fs91.open(file, flags, mode, fileOpened);
11095
11107
  }
11096
11108
  }
11097
11109
  function SonicBoom(opts) {
@@ -11132,8 +11144,8 @@ var require_sonic_boom = __commonJS({
11132
11144
  this.flush = flushBuffer;
11133
11145
  this.flushSync = flushBufferSync;
11134
11146
  this._actualWrite = actualWriteBuffer;
11135
- fsWriteSync = () => fs90.writeSync(this.fd, this._writingBuf);
11136
- fsWrite = () => fs90.write(this.fd, this._writingBuf, this.release);
11147
+ fsWriteSync = () => fs91.writeSync(this.fd, this._writingBuf);
11148
+ fsWrite = () => fs91.write(this.fd, this._writingBuf, this.release);
11137
11149
  } else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
11138
11150
  this._writingBuf = "";
11139
11151
  this.write = write;
@@ -11142,15 +11154,15 @@ var require_sonic_boom = __commonJS({
11142
11154
  this._actualWrite = actualWrite;
11143
11155
  fsWriteSync = () => {
11144
11156
  if (Buffer.isBuffer(this._writingBuf)) {
11145
- return fs90.writeSync(this.fd, this._writingBuf);
11157
+ return fs91.writeSync(this.fd, this._writingBuf);
11146
11158
  }
11147
- return fs90.writeSync(this.fd, this._writingBuf, "utf8");
11159
+ return fs91.writeSync(this.fd, this._writingBuf, "utf8");
11148
11160
  };
11149
11161
  fsWrite = () => {
11150
11162
  if (Buffer.isBuffer(this._writingBuf)) {
11151
- return fs90.write(this.fd, this._writingBuf, this.release);
11163
+ return fs91.write(this.fd, this._writingBuf, this.release);
11152
11164
  }
11153
- return fs90.write(this.fd, this._writingBuf, "utf8", this.release);
11165
+ return fs91.write(this.fd, this._writingBuf, "utf8", this.release);
11154
11166
  };
11155
11167
  } else {
11156
11168
  throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
@@ -11207,7 +11219,7 @@ var require_sonic_boom = __commonJS({
11207
11219
  }
11208
11220
  }
11209
11221
  if (this._fsync) {
11210
- fs90.fsyncSync(this.fd);
11222
+ fs91.fsyncSync(this.fd);
11211
11223
  }
11212
11224
  const len = this._len;
11213
11225
  if (this._reopening) {
@@ -11321,7 +11333,7 @@ var require_sonic_boom = __commonJS({
11321
11333
  const onDrain = () => {
11322
11334
  if (!this._fsync) {
11323
11335
  try {
11324
- fs90.fsync(this.fd, (err) => {
11336
+ fs91.fsync(this.fd, (err) => {
11325
11337
  this._flushPending = false;
11326
11338
  cb(err);
11327
11339
  });
@@ -11423,7 +11435,7 @@ var require_sonic_boom = __commonJS({
11423
11435
  const fd = this.fd;
11424
11436
  this.once("ready", () => {
11425
11437
  if (fd !== this.fd) {
11426
- fs90.close(fd, (err) => {
11438
+ fs91.close(fd, (err) => {
11427
11439
  if (err) {
11428
11440
  return this.emit("error", err);
11429
11441
  }
@@ -11472,7 +11484,7 @@ var require_sonic_boom = __commonJS({
11472
11484
  buf = this._bufs[0];
11473
11485
  }
11474
11486
  try {
11475
- const n2 = Buffer.isBuffer(buf) ? fs90.writeSync(this.fd, buf) : fs90.writeSync(this.fd, buf, "utf8");
11487
+ const n2 = Buffer.isBuffer(buf) ? fs91.writeSync(this.fd, buf) : fs91.writeSync(this.fd, buf, "utf8");
11476
11488
  const releasedBufObj = releaseWritingBuf(buf, this._len, n2);
11477
11489
  buf = releasedBufObj.writingBuf;
11478
11490
  this._len = releasedBufObj.len;
@@ -11488,7 +11500,7 @@ var require_sonic_boom = __commonJS({
11488
11500
  }
11489
11501
  }
11490
11502
  try {
11491
- fs90.fsyncSync(this.fd);
11503
+ fs91.fsyncSync(this.fd);
11492
11504
  } catch {
11493
11505
  }
11494
11506
  }
@@ -11509,7 +11521,7 @@ var require_sonic_boom = __commonJS({
11509
11521
  buf = mergeBuf(this._bufs[0], this._lens[0]);
11510
11522
  }
11511
11523
  try {
11512
- const n2 = fs90.writeSync(this.fd, buf);
11524
+ const n2 = fs91.writeSync(this.fd, buf);
11513
11525
  buf = buf.subarray(n2);
11514
11526
  this._len = Math.max(this._len - n2, 0);
11515
11527
  if (buf.length <= 0) {
@@ -11537,13 +11549,13 @@ var require_sonic_boom = __commonJS({
11537
11549
  this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
11538
11550
  if (this.sync) {
11539
11551
  try {
11540
- const written = Buffer.isBuffer(this._writingBuf) ? fs90.writeSync(this.fd, this._writingBuf) : fs90.writeSync(this.fd, this._writingBuf, "utf8");
11552
+ const written = Buffer.isBuffer(this._writingBuf) ? fs91.writeSync(this.fd, this._writingBuf) : fs91.writeSync(this.fd, this._writingBuf, "utf8");
11541
11553
  release2(null, written);
11542
11554
  } catch (err) {
11543
11555
  release2(err);
11544
11556
  }
11545
11557
  } else {
11546
- fs90.write(this.fd, this._writingBuf, release2);
11558
+ fs91.write(this.fd, this._writingBuf, release2);
11547
11559
  }
11548
11560
  }
11549
11561
  function actualWriteBuffer() {
@@ -11552,7 +11564,7 @@ var require_sonic_boom = __commonJS({
11552
11564
  this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
11553
11565
  if (this.sync) {
11554
11566
  try {
11555
- const written = fs90.writeSync(this.fd, this._writingBuf);
11567
+ const written = fs91.writeSync(this.fd, this._writingBuf);
11556
11568
  release2(null, written);
11557
11569
  } catch (err) {
11558
11570
  release2(err);
@@ -11561,7 +11573,7 @@ var require_sonic_boom = __commonJS({
11561
11573
  if (kCopyBuffer) {
11562
11574
  this._writingBuf = Buffer.from(this._writingBuf);
11563
11575
  }
11564
- fs90.write(this.fd, this._writingBuf, release2);
11576
+ fs91.write(this.fd, this._writingBuf, release2);
11565
11577
  }
11566
11578
  }
11567
11579
  function actualClose(sonic) {
@@ -11577,12 +11589,12 @@ var require_sonic_boom = __commonJS({
11577
11589
  sonic._lens = [];
11578
11590
  assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
11579
11591
  try {
11580
- fs90.fsync(sonic.fd, closeWrapped);
11592
+ fs91.fsync(sonic.fd, closeWrapped);
11581
11593
  } catch {
11582
11594
  }
11583
11595
  function closeWrapped() {
11584
11596
  if (sonic.fd !== 1 && sonic.fd !== 2) {
11585
- fs90.close(sonic.fd, done);
11597
+ fs91.close(sonic.fd, done);
11586
11598
  } else {
11587
11599
  done();
11588
11600
  }
@@ -12313,7 +12325,7 @@ var require_transport = __commonJS({
12313
12325
  stream.flushSync();
12314
12326
  }
12315
12327
  function transport(fullOptions) {
12316
- const { pipeline: pipeline3, targets, levels, dedupe, worker = {}, caller = getCallers(), sync = false } = fullOptions;
12328
+ const { pipeline: pipeline4, targets, levels, dedupe, worker = {}, caller = getCallers(), sync = false } = fullOptions;
12317
12329
  const options = {
12318
12330
  ...fullOptions.options
12319
12331
  };
@@ -12341,9 +12353,9 @@ var require_transport = __commonJS({
12341
12353
  };
12342
12354
  });
12343
12355
  });
12344
- } else if (pipeline3) {
12356
+ } else if (pipeline4) {
12345
12357
  target = bundlerOverrides["pino-worker"] || join17(__dirname, "worker.js");
12346
- options.pipelines = [pipeline3.map((dest) => {
12358
+ options.pipelines = [pipeline4.map((dest) => {
12347
12359
  return {
12348
12360
  ...dest,
12349
12361
  target: fixTarget(dest.target)
@@ -13946,7 +13958,7 @@ var require_multistream = __commonJS({
13946
13958
  var require_pino = __commonJS({
13947
13959
  "../node_modules/.pnpm/pino@9.14.0/node_modules/pino/pino.js"(exports2, module2) {
13948
13960
  "use strict";
13949
- var os33 = require("os");
13961
+ var os34 = require("os");
13950
13962
  var stdSerializers = require_pino_std_serializers();
13951
13963
  var caller = require_caller();
13952
13964
  var redaction = require_redaction();
@@ -13993,7 +14005,7 @@ var require_pino = __commonJS({
13993
14005
  } = symbols;
13994
14006
  var { epochTime, nullTime } = time;
13995
14007
  var { pid } = process;
13996
- var hostname = os33.hostname();
14008
+ var hostname = os34.hostname();
13997
14009
  var defaultErrorSerializer = stdSerializers.err;
13998
14010
  var defaultOptions2 = {
13999
14011
  level: "info",
@@ -14717,11 +14729,11 @@ var init_lib = __esm({
14717
14729
  }
14718
14730
  }
14719
14731
  },
14720
- addToPath: function addToPath(path100, added, removed, oldPosInc, options) {
14721
- var last = path100.lastComponent;
14732
+ addToPath: function addToPath(path101, added, removed, oldPosInc, options) {
14733
+ var last = path101.lastComponent;
14722
14734
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
14723
14735
  return {
14724
- oldPos: path100.oldPos + oldPosInc,
14736
+ oldPos: path101.oldPos + oldPosInc,
14725
14737
  lastComponent: {
14726
14738
  count: last.count + 1,
14727
14739
  added,
@@ -14731,7 +14743,7 @@ var init_lib = __esm({
14731
14743
  };
14732
14744
  } else {
14733
14745
  return {
14734
- oldPos: path100.oldPos + oldPosInc,
14746
+ oldPos: path101.oldPos + oldPosInc,
14735
14747
  lastComponent: {
14736
14748
  count: 1,
14737
14749
  added,
@@ -15313,10 +15325,10 @@ function attachmentToHistoryMessage(o2, ts) {
15313
15325
  const memories = raw.map((m3) => {
15314
15326
  if (!m3 || typeof m3 !== "object") return null;
15315
15327
  const rec6 = m3;
15316
- const path100 = typeof rec6.path === "string" ? rec6.path : null;
15328
+ const path101 = typeof rec6.path === "string" ? rec6.path : null;
15317
15329
  const content = typeof rec6.content === "string" ? rec6.content : null;
15318
- if (!path100 || content == null) return null;
15319
- const entry = { path: path100, content };
15330
+ if (!path101 || content == null) return null;
15331
+ const entry = { path: path101, content };
15320
15332
  if (typeof rec6.mtimeMs === "number") entry.mtimeMs = rec6.mtimeMs;
15321
15333
  return entry;
15322
15334
  }).filter((m3) => m3 !== null);
@@ -16182,10 +16194,10 @@ function parseAttachment(obj) {
16182
16194
  const memories = raw.map((m3) => {
16183
16195
  if (!m3 || typeof m3 !== "object") return null;
16184
16196
  const rec6 = m3;
16185
- const path100 = typeof rec6.path === "string" ? rec6.path : null;
16197
+ const path101 = typeof rec6.path === "string" ? rec6.path : null;
16186
16198
  const content = typeof rec6.content === "string" ? rec6.content : null;
16187
- if (!path100 || content == null) return null;
16188
- const out = { path: path100, content };
16199
+ if (!path101 || content == null) return null;
16200
+ const out = { path: path101, content };
16189
16201
  if (typeof rec6.mtimeMs === "number") out.mtimeMs = rec6.mtimeMs;
16190
16202
  return out;
16191
16203
  }).filter((m3) => m3 !== null);
@@ -32869,8 +32881,8 @@ var require_websocket = __commonJS({
32869
32881
  var http2 = require("http");
32870
32882
  var net2 = require("net");
32871
32883
  var tls = require("tls");
32872
- var { randomBytes: randomBytes2, createHash: createHash2 } = require("crypto");
32873
- var { Duplex, Readable: Readable3 } = require("stream");
32884
+ var { randomBytes: randomBytes2, createHash: createHash3 } = require("crypto");
32885
+ var { Duplex, Readable: Readable4 } = require("stream");
32874
32886
  var { URL: URL2 } = require("url");
32875
32887
  var PerMessageDeflate2 = require_permessage_deflate();
32876
32888
  var Receiver2 = require_receiver();
@@ -33529,7 +33541,7 @@ var require_websocket = __commonJS({
33529
33541
  abortHandshake(websocket, socket, "Invalid Upgrade header");
33530
33542
  return;
33531
33543
  }
33532
- const digest = createHash2("sha1").update(key + GUID).digest("base64");
33544
+ const digest = createHash3("sha1").update(key + GUID).digest("base64");
33533
33545
  if (res.headers["sec-websocket-accept"] !== digest) {
33534
33546
  abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
33535
33547
  return;
@@ -33896,7 +33908,7 @@ var require_websocket_server = __commonJS({
33896
33908
  var EventEmitter2 = require("events");
33897
33909
  var http2 = require("http");
33898
33910
  var { Duplex } = require("stream");
33899
- var { createHash: createHash2 } = require("crypto");
33911
+ var { createHash: createHash3 } = require("crypto");
33900
33912
  var extension2 = require_extension();
33901
33913
  var PerMessageDeflate2 = require_permessage_deflate();
33902
33914
  var subprotocol2 = require_subprotocol();
@@ -34197,7 +34209,7 @@ var require_websocket_server = __commonJS({
34197
34209
  );
34198
34210
  }
34199
34211
  if (this._state > RUNNING) return abortHandshake(socket, 503);
34200
- const digest = createHash2("sha1").update(key + GUID).digest("base64");
34212
+ const digest = createHash3("sha1").update(key + GUID).digest("base64");
34201
34213
  const headers = [
34202
34214
  "HTTP/1.1 101 Switching Protocols",
34203
34215
  "Upgrade: websocket",
@@ -35133,9 +35145,9 @@ var require_stream_duplex = __commonJS({
35133
35145
  module2.exports = Duplex;
35134
35146
  var util2 = Object.create(require_util());
35135
35147
  util2.inherits = require_inherits();
35136
- var Readable3 = require_stream_readable();
35148
+ var Readable4 = require_stream_readable();
35137
35149
  var Writable3 = require_stream_writable();
35138
- util2.inherits(Duplex, Readable3);
35150
+ util2.inherits(Duplex, Readable4);
35139
35151
  {
35140
35152
  keys = objectKeys(Writable3.prototype);
35141
35153
  for (v3 = 0; v3 < keys.length; v3++) {
@@ -35148,7 +35160,7 @@ var require_stream_duplex = __commonJS({
35148
35160
  var v3;
35149
35161
  function Duplex(options) {
35150
35162
  if (!(this instanceof Duplex)) return new Duplex(options);
35151
- Readable3.call(this, options);
35163
+ Readable4.call(this, options);
35152
35164
  Writable3.call(this, options);
35153
35165
  if (options && options.readable === false) this.readable = false;
35154
35166
  if (options && options.writable === false) this.writable = false;
@@ -35438,10 +35450,10 @@ var require_stream_readable = __commonJS({
35438
35450
  "../node_modules/.pnpm/readable-stream@2.3.8/node_modules/readable-stream/lib/_stream_readable.js"(exports2, module2) {
35439
35451
  "use strict";
35440
35452
  var pna = require_process_nextick_args();
35441
- module2.exports = Readable3;
35453
+ module2.exports = Readable4;
35442
35454
  var isArray = require_isarray();
35443
35455
  var Duplex;
35444
- Readable3.ReadableState = ReadableState;
35456
+ Readable4.ReadableState = ReadableState;
35445
35457
  var EE = require("events").EventEmitter;
35446
35458
  var EElistenerCount = function(emitter, type) {
35447
35459
  return emitter.listeners(type).length;
@@ -35469,7 +35481,7 @@ var require_stream_readable = __commonJS({
35469
35481
  var BufferList = require_BufferList();
35470
35482
  var destroyImpl = require_destroy();
35471
35483
  var StringDecoder2;
35472
- util2.inherits(Readable3, Stream);
35484
+ util2.inherits(Readable4, Stream);
35473
35485
  var kProxyEvents = ["error", "close", "destroy", "pause", "resume"];
35474
35486
  function prependListener(emitter, event, fn) {
35475
35487
  if (typeof emitter.prependListener === "function") return emitter.prependListener(event, fn);
@@ -35515,9 +35527,9 @@ var require_stream_readable = __commonJS({
35515
35527
  this.encoding = options.encoding;
35516
35528
  }
35517
35529
  }
35518
- function Readable3(options) {
35530
+ function Readable4(options) {
35519
35531
  Duplex = Duplex || require_stream_duplex();
35520
- if (!(this instanceof Readable3)) return new Readable3(options);
35532
+ if (!(this instanceof Readable4)) return new Readable4(options);
35521
35533
  this._readableState = new ReadableState(options, this);
35522
35534
  this.readable = true;
35523
35535
  if (options) {
@@ -35526,7 +35538,7 @@ var require_stream_readable = __commonJS({
35526
35538
  }
35527
35539
  Stream.call(this);
35528
35540
  }
35529
- Object.defineProperty(Readable3.prototype, "destroyed", {
35541
+ Object.defineProperty(Readable4.prototype, "destroyed", {
35530
35542
  get: function() {
35531
35543
  if (this._readableState === void 0) {
35532
35544
  return false;
@@ -35540,13 +35552,13 @@ var require_stream_readable = __commonJS({
35540
35552
  this._readableState.destroyed = value;
35541
35553
  }
35542
35554
  });
35543
- Readable3.prototype.destroy = destroyImpl.destroy;
35544
- Readable3.prototype._undestroy = destroyImpl.undestroy;
35545
- Readable3.prototype._destroy = function(err, cb) {
35555
+ Readable4.prototype.destroy = destroyImpl.destroy;
35556
+ Readable4.prototype._undestroy = destroyImpl.undestroy;
35557
+ Readable4.prototype._destroy = function(err, cb) {
35546
35558
  this.push(null);
35547
35559
  cb(err);
35548
35560
  };
35549
- Readable3.prototype.push = function(chunk, encoding) {
35561
+ Readable4.prototype.push = function(chunk, encoding) {
35550
35562
  var state = this._readableState;
35551
35563
  var skipChunkCheck;
35552
35564
  if (!state.objectMode) {
@@ -35563,7 +35575,7 @@ var require_stream_readable = __commonJS({
35563
35575
  }
35564
35576
  return readableAddChunk(this, chunk, encoding, false, skipChunkCheck);
35565
35577
  };
35566
- Readable3.prototype.unshift = function(chunk) {
35578
+ Readable4.prototype.unshift = function(chunk) {
35567
35579
  return readableAddChunk(this, chunk, null, true, false);
35568
35580
  };
35569
35581
  function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) {
@@ -35623,10 +35635,10 @@ var require_stream_readable = __commonJS({
35623
35635
  function needMoreData(state) {
35624
35636
  return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0);
35625
35637
  }
35626
- Readable3.prototype.isPaused = function() {
35638
+ Readable4.prototype.isPaused = function() {
35627
35639
  return this._readableState.flowing === false;
35628
35640
  };
35629
- Readable3.prototype.setEncoding = function(enc) {
35641
+ Readable4.prototype.setEncoding = function(enc) {
35630
35642
  if (!StringDecoder2) StringDecoder2 = require_string_decoder().StringDecoder;
35631
35643
  this._readableState.decoder = new StringDecoder2(enc);
35632
35644
  this._readableState.encoding = enc;
@@ -35662,7 +35674,7 @@ var require_stream_readable = __commonJS({
35662
35674
  }
35663
35675
  return state.length;
35664
35676
  }
35665
- Readable3.prototype.read = function(n2) {
35677
+ Readable4.prototype.read = function(n2) {
35666
35678
  debug("read", n2);
35667
35679
  n2 = parseInt(n2, 10);
35668
35680
  var state = this._readableState;
@@ -35757,10 +35769,10 @@ var require_stream_readable = __commonJS({
35757
35769
  }
35758
35770
  state.readingMore = false;
35759
35771
  }
35760
- Readable3.prototype._read = function(n2) {
35772
+ Readable4.prototype._read = function(n2) {
35761
35773
  this.emit("error", new Error("_read() is not implemented"));
35762
35774
  };
35763
- Readable3.prototype.pipe = function(dest, pipeOpts) {
35775
+ Readable4.prototype.pipe = function(dest, pipeOpts) {
35764
35776
  var src = this;
35765
35777
  var state = this._readableState;
35766
35778
  switch (state.pipesCount) {
@@ -35865,7 +35877,7 @@ var require_stream_readable = __commonJS({
35865
35877
  }
35866
35878
  };
35867
35879
  }
35868
- Readable3.prototype.unpipe = function(dest) {
35880
+ Readable4.prototype.unpipe = function(dest) {
35869
35881
  var state = this._readableState;
35870
35882
  var unpipeInfo = { hasUnpiped: false };
35871
35883
  if (state.pipesCount === 0) return this;
@@ -35897,7 +35909,7 @@ var require_stream_readable = __commonJS({
35897
35909
  dest.emit("unpipe", this, unpipeInfo);
35898
35910
  return this;
35899
35911
  };
35900
- Readable3.prototype.on = function(ev, fn) {
35912
+ Readable4.prototype.on = function(ev, fn) {
35901
35913
  var res = Stream.prototype.on.call(this, ev, fn);
35902
35914
  if (ev === "data") {
35903
35915
  if (this._readableState.flowing !== false) this.resume();
@@ -35915,12 +35927,12 @@ var require_stream_readable = __commonJS({
35915
35927
  }
35916
35928
  return res;
35917
35929
  };
35918
- Readable3.prototype.addListener = Readable3.prototype.on;
35930
+ Readable4.prototype.addListener = Readable4.prototype.on;
35919
35931
  function nReadingNextTick(self2) {
35920
35932
  debug("readable nexttick read 0");
35921
35933
  self2.read(0);
35922
35934
  }
35923
- Readable3.prototype.resume = function() {
35935
+ Readable4.prototype.resume = function() {
35924
35936
  var state = this._readableState;
35925
35937
  if (!state.flowing) {
35926
35938
  debug("resume");
@@ -35946,7 +35958,7 @@ var require_stream_readable = __commonJS({
35946
35958
  flow(stream);
35947
35959
  if (state.flowing && !state.reading) stream.read(0);
35948
35960
  }
35949
- Readable3.prototype.pause = function() {
35961
+ Readable4.prototype.pause = function() {
35950
35962
  debug("call pause flowing=%j", this._readableState.flowing);
35951
35963
  if (false !== this._readableState.flowing) {
35952
35964
  debug("pause");
@@ -35961,7 +35973,7 @@ var require_stream_readable = __commonJS({
35961
35973
  while (state.flowing && stream.read() !== null) {
35962
35974
  }
35963
35975
  }
35964
- Readable3.prototype.wrap = function(stream) {
35976
+ Readable4.prototype.wrap = function(stream) {
35965
35977
  var _this = this;
35966
35978
  var state = this._readableState;
35967
35979
  var paused = false;
@@ -36005,7 +36017,7 @@ var require_stream_readable = __commonJS({
36005
36017
  };
36006
36018
  return this;
36007
36019
  };
36008
- Object.defineProperty(Readable3.prototype, "readableHighWaterMark", {
36020
+ Object.defineProperty(Readable4.prototype, "readableHighWaterMark", {
36009
36021
  // making it explicit this property is not enumerable
36010
36022
  // because otherwise some prototype manipulation in
36011
36023
  // userland will fail
@@ -36014,7 +36026,7 @@ var require_stream_readable = __commonJS({
36014
36026
  return this._readableState.highWaterMark;
36015
36027
  }
36016
36028
  });
36017
- Readable3._fromList = fromList;
36029
+ Readable4._fromList = fromList;
36018
36030
  function fromList(n2, state) {
36019
36031
  if (state.length === 0) return null;
36020
36032
  var ret;
@@ -36123,11 +36135,11 @@ var require_stream_readable = __commonJS({
36123
36135
  var require_stream_transform = __commonJS({
36124
36136
  "../node_modules/.pnpm/readable-stream@2.3.8/node_modules/readable-stream/lib/_stream_transform.js"(exports2, module2) {
36125
36137
  "use strict";
36126
- module2.exports = Transform;
36138
+ module2.exports = Transform2;
36127
36139
  var Duplex = require_stream_duplex();
36128
36140
  var util2 = Object.create(require_util());
36129
36141
  util2.inherits = require_inherits();
36130
- util2.inherits(Transform, Duplex);
36142
+ util2.inherits(Transform2, Duplex);
36131
36143
  function afterTransform(er2, data) {
36132
36144
  var ts = this._transformState;
36133
36145
  ts.transforming = false;
@@ -36146,8 +36158,8 @@ var require_stream_transform = __commonJS({
36146
36158
  this._read(rs.highWaterMark);
36147
36159
  }
36148
36160
  }
36149
- function Transform(options) {
36150
- if (!(this instanceof Transform)) return new Transform(options);
36161
+ function Transform2(options) {
36162
+ if (!(this instanceof Transform2)) return new Transform2(options);
36151
36163
  Duplex.call(this, options);
36152
36164
  this._transformState = {
36153
36165
  afterTransform: afterTransform.bind(this),
@@ -36175,14 +36187,14 @@ var require_stream_transform = __commonJS({
36175
36187
  done(this, null, null);
36176
36188
  }
36177
36189
  }
36178
- Transform.prototype.push = function(chunk, encoding) {
36190
+ Transform2.prototype.push = function(chunk, encoding) {
36179
36191
  this._transformState.needTransform = false;
36180
36192
  return Duplex.prototype.push.call(this, chunk, encoding);
36181
36193
  };
36182
- Transform.prototype._transform = function(chunk, encoding, cb) {
36194
+ Transform2.prototype._transform = function(chunk, encoding, cb) {
36183
36195
  throw new Error("_transform() is not implemented");
36184
36196
  };
36185
- Transform.prototype._write = function(chunk, encoding, cb) {
36197
+ Transform2.prototype._write = function(chunk, encoding, cb) {
36186
36198
  var ts = this._transformState;
36187
36199
  ts.writecb = cb;
36188
36200
  ts.writechunk = chunk;
@@ -36192,7 +36204,7 @@ var require_stream_transform = __commonJS({
36192
36204
  if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);
36193
36205
  }
36194
36206
  };
36195
- Transform.prototype._read = function(n2) {
36207
+ Transform2.prototype._read = function(n2) {
36196
36208
  var ts = this._transformState;
36197
36209
  if (ts.writechunk !== null && ts.writecb && !ts.transforming) {
36198
36210
  ts.transforming = true;
@@ -36201,7 +36213,7 @@ var require_stream_transform = __commonJS({
36201
36213
  ts.needTransform = true;
36202
36214
  }
36203
36215
  };
36204
- Transform.prototype._destroy = function(err, cb) {
36216
+ Transform2.prototype._destroy = function(err, cb) {
36205
36217
  var _this2 = this;
36206
36218
  Duplex.prototype._destroy.call(this, err, function(err2) {
36207
36219
  cb(err2);
@@ -36224,13 +36236,13 @@ var require_stream_passthrough = __commonJS({
36224
36236
  "../node_modules/.pnpm/readable-stream@2.3.8/node_modules/readable-stream/lib/_stream_passthrough.js"(exports2, module2) {
36225
36237
  "use strict";
36226
36238
  module2.exports = PassThrough;
36227
- var Transform = require_stream_transform();
36239
+ var Transform2 = require_stream_transform();
36228
36240
  var util2 = Object.create(require_util());
36229
36241
  util2.inherits = require_inherits();
36230
- util2.inherits(PassThrough, Transform);
36242
+ util2.inherits(PassThrough, Transform2);
36231
36243
  function PassThrough(options) {
36232
36244
  if (!(this instanceof PassThrough)) return new PassThrough(options);
36233
- Transform.call(this, options);
36245
+ Transform2.call(this, options);
36234
36246
  }
36235
36247
  PassThrough.prototype._transform = function(chunk, encoding, cb) {
36236
36248
  cb(null, chunk);
@@ -37159,8 +37171,8 @@ var require_utils = __commonJS({
37159
37171
  var result = transform[inputType][outputType](input);
37160
37172
  return result;
37161
37173
  };
37162
- exports2.resolve = function(path100) {
37163
- var parts = path100.split("/");
37174
+ exports2.resolve = function(path101) {
37175
+ var parts = path101.split("/");
37164
37176
  var result = [];
37165
37177
  for (var index = 0; index < parts.length; index++) {
37166
37178
  var part = parts[index];
@@ -37713,11 +37725,11 @@ var require_ConvertWorker = __commonJS({
37713
37725
  var require_NodejsStreamOutputAdapter = __commonJS({
37714
37726
  "../node_modules/.pnpm/jszip@3.10.1/node_modules/jszip/lib/nodejs/NodejsStreamOutputAdapter.js"(exports2, module2) {
37715
37727
  "use strict";
37716
- var Readable3 = require_readable().Readable;
37728
+ var Readable4 = require_readable().Readable;
37717
37729
  var utils = require_utils();
37718
- utils.inherits(NodejsStreamOutputAdapter, Readable3);
37730
+ utils.inherits(NodejsStreamOutputAdapter, Readable4);
37719
37731
  function NodejsStreamOutputAdapter(helper, options, updateCb) {
37720
- Readable3.call(this, options);
37732
+ Readable4.call(this, options);
37721
37733
  this._helper = helper;
37722
37734
  var self2 = this;
37723
37735
  helper.on("data", function(data, meta) {
@@ -43013,18 +43025,18 @@ var require_object = __commonJS({
43013
43025
  var object = new ZipObject(name, zipObjectContent, o2);
43014
43026
  this.files[name] = object;
43015
43027
  };
43016
- var parentFolder = function(path100) {
43017
- if (path100.slice(-1) === "/") {
43018
- path100 = path100.substring(0, path100.length - 1);
43028
+ var parentFolder = function(path101) {
43029
+ if (path101.slice(-1) === "/") {
43030
+ path101 = path101.substring(0, path101.length - 1);
43019
43031
  }
43020
- var lastSlash = path100.lastIndexOf("/");
43021
- return lastSlash > 0 ? path100.substring(0, lastSlash) : "";
43032
+ var lastSlash = path101.lastIndexOf("/");
43033
+ return lastSlash > 0 ? path101.substring(0, lastSlash) : "";
43022
43034
  };
43023
- var forceTrailingSlash = function(path100) {
43024
- if (path100.slice(-1) !== "/") {
43025
- path100 += "/";
43035
+ var forceTrailingSlash = function(path101) {
43036
+ if (path101.slice(-1) !== "/") {
43037
+ path101 += "/";
43026
43038
  }
43027
- return path100;
43039
+ return path101;
43028
43040
  };
43029
43041
  var folderAdd = function(name, createFolders) {
43030
43042
  createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
@@ -44026,7 +44038,7 @@ var require_lib3 = __commonJS({
44026
44038
  // src/run-case/recorder.ts
44027
44039
  function startRunCaseRecorder(opts) {
44028
44040
  const now = opts.now ?? Date.now;
44029
- const dir = import_node_path79.default.dirname(opts.recordPath);
44041
+ const dir = import_node_path80.default.dirname(opts.recordPath);
44030
44042
  let stream = null;
44031
44043
  let closing = false;
44032
44044
  let closedSettled = false;
@@ -44040,8 +44052,8 @@ function startRunCaseRecorder(opts) {
44040
44052
  });
44041
44053
  const ensureStream = () => {
44042
44054
  if (stream) return stream;
44043
- import_node_fs61.default.mkdirSync(dir, { recursive: true });
44044
- stream = import_node_fs61.default.createWriteStream(opts.recordPath, { flags: "a" });
44055
+ import_node_fs62.default.mkdirSync(dir, { recursive: true });
44056
+ stream = import_node_fs62.default.createWriteStream(opts.recordPath, { flags: "a" });
44045
44057
  stream.on("close", () => closedResolve());
44046
44058
  return stream;
44047
44059
  };
@@ -44066,12 +44078,12 @@ function startRunCaseRecorder(opts) {
44066
44078
  };
44067
44079
  return { tap, close, closed };
44068
44080
  }
44069
- var import_node_fs61, import_node_path79;
44081
+ var import_node_fs62, import_node_path80;
44070
44082
  var init_recorder = __esm({
44071
44083
  "src/run-case/recorder.ts"() {
44072
44084
  "use strict";
44073
- import_node_fs61 = __toESM(require("fs"), 1);
44074
- import_node_path79 = __toESM(require("path"), 1);
44085
+ import_node_fs62 = __toESM(require("fs"), 1);
44086
+ import_node_path80 = __toESM(require("path"), 1);
44075
44087
  }
44076
44088
  });
44077
44089
 
@@ -44114,7 +44126,7 @@ var init_wire = __esm({
44114
44126
  // src/run-case/controller.ts
44115
44127
  async function runController(opts) {
44116
44128
  const now = opts.now ?? Date.now;
44117
- const cwd = opts.cwd ?? (0, import_node_fs62.mkdtempSync)(import_node_path80.default.join(import_node_os29.default.tmpdir(), "clawd-runcase-"));
44129
+ const cwd = opts.cwd ?? (0, import_node_fs63.mkdtempSync)(import_node_path81.default.join(import_node_os30.default.tmpdir(), "clawd-runcase-"));
44118
44130
  const ownsCwd = opts.cwd === void 0;
44119
44131
  const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
44120
44132
  const spawnCtx = { cwd };
@@ -44275,19 +44287,19 @@ async function runController(opts) {
44275
44287
  if (sigintHandler) process.off("SIGINT", sigintHandler);
44276
44288
  if (ownsCwd) {
44277
44289
  try {
44278
- (0, import_node_fs62.rmSync)(cwd, { recursive: true, force: true });
44290
+ (0, import_node_fs63.rmSync)(cwd, { recursive: true, force: true });
44279
44291
  } catch {
44280
44292
  }
44281
44293
  }
44282
44294
  return exitCode ?? 0;
44283
44295
  }
44284
- var import_node_fs62, import_node_os29, import_node_path80;
44296
+ var import_node_fs63, import_node_os30, import_node_path81;
44285
44297
  var init_controller = __esm({
44286
44298
  "src/run-case/controller.ts"() {
44287
44299
  "use strict";
44288
- import_node_fs62 = require("fs");
44289
- import_node_os29 = __toESM(require("os"), 1);
44290
- import_node_path80 = __toESM(require("path"), 1);
44300
+ import_node_fs63 = require("fs");
44301
+ import_node_os30 = __toESM(require("os"), 1);
44302
+ import_node_path81 = __toESM(require("path"), 1);
44291
44303
  init_claude();
44292
44304
  init_stdout_splitter();
44293
44305
  init_permission_stdio();
@@ -44559,10 +44571,10 @@ Env (advanced):
44559
44571
  `;
44560
44572
 
44561
44573
  // src/index.ts
44562
- var import_node_path78 = __toESM(require("path"), 1);
44563
- var import_node_fs60 = __toESM(require("fs"), 1);
44564
- var import_node_os28 = __toESM(require("os"), 1);
44565
- var import_node_crypto24 = require("crypto");
44574
+ var import_node_path79 = __toESM(require("path"), 1);
44575
+ var import_node_fs61 = __toESM(require("fs"), 1);
44576
+ var import_node_os29 = __toESM(require("os"), 1);
44577
+ var import_node_crypto25 = require("crypto");
44566
44578
  var import_node_url5 = require("url");
44567
44579
 
44568
44580
  // src/logger.ts
@@ -51873,8 +51885,8 @@ function turnStartInput(text, resolveImage) {
51873
51885
  const items = [];
51874
51886
  let leftover = text;
51875
51887
  for (const m3 of text.matchAll(SKILL_RE)) {
51876
- const [marker, name, path100] = m3;
51877
- items.push({ type: "skill", name, path: path100 });
51888
+ const [marker, name, path101] = m3;
51889
+ items.push({ type: "skill", name, path: path101 });
51878
51890
  leftover = leftover.replace(marker, "");
51879
51891
  }
51880
51892
  for (const m3 of text.matchAll(ATTACHMENT_RE2)) {
@@ -55654,7 +55666,7 @@ function replaceScan(file, entry) {
55654
55666
  function emptyDeployFile() {
55655
55667
  return { version: 1, manifest: { version: 1, packages: [], secrets: [], connectors: [] } };
55656
55668
  }
55657
- var PackageFindingSchema = EnvPackageSchema.omit({ localVersion: true, artifact: true }).extend({
55669
+ var PackageFindingSchema = EnvPackageSchema.omit({ localVersion: true, artifact: true, aptMissing: true, aptVersion: true }).extend({
55658
55670
  artifact: external_exports.object({ url: external_exports.string().url(), bin: external_exports.string() }).strict().optional()
55659
55671
  });
55660
55672
  var FINDING_SCHEMAS = {
@@ -55695,6 +55707,14 @@ function requiredEnvNames(manifest) {
55695
55707
  }
55696
55708
 
55697
55709
  // src/deploy/artifact.ts
55710
+ var import_node_crypto9 = require("crypto");
55711
+ var import_node_fs30 = __toESM(require("fs"), 1);
55712
+ var import_node_os10 = __toESM(require("os"), 1);
55713
+ var import_node_path34 = __toESM(require("path"), 1);
55714
+ var import_node_stream3 = require("stream");
55715
+ var import_promises5 = require("stream/promises");
55716
+ var ARTIFACT_MAX_BYTES = 200 * 1024 * 1024;
55717
+ var ARTIFACT_TIMEOUT_MS = 6e4;
55698
55718
  function artifactKind(url, bin) {
55699
55719
  const u2 = new URL(url);
55700
55720
  if (u2.protocol !== "https:") throw new Error(`\u8D44\u4EA7\u53EA\u6536 https \u76F4\u94FE\uFF1A${url}`);
@@ -55706,10 +55726,98 @@ function artifactKind(url, bin) {
55706
55726
  if (bin === "") return "bare";
55707
55727
  throw new Error(`\u8D44\u4EA7\u53EA\u8BA4 .tar.gz / .tgz\uFF0C\u6216\u88F8\u4E8C\u8FDB\u5236\uFF08bin \u7559\u7A7A\uFF09\uFF1A${url}`);
55708
55728
  }
55729
+ async function verifyArtifact(fetchArtifact, a2) {
55730
+ const kind = artifactKind(a2.url, a2.bin);
55731
+ const got = await fetchArtifact(a2.url, { listEntries: kind === "tgz" });
55732
+ if (kind === "tgz") {
55733
+ const names = (got.entries ?? []).map((e) => e.replace(/^\.\//, ""));
55734
+ if (!names.includes(a2.bin)) {
55735
+ const shown = names.slice(0, 10).join(", ") + (names.length > 10 ? "\u2026" : "");
55736
+ throw new Error(`\u538B\u7F29\u5305\u91CC\u6CA1\u6709 \`${a2.bin}\`\uFF1A${a2.url}\uFF08\u5305\u91CC\u6709\uFF1A${shown}\uFF09`);
55737
+ }
55738
+ }
55739
+ return { sha256: got.sha256, size: got.size };
55740
+ }
55741
+ function downloadArtifact(exec) {
55742
+ return async (url, { listEntries }) => {
55743
+ const res = await fetch(url, { signal: AbortSignal.timeout(ARTIFACT_TIMEOUT_MS), redirect: "follow" });
55744
+ if (!res.ok || !res.body) throw new Error(`\u4E0B\u8F7D\u5931\u8D25 HTTP ${res.status}\uFF1A${url}`);
55745
+ const declared = Number(res.headers.get("content-length") ?? 0);
55746
+ if (declared > ARTIFACT_MAX_BYTES) throw new Error(`\u8D44\u4EA7 ${declared} \u5B57\u8282\uFF0C\u8D85\u8FC7\u4E0A\u9650 ${ARTIFACT_MAX_BYTES}\uFF1A${url}`);
55747
+ const dir = await import_node_fs30.default.promises.mkdtemp(import_node_path34.default.join(import_node_os10.default.tmpdir(), "clawd-artifact-"));
55748
+ const file = import_node_path34.default.join(dir, "pkg");
55749
+ const hash = (0, import_node_crypto9.createHash)("sha256");
55750
+ let size = 0;
55751
+ const meter = new import_node_stream3.Transform({
55752
+ transform(chunk, _enc, cb) {
55753
+ size += chunk.length;
55754
+ if (size > ARTIFACT_MAX_BYTES) return cb(new Error(`\u8D44\u4EA7\u8D85\u8FC7\u4E0A\u9650 ${ARTIFACT_MAX_BYTES} \u5B57\u8282\uFF1A${url}`));
55755
+ hash.update(chunk);
55756
+ cb(null, chunk);
55757
+ }
55758
+ });
55759
+ try {
55760
+ await (0, import_promises5.pipeline)(import_node_stream3.Readable.fromWeb(res.body), meter, import_node_fs30.default.createWriteStream(file));
55761
+ let entries;
55762
+ if (listEntries) {
55763
+ const r2 = await exec("tar", ["-tzf", file], { timeoutMs: 3e4 });
55764
+ if (r2.code !== 0) throw new Error(`\u4E0D\u662F\u5408\u6CD5\u7684 tar.gz\uFF1A${url}\uFF08${r2.stderr.trim()}\uFF09`);
55765
+ entries = r2.stdout.split("\n").filter(Boolean);
55766
+ }
55767
+ return { sha256: hash.digest("hex"), size, ...entries ? { entries } : {} };
55768
+ } finally {
55769
+ await import_node_fs30.default.promises.rm(dir, { recursive: true, force: true });
55770
+ }
55771
+ };
55772
+ }
55773
+
55774
+ // src/deploy/debian-apt.ts
55775
+ var DEBIAN_SUITE = "bookworm";
55776
+ var MADISON_TIMEOUT_MS = 1e4;
55777
+ function aptPackageName(from) {
55778
+ const m3 = /^apt:([A-Za-z0-9][A-Za-z0-9+.-]*)$/.exec(from ?? "");
55779
+ return m3?.[1];
55780
+ }
55781
+ function madisonUrl(pkg, suite = DEBIAN_SUITE) {
55782
+ return `https://api.ftp-master.debian.org/madison?package=${encodeURIComponent(pkg)}&s=${encodeURIComponent(suite)}&a=amd64,all&text=on`;
55783
+ }
55784
+ function upstreamVersion(debianVersion) {
55785
+ const noEpoch = debianVersion.replace(/^\d+:/, "");
55786
+ const m3 = /^(\d+\.\d+(?:\.\d+)?)(?:[-+~]|$)/.exec(noEpoch);
55787
+ return m3?.[1];
55788
+ }
55789
+ function parseMadison(text, pkg) {
55790
+ for (const line of String(text).split("\n")) {
55791
+ const cols = line.split("|").map((s2) => s2.trim());
55792
+ if (cols.length < 3 || cols[0] !== pkg || !cols[1]) continue;
55793
+ return { debianVersion: cols[1], upstream: upstreamVersion(cols[1]) };
55794
+ }
55795
+ return void 0;
55796
+ }
55797
+ function gteVersion(a2, b3) {
55798
+ const A4 = a2.split(".").map(Number);
55799
+ const B3 = b3.split(".").map(Number);
55800
+ for (let i2 = 0; i2 < Math.max(A4.length, B3.length); i2++) {
55801
+ const x2 = A4[i2] ?? 0;
55802
+ const y3 = B3[i2] ?? 0;
55803
+ if (x2 !== y3) return x2 > y3;
55804
+ }
55805
+ return true;
55806
+ }
55807
+ function lookupDebianPackage(fetchFn = fetch) {
55808
+ return async (pkg) => {
55809
+ const res = await fetchFn(madisonUrl(pkg), { signal: AbortSignal.timeout(MADISON_TIMEOUT_MS) });
55810
+ if (!res.ok) throw new Error(`madison HTTP ${res.status}`);
55811
+ return parseMadison(await res.text(), pkg);
55812
+ };
55813
+ }
55814
+
55815
+ // src/handlers/deploy.ts
55816
+ init_protocol();
55709
55817
 
55710
55818
  // src/deploy/repo.ts
55711
- var import_promises5 = __toESM(require("fs/promises"), 1);
55712
- var import_node_path34 = __toESM(require("path"), 1);
55819
+ var import_promises6 = __toESM(require("fs/promises"), 1);
55820
+ var import_node_path35 = __toESM(require("path"), 1);
55713
55821
  init_protocol();
55714
55822
 
55715
55823
  // ../node_modules/.pnpm/libsodium@0.8.4/node_modules/libsodium/dist/modules-esm/libsodium.mjs
@@ -59170,10 +59278,10 @@ function createGithubApi(args) {
59170
59278
  const doFetch = args.fetch ?? fetch;
59171
59279
  const seal = args.seal ?? sealWithSodium;
59172
59280
  const timeoutMs = args.timeoutMs ?? TIMEOUT_MS;
59173
- async function request(method, path100, body) {
59281
+ async function request(method, path101, body) {
59174
59282
  let res;
59175
59283
  try {
59176
- res = await doFetch(`${API}${path100}`, {
59284
+ res = await doFetch(`${API}${path101}`, {
59177
59285
  method,
59178
59286
  headers: {
59179
59287
  Authorization: `Bearer ${args.token}`,
@@ -59198,8 +59306,8 @@ function createGithubApi(args) {
59198
59306
  }
59199
59307
  return { status: res.status, json };
59200
59308
  }
59201
- async function must(method, path100, what, body) {
59202
- const r2 = await request(method, path100, body);
59309
+ async function must(method, path101, what, body) {
59310
+ const r2 = await request(method, path101, body);
59203
59311
  if (r2.status < 200 || r2.status >= 300) throw new GithubApiError(r2.status, explain(r2.status, what, r2.json));
59204
59312
  return r2.json;
59205
59313
  }
@@ -59239,9 +59347,9 @@ function createGithubApi(args) {
59239
59347
  return { env: x2.name, ...Number.isFinite(at3) ? { setAt: at3 } : {} };
59240
59348
  });
59241
59349
  },
59242
- async getJson(path100) {
59350
+ async getJson(path101) {
59243
59351
  try {
59244
- const r2 = await request("GET", path100);
59352
+ const r2 = await request("GET", path101);
59245
59353
  return r2.status >= 200 && r2.status < 300 ? r2.json : void 0;
59246
59354
  } catch {
59247
59355
  return void 0;
@@ -59606,7 +59714,7 @@ var runCommand = (cmd, args, opts = {}) => new Promise((resolve9) => {
59606
59714
  });
59607
59715
 
59608
59716
  // src/deploy/repo.ts
59609
- var DEPLOY_FILE_REL = DEPLOY_FILE.split(import_node_path34.default.sep).join("/");
59717
+ var DEPLOY_FILE_REL = DEPLOY_FILE.split(import_node_path35.default.sep).join("/");
59610
59718
  var PERSONA_FILE_REL = ".clawd/persona.json";
59611
59719
  var DIRTY_IGNORED = [DEPLOY_FILE_REL, PERSONA_FILE_REL];
59612
59720
  var RepoError = class extends Error {
@@ -59643,9 +59751,9 @@ async function isToplevel(exec, dir) {
59643
59751
  async function samePath(a2, b3) {
59644
59752
  const real = async (x2) => {
59645
59753
  try {
59646
- return await import_promises5.default.realpath(x2);
59754
+ return await import_promises6.default.realpath(x2);
59647
59755
  } catch {
59648
- return import_node_path34.default.resolve(x2);
59756
+ return import_node_path35.default.resolve(x2);
59649
59757
  }
59650
59758
  };
59651
59759
  return await real(a2) === await real(b3);
@@ -59671,23 +59779,23 @@ async function identityArgs(exec, dir) {
59671
59779
  return ["-c", "user.name=clawd", "-c", "user.email=clawd@clawos.local"];
59672
59780
  }
59673
59781
  async function writeGitignore(dir) {
59674
- const gi = import_node_path34.default.join(dir, ".gitignore");
59782
+ const gi = import_node_path35.default.join(dir, ".gitignore");
59675
59783
  let existing;
59676
59784
  try {
59677
- existing = await import_promises5.default.readFile(gi, "utf8");
59785
+ existing = await import_promises6.default.readFile(gi, "utf8");
59678
59786
  } catch {
59679
59787
  existing = void 0;
59680
59788
  }
59681
- await import_promises5.default.writeFile(gi, mergeGitignore(existing));
59789
+ await import_promises6.default.writeFile(gi, mergeGitignore(existing));
59682
59790
  }
59683
59791
  async function writeWorkflow(dir) {
59684
- const wf = import_node_path34.default.join(dir, WORKFLOW_PATH);
59685
- await import_promises5.default.mkdir(import_node_path34.default.dirname(wf), { recursive: true });
59686
- await import_promises5.default.writeFile(wf, WORKFLOW_TEMPLATE);
59792
+ const wf = import_node_path35.default.join(dir, WORKFLOW_PATH);
59793
+ await import_promises6.default.mkdir(import_node_path35.default.dirname(wf), { recursive: true });
59794
+ await import_promises6.default.writeFile(wf, WORKFLOW_TEMPLATE);
59687
59795
  }
59688
59796
  async function writeDockerfile(dir, personaId2) {
59689
- await import_promises5.default.writeFile(import_node_path34.default.join(dir, DOCKERFILE_PATH), renderDockerfile(personaId2));
59690
- await import_promises5.default.writeFile(import_node_path34.default.join(dir, DOCKERIGNORE_PATH), DOCKERIGNORE_TEMPLATE);
59797
+ await import_promises6.default.writeFile(import_node_path35.default.join(dir, DOCKERFILE_PATH), renderDockerfile(personaId2));
59798
+ await import_promises6.default.writeFile(import_node_path35.default.join(dir, DOCKERIGNORE_PATH), DOCKERIGNORE_TEMPLATE);
59691
59799
  }
59692
59800
  var RepoAlreadyExistsError = class extends RepoError {
59693
59801
  constructor(slug) {
@@ -59724,7 +59832,7 @@ async function ensureRepo(exec, api, args) {
59724
59832
  const existing = await repoInfo(exec, dir);
59725
59833
  if (existing) return { created: false, url: existing.url };
59726
59834
  await writeGitignore(dir);
59727
- await import_promises5.default.rm(import_node_path34.default.join(dir, WORKFLOW_PATH), { force: true });
59835
+ await import_promises6.default.rm(import_node_path35.default.join(dir, WORKFLOW_PATH), { force: true });
59728
59836
  let created;
59729
59837
  try {
59730
59838
  created = await createOrgRepo(exec, api, { dir, org, repoName: personaId2, message: "clawd: \u4E0A\u4E91", auth: args.auth });
@@ -60111,18 +60219,43 @@ function buildDeployHandlers(deps) {
60111
60219
  };
60112
60220
  async function settlePackage(pkg) {
60113
60221
  const localVersion = await deps.probeLocalVersion(pkg);
60114
- const version2 = localVersion ?? pkg.version;
60115
60222
  const { artifact: reported, ...rest } = pkg;
60223
+ if (pkg.from?.startsWith("apt:")) {
60224
+ if (reported) throw invalid(`\`${pkg.name}\` \u662F apt \u6761\u76EE\uFF0C\u4E0D\u5E26 artifact\uFF08\u90A3\u662F github: \u4E13\u7528\uFF09`);
60225
+ return settleApt(aptPackageName(pkg.from), rest, localVersion, pkg.min);
60226
+ }
60227
+ const version2 = localVersion ?? pkg.version;
60116
60228
  const out = { ...rest, ...version2 ? { version: version2 } : {}, ...localVersion ? { localVersion } : {} };
60117
60229
  if (!reported) return out;
60118
60230
  if (!pkg.version) throw invalid(`\u9489\u8D44\u4EA7\u8981\u5148\u8BF4\u6E05\u662F\u54EA\u4E2A\u7248\u672C\u7684\uFF1A\`${pkg.name}\` \u5E26 artifact \u7684\u4E0A\u62A5\u5FC5\u987B\u540C\u65F6\u5E26 version`);
60119
60231
  if (pkg.version !== version2) throw invalid(`\u672C\u673A\u88C5\u7684 \`${pkg.name}\` \u662F ${version2}\uFF0C\u4F60\u6309 ${pkg.version} \u627E\u7684\u8D44\u4EA7\uFF1B\u6309 ${version2} \u91CD\u627E`);
60232
+ let verified;
60233
+ try {
60234
+ verified = await verifyArtifact(deps.fetchArtifact, reported);
60235
+ } catch (err) {
60236
+ throw invalid(`\`${pkg.name}\` \u7684\u8D44\u4EA7\u6838\u4E0D\u8FC7\uFF1A${err instanceof Error ? err.message : String(err)}`);
60237
+ }
60238
+ return { ...out, artifact: { ...reported, ...verified } };
60239
+ }
60240
+ async function settleApt(aptName, fields, localVersion, min) {
60241
+ const { version: _agentVersion, ...rest } = fields;
60242
+ const local = localVersion ? { localVersion } : {};
60243
+ if (CLOUD_ROOT_PROVIDES.includes(fields.name)) return { ...rest, ...local };
60244
+ if (!aptName) {
60245
+ deps.warn?.("deploy.apt.badName", { from: fields.from });
60246
+ return { ...rest, ...local };
60247
+ }
60248
+ let found;
60120
60249
  try {
60121
- artifactKind(reported.url, reported.bin);
60250
+ found = await deps.debianPackage(aptName);
60122
60251
  } catch (err) {
60123
- throw invalid(`\`${pkg.name}\` \u7684\u8D44\u4EA7\u4E0D\u5408\u5F62\u72B6\uFF1A${err instanceof Error ? err.message : String(err)}`);
60252
+ deps.warn?.("deploy.apt.lookupFailed", { pkg: aptName, error: err instanceof Error ? err.message : String(err) });
60253
+ return { ...rest, ...local };
60124
60254
  }
60125
- return { ...out, artifact: reported };
60255
+ if (!found) return { ...rest, ...local, aptMissing: true };
60256
+ const aptVersion = found.upstream ?? (found.debianVersion || void 0);
60257
+ const pin = found.upstream && !(min && !gteVersion(found.upstream, min)) ? { version: found.upstream } : {};
60258
+ return { ...rest, ...pin, ...local, ...aptVersion ? { aptVersion } : {} };
60126
60259
  }
60127
60260
  const reportFinding = async (frame, _client, ctx) => {
60128
60261
  ensureOwner(ctx);
@@ -60335,18 +60468,18 @@ async function probeLocalVersion(exec, pkg) {
60335
60468
 
60336
60469
  // src/tools/shell-path.ts
60337
60470
  var import_node_child_process10 = require("child_process");
60338
- var import_node_os10 = __toESM(require("os"), 1);
60471
+ var import_node_os11 = __toESM(require("os"), 1);
60339
60472
  function refreshPathFromLoginShell() {
60340
60473
  if (process.platform === "win32") return;
60341
- const shell = process.env.SHELL ?? import_node_os10.default.userInfo().shell ?? "/bin/zsh";
60474
+ const shell = process.env.SHELL ?? import_node_os11.default.userInfo().shell ?? "/bin/zsh";
60342
60475
  try {
60343
60476
  const out = (0, import_node_child_process10.execFileSync)(shell, ["-ilc", 'command echo -n "$PATH"'], {
60344
60477
  encoding: "utf8",
60345
60478
  timeout: 3e3,
60346
60479
  stdio: ["ignore", "pipe", "ignore"]
60347
60480
  });
60348
- const path100 = out.trim();
60349
- if (path100) process.env.PATH = path100;
60481
+ const path101 = out.trim();
60482
+ if (path101) process.env.PATH = path101;
60350
60483
  } catch {
60351
60484
  }
60352
60485
  }
@@ -60884,15 +61017,15 @@ async function refreshTunnelUrlOnStartup(deps) {
60884
61017
  }
60885
61018
 
60886
61019
  // src/lark-bot-connector/binding-store.ts
60887
- var import_node_fs30 = __toESM(require("fs"), 1);
60888
- var import_node_path35 = __toESM(require("path"), 1);
61020
+ var import_node_fs31 = __toESM(require("fs"), 1);
61021
+ var import_node_path36 = __toESM(require("path"), 1);
60889
61022
  function createLarkBotBindingStore(personaRoot) {
60890
- const filePath = (personaId2) => import_node_path35.default.join(personaRoot, safeFileName(personaId2), ".clawd", "lark-bot.json");
61023
+ const filePath = (personaId2) => import_node_path36.default.join(personaRoot, safeFileName(personaId2), ".clawd", "lark-bot.json");
60891
61024
  const read = (personaId2) => {
60892
61025
  const file = filePath(personaId2);
60893
- if (!import_node_fs30.default.existsSync(file)) return null;
61026
+ if (!import_node_fs31.default.existsSync(file)) return null;
60894
61027
  try {
60895
- const raw = JSON.parse(import_node_fs30.default.readFileSync(file, "utf8"));
61028
+ const raw = JSON.parse(import_node_fs31.default.readFileSync(file, "utf8"));
60896
61029
  if (typeof raw?.appId !== "string" || raw.appId.length === 0) return null;
60897
61030
  return raw;
60898
61031
  } catch {
@@ -60901,16 +61034,16 @@ function createLarkBotBindingStore(personaRoot) {
60901
61034
  };
60902
61035
  const write = (personaId2, meta) => {
60903
61036
  const file = filePath(personaId2);
60904
- import_node_fs30.default.mkdirSync(import_node_path35.default.dirname(file), { recursive: true });
61037
+ import_node_fs31.default.mkdirSync(import_node_path36.default.dirname(file), { recursive: true });
60905
61038
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
60906
- import_node_fs30.default.writeFileSync(tmp, JSON.stringify(meta, null, 2), { mode: 384 });
60907
- import_node_fs30.default.renameSync(tmp, file);
61039
+ import_node_fs31.default.writeFileSync(tmp, JSON.stringify(meta, null, 2), { mode: 384 });
61040
+ import_node_fs31.default.renameSync(tmp, file);
60908
61041
  };
60909
61042
  return {
60910
61043
  read,
60911
61044
  write,
60912
61045
  remove(personaId2) {
60913
- import_node_fs30.default.rmSync(filePath(personaId2), { force: true });
61046
+ import_node_fs31.default.rmSync(filePath(personaId2), { force: true });
60914
61047
  },
60915
61048
  addRemovedChat(personaId2, chatId) {
60916
61049
  const meta = read(personaId2);
@@ -61062,8 +61195,8 @@ function createLarkBotCloudClient(opts) {
61062
61195
  }
61063
61196
 
61064
61197
  // src/lark-bot-connector/chat-router.ts
61065
- var import_node_fs31 = __toESM(require("fs"), 1);
61066
- var import_node_path36 = __toESM(require("path"), 1);
61198
+ var import_node_fs32 = __toESM(require("fs"), 1);
61199
+ var import_node_path37 = __toESM(require("path"), 1);
61067
61200
  init_protocol();
61068
61201
  var ERROR_REPLY_TEXT = "\u5904\u7406\u51FA\u9519\u4E86\uFF0C\u8BF7\u91CD\u8BD5";
61069
61202
  var LOCAL_TURN_RETRIES = 2;
@@ -61141,9 +61274,9 @@ function createLarkChatRouter(deps) {
61141
61274
  continue;
61142
61275
  }
61143
61276
  const dir = deps.mediaRootFor(env.chatId);
61144
- import_node_fs31.default.mkdirSync(dir, { recursive: true });
61145
- const p3 = import_node_path36.default.join(dir, `${safeMediaName(ownerMessageId)}-${i2}.${ext}`);
61146
- import_node_fs31.default.writeFileSync(p3, r2.data);
61277
+ import_node_fs32.default.mkdirSync(dir, { recursive: true });
61278
+ const p3 = import_node_path37.default.join(dir, `${safeMediaName(ownerMessageId)}-${i2}.${ext}`);
61279
+ import_node_fs32.default.writeFileSync(p3, r2.data);
61147
61280
  lines.push(`[\u56FE\u7247: ${p3}]\uFF08\u7528 Read \u5DE5\u5177\u67E5\u770B\uFF09`);
61148
61281
  } catch (err) {
61149
61282
  deps.logger?.warn(`larkBot image fetch failed ${key}: ${err.message}`);
@@ -61164,9 +61297,9 @@ function createLarkChatRouter(deps) {
61164
61297
  continue;
61165
61298
  }
61166
61299
  const dir = deps.mediaRootFor(env.chatId);
61167
- import_node_fs31.default.mkdirSync(dir, { recursive: true });
61168
- const p3 = import_node_path36.default.join(dir, `${safeMediaName(ownerMessageId)}-${i2}-${safeAttachmentName(f2.name)}`);
61169
- import_node_fs31.default.writeFileSync(p3, r2.data);
61300
+ import_node_fs32.default.mkdirSync(dir, { recursive: true });
61301
+ const p3 = import_node_path37.default.join(dir, `${safeMediaName(ownerMessageId)}-${i2}-${safeAttachmentName(f2.name)}`);
61302
+ import_node_fs32.default.writeFileSync(p3, r2.data);
61170
61303
  lines.push(`[\u6587\u4EF6: ${p3}]\uFF08\u7528 Read \u5DE5\u5177\u67E5\u770B\uFF09`);
61171
61304
  } catch (err) {
61172
61305
  deps.logger?.warn(`larkBot file fetch failed ${f2.key}: ${err.message}`);
@@ -61380,7 +61513,7 @@ ${formatLarkSpeakerReminder(speaker)}`
61380
61513
  }
61381
61514
 
61382
61515
  // src/lark-bot-connector/envelope.ts
61383
- var import_node_crypto9 = require("crypto");
61516
+ var import_node_crypto10 = require("crypto");
61384
61517
  var LARK_ENVELOPE_PREFIX = "clawdlbe1";
61385
61518
  function verifyLarkEventEnvelope(args) {
61386
61519
  const { token, publicKeyPem } = args;
@@ -61399,7 +61532,7 @@ function verifyLarkEventEnvelope(args) {
61399
61532
  const data = Buffer.from(`${prefix}.${payloadB64}`, "utf8");
61400
61533
  let sigOk = false;
61401
61534
  try {
61402
- sigOk = (0, import_node_crypto9.verify)(null, data, publicKeyPem, Buffer.from(sigB64, "base64url"));
61535
+ sigOk = (0, import_node_crypto10.verify)(null, data, publicKeyPem, Buffer.from(sigB64, "base64url"));
61403
61536
  } catch {
61404
61537
  sigOk = false;
61405
61538
  }
@@ -61990,12 +62123,12 @@ async function forwardPeerExecToPeer(args) {
61990
62123
  }
61991
62124
 
61992
62125
  // src/tools/codex-history.ts
61993
- var import_node_fs33 = __toESM(require("fs"), 1);
61994
- var import_node_path38 = __toESM(require("path"), 1);
62126
+ var import_node_fs34 = __toESM(require("fs"), 1);
62127
+ var import_node_path39 = __toESM(require("path"), 1);
61995
62128
 
61996
62129
  // src/tools/transcript-search.ts
61997
- var import_node_fs32 = __toESM(require("fs"), 1);
61998
- var import_node_path37 = __toESM(require("path"), 1);
62130
+ var import_node_fs33 = __toESM(require("fs"), 1);
62131
+ var import_node_path38 = __toESM(require("path"), 1);
61999
62132
  var SNIPPET_PAD = 60;
62000
62133
  var INJECTED_ENVELOPE_RE = /^<(system-reminder|command-name|command-message|command-args|local-command-stdout|local-command-stderr|task-notification|user-prompt-submit-hook|environment_context|user_instructions)\b/;
62001
62134
  var CODEX_WRAPPER_RE = /<(related-dir|environment_context|user_instructions)>[\s\S]*?<\/\1>/g;
@@ -62050,7 +62183,7 @@ function makeSnippet(text, at3, needleLength) {
62050
62183
  function searchTranscriptFile(file, query) {
62051
62184
  let buf;
62052
62185
  try {
62053
- buf = import_node_fs32.default.readFileSync(file);
62186
+ buf = import_node_fs33.default.readFileSync(file);
62054
62187
  } catch {
62055
62188
  return null;
62056
62189
  }
@@ -62083,12 +62216,12 @@ function createCodexRolloutLocator(roots) {
62083
62216
  const walk2 = (dir, into) => {
62084
62217
  let entries;
62085
62218
  try {
62086
- entries = import_node_fs32.default.readdirSync(dir, { withFileTypes: true });
62219
+ entries = import_node_fs33.default.readdirSync(dir, { withFileTypes: true });
62087
62220
  } catch {
62088
62221
  return;
62089
62222
  }
62090
62223
  for (const entry of entries) {
62091
- const full = import_node_path37.default.join(dir, entry.name);
62224
+ const full = import_node_path38.default.join(dir, entry.name);
62092
62225
  if (entry.isDirectory()) {
62093
62226
  walk2(full, into);
62094
62227
  continue;
@@ -62310,18 +62443,18 @@ var TITLE_BYTES = 256 * 1024;
62310
62443
  function readHead(file, bytes) {
62311
62444
  let fd;
62312
62445
  try {
62313
- fd = import_node_fs33.default.openSync(file, "r");
62446
+ fd = import_node_fs34.default.openSync(file, "r");
62314
62447
  } catch {
62315
62448
  return null;
62316
62449
  }
62317
62450
  try {
62318
62451
  const buf = Buffer.alloc(bytes);
62319
- const n2 = import_node_fs33.default.readSync(fd, buf, 0, bytes, 0);
62452
+ const n2 = import_node_fs34.default.readSync(fd, buf, 0, bytes, 0);
62320
62453
  return buf.subarray(0, n2).toString("utf8");
62321
62454
  } catch {
62322
62455
  return null;
62323
62456
  } finally {
62324
- import_node_fs33.default.closeSync(fd);
62457
+ import_node_fs34.default.closeSync(fd);
62325
62458
  }
62326
62459
  }
62327
62460
  function peekSessionCwd(head) {
@@ -62337,7 +62470,7 @@ function peekSessionCwd(head) {
62337
62470
  function readFirstLine(file, max = 512 * 1024) {
62338
62471
  let fd;
62339
62472
  try {
62340
- fd = import_node_fs33.default.openSync(file, "r");
62473
+ fd = import_node_fs34.default.openSync(file, "r");
62341
62474
  } catch {
62342
62475
  return null;
62343
62476
  }
@@ -62346,7 +62479,7 @@ function readFirstLine(file, max = 512 * 1024) {
62346
62479
  const parts = [];
62347
62480
  let total = 0;
62348
62481
  while (total < max) {
62349
- const n2 = import_node_fs33.default.readSync(fd, chunk, 0, chunk.length, total);
62482
+ const n2 = import_node_fs34.default.readSync(fd, chunk, 0, chunk.length, total);
62350
62483
  if (n2 <= 0) break;
62351
62484
  const nl = chunk.subarray(0, n2).indexOf(10);
62352
62485
  if (nl >= 0) {
@@ -62360,7 +62493,7 @@ function readFirstLine(file, max = 512 * 1024) {
62360
62493
  } catch {
62361
62494
  return null;
62362
62495
  } finally {
62363
- import_node_fs33.default.closeSync(fd);
62496
+ import_node_fs34.default.closeSync(fd);
62364
62497
  }
62365
62498
  }
62366
62499
  function readThreadNames(sharedHome) {
@@ -62368,7 +62501,7 @@ function readThreadNames(sharedHome) {
62368
62501
  if (!sharedHome) return names;
62369
62502
  let raw;
62370
62503
  try {
62371
- raw = import_node_fs33.default.readFileSync(import_node_path38.default.join(sharedHome, "session_index.jsonl"), "utf8");
62504
+ raw = import_node_fs34.default.readFileSync(import_node_path39.default.join(sharedHome, "session_index.jsonl"), "utf8");
62372
62505
  } catch {
62373
62506
  return names;
62374
62507
  }
@@ -62387,13 +62520,13 @@ function readThreadNames(sharedHome) {
62387
62520
  function walkRollouts(dir, visit) {
62388
62521
  let entries;
62389
62522
  try {
62390
- entries = import_node_fs33.default.readdirSync(dir, { withFileTypes: true });
62523
+ entries = import_node_fs34.default.readdirSync(dir, { withFileTypes: true });
62391
62524
  } catch {
62392
62525
  return true;
62393
62526
  }
62394
62527
  entries.sort((a2, b3) => a2.name < b3.name ? 1 : a2.name > b3.name ? -1 : 0);
62395
62528
  for (const entry of entries) {
62396
- const full = import_node_path38.default.join(dir, entry.name);
62529
+ const full = import_node_path39.default.join(dir, entry.name);
62397
62530
  if (entry.isDirectory()) {
62398
62531
  if (!walkRollouts(full, visit)) return false;
62399
62532
  } else if (ROLLOUT_NAME_RE.test(entry.name)) {
@@ -62461,7 +62594,7 @@ var CodexHistoryReader = class {
62461
62594
  return [];
62462
62595
  }
62463
62596
  async listSessions(args) {
62464
- const want = import_node_path38.default.resolve(args.projectPath);
62597
+ const want = import_node_path39.default.resolve(args.projectPath);
62465
62598
  const names = readThreadNames(this.deps.sharedHome);
62466
62599
  const found = [];
62467
62600
  let scanned = 0;
@@ -62470,13 +62603,13 @@ var CodexHistoryReader = class {
62470
62603
  if (++scanned > CODEX_LIST_SESSIONS_SCAN_CAP) return false;
62471
62604
  const head = readHead(file, PEEK_BYTES);
62472
62605
  const cwd = head === null ? null : peekSessionCwd(head);
62473
- if (!cwd || import_node_path38.default.resolve(cwd) !== want) return;
62606
+ if (!cwd || import_node_path39.default.resolve(cwd) !== want) return;
62474
62607
  const first = readFirstLine(file);
62475
62608
  const meta = first === null ? null : parseCodexRolloutMeta(first);
62476
62609
  if (!meta) return;
62477
62610
  let mtimeMs;
62478
62611
  try {
62479
- mtimeMs = import_node_fs33.default.statSync(file).mtimeMs;
62612
+ mtimeMs = import_node_fs34.default.statSync(file).mtimeMs;
62480
62613
  } catch {
62481
62614
  return;
62482
62615
  }
@@ -62508,7 +62641,7 @@ var CodexHistoryReader = class {
62508
62641
  args.toolSessionId,
62509
62642
  async (agentId) => {
62510
62643
  const file = locate(agentId);
62511
- return file ? import_node_fs33.default.readFileSync(file, "utf8") : null;
62644
+ return file ? import_node_fs34.default.readFileSync(file, "utf8") : null;
62512
62645
  },
62513
62646
  this.deps.logger
62514
62647
  );
@@ -62535,7 +62668,7 @@ var CodexHistoryReader = class {
62535
62668
  parseThread(locate, threadId) {
62536
62669
  const file = locate(threadId);
62537
62670
  if (!file) throw new Error(`Codex rollout not found for thread ${threadId}`);
62538
- return parseCodexRollout(import_node_fs33.default.readFileSync(file, "utf8"));
62671
+ return parseCodexRollout(import_node_fs34.default.readFileSync(file, "utf8"));
62539
62672
  }
62540
62673
  };
62541
62674
 
@@ -62554,9 +62687,9 @@ var CentralClientError = class extends Error {
62554
62687
  code;
62555
62688
  cause;
62556
62689
  };
62557
- async function centralRequest(opts, path100, init) {
62690
+ async function centralRequest(opts, path101, init) {
62558
62691
  const f2 = opts.fetchImpl ?? globalThis.fetch;
62559
- const url = `${opts.api.replace(/\/+$/, "")}${path100}`;
62692
+ const url = `${opts.api.replace(/\/+$/, "")}${path101}`;
62560
62693
  const ctrl = new AbortController();
62561
62694
  const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
62562
62695
  let res;
@@ -63090,7 +63223,7 @@ function openHttpLineStream(opts) {
63090
63223
  init_protocol();
63091
63224
 
63092
63225
  // src/tools/codex-cloud-session.ts
63093
- var import_node_fs34 = __toESM(require("fs"), 1);
63226
+ var import_node_fs35 = __toESM(require("fs"), 1);
63094
63227
 
63095
63228
  // src/tools/codex-cloud-history.ts
63096
63229
  function personaIdFromCloudCwd(cwd) {
@@ -63208,7 +63341,7 @@ function cloudImageInput(deps) {
63208
63341
  const mime = lookupMime(p3);
63209
63342
  if (!mime.startsWith("image/")) return null;
63210
63343
  try {
63211
- const bytes = (deps.readFile ?? import_node_fs34.default.readFileSync)(p3);
63344
+ const bytes = (deps.readFile ?? import_node_fs35.default.readFileSync)(p3);
63212
63345
  return { type: "image", url: `data:${mime};base64,${bytes.toString("base64")}` };
63213
63346
  } catch (e) {
63214
63347
  deps.logger?.warn("cloud image attachment unreadable", { path: p3, message: e.message });
@@ -63338,7 +63471,7 @@ init_protocol();
63338
63471
 
63339
63472
  // src/tools/pi.ts
63340
63473
  var import_node_child_process12 = require("child_process");
63341
- var import_node_fs37 = __toESM(require("fs"), 1);
63474
+ var import_node_fs38 = __toESM(require("fs"), 1);
63342
63475
  init_protocol();
63343
63476
 
63344
63477
  // src/tools/pi-rpc-client.ts
@@ -63438,9 +63571,9 @@ var PiRpcClient = class {
63438
63571
 
63439
63572
  // src/tools/pi-session.ts
63440
63573
  var import_node_child_process11 = require("child_process");
63441
- var import_node_crypto10 = require("crypto");
63442
- var import_node_fs35 = __toESM(require("fs"), 1);
63443
- var import_node_path39 = __toESM(require("path"), 1);
63574
+ var import_node_crypto11 = require("crypto");
63575
+ var import_node_fs36 = __toESM(require("fs"), 1);
63576
+ var import_node_path40 = __toESM(require("path"), 1);
63444
63577
 
63445
63578
  // src/tools/pi-events.ts
63446
63579
  init_protocol();
@@ -63707,9 +63840,9 @@ ${dirs.map((d2) => `- ${d2}`).join("\n")}`;
63707
63840
  }
63708
63841
  function createPiSession(ctx, sink, deps = {}) {
63709
63842
  const cmd = process.env.PI_BIN ?? "pi";
63710
- const sessionId = ctx.toolSessionId ?? (0, import_node_crypto10.randomUUID)();
63711
- const skillsDir = import_node_path39.default.join(ctx.cwd, ".claude", "skills");
63712
- const exists = deps.skillsDirExists ?? ((d2) => import_node_fs35.default.existsSync(d2));
63843
+ const sessionId = ctx.toolSessionId ?? (0, import_node_crypto11.randomUUID)();
63844
+ const skillsDir = import_node_path40.default.join(ctx.cwd, ".claude", "skills");
63845
+ const exists = deps.skillsDirExists ?? ((d2) => import_node_fs36.default.existsSync(d2));
63713
63846
  const args = buildPiArgs(ctx, {
63714
63847
  sessionId,
63715
63848
  skillsDir: exists(skillsDir) ? skillsDir : void 0,
@@ -63753,45 +63886,45 @@ function createPiSession(ctx, sink, deps = {}) {
63753
63886
  }
63754
63887
 
63755
63888
  // src/tools/pi-history.ts
63756
- var import_node_fs36 = __toESM(require("fs"), 1);
63757
- var import_node_os11 = __toESM(require("os"), 1);
63758
- var import_node_path40 = __toESM(require("path"), 1);
63889
+ var import_node_fs37 = __toESM(require("fs"), 1);
63890
+ var import_node_os12 = __toESM(require("os"), 1);
63891
+ var import_node_path41 = __toESM(require("path"), 1);
63759
63892
  var PI_LIST_SESSIONS_LIMIT = 100;
63760
63893
  var PI_LIST_SESSIONS_SCAN_CAP = 4e3;
63761
63894
  function piAgentDir(env = process.env) {
63762
- return env.PI_CODING_AGENT_DIR || import_node_path40.default.join(import_node_os11.default.homedir(), ".pi", "agent");
63895
+ return env.PI_CODING_AGENT_DIR || import_node_path41.default.join(import_node_os12.default.homedir(), ".pi", "agent");
63763
63896
  }
63764
63897
  function piSessionsRoot(env = process.env) {
63765
- return import_node_path40.default.join(piAgentDir(env), "sessions");
63898
+ return import_node_path41.default.join(piAgentDir(env), "sessions");
63766
63899
  }
63767
63900
  function encodePiCwd(cwd) {
63768
63901
  return `--${cwd.replace(/^[\\/]+/, "").replace(/[\\/:]/g, "-")}--`;
63769
63902
  }
63770
63903
  function piProjectSessionDir(sessionsRoot, cwd) {
63771
- return import_node_path40.default.join(sessionsRoot, encodePiCwd(cwd));
63904
+ return import_node_path41.default.join(sessionsRoot, encodePiCwd(cwd));
63772
63905
  }
63773
63906
  function findInDir(dir, toolSessionId) {
63774
63907
  let names;
63775
63908
  try {
63776
- names = import_node_fs36.default.readdirSync(dir);
63909
+ names = import_node_fs37.default.readdirSync(dir);
63777
63910
  } catch {
63778
63911
  return null;
63779
63912
  }
63780
63913
  const suffix = `_${toolSessionId}.jsonl`;
63781
63914
  const hit = names.filter((n2) => n2.endsWith(suffix)).sort().at(-1);
63782
- return hit ? import_node_path40.default.join(dir, hit) : null;
63915
+ return hit ? import_node_path41.default.join(dir, hit) : null;
63783
63916
  }
63784
63917
  function locatePiSessionFile(sessionsRoot, cwd, toolSessionId) {
63785
63918
  const direct = findInDir(piProjectSessionDir(sessionsRoot, cwd), toolSessionId);
63786
63919
  if (direct) return direct;
63787
63920
  let dirs;
63788
63921
  try {
63789
- dirs = import_node_fs36.default.readdirSync(sessionsRoot, { withFileTypes: true }).filter((d2) => d2.isDirectory()).map((d2) => d2.name);
63922
+ dirs = import_node_fs37.default.readdirSync(sessionsRoot, { withFileTypes: true }).filter((d2) => d2.isDirectory()).map((d2) => d2.name);
63790
63923
  } catch {
63791
63924
  return null;
63792
63925
  }
63793
63926
  for (const d2 of dirs) {
63794
- const hit = findInDir(import_node_path40.default.join(sessionsRoot, d2), toolSessionId);
63927
+ const hit = findInDir(import_node_path41.default.join(sessionsRoot, d2), toolSessionId);
63795
63928
  if (hit) return hit;
63796
63929
  }
63797
63930
  return null;
@@ -63890,11 +64023,11 @@ var PiHistoryReader = class {
63890
64023
  return [];
63891
64024
  }
63892
64025
  async listSessions(args) {
63893
- const want = import_node_path40.default.resolve(args.projectPath);
64026
+ const want = import_node_path41.default.resolve(args.projectPath);
63894
64027
  const dir = piProjectSessionDir(this.deps.sessionsRoot, want);
63895
64028
  let names;
63896
64029
  try {
63897
- names = import_node_fs36.default.readdirSync(dir).filter((n2) => n2.endsWith(".jsonl"));
64030
+ names = import_node_fs37.default.readdirSync(dir).filter((n2) => n2.endsWith(".jsonl"));
63898
64031
  } catch {
63899
64032
  return [];
63900
64033
  }
@@ -63902,15 +64035,15 @@ var PiHistoryReader = class {
63902
64035
  let scanned = 0;
63903
64036
  for (const n2 of names) {
63904
64037
  if (++scanned > PI_LIST_SESSIONS_SCAN_CAP) break;
63905
- const file = import_node_path40.default.join(dir, n2);
64038
+ const file = import_node_path41.default.join(dir, n2);
63906
64039
  const head = parseLine2(readFirstLine(file) ?? "");
63907
64040
  if (!head || head.type !== "session") continue;
63908
64041
  const cwd = str3(head.cwd);
63909
64042
  const id = str3(head.id);
63910
- if (!cwd || !id || import_node_path40.default.resolve(cwd) !== want) continue;
64043
+ if (!cwd || !id || import_node_path41.default.resolve(cwd) !== want) continue;
63911
64044
  let mtimeMs;
63912
64045
  try {
63913
- mtimeMs = import_node_fs36.default.statSync(file).mtimeMs;
64046
+ mtimeMs = import_node_fs37.default.statSync(file).mtimeMs;
63914
64047
  } catch {
63915
64048
  continue;
63916
64049
  }
@@ -63918,7 +64051,7 @@ var PiHistoryReader = class {
63918
64051
  }
63919
64052
  found.sort((a2, b3) => b3.mtimeMs - a2.mtimeMs);
63920
64053
  return found.slice(0, PI_LIST_SESSIONS_LIMIT).map((f2) => {
63921
- const parsed = parsePiSession(import_node_fs36.default.readFileSync(f2.file, "utf8"));
64054
+ const parsed = parsePiSession(import_node_fs37.default.readFileSync(f2.file, "utf8"));
63922
64055
  const firstUser = parsed.messages.find((m3) => m3.kind === "user-text");
63923
64056
  return {
63924
64057
  toolSessionId: f2.id,
@@ -63931,7 +64064,7 @@ var PiHistoryReader = class {
63931
64064
  async read(args) {
63932
64065
  const file = locatePiSessionFile(this.deps.sessionsRoot, args.cwd, args.toolSessionId);
63933
64066
  if (!file) throw new Error(`pi session not found for ${args.toolSessionId}`);
63934
- return pageMessages(parsePiSession(import_node_fs36.default.readFileSync(file, "utf8")).messages, args);
64067
+ return pageMessages(parsePiSession(import_node_fs37.default.readFileSync(file, "utf8")).messages, args);
63935
64068
  }
63936
64069
  async listSubagents(_args) {
63937
64070
  return [];
@@ -63966,10 +64099,10 @@ var PI_DEFAULT_MODEL_ENTRY = {
63966
64099
  };
63967
64100
  var PI_FULL_ACCESS = { id: "never", label: "Full Access", description: "pi \u65E0\u5BA1\u6279\uFF1A\u4ECE\u4E0D\u8BE2\u95EE\uFF0C\u81EA\u4E3B\u6267\u884C" };
63968
64101
  async function probePi(env = process.env) {
63969
- if (env.PI_BIN && import_node_fs37.default.existsSync(env.PI_BIN)) return { available: true, path: env.PI_BIN };
64102
+ if (env.PI_BIN && import_node_fs38.default.existsSync(env.PI_BIN)) return { available: true, path: env.PI_BIN };
63970
64103
  try {
63971
64104
  const out = (0, import_node_child_process12.execFileSync)("which", ["pi"], { encoding: "utf8" }).trim();
63972
- if (out && import_node_fs37.default.existsSync(out)) return { available: true, path: out };
64105
+ if (out && import_node_fs38.default.existsSync(out)) return { available: true, path: out };
63973
64106
  } catch {
63974
64107
  }
63975
64108
  return { available: false };
@@ -64139,13 +64272,13 @@ var PiAdapter = class {
64139
64272
  };
64140
64273
 
64141
64274
  // src/tools/pi-cloud-session.ts
64142
- var import_node_crypto11 = require("crypto");
64275
+ var import_node_crypto12 = require("crypto");
64143
64276
  function cloudPiInstructions(ctx) {
64144
64277
  return [ctx.extraSystemPrompt, workDirPrompt(CLOUD_WORKSPACE_SLOT, ctx.personaMode ?? "owner")].filter((x2) => Boolean(x2)).join("\n\n");
64145
64278
  }
64146
64279
  function createCloudPiSession(ctx, sink, deps) {
64147
64280
  const personaId2 = personaIdFromCloudCwd(ctx.cwd);
64148
- const sessionId = ctx.toolSessionId ?? (0, import_node_crypto11.randomUUID)();
64281
+ const sessionId = ctx.toolSessionId ?? (0, import_node_crypto12.randomUUID)();
64149
64282
  const stream = deferredLineStream();
64150
64283
  let channel = null;
64151
64284
  const driver = drivePiSession({
@@ -64288,7 +64421,7 @@ var CloudPiAdapter = class {
64288
64421
  init_protocol();
64289
64422
 
64290
64423
  // src/tools/codex-skills.ts
64291
- var import_node_path41 = __toESM(require("path"), 1);
64424
+ var import_node_path42 = __toESM(require("path"), 1);
64292
64425
  function str4(v3) {
64293
64426
  return typeof v3 === "string" ? v3 : void 0;
64294
64427
  }
@@ -64303,13 +64436,13 @@ function mapSkillsListResponse(res) {
64303
64436
  const r2 = s2 ?? {};
64304
64437
  const name = str4(r2.name);
64305
64438
  if (!name) continue;
64306
- const path100 = str4(r2.path);
64439
+ const path101 = str4(r2.path);
64307
64440
  const description = str4(r2.description);
64308
64441
  const isPlugin = name.includes(":");
64309
64442
  out.push({
64310
64443
  name,
64311
64444
  source: isPlugin ? "plugin" : "project",
64312
- ...path100 ? { path: path100 } : {},
64445
+ ...path101 ? { path: path101 } : {},
64313
64446
  ...description ? { description } : {},
64314
64447
  ...isPlugin ? { plugin: name.split(":")[0] } : {}
64315
64448
  });
@@ -64325,14 +64458,14 @@ async function listCodexSkills(cwd, deps = {}) {
64325
64458
  // 先写 extraRoots 再写 list(stdio 按写入顺序处理,fire-and-forget 不 await 回包;
64326
64459
  // codex-session.ts ready 序列同款,两处保持一致)。失败不阻塞 list。
64327
64460
  beforeRequest: (client) => {
64328
- void client.request("skills/extraRoots/set", { extraRoots: [import_node_path41.default.join(cwd, ".claude", "skills")] }).catch(() => void 0);
64461
+ void client.request("skills/extraRoots/set", { extraRoots: [import_node_path42.default.join(cwd, ".claude", "skills")] }).catch(() => void 0);
64329
64462
  }
64330
64463
  });
64331
64464
  return mapSkillsListResponse(res);
64332
64465
  }
64333
64466
 
64334
64467
  // src/tools/codex-turn-context.ts
64335
- var import_promises6 = __toESM(require("fs/promises"), 1);
64468
+ var import_promises7 = __toESM(require("fs/promises"), 1);
64336
64469
  function parseTurnContextFromRollout(raw) {
64337
64470
  const lines = raw.split("\n");
64338
64471
  for (let i2 = lines.length - 1; i2 >= 0; i2--) {
@@ -64359,7 +64492,7 @@ function parseTurnContextFromRollout(raw) {
64359
64492
  async function readCodexTurnContext(args, deps) {
64360
64493
  const rolloutPath = createCodexRolloutLocator(deps.roots)(args.threadId);
64361
64494
  if (!rolloutPath) return null;
64362
- return parseTurnContextFromRollout(await import_promises6.default.readFile(rolloutPath, "utf8"));
64495
+ return parseTurnContextFromRollout(await import_promises7.default.readFile(rolloutPath, "utf8"));
64363
64496
  }
64364
64497
  function createCodexResolvedMetaHydrator(deps) {
64365
64498
  const fetchedThreadIds = /* @__PURE__ */ new Set();
@@ -64399,23 +64532,23 @@ function rec4(v3) {
64399
64532
  }
64400
64533
 
64401
64534
  // src/workspace/browser.ts
64402
- var import_node_fs38 = __toESM(require("fs"), 1);
64403
- var import_node_os12 = __toESM(require("os"), 1);
64404
- var import_node_path42 = __toESM(require("path"), 1);
64535
+ var import_node_fs39 = __toESM(require("fs"), 1);
64536
+ var import_node_os13 = __toESM(require("os"), 1);
64537
+ var import_node_path43 = __toESM(require("path"), 1);
64405
64538
  init_protocol();
64406
64539
  var MAX_FILE_BYTES2 = 2 * 1024 * 1024;
64407
64540
  function resolveInsideCwd(cwd, subpath) {
64408
- const absCwd = import_node_path42.default.resolve(cwd);
64409
- const joined = import_node_path42.default.resolve(absCwd, subpath ?? ".");
64410
- const rel = import_node_path42.default.relative(absCwd, joined);
64411
- if (rel.startsWith("..") || import_node_path42.default.isAbsolute(rel)) {
64541
+ const absCwd = import_node_path43.default.resolve(cwd);
64542
+ const joined = import_node_path43.default.resolve(absCwd, subpath ?? ".");
64543
+ const rel = import_node_path43.default.relative(absCwd, joined);
64544
+ if (rel.startsWith("..") || import_node_path43.default.isAbsolute(rel)) {
64412
64545
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
64413
64546
  }
64414
64547
  return joined;
64415
64548
  }
64416
64549
  function ensureCwd(cwd) {
64417
64550
  try {
64418
- const stat = import_node_fs38.default.statSync(cwd);
64551
+ const stat = import_node_fs39.default.statSync(cwd);
64419
64552
  if (!stat.isDirectory()) {
64420
64553
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${cwd}`);
64421
64554
  }
@@ -64426,10 +64559,10 @@ function ensureCwd(cwd) {
64426
64559
  }
64427
64560
  var WorkspaceBrowser = class {
64428
64561
  list(args) {
64429
- const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os12.default.homedir();
64562
+ const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os13.default.homedir();
64430
64563
  ensureCwd(cwd);
64431
64564
  const full = resolveInsideCwd(cwd, args.path);
64432
- const dirents = import_node_fs38.default.readdirSync(full, { withFileTypes: true });
64565
+ const dirents = import_node_fs39.default.readdirSync(full, { withFileTypes: true });
64433
64566
  const entries = [];
64434
64567
  for (const d2 of dirents) {
64435
64568
  if (!args.showHidden && d2.name.startsWith(".")) continue;
@@ -64439,7 +64572,7 @@ var WorkspaceBrowser = class {
64439
64572
  mtime: ""
64440
64573
  };
64441
64574
  try {
64442
- const st2 = import_node_fs38.default.statSync(import_node_path42.default.join(full, d2.name));
64575
+ const st2 = import_node_fs39.default.statSync(import_node_path43.default.join(full, d2.name));
64443
64576
  entry.mtime = new Date(st2.mtimeMs).toISOString();
64444
64577
  if (d2.isFile()) entry.size = st2.size;
64445
64578
  } catch {
@@ -64455,14 +64588,14 @@ var WorkspaceBrowser = class {
64455
64588
  read(args) {
64456
64589
  ensureCwd(args.cwd);
64457
64590
  const full = resolveInsideCwd(args.cwd, args.path);
64458
- const st2 = import_node_fs38.default.statSync(full);
64591
+ const st2 = import_node_fs39.default.statSync(full);
64459
64592
  if (!st2.isFile()) {
64460
64593
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `not a file: ${args.path}`);
64461
64594
  }
64462
64595
  if (st2.size > MAX_FILE_BYTES2) {
64463
64596
  throw new ClawdError(ERROR_CODES.FILE_TOO_LARGE, `file > ${MAX_FILE_BYTES2} bytes`);
64464
64597
  }
64465
- const buf = import_node_fs38.default.readFileSync(full);
64598
+ const buf = import_node_fs39.default.readFileSync(full);
64466
64599
  const isBinary = buf.includes(0);
64467
64600
  if (isBinary) {
64468
64601
  return {
@@ -64484,20 +64617,20 @@ var WorkspaceBrowser = class {
64484
64617
  };
64485
64618
 
64486
64619
  // src/skills/agents-scanner.ts
64487
- var import_node_fs39 = __toESM(require("fs"), 1);
64488
- var import_node_os13 = __toESM(require("os"), 1);
64489
- var import_node_path43 = __toESM(require("path"), 1);
64620
+ var import_node_fs40 = __toESM(require("fs"), 1);
64621
+ var import_node_os14 = __toESM(require("os"), 1);
64622
+ var import_node_path44 = __toESM(require("path"), 1);
64490
64623
  var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
64491
64624
  function isDirLikeSync2(p3) {
64492
64625
  try {
64493
- return import_node_fs39.default.statSync(p3).isDirectory();
64626
+ return import_node_fs40.default.statSync(p3).isDirectory();
64494
64627
  } catch {
64495
64628
  return false;
64496
64629
  }
64497
64630
  }
64498
64631
  function fileExistsSync(p3) {
64499
64632
  try {
64500
- return import_node_fs39.default.statSync(p3).isFile();
64633
+ return import_node_fs40.default.statSync(p3).isFile();
64501
64634
  } catch {
64502
64635
  return false;
64503
64636
  }
@@ -64505,7 +64638,7 @@ function fileExistsSync(p3) {
64505
64638
  function parseAgentFile(filePath) {
64506
64639
  let content;
64507
64640
  try {
64508
- content = import_node_fs39.default.readFileSync(filePath, "utf8");
64641
+ content = import_node_fs40.default.readFileSync(filePath, "utf8");
64509
64642
  } catch {
64510
64643
  return {};
64511
64644
  }
@@ -64518,16 +64651,16 @@ function parseAgentFile(filePath) {
64518
64651
  function scanAgentsDir(dir, source, seen, out) {
64519
64652
  let entries;
64520
64653
  try {
64521
- entries = import_node_fs39.default.readdirSync(dir, { withFileTypes: true });
64654
+ entries = import_node_fs40.default.readdirSync(dir, { withFileTypes: true });
64522
64655
  } catch {
64523
64656
  return;
64524
64657
  }
64525
64658
  for (const ent of entries) {
64526
64659
  if (!ent.name.endsWith(".md")) continue;
64527
- if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path43.default.join(dir, ent.name)))) {
64660
+ if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path44.default.join(dir, ent.name)))) {
64528
64661
  continue;
64529
64662
  }
64530
- const filePath = import_node_path43.default.join(dir, ent.name);
64663
+ const filePath = import_node_path44.default.join(dir, ent.name);
64531
64664
  const baseName = ent.name.replace(/\.md$/, "");
64532
64665
  if (seen.has(baseName)) continue;
64533
64666
  seen.add(baseName);
@@ -64545,12 +64678,12 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
64545
64678
  function walk2(dir, namespaces) {
64546
64679
  let entries;
64547
64680
  try {
64548
- entries = import_node_fs39.default.readdirSync(dir, { withFileTypes: true });
64681
+ entries = import_node_fs40.default.readdirSync(dir, { withFileTypes: true });
64549
64682
  } catch {
64550
64683
  return;
64551
64684
  }
64552
64685
  for (const ent of entries) {
64553
- const childPath = import_node_path43.default.join(dir, ent.name);
64686
+ const childPath = import_node_path44.default.join(dir, ent.name);
64554
64687
  if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
64555
64688
  walk2(childPath, [...namespaces, ent.name]);
64556
64689
  continue;
@@ -64575,13 +64708,13 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
64575
64708
  walk2(root, []);
64576
64709
  }
64577
64710
  function readInstalledPlugins2(home) {
64578
- const pluginsDir = import_node_path43.default.join(home, ".claude", "plugins");
64579
- const v22 = import_node_path43.default.join(pluginsDir, "installed_plugins_v2.json");
64580
- const v1 = import_node_path43.default.join(pluginsDir, "installed_plugins.json");
64711
+ const pluginsDir = import_node_path44.default.join(home, ".claude", "plugins");
64712
+ const v22 = import_node_path44.default.join(pluginsDir, "installed_plugins_v2.json");
64713
+ const v1 = import_node_path44.default.join(pluginsDir, "installed_plugins.json");
64581
64714
  let raw = null;
64582
64715
  for (const candidate of [v22, v1]) {
64583
64716
  try {
64584
- raw = import_node_fs39.default.readFileSync(candidate, "utf8");
64717
+ raw = import_node_fs40.default.readFileSync(candidate, "utf8");
64585
64718
  break;
64586
64719
  } catch {
64587
64720
  }
@@ -64606,19 +64739,19 @@ function readInstalledPlugins2(home) {
64606
64739
  return out;
64607
64740
  }
64608
64741
  function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
64609
- let cur = import_node_path43.default.resolve(startCwd);
64610
- const fsRoot = import_node_path43.default.parse(cur).root;
64742
+ let cur = import_node_path44.default.resolve(startCwd);
64743
+ const fsRoot = import_node_path44.default.parse(cur).root;
64611
64744
  while (true) {
64612
- scanAgentsDir(import_node_path43.default.join(cur, ".claude", "agents"), "project", seen, out);
64745
+ scanAgentsDir(import_node_path44.default.join(cur, ".claude", "agents"), "project", seen, out);
64613
64746
  let hasGit = false;
64614
64747
  try {
64615
- hasGit = import_node_fs39.default.existsSync(import_node_path43.default.join(cur, ".git"));
64748
+ hasGit = import_node_fs40.default.existsSync(import_node_path44.default.join(cur, ".git"));
64616
64749
  } catch {
64617
64750
  }
64618
64751
  if (hasGit) return;
64619
64752
  if (cur === home) return;
64620
64753
  if (cur === fsRoot) return;
64621
- const parent = import_node_path43.default.dirname(cur);
64754
+ const parent = import_node_path44.default.dirname(cur);
64622
64755
  if (parent === cur) return;
64623
64756
  cur = parent;
64624
64757
  }
@@ -64628,7 +64761,7 @@ var AgentsScanner = class {
64628
64761
  extraPluginRoots;
64629
64762
  policyDir;
64630
64763
  constructor(opts = {}) {
64631
- this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os13.default.homedir();
64764
+ this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os14.default.homedir();
64632
64765
  this.extraPluginRoots = opts.extraPluginRoots ?? [];
64633
64766
  if (opts.policyDir !== void 0) {
64634
64767
  this.policyDir = opts.policyDir;
@@ -64653,7 +64786,7 @@ var AgentsScanner = class {
64653
64786
  }
64654
64787
  const fsBlock = [];
64655
64788
  scanAgentsDir(
64656
- import_node_path43.default.join(this.home, ".claude", "agents"),
64789
+ import_node_path44.default.join(this.home, ".claude", "agents"),
64657
64790
  "global",
64658
64791
  seen,
64659
64792
  fsBlock
@@ -64667,7 +64800,7 @@ var AgentsScanner = class {
64667
64800
  ...this.extraPluginRoots
64668
64801
  ];
64669
64802
  for (const { name, root } of plugins) {
64670
- const agentsRoot = import_node_path43.default.join(root, "agents");
64803
+ const agentsRoot = import_node_path44.default.join(root, "agents");
64671
64804
  scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
64672
64805
  }
64673
64806
  return [...builtinBlock, ...fsBlock];
@@ -64675,28 +64808,28 @@ var AgentsScanner = class {
64675
64808
  };
64676
64809
 
64677
64810
  // src/observer/session-observer.ts
64678
- var import_node_fs41 = __toESM(require("fs"), 1);
64679
- var import_node_os15 = __toESM(require("os"), 1);
64680
- var import_node_path45 = __toESM(require("path"), 1);
64811
+ var import_node_fs42 = __toESM(require("fs"), 1);
64812
+ var import_node_os16 = __toESM(require("os"), 1);
64813
+ var import_node_path46 = __toESM(require("path"), 1);
64681
64814
  init_claude_history();
64682
64815
 
64683
64816
  // src/observer/subagent-meta-observer.ts
64684
- var import_node_fs40 = __toESM(require("fs"), 1);
64685
- var import_node_os14 = __toESM(require("os"), 1);
64686
- var import_node_path44 = __toESM(require("path"), 1);
64817
+ var import_node_fs41 = __toESM(require("fs"), 1);
64818
+ var import_node_os15 = __toESM(require("os"), 1);
64819
+ var import_node_path45 = __toESM(require("path"), 1);
64687
64820
  init_claude_history();
64688
64821
  var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
64689
64822
  var SubagentMetaObserver = class {
64690
64823
  constructor(opts) {
64691
64824
  this.opts = opts;
64692
- this.home = opts.home ?? import_node_os14.default.homedir();
64825
+ this.home = opts.home ?? import_node_os15.default.homedir();
64693
64826
  }
64694
64827
  opts;
64695
64828
  home;
64696
64829
  watches = /* @__PURE__ */ new Map();
64697
64830
  // public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
64698
64831
  resolveSubagentDir(cwd, toolSessionId) {
64699
- return import_node_path44.default.join(
64832
+ return import_node_path45.default.join(
64700
64833
  this.home,
64701
64834
  ".claude",
64702
64835
  "projects",
@@ -64726,7 +64859,7 @@ var SubagentMetaObserver = class {
64726
64859
  attachWatcher(w3) {
64727
64860
  if (w3.watcher) return;
64728
64861
  try {
64729
- w3.watcher = import_node_fs40.default.watch(w3.dirPath, { persistent: false }, (_evt, name) => {
64862
+ w3.watcher = import_node_fs41.default.watch(w3.dirPath, { persistent: false }, (_evt, name) => {
64730
64863
  if (!name) return;
64731
64864
  const m3 = META_RE.exec(String(name));
64732
64865
  if (!m3) return;
@@ -64738,7 +64871,7 @@ var SubagentMetaObserver = class {
64738
64871
  scan(w3) {
64739
64872
  let entries;
64740
64873
  try {
64741
- entries = import_node_fs40.default.readdirSync(w3.dirPath);
64874
+ entries = import_node_fs41.default.readdirSync(w3.dirPath);
64742
64875
  } catch {
64743
64876
  return;
64744
64877
  }
@@ -64752,10 +64885,10 @@ var SubagentMetaObserver = class {
64752
64885
  if (!m3) return;
64753
64886
  const agentId = m3[1];
64754
64887
  if (w3.emitted.has(agentId)) return;
64755
- const file = import_node_path44.default.join(w3.dirPath, name);
64888
+ const file = import_node_path45.default.join(w3.dirPath, name);
64756
64889
  let raw;
64757
64890
  try {
64758
- raw = import_node_fs40.default.readFileSync(file, "utf8");
64891
+ raw = import_node_fs41.default.readFileSync(file, "utf8");
64759
64892
  } catch {
64760
64893
  return;
64761
64894
  }
@@ -64800,7 +64933,7 @@ var SubagentMetaObserver = class {
64800
64933
  var SessionObserver = class {
64801
64934
  constructor(opts) {
64802
64935
  this.opts = opts;
64803
- this.home = opts.home ?? import_node_os15.default.homedir();
64936
+ this.home = opts.home ?? import_node_os16.default.homedir();
64804
64937
  this.metaObserver = opts.enableSubagentMetaObserver ? new SubagentMetaObserver({ home: this.home, onEvent: opts.onEvent }) : null;
64805
64938
  }
64806
64939
  opts;
@@ -64812,14 +64945,14 @@ var SessionObserver = class {
64812
64945
  metaObserver;
64813
64946
  resolveJsonlPath(cwd, toolSessionId, override) {
64814
64947
  if (override) return override;
64815
- return import_node_path45.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
64948
+ return import_node_path46.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
64816
64949
  }
64817
64950
  start(args) {
64818
64951
  this.stop(args.sessionId);
64819
64952
  const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
64820
64953
  let size = 0;
64821
64954
  try {
64822
- size = import_node_fs41.default.statSync(filePath).size;
64955
+ size = import_node_fs42.default.statSync(filePath).size;
64823
64956
  } catch {
64824
64957
  }
64825
64958
  const w3 = {
@@ -64832,16 +64965,16 @@ var SessionObserver = class {
64832
64965
  adapter: args.adapter,
64833
64966
  prevIsRejectSentinel: false,
64834
64967
  toolSessionId: args.toolSessionId,
64835
- sawFile: import_node_fs41.default.existsSync(filePath),
64968
+ sawFile: import_node_fs42.default.existsSync(filePath),
64836
64969
  lastRelocateScanMs: 0,
64837
64970
  pendingCwdDerive: false,
64838
64971
  lastDeriveMs: 0
64839
64972
  };
64840
64973
  try {
64841
- import_node_fs41.default.mkdirSync(import_node_path45.default.dirname(filePath), { recursive: true });
64974
+ import_node_fs42.default.mkdirSync(import_node_path46.default.dirname(filePath), { recursive: true });
64842
64975
  } catch {
64843
64976
  }
64844
- w3.watcher = import_node_fs41.default.watch(import_node_path45.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
64977
+ w3.watcher = import_node_fs42.default.watch(import_node_path46.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
64845
64978
  if (!changedName || !w3.filePath.endsWith(changedName)) return;
64846
64979
  this.poll(w3);
64847
64980
  });
@@ -64864,7 +64997,7 @@ var SessionObserver = class {
64864
64997
  // 异常静默吞,不阻塞 watcher 启动
64865
64998
  hydrateMetaTail(w3, maxLines = 200) {
64866
64999
  try {
64867
- const raw = import_node_fs41.default.readFileSync(w3.filePath, "utf8");
65000
+ const raw = import_node_fs42.default.readFileSync(w3.filePath, "utf8");
64868
65001
  if (!raw) return;
64869
65002
  const allLines = raw.split("\n").filter((l2) => l2.trim().length > 0);
64870
65003
  if (allLines.length === 0) return;
@@ -64888,7 +65021,7 @@ var SessionObserver = class {
64888
65021
  poll(w3) {
64889
65022
  let size = 0;
64890
65023
  try {
64891
- size = import_node_fs41.default.statSync(w3.filePath).size;
65024
+ size = import_node_fs42.default.statSync(w3.filePath).size;
64892
65025
  } catch {
64893
65026
  if (w3.sawFile) this.maybeRelocate(w3);
64894
65027
  return;
@@ -64899,11 +65032,11 @@ var SessionObserver = class {
64899
65032
  w3.buf = "";
64900
65033
  }
64901
65034
  if (size === w3.lastSize) return;
64902
- const fd = import_node_fs41.default.openSync(w3.filePath, "r");
65035
+ const fd = import_node_fs42.default.openSync(w3.filePath, "r");
64903
65036
  try {
64904
65037
  const len = size - w3.lastSize;
64905
65038
  const buf = Buffer.alloc(len);
64906
- import_node_fs41.default.readSync(fd, buf, 0, len, w3.lastSize);
65039
+ import_node_fs42.default.readSync(fd, buf, 0, len, w3.lastSize);
64907
65040
  w3.lastSize = size;
64908
65041
  w3.buf += buf.toString("utf8");
64909
65042
  let newlineIndex;
@@ -64926,7 +65059,7 @@ var SessionObserver = class {
64926
65059
  }
64927
65060
  }
64928
65061
  } finally {
64929
- import_node_fs41.default.closeSync(fd);
65062
+ import_node_fs42.default.closeSync(fd);
64930
65063
  }
64931
65064
  if (w3.pendingCwdDerive) this.maybeDeriveCwd(w3);
64932
65065
  }
@@ -64938,7 +65071,7 @@ var SessionObserver = class {
64938
65071
  const now = Date.now();
64939
65072
  if (now - w3.lastRelocateScanMs < 1e3) return;
64940
65073
  w3.lastRelocateScanMs = now;
64941
- const projectsRoot = import_node_path45.default.join(this.home, ".claude", "projects");
65074
+ const projectsRoot = import_node_path46.default.join(this.home, ".claude", "projects");
64942
65075
  const found = findTranscriptByToolSessionId(projectsRoot, w3.toolSessionId);
64943
65076
  if (!found || found === w3.filePath) return;
64944
65077
  try {
@@ -64947,7 +65080,7 @@ var SessionObserver = class {
64947
65080
  }
64948
65081
  w3.filePath = found;
64949
65082
  try {
64950
- w3.watcher = import_node_fs41.default.watch(import_node_path45.default.dirname(found), { persistent: false }, (_event, changedName) => {
65083
+ w3.watcher = import_node_fs42.default.watch(import_node_path46.default.dirname(found), { persistent: false }, (_event, changedName) => {
64951
65084
  if (!changedName || !w3.filePath.endsWith(changedName)) return;
64952
65085
  this.poll(w3);
64953
65086
  });
@@ -65069,9 +65202,9 @@ function listRegistered() {
65069
65202
  // src/tools/title-generator.ts
65070
65203
  var import_node_child_process13 = require("child_process");
65071
65204
  init_protocol();
65072
- var import_node_fs42 = __toESM(require("fs"), 1);
65073
- var import_node_os16 = __toESM(require("os"), 1);
65074
- var import_node_path46 = __toESM(require("path"), 1);
65205
+ var import_node_fs43 = __toESM(require("fs"), 1);
65206
+ var import_node_os17 = __toESM(require("os"), 1);
65207
+ var import_node_path47 = __toESM(require("path"), 1);
65075
65208
  var TITLE_GEN_DIR_PREFIX = "clawd-title-";
65076
65209
  var TITLE_MODEL_BY_TOOL = {
65077
65210
  claude: "haiku",
@@ -65142,21 +65275,21 @@ async function generateSessionTitle(tool, firstMessage, deps = {}) {
65142
65275
  if (!text) return null;
65143
65276
  let workDir;
65144
65277
  try {
65145
- workDir = import_node_fs42.default.mkdtempSync(import_node_path46.default.join(import_node_os16.default.tmpdir(), TITLE_GEN_DIR_PREFIX));
65278
+ workDir = import_node_fs43.default.mkdtempSync(import_node_path47.default.join(import_node_os17.default.tmpdir(), TITLE_GEN_DIR_PREFIX));
65146
65279
  } catch {
65147
65280
  return null;
65148
65281
  }
65149
65282
  const cleanupWorkDir = () => {
65150
65283
  try {
65151
- import_node_fs42.default.rmSync(workDir, { recursive: true, force: true });
65284
+ import_node_fs43.default.rmSync(workDir, { recursive: true, force: true });
65152
65285
  } catch {
65153
65286
  }
65154
65287
  };
65155
- const outFile = import_node_path46.default.join(workDir, `codex-title-${process.pid}-${++outFileSeq}-${Date.now()}.txt`);
65156
- const schemaFile = import_node_path46.default.join(workDir, "title-schema.json");
65288
+ const outFile = import_node_path47.default.join(workDir, `codex-title-${process.pid}-${++outFileSeq}-${Date.now()}.txt`);
65289
+ const schemaFile = import_node_path47.default.join(workDir, "title-schema.json");
65157
65290
  if (isCodexFamily(tool)) {
65158
65291
  try {
65159
- import_node_fs42.default.writeFileSync(schemaFile, CODEX_TITLE_SCHEMA);
65292
+ import_node_fs43.default.writeFileSync(schemaFile, CODEX_TITLE_SCHEMA);
65160
65293
  } catch {
65161
65294
  cleanupWorkDir();
65162
65295
  return null;
@@ -65206,7 +65339,7 @@ async function generateSessionTitle(tool, firstMessage, deps = {}) {
65206
65339
  if (tool === "claude") return finish(parseTitleJson(stdout));
65207
65340
  let fileText = "";
65208
65341
  try {
65209
- fileText = import_node_fs42.default.readFileSync(outFile, "utf8");
65342
+ fileText = import_node_fs43.default.readFileSync(outFile, "utf8");
65210
65343
  } catch {
65211
65344
  return finish(null);
65212
65345
  }
@@ -65228,7 +65361,7 @@ var wrapper_default = import_websocket.default;
65228
65361
 
65229
65362
  // src/transport/local-ws-server.ts
65230
65363
  var import_node_http = __toESM(require("http"), 1);
65231
- var import_node_crypto12 = require("crypto");
65364
+ var import_node_crypto13 = require("crypto");
65232
65365
  var LocalWsServer = class {
65233
65366
  constructor(opts) {
65234
65367
  this.opts = opts;
@@ -65445,7 +65578,7 @@ var LocalWsServer = class {
65445
65578
  }
65446
65579
  }
65447
65580
  onConnection(socket, remoteAddress) {
65448
- const id = (0, import_node_crypto12.randomUUID)();
65581
+ const id = (0, import_node_crypto13.randomUUID)();
65449
65582
  const subscribedSessions = /* @__PURE__ */ new Map();
65450
65583
  const handle = {
65451
65584
  id,
@@ -65851,8 +65984,8 @@ async function authenticate(token, deps) {
65851
65984
  }
65852
65985
 
65853
65986
  // src/legacy-cleanup.ts
65854
- var fs53 = __toESM(require("fs/promises"), 1);
65855
- var path54 = __toESM(require("path"), 1);
65987
+ var fs54 = __toESM(require("fs/promises"), 1);
65988
+ var path55 = __toESM(require("path"), 1);
65856
65989
  var LEGACY_FILES = [
65857
65990
  "personal-capability.json",
65858
65991
  "received-capabilities.json",
@@ -65861,9 +65994,9 @@ var LEGACY_FILES = [
65861
65994
  async function cleanupLegacyCapabilityFiles(dataDir, logger) {
65862
65995
  const removed = [];
65863
65996
  for (const name of LEGACY_FILES) {
65864
- const p3 = path54.join(dataDir, name);
65997
+ const p3 = path55.join(dataDir, name);
65865
65998
  try {
65866
- await fs53.unlink(p3);
65999
+ await fs54.unlink(p3);
65867
66000
  removed.push(name);
65868
66001
  logger.debug("legacy capability file removed", { file: name });
65869
66002
  } catch (err) {
@@ -65875,13 +66008,13 @@ async function cleanupLegacyCapabilityFiles(dataDir, logger) {
65875
66008
  }
65876
66009
 
65877
66010
  // src/inbox/inbox-store.ts
65878
- var fs54 = __toESM(require("fs"), 1);
65879
- var path55 = __toESM(require("path"), 1);
66011
+ var fs55 = __toESM(require("fs"), 1);
66012
+ var path56 = __toESM(require("path"), 1);
65880
66013
  var INBOX_SUBDIR = "inbox";
65881
66014
  var InboxStore = class {
65882
66015
  constructor(dataDir) {
65883
66016
  this.dataDir = dataDir;
65884
- fs54.mkdirSync(this.dirPath(), { recursive: true });
66017
+ fs55.mkdirSync(this.dirPath(), { recursive: true });
65885
66018
  }
65886
66019
  dataDir;
65887
66020
  /**
@@ -65893,7 +66026,7 @@ var InboxStore = class {
65893
66026
  const file = this.filePath(peerDeviceId);
65894
66027
  let raw;
65895
66028
  try {
65896
- raw = fs54.readFileSync(file, "utf8");
66029
+ raw = fs55.readFileSync(file, "utf8");
65897
66030
  } catch (err) {
65898
66031
  if (err?.code === "ENOENT") return [];
65899
66032
  return [];
@@ -65909,7 +66042,7 @@ var InboxStore = class {
65909
66042
  const dir = this.dirPath();
65910
66043
  let entries;
65911
66044
  try {
65912
- entries = fs54.readdirSync(dir);
66045
+ entries = fs55.readdirSync(dir);
65913
66046
  } catch (err) {
65914
66047
  if (err?.code === "ENOENT") return [];
65915
66048
  return [];
@@ -65925,9 +66058,9 @@ var InboxStore = class {
65925
66058
  if (existing.some((m3) => m3.id === message.id)) return;
65926
66059
  const file = this.filePath(message.peerDeviceId);
65927
66060
  const line = JSON.stringify(message) + "\n";
65928
- fs54.appendFileSync(file, line, { mode: 384 });
66061
+ fs55.appendFileSync(file, line, { mode: 384 });
65929
66062
  try {
65930
- fs54.chmodSync(file, 384);
66063
+ fs55.chmodSync(file, 384);
65931
66064
  } catch {
65932
66065
  }
65933
66066
  }
@@ -65957,7 +66090,7 @@ var InboxStore = class {
65957
66090
  removeByPeerDeviceId(peerDeviceId) {
65958
66091
  const file = this.filePath(peerDeviceId);
65959
66092
  try {
65960
- fs54.unlinkSync(file);
66093
+ fs55.unlinkSync(file);
65961
66094
  } catch (err) {
65962
66095
  if (err?.code === "ENOENT") return;
65963
66096
  }
@@ -65966,18 +66099,18 @@ var InboxStore = class {
65966
66099
  const file = this.filePath(peerDeviceId);
65967
66100
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
65968
66101
  const content = messages.map((m3) => JSON.stringify(m3)).join("\n") + (messages.length > 0 ? "\n" : "");
65969
- fs54.writeFileSync(tmp, content, { mode: 384 });
65970
- fs54.renameSync(tmp, file);
66102
+ fs55.writeFileSync(tmp, content, { mode: 384 });
66103
+ fs55.renameSync(tmp, file);
65971
66104
  try {
65972
- fs54.chmodSync(file, 384);
66105
+ fs55.chmodSync(file, 384);
65973
66106
  } catch {
65974
66107
  }
65975
66108
  }
65976
66109
  dirPath() {
65977
- return path55.join(this.dataDir, INBOX_SUBDIR);
66110
+ return path56.join(this.dataDir, INBOX_SUBDIR);
65978
66111
  }
65979
66112
  filePath(peerDeviceId) {
65980
- return path55.join(this.dirPath(), `${peerDeviceId}.jsonl`);
66113
+ return path56.join(this.dirPath(), `${peerDeviceId}.jsonl`);
65981
66114
  }
65982
66115
  };
65983
66116
  function parseAllLines(raw) {
@@ -66065,8 +66198,8 @@ var InboxManager = class {
66065
66198
  };
66066
66199
 
66067
66200
  // src/state/contact-store.ts
66068
- var fs55 = __toESM(require("fs"), 1);
66069
- var path56 = __toESM(require("path"), 1);
66201
+ var fs56 = __toESM(require("fs"), 1);
66202
+ var path57 = __toESM(require("path"), 1);
66070
66203
  var FILE_NAME = "contacts.json";
66071
66204
  var ContactStore = class {
66072
66205
  constructor(dataDir) {
@@ -66076,10 +66209,10 @@ var ContactStore = class {
66076
66209
  contacts = /* @__PURE__ */ new Map();
66077
66210
  load() {
66078
66211
  this.contacts.clear();
66079
- const file = path56.join(this.dataDir, FILE_NAME);
66212
+ const file = path57.join(this.dataDir, FILE_NAME);
66080
66213
  let raw;
66081
66214
  try {
66082
- raw = fs55.readFileSync(file, "utf8");
66215
+ raw = fs56.readFileSync(file, "utf8");
66083
66216
  } catch (err) {
66084
66217
  if (err?.code !== "ENOENT") this.renameBak(file);
66085
66218
  return;
@@ -66160,20 +66293,20 @@ var ContactStore = class {
66160
66293
  return true;
66161
66294
  }
66162
66295
  flush() {
66163
- const file = path56.join(this.dataDir, FILE_NAME);
66296
+ const file = path57.join(this.dataDir, FILE_NAME);
66164
66297
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
66165
66298
  const content = JSON.stringify(
66166
66299
  { contacts: Array.from(this.contacts.values()) },
66167
66300
  null,
66168
66301
  2
66169
66302
  );
66170
- fs55.mkdirSync(this.dataDir, { recursive: true });
66171
- fs55.writeFileSync(tmp, content, { mode: 384 });
66172
- fs55.renameSync(tmp, file);
66303
+ fs56.mkdirSync(this.dataDir, { recursive: true });
66304
+ fs56.writeFileSync(tmp, content, { mode: 384 });
66305
+ fs56.renameSync(tmp, file);
66173
66306
  }
66174
66307
  renameBak(file) {
66175
66308
  try {
66176
- fs55.renameSync(file, `${file}.bak`);
66309
+ fs56.renameSync(file, `${file}.bak`);
66177
66310
  } catch {
66178
66311
  }
66179
66312
  }
@@ -66281,61 +66414,61 @@ async function connectRemote(args) {
66281
66414
  }
66282
66415
 
66283
66416
  // src/migrations/2026-05-20-flatten-sessions.ts
66284
- var fs56 = __toESM(require("fs"), 1);
66285
- var path57 = __toESM(require("path"), 1);
66417
+ var fs57 = __toESM(require("fs"), 1);
66418
+ var path58 = __toESM(require("path"), 1);
66286
66419
  var MIGRATION_FLAG_NAME = ".migration.v1.done";
66287
66420
  function migrateFlattenSessions(opts) {
66288
66421
  const dataDir = opts.dataDir;
66289
66422
  const now = opts.now ?? Date.now;
66290
- const sessionsDir = path57.join(dataDir, "sessions");
66291
- const flagPath = path57.join(sessionsDir, MIGRATION_FLAG_NAME);
66423
+ const sessionsDir = path58.join(dataDir, "sessions");
66424
+ const flagPath = path58.join(sessionsDir, MIGRATION_FLAG_NAME);
66292
66425
  if (existsSync3(flagPath)) {
66293
66426
  return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
66294
66427
  }
66295
66428
  let movedBare = 0;
66296
66429
  let movedVmOwner = 0;
66297
66430
  let archivedListener = 0;
66298
- const defaultDir = path57.join(sessionsDir, "default");
66431
+ const defaultDir = path58.join(sessionsDir, "default");
66299
66432
  if (existsSync3(defaultDir)) {
66300
66433
  for (const entry of readdirSafe(defaultDir)) {
66301
66434
  if (!entry.endsWith(".json")) continue;
66302
- const src = path57.join(defaultDir, entry);
66303
- const dst = path57.join(sessionsDir, entry);
66304
- fs56.renameSync(src, dst);
66435
+ const src = path58.join(defaultDir, entry);
66436
+ const dst = path58.join(sessionsDir, entry);
66437
+ fs57.renameSync(src, dst);
66305
66438
  movedBare += 1;
66306
66439
  }
66307
66440
  rmdirIfEmpty(defaultDir);
66308
66441
  }
66309
66442
  for (const pid of readdirSafe(sessionsDir)) {
66310
- const personaDir = path57.join(sessionsDir, pid);
66443
+ const personaDir = path58.join(sessionsDir, pid);
66311
66444
  if (!isDir(personaDir)) continue;
66312
66445
  if (pid === "default") continue;
66313
- const ownerSrc = path57.join(personaDir, "owner");
66446
+ const ownerSrc = path58.join(personaDir, "owner");
66314
66447
  if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
66315
- const ownerDst = path57.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
66316
- fs56.mkdirSync(ownerDst, { recursive: true });
66448
+ const ownerDst = path58.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
66449
+ fs57.mkdirSync(ownerDst, { recursive: true });
66317
66450
  for (const file of readdirSafe(ownerSrc)) {
66318
66451
  if (!file.endsWith(".json")) continue;
66319
- fs56.renameSync(path57.join(ownerSrc, file), path57.join(ownerDst, file));
66452
+ fs57.renameSync(path58.join(ownerSrc, file), path58.join(ownerDst, file));
66320
66453
  movedVmOwner += 1;
66321
66454
  }
66322
66455
  rmdirIfEmpty(ownerSrc);
66323
66456
  }
66324
- const listenerSrc = path57.join(personaDir, "listener");
66457
+ const listenerSrc = path58.join(personaDir, "listener");
66325
66458
  if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
66326
- const archiveDst = path57.join(dataDir, ".legacy", `listener-${pid}`);
66327
- fs56.mkdirSync(archiveDst, { recursive: true });
66459
+ const archiveDst = path58.join(dataDir, ".legacy", `listener-${pid}`);
66460
+ fs57.mkdirSync(archiveDst, { recursive: true });
66328
66461
  for (const file of readdirSafe(listenerSrc)) {
66329
66462
  if (!file.endsWith(".json")) continue;
66330
- fs56.renameSync(path57.join(listenerSrc, file), path57.join(archiveDst, file));
66463
+ fs57.renameSync(path58.join(listenerSrc, file), path58.join(archiveDst, file));
66331
66464
  archivedListener += 1;
66332
66465
  }
66333
66466
  rmdirIfEmpty(listenerSrc);
66334
66467
  }
66335
66468
  rmdirIfEmpty(personaDir);
66336
66469
  }
66337
- fs56.mkdirSync(sessionsDir, { recursive: true });
66338
- fs56.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
66470
+ fs57.mkdirSync(sessionsDir, { recursive: true });
66471
+ fs57.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
66339
66472
  return {
66340
66473
  skipped: false,
66341
66474
  flagWritten: true,
@@ -66346,7 +66479,7 @@ function migrateFlattenSessions(opts) {
66346
66479
  }
66347
66480
  function existsSync3(p3) {
66348
66481
  try {
66349
- fs56.statSync(p3);
66482
+ fs57.statSync(p3);
66350
66483
  return true;
66351
66484
  } catch {
66352
66485
  return false;
@@ -66354,64 +66487,64 @@ function existsSync3(p3) {
66354
66487
  }
66355
66488
  function isDir(p3) {
66356
66489
  try {
66357
- return fs56.statSync(p3).isDirectory();
66490
+ return fs57.statSync(p3).isDirectory();
66358
66491
  } catch {
66359
66492
  return false;
66360
66493
  }
66361
66494
  }
66362
66495
  function readdirSafe(p3) {
66363
66496
  try {
66364
- return fs56.readdirSync(p3);
66497
+ return fs57.readdirSync(p3);
66365
66498
  } catch {
66366
66499
  return [];
66367
66500
  }
66368
66501
  }
66369
66502
  function rmdirIfEmpty(p3) {
66370
66503
  try {
66371
- fs56.rmdirSync(p3);
66504
+ fs57.rmdirSync(p3);
66372
66505
  } catch {
66373
66506
  }
66374
66507
  }
66375
66508
 
66376
66509
  // src/migrations/2026-08-18-drop-seeded-projects.ts
66377
- var fs57 = __toESM(require("fs"), 1);
66378
- var path58 = __toESM(require("path"), 1);
66510
+ var fs58 = __toESM(require("fs"), 1);
66511
+ var path59 = __toESM(require("path"), 1);
66379
66512
  var DROP_SEEDED_PROJECTS_FLAG = ".projects-seed-dropped.v1.done";
66380
66513
  function dropSeededProjects(opts) {
66381
- fs57.mkdirSync(opts.dataDir, { recursive: true });
66382
- const flag = path58.join(opts.dataDir, DROP_SEEDED_PROJECTS_FLAG);
66383
- if (fs57.existsSync(flag)) return { skipped: true, dropped: 0, backup: null };
66384
- const file = path58.join(opts.dataDir, "projects.json");
66514
+ fs58.mkdirSync(opts.dataDir, { recursive: true });
66515
+ const flag = path59.join(opts.dataDir, DROP_SEEDED_PROJECTS_FLAG);
66516
+ if (fs58.existsSync(flag)) return { skipped: true, dropped: 0, backup: null };
66517
+ const file = path59.join(opts.dataDir, "projects.json");
66385
66518
  let raw = null;
66386
66519
  let dropped = 0;
66387
66520
  try {
66388
- raw = fs57.readFileSync(file, "utf8");
66521
+ raw = fs58.readFileSync(file, "utf8");
66389
66522
  dropped = JSON.parse(raw).projects?.length ?? 0;
66390
66523
  } catch {
66391
66524
  }
66392
66525
  let backup = null;
66393
66526
  if (raw != null && dropped > 0) {
66394
- const dir = path58.join(opts.dataDir, "backups");
66395
- fs57.mkdirSync(dir, { recursive: true });
66396
- backup = path58.join(dir, `projects.seed-dropped.${(opts.now ?? Date.now)()}.json`);
66397
- fs57.writeFileSync(backup, raw);
66527
+ const dir = path59.join(opts.dataDir, "backups");
66528
+ fs58.mkdirSync(dir, { recursive: true });
66529
+ backup = path59.join(dir, `projects.seed-dropped.${(opts.now ?? Date.now)()}.json`);
66530
+ fs58.writeFileSync(backup, raw);
66398
66531
  }
66399
66532
  if (raw != null || dropped > 0) {
66400
- fs57.writeFileSync(file, JSON.stringify({ projects: [] }, null, 2));
66533
+ fs58.writeFileSync(file, JSON.stringify({ projects: [] }, null, 2));
66401
66534
  }
66402
- fs57.writeFileSync(flag, (/* @__PURE__ */ new Date()).toISOString());
66535
+ fs58.writeFileSync(flag, (/* @__PURE__ */ new Date()).toISOString());
66403
66536
  return { skipped: false, dropped, backup };
66404
66537
  }
66405
66538
 
66406
66539
  // src/transport/http-router.ts
66407
- var import_node_fs44 = __toESM(require("fs"), 1);
66408
- var import_node_path49 = __toESM(require("path"), 1);
66540
+ var import_node_fs45 = __toESM(require("fs"), 1);
66541
+ var import_node_path50 = __toESM(require("path"), 1);
66409
66542
 
66410
66543
  // src/attachment/upload.ts
66411
- var import_node_fs43 = __toESM(require("fs"), 1);
66412
- var import_node_path47 = __toESM(require("path"), 1);
66413
- var import_node_crypto13 = __toESM(require("crypto"), 1);
66414
- var import_promises7 = require("stream/promises");
66544
+ var import_node_fs44 = __toESM(require("fs"), 1);
66545
+ var import_node_path48 = __toESM(require("path"), 1);
66546
+ var import_node_crypto14 = __toESM(require("crypto"), 1);
66547
+ var import_promises8 = require("stream/promises");
66415
66548
  var UploadError = class extends Error {
66416
66549
  constructor(code, message) {
66417
66550
  super(message);
@@ -66421,27 +66554,27 @@ var UploadError = class extends Error {
66421
66554
  code;
66422
66555
  };
66423
66556
  function assertValidFileName(fileName) {
66424
- if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path47.default.basename(fileName)) {
66557
+ if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path48.default.basename(fileName)) {
66425
66558
  throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
66426
66559
  }
66427
66560
  }
66428
66561
  var HASH_PREFIX_LEN = 16;
66429
66562
  async function writeUploadedAttachment(args) {
66430
66563
  assertValidFileName(args.fileName);
66431
- const attachmentsRoot = import_node_path47.default.join(args.baseDir, ".attachments");
66564
+ const attachmentsRoot = import_node_path48.default.join(args.baseDir, ".attachments");
66432
66565
  try {
66433
- import_node_fs43.default.mkdirSync(attachmentsRoot, { recursive: true });
66566
+ import_node_fs44.default.mkdirSync(attachmentsRoot, { recursive: true });
66434
66567
  } catch (err) {
66435
66568
  throw new UploadError("STORAGE_ERROR", `mkdir failed: ${err.message}`);
66436
66569
  }
66437
- const hasher = import_node_crypto13.default.createHash("sha256");
66570
+ const hasher = import_node_crypto14.default.createHash("sha256");
66438
66571
  let actualSize = 0;
66439
- const tmpPath = import_node_path47.default.join(
66572
+ const tmpPath = import_node_path48.default.join(
66440
66573
  attachmentsRoot,
66441
- `.upload-${process.pid}-${Date.now()}-${import_node_crypto13.default.randomBytes(4).toString("hex")}`
66574
+ `.upload-${process.pid}-${Date.now()}-${import_node_crypto14.default.randomBytes(4).toString("hex")}`
66442
66575
  );
66443
66576
  try {
66444
- await (0, import_promises7.pipeline)(
66577
+ await (0, import_promises8.pipeline)(
66445
66578
  args.body,
66446
66579
  async function* (source) {
66447
66580
  for await (const chunk of source) {
@@ -66451,18 +66584,18 @@ async function writeUploadedAttachment(args) {
66451
66584
  yield buf;
66452
66585
  }
66453
66586
  },
66454
- import_node_fs43.default.createWriteStream(tmpPath, { mode: 384 })
66587
+ import_node_fs44.default.createWriteStream(tmpPath, { mode: 384 })
66455
66588
  );
66456
66589
  } catch (err) {
66457
66590
  try {
66458
- import_node_fs43.default.unlinkSync(tmpPath);
66591
+ import_node_fs44.default.unlinkSync(tmpPath);
66459
66592
  } catch {
66460
66593
  }
66461
66594
  throw new UploadError("STORAGE_ERROR", `write failed: ${err.message}`);
66462
66595
  }
66463
66596
  if (actualSize !== args.contentLength) {
66464
66597
  try {
66465
- import_node_fs43.default.unlinkSync(tmpPath);
66598
+ import_node_fs44.default.unlinkSync(tmpPath);
66466
66599
  } catch {
66467
66600
  }
66468
66601
  throw new UploadError(
@@ -66471,34 +66604,34 @@ async function writeUploadedAttachment(args) {
66471
66604
  );
66472
66605
  }
66473
66606
  const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
66474
- const hashDir = import_node_path47.default.join(attachmentsRoot, attachmentId);
66607
+ const hashDir = import_node_path48.default.join(attachmentsRoot, attachmentId);
66475
66608
  let finalFileName;
66476
66609
  let hashDirExists = false;
66477
66610
  try {
66478
- hashDirExists = import_node_fs43.default.statSync(hashDir).isDirectory();
66611
+ hashDirExists = import_node_fs44.default.statSync(hashDir).isDirectory();
66479
66612
  } catch {
66480
66613
  }
66481
66614
  if (hashDirExists) {
66482
- const existing = import_node_fs43.default.readdirSync(hashDir).filter((n2) => !n2.startsWith("."));
66615
+ const existing = import_node_fs44.default.readdirSync(hashDir).filter((n2) => !n2.startsWith("."));
66483
66616
  finalFileName = existing[0] ?? args.fileName;
66484
66617
  try {
66485
- import_node_fs43.default.unlinkSync(tmpPath);
66618
+ import_node_fs44.default.unlinkSync(tmpPath);
66486
66619
  } catch {
66487
66620
  }
66488
66621
  } else {
66489
66622
  try {
66490
- import_node_fs43.default.mkdirSync(hashDir, { recursive: true });
66623
+ import_node_fs44.default.mkdirSync(hashDir, { recursive: true });
66491
66624
  finalFileName = args.fileName;
66492
- import_node_fs43.default.renameSync(tmpPath, import_node_path47.default.join(hashDir, finalFileName));
66625
+ import_node_fs44.default.renameSync(tmpPath, import_node_path48.default.join(hashDir, finalFileName));
66493
66626
  } catch (err) {
66494
66627
  try {
66495
- import_node_fs43.default.unlinkSync(tmpPath);
66628
+ import_node_fs44.default.unlinkSync(tmpPath);
66496
66629
  } catch {
66497
66630
  }
66498
66631
  throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
66499
66632
  }
66500
66633
  }
66501
- const absPath = import_node_path47.default.join(hashDir, finalFileName);
66634
+ const absPath = import_node_path48.default.join(hashDir, finalFileName);
66502
66635
  const relPath = absPath;
66503
66636
  args.groupFileStore.upsert(args.scope, args.sessionId, {
66504
66637
  relPath: absPath,
@@ -66512,9 +66645,9 @@ async function writeUploadedAttachment(args) {
66512
66645
  }
66513
66646
 
66514
66647
  // src/extension/import.ts
66515
- var import_promises8 = __toESM(require("fs/promises"), 1);
66516
- var import_node_path48 = __toESM(require("path"), 1);
66517
- var import_node_os17 = __toESM(require("os"), 1);
66648
+ var import_promises9 = __toESM(require("fs/promises"), 1);
66649
+ var import_node_path49 = __toESM(require("path"), 1);
66650
+ var import_node_os18 = __toESM(require("os"), 1);
66518
66651
  var import_jszip = __toESM(require_lib3(), 1);
66519
66652
  var ImportError = class extends Error {
66520
66653
  constructor(code, message) {
@@ -66531,7 +66664,7 @@ async function importZip(buf, root) {
66531
66664
  throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
66532
66665
  }
66533
66666
  for (const name of Object.keys(zip.files)) {
66534
- if (name.includes("..") || name.startsWith("/") || import_node_path48.default.isAbsolute(name)) {
66667
+ if (name.includes("..") || name.startsWith("/") || import_node_path49.default.isAbsolute(name)) {
66535
66668
  throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
66536
66669
  }
66537
66670
  }
@@ -66564,33 +66697,33 @@ async function importZip(buf, root) {
66564
66697
  );
66565
66698
  }
66566
66699
  }
66567
- const destDir = import_node_path48.default.join(root, manifest.id);
66700
+ const destDir = import_node_path49.default.join(root, manifest.id);
66568
66701
  let destExists = false;
66569
66702
  try {
66570
- await import_promises8.default.access(destDir);
66703
+ await import_promises9.default.access(destDir);
66571
66704
  destExists = true;
66572
66705
  } catch {
66573
66706
  }
66574
66707
  if (destExists) {
66575
66708
  throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
66576
66709
  }
66577
- const stage = await import_promises8.default.mkdtemp(import_node_path48.default.join(import_node_os17.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
66710
+ const stage = await import_promises9.default.mkdtemp(import_node_path49.default.join(import_node_os18.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
66578
66711
  try {
66579
66712
  for (const [name, entry] of Object.entries(zip.files)) {
66580
- const dest = import_node_path48.default.join(stage, name);
66713
+ const dest = import_node_path49.default.join(stage, name);
66581
66714
  if (entry.dir) {
66582
- await import_promises8.default.mkdir(dest, { recursive: true });
66715
+ await import_promises9.default.mkdir(dest, { recursive: true });
66583
66716
  continue;
66584
66717
  }
66585
- await import_promises8.default.mkdir(import_node_path48.default.dirname(dest), { recursive: true });
66718
+ await import_promises9.default.mkdir(import_node_path49.default.dirname(dest), { recursive: true });
66586
66719
  const content = await entry.async("nodebuffer");
66587
- await import_promises8.default.writeFile(dest, content);
66720
+ await import_promises9.default.writeFile(dest, content);
66588
66721
  }
66589
- await import_promises8.default.mkdir(root, { recursive: true });
66590
- await import_promises8.default.rename(stage, destDir);
66722
+ await import_promises9.default.mkdir(root, { recursive: true });
66723
+ await import_promises9.default.rename(stage, destDir);
66591
66724
  return { extId: manifest.id };
66592
66725
  } catch (e) {
66593
- await import_promises8.default.rm(stage, { recursive: true, force: true }).catch(() => {
66726
+ await import_promises9.default.rm(stage, { recursive: true, force: true }).catch(() => {
66594
66727
  });
66595
66728
  throw e;
66596
66729
  }
@@ -66636,7 +66769,7 @@ var SHARE_UI_ASSET_MIME = {
66636
66769
  ".wasm": "application/wasm"
66637
66770
  };
66638
66771
  function shareUiAssetMime(filePath) {
66639
- const ext = import_node_path49.default.extname(filePath).toLowerCase();
66772
+ const ext = import_node_path50.default.extname(filePath).toLowerCase();
66640
66773
  return SHARE_UI_ASSET_MIME[ext] ?? lookupMime(filePath);
66641
66774
  }
66642
66775
  var AUTHED_RPC_ROUTE_PREFIX = "/rpc/";
@@ -66735,7 +66868,7 @@ function isValidUploadFileName(fileName) {
66735
66868
  if (fileName === "." || fileName === "..") return false;
66736
66869
  if (fileName.startsWith(".")) return false;
66737
66870
  if (fileName.includes("/") || fileName.includes("\\")) return false;
66738
- return fileName === import_node_path49.default.basename(fileName);
66871
+ return fileName === import_node_path50.default.basename(fileName);
66739
66872
  }
66740
66873
  function createHttpRouter(deps) {
66741
66874
  return async (req, res) => {
@@ -66819,7 +66952,7 @@ function createHttpRouter(deps) {
66819
66952
  }
66820
66953
  let buf;
66821
66954
  try {
66822
- buf = await import_node_fs44.default.promises.readFile(abs);
66955
+ buf = await import_node_fs45.default.promises.readFile(abs);
66823
66956
  } catch {
66824
66957
  sendJson(res, 404, { code: "NOT_FOUND", message: "asset not found" });
66825
66958
  return true;
@@ -66958,7 +67091,7 @@ function createHttpRouter(deps) {
66958
67091
  sendHtml(res, statusByCode[r2.code], loader.renderErrorHtml(r2.code, msgByCode[r2.code]));
66959
67092
  return true;
66960
67093
  }
66961
- sendHtml(res, 200, loader.renderViewerHtml(import_node_path49.default.basename(r2.absPath)));
67094
+ sendHtml(res, 200, loader.renderViewerHtml(import_node_path50.default.basename(r2.absPath)));
66962
67095
  return true;
66963
67096
  }
66964
67097
  const ctx = deps.authResolver.resolveFromHeader(
@@ -67079,7 +67212,7 @@ function createHttpRouter(deps) {
67079
67212
  return true;
67080
67213
  }
67081
67214
  let absPath;
67082
- if (import_node_path49.default.isAbsolute(pathParam)) {
67215
+ if (import_node_path50.default.isAbsolute(pathParam)) {
67083
67216
  absPath = pathParam;
67084
67217
  } else if (deps.sessionStore) {
67085
67218
  const file = deps.sessionStore.read(sid);
@@ -67087,7 +67220,7 @@ function createHttpRouter(deps) {
67087
67220
  sendJson(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
67088
67221
  return true;
67089
67222
  }
67090
- absPath = import_node_path49.default.join(file.cwd, pathParam);
67223
+ absPath = import_node_path50.default.join(file.cwd, pathParam);
67091
67224
  } else {
67092
67225
  sendJson(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
67093
67226
  return true;
@@ -67171,7 +67304,7 @@ function withCtx(ctx, body) {
67171
67304
  function streamFile(res, absPath, logger) {
67172
67305
  let stat;
67173
67306
  try {
67174
- stat = import_node_fs44.default.statSync(absPath);
67307
+ stat = import_node_fs45.default.statSync(absPath);
67175
67308
  } catch (err) {
67176
67309
  const code = err?.code;
67177
67310
  if (code === "ENOENT") {
@@ -67186,7 +67319,7 @@ function streamFile(res, absPath, logger) {
67186
67319
  return;
67187
67320
  }
67188
67321
  const mime = lookupMime(absPath);
67189
- const basename2 = import_node_path49.default.basename(absPath);
67322
+ const basename2 = import_node_path50.default.basename(absPath);
67190
67323
  res.writeHead(200, {
67191
67324
  "Content-Type": mime,
67192
67325
  "Content-Length": String(stat.size),
@@ -67194,7 +67327,7 @@ function streamFile(res, absPath, logger) {
67194
67327
  // 防止浏览器把任意 mime 当 html 渲染
67195
67328
  "X-Content-Type-Options": "nosniff"
67196
67329
  });
67197
- const stream = import_node_fs44.default.createReadStream(absPath);
67330
+ const stream = import_node_fs45.default.createReadStream(absPath);
67198
67331
  stream.on("error", (err) => {
67199
67332
  logger?.warn("streamFile read error", { absPath, err: err.message });
67200
67333
  res.destroy();
@@ -67203,8 +67336,8 @@ function streamFile(res, absPath, logger) {
67203
67336
  }
67204
67337
 
67205
67338
  // src/attachment/gc.ts
67206
- var import_node_fs45 = __toESM(require("fs"), 1);
67207
- var import_node_path50 = __toESM(require("path"), 1);
67339
+ var import_node_fs46 = __toESM(require("fs"), 1);
67340
+ var import_node_path51 = __toESM(require("path"), 1);
67208
67341
  var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
67209
67342
  function runAttachmentGc(args) {
67210
67343
  const now = (args.now ?? Date.now)();
@@ -67213,12 +67346,12 @@ function runAttachmentGc(args) {
67213
67346
  for (const { scope, sessionId } of args.sessionScopes) {
67214
67347
  for (const entry of args.groupFileStore.list(scope, sessionId)) {
67215
67348
  if (entry.stale) continue;
67216
- if (import_node_path50.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
67349
+ if (import_node_path51.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
67217
67350
  }
67218
67351
  }
67219
67352
  const visited = /* @__PURE__ */ new Set();
67220
67353
  for (const { scope, sessionId } of args.sessionScopes) {
67221
- const legacyDir = args.getSessionCwd?.(sessionId) ?? import_node_path50.default.join(
67354
+ const legacyDir = args.getSessionCwd?.(sessionId) ?? import_node_path51.default.join(
67222
67355
  args.dataDir,
67223
67356
  "sessions",
67224
67357
  ...scopeSubPath(scope).map(safeFileName),
@@ -67231,28 +67364,28 @@ function runAttachmentGc(args) {
67231
67364
  return true;
67232
67365
  });
67233
67366
  for (const rootDir of roots) {
67234
- const attRoot = import_node_path50.default.join(rootDir, ".attachments");
67367
+ const attRoot = import_node_path51.default.join(rootDir, ".attachments");
67235
67368
  let hashDirs;
67236
67369
  try {
67237
- hashDirs = import_node_fs45.default.readdirSync(attRoot);
67370
+ hashDirs = import_node_fs46.default.readdirSync(attRoot);
67238
67371
  } catch (err) {
67239
67372
  if (err.code === "ENOENT") continue;
67240
67373
  args.logger?.warn("attachment gc: readdir failed", { attRoot, err: err.message });
67241
67374
  continue;
67242
67375
  }
67243
67376
  for (const hashDir of hashDirs) {
67244
- const hashDirAbs = import_node_path50.default.join(attRoot, hashDir);
67377
+ const hashDirAbs = import_node_path51.default.join(attRoot, hashDir);
67245
67378
  let files;
67246
67379
  try {
67247
- files = import_node_fs45.default.readdirSync(hashDirAbs);
67380
+ files = import_node_fs46.default.readdirSync(hashDirAbs);
67248
67381
  } catch {
67249
67382
  continue;
67250
67383
  }
67251
67384
  for (const name of files) {
67252
- const file = import_node_path50.default.join(hashDirAbs, name);
67385
+ const file = import_node_path51.default.join(hashDirAbs, name);
67253
67386
  let stat;
67254
67387
  try {
67255
- stat = import_node_fs45.default.statSync(file);
67388
+ stat = import_node_fs46.default.statSync(file);
67256
67389
  } catch {
67257
67390
  continue;
67258
67391
  }
@@ -67261,18 +67394,18 @@ function runAttachmentGc(args) {
67261
67394
  if (age < ttlMs) continue;
67262
67395
  if (liveAbs.has(file)) continue;
67263
67396
  try {
67264
- import_node_fs45.default.unlinkSync(file);
67397
+ import_node_fs46.default.unlinkSync(file);
67265
67398
  } catch (err) {
67266
67399
  args.logger?.warn("attachment gc: unlink failed", { file, err: err.message });
67267
67400
  }
67268
67401
  }
67269
67402
  try {
67270
- if (import_node_fs45.default.readdirSync(hashDirAbs).length === 0) import_node_fs45.default.rmdirSync(hashDirAbs);
67403
+ if (import_node_fs46.default.readdirSync(hashDirAbs).length === 0) import_node_fs46.default.rmdirSync(hashDirAbs);
67271
67404
  } catch {
67272
67405
  }
67273
67406
  }
67274
67407
  try {
67275
- if (import_node_fs45.default.readdirSync(attRoot).length === 0) import_node_fs45.default.rmdirSync(attRoot);
67408
+ if (import_node_fs46.default.readdirSync(attRoot).length === 0) import_node_fs46.default.rmdirSync(attRoot);
67276
67409
  } catch {
67277
67410
  }
67278
67411
  }
@@ -67280,9 +67413,9 @@ function runAttachmentGc(args) {
67280
67413
  }
67281
67414
 
67282
67415
  // src/attachment/group.ts
67283
- var import_node_fs46 = __toESM(require("fs"), 1);
67284
- var import_node_path51 = __toESM(require("path"), 1);
67285
- var import_node_crypto14 = __toESM(require("crypto"), 1);
67416
+ var import_node_fs47 = __toESM(require("fs"), 1);
67417
+ var import_node_path52 = __toESM(require("path"), 1);
67418
+ var import_node_crypto15 = __toESM(require("crypto"), 1);
67286
67419
  init_protocol();
67287
67420
  var GroupFileStore = class {
67288
67421
  dataDir;
@@ -67293,11 +67426,11 @@ var GroupFileStore = class {
67293
67426
  this.logger = opts.logger;
67294
67427
  }
67295
67428
  rootForScope(scope) {
67296
- return import_node_path51.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
67429
+ return import_node_path52.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
67297
67430
  }
67298
67431
  /** 与 SessionStore.filePath 平级,扩展名 .group-files.json */
67299
67432
  filePath(scope, sessionId) {
67300
- return import_node_path51.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
67433
+ return import_node_path52.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
67301
67434
  }
67302
67435
  cacheKey(scope, sessionId) {
67303
67436
  return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
@@ -67306,7 +67439,7 @@ var GroupFileStore = class {
67306
67439
  readFile(scope, sessionId) {
67307
67440
  const file = this.filePath(scope, sessionId);
67308
67441
  try {
67309
- const raw = import_node_fs46.default.readFileSync(file, "utf8");
67442
+ const raw = import_node_fs47.default.readFileSync(file, "utf8");
67310
67443
  const parsed = JSON.parse(raw);
67311
67444
  if (!Array.isArray(parsed)) {
67312
67445
  this.logger?.warn("GroupFileStore.readFile: not an array; resetting session entries", {
@@ -67332,10 +67465,10 @@ var GroupFileStore = class {
67332
67465
  }
67333
67466
  writeFile(scope, sessionId, entries) {
67334
67467
  const file = this.filePath(scope, sessionId);
67335
- import_node_fs46.default.mkdirSync(import_node_path51.default.dirname(file), { recursive: true });
67468
+ import_node_fs47.default.mkdirSync(import_node_path52.default.dirname(file), { recursive: true });
67336
67469
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
67337
- import_node_fs46.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
67338
- import_node_fs46.default.renameSync(tmp, file);
67470
+ import_node_fs47.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
67471
+ import_node_fs47.default.renameSync(tmp, file);
67339
67472
  }
67340
67473
  /** 拉一份当前 session 的清单。读盘 → cache;之后调用复用 cache */
67341
67474
  list(scope, sessionId) {
@@ -67371,7 +67504,7 @@ var GroupFileStore = class {
67371
67504
  entries[idx] = next;
67372
67505
  } else {
67373
67506
  next = {
67374
- id: `gf-${import_node_crypto14.default.randomBytes(6).toString("base64url")}`,
67507
+ id: `gf-${import_node_crypto15.default.randomBytes(6).toString("base64url")}`,
67375
67508
  relPath: input.relPath,
67376
67509
  from: input.from,
67377
67510
  label: input.label,
@@ -67427,7 +67560,7 @@ var GroupFileStore = class {
67427
67560
  */
67428
67561
  deleteSession(scope, sessionId) {
67429
67562
  try {
67430
- import_node_fs46.default.unlinkSync(this.filePath(scope, sessionId));
67563
+ import_node_fs47.default.unlinkSync(this.filePath(scope, sessionId));
67431
67564
  } catch (err) {
67432
67565
  if (err?.code !== "ENOENT") throw err;
67433
67566
  }
@@ -67440,7 +67573,7 @@ var GroupFileStore = class {
67440
67573
  * 不在 persona 目录里(见文件头的路径约定)。没树的 persona 是 noop。
67441
67574
  */
67442
67575
  deletePersona(personaId2) {
67443
- import_node_fs46.default.rmSync(import_node_path51.default.join(this.dataDir, "sessions", safeFileName(personaId2)), { recursive: true, force: true });
67576
+ import_node_fs47.default.rmSync(import_node_path52.default.join(this.dataDir, "sessions", safeFileName(personaId2)), { recursive: true, force: true });
67444
67577
  const prefix = `persona:${personaId2}:`;
67445
67578
  for (const key of this.cache.keys()) {
67446
67579
  if (key.startsWith(prefix)) this.cache.delete(key);
@@ -67449,10 +67582,10 @@ var GroupFileStore = class {
67449
67582
  };
67450
67583
 
67451
67584
  // src/discovery/state-file.ts
67452
- var import_node_fs47 = __toESM(require("fs"), 1);
67453
- var import_node_path52 = __toESM(require("path"), 1);
67585
+ var import_node_fs48 = __toESM(require("fs"), 1);
67586
+ var import_node_path53 = __toESM(require("path"), 1);
67454
67587
  function defaultStateFilePath(dataDir) {
67455
- return import_node_path52.default.join(dataDir, "state.json");
67588
+ return import_node_path53.default.join(dataDir, "state.json");
67456
67589
  }
67457
67590
  function isPidAlive(pid) {
67458
67591
  if (!Number.isFinite(pid) || pid <= 0) return false;
@@ -67474,7 +67607,7 @@ var StateFileManager = class {
67474
67607
  }
67475
67608
  read() {
67476
67609
  try {
67477
- const raw = import_node_fs47.default.readFileSync(this.file, "utf8");
67610
+ const raw = import_node_fs48.default.readFileSync(this.file, "utf8");
67478
67611
  const parsed = JSON.parse(raw);
67479
67612
  return parsed;
67480
67613
  } catch {
@@ -67488,20 +67621,20 @@ var StateFileManager = class {
67488
67621
  return { status: "stale", existing };
67489
67622
  }
67490
67623
  write(state) {
67491
- import_node_fs47.default.mkdirSync(import_node_path52.default.dirname(this.file), { recursive: true });
67624
+ import_node_fs48.default.mkdirSync(import_node_path53.default.dirname(this.file), { recursive: true });
67492
67625
  const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
67493
- import_node_fs47.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
67494
- import_node_fs47.default.renameSync(tmp, this.file);
67626
+ import_node_fs48.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
67627
+ import_node_fs48.default.renameSync(tmp, this.file);
67495
67628
  if (process.platform !== "win32") {
67496
67629
  try {
67497
- import_node_fs47.default.chmodSync(this.file, 384);
67630
+ import_node_fs48.default.chmodSync(this.file, 384);
67498
67631
  } catch {
67499
67632
  }
67500
67633
  }
67501
67634
  }
67502
67635
  delete() {
67503
67636
  try {
67504
- import_node_fs47.default.unlinkSync(this.file);
67637
+ import_node_fs48.default.unlinkSync(this.file);
67505
67638
  } catch {
67506
67639
  }
67507
67640
  }
@@ -67515,14 +67648,14 @@ function readSpawnedByDesktopFromEnv(env = process.env) {
67515
67648
  }
67516
67649
 
67517
67650
  // src/tunnel/tunnel-manager.ts
67518
- var import_node_fs51 = __toESM(require("fs"), 1);
67519
- var import_node_path56 = __toESM(require("path"), 1);
67520
- var import_node_crypto15 = __toESM(require("crypto"), 1);
67651
+ var import_node_fs52 = __toESM(require("fs"), 1);
67652
+ var import_node_path57 = __toESM(require("path"), 1);
67653
+ var import_node_crypto16 = __toESM(require("crypto"), 1);
67521
67654
  var import_node_child_process16 = require("child_process");
67522
67655
 
67523
67656
  // src/tunnel/tunnel-store.ts
67524
- var import_node_fs48 = __toESM(require("fs"), 1);
67525
- var import_node_path53 = __toESM(require("path"), 1);
67657
+ var import_node_fs49 = __toESM(require("fs"), 1);
67658
+ var import_node_path54 = __toESM(require("path"), 1);
67526
67659
  var TunnelStore = class {
67527
67660
  constructor(filePath) {
67528
67661
  this.filePath = filePath;
@@ -67530,7 +67663,7 @@ var TunnelStore = class {
67530
67663
  filePath;
67531
67664
  async get() {
67532
67665
  try {
67533
- const raw = await import_node_fs48.default.promises.readFile(this.filePath, "utf8");
67666
+ const raw = await import_node_fs49.default.promises.readFile(this.filePath, "utf8");
67534
67667
  const obj = JSON.parse(raw);
67535
67668
  if (!isPersistedTunnel(obj)) return null;
67536
67669
  return obj;
@@ -67541,22 +67674,22 @@ var TunnelStore = class {
67541
67674
  }
67542
67675
  }
67543
67676
  async set(v3) {
67544
- const dir = import_node_path53.default.dirname(this.filePath);
67545
- await import_node_fs48.default.promises.mkdir(dir, { recursive: true });
67677
+ const dir = import_node_path54.default.dirname(this.filePath);
67678
+ await import_node_fs49.default.promises.mkdir(dir, { recursive: true });
67546
67679
  const data = JSON.stringify(v3, null, 2);
67547
67680
  const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
67548
- await import_node_fs48.default.promises.writeFile(tmp, data, { mode: 384 });
67681
+ await import_node_fs49.default.promises.writeFile(tmp, data, { mode: 384 });
67549
67682
  if (process.platform !== "win32") {
67550
67683
  try {
67551
- await import_node_fs48.default.promises.chmod(tmp, 384);
67684
+ await import_node_fs49.default.promises.chmod(tmp, 384);
67552
67685
  } catch {
67553
67686
  }
67554
67687
  }
67555
- await import_node_fs48.default.promises.rename(tmp, this.filePath);
67688
+ await import_node_fs49.default.promises.rename(tmp, this.filePath);
67556
67689
  }
67557
67690
  async clear() {
67558
67691
  try {
67559
- await import_node_fs48.default.promises.unlink(this.filePath);
67692
+ await import_node_fs49.default.promises.unlink(this.filePath);
67560
67693
  } catch (err) {
67561
67694
  const code = err?.code;
67562
67695
  if (code !== "ENOENT") throw err;
@@ -67651,12 +67784,12 @@ function escape2(v3) {
67651
67784
  }
67652
67785
 
67653
67786
  // src/tunnel/frpc-binary.ts
67654
- var import_node_fs49 = __toESM(require("fs"), 1);
67655
- var import_node_os18 = __toESM(require("os"), 1);
67656
- var import_node_path54 = __toESM(require("path"), 1);
67787
+ var import_node_fs50 = __toESM(require("fs"), 1);
67788
+ var import_node_os19 = __toESM(require("os"), 1);
67789
+ var import_node_path55 = __toESM(require("path"), 1);
67657
67790
  var import_node_child_process14 = require("child_process");
67658
- var import_node_stream3 = require("stream");
67659
- var import_promises9 = require("stream/promises");
67791
+ var import_node_stream4 = require("stream");
67792
+ var import_promises10 = require("stream/promises");
67660
67793
  var FRPC_VERSION = "0.68.0";
67661
67794
  var UnsupportedPlatformError = class extends Error {
67662
67795
  constructor(platform, arch) {
@@ -67685,20 +67818,20 @@ function frpcDownloadUrl(version2, p3) {
67685
67818
  }
67686
67819
  async function ensureFrpcBinary(opts) {
67687
67820
  if (opts.override) {
67688
- if (!import_node_fs49.default.existsSync(opts.override)) {
67821
+ if (!import_node_fs50.default.existsSync(opts.override)) {
67689
67822
  throw new Error(`frpc binary not found at override path: ${opts.override}`);
67690
67823
  }
67691
67824
  return opts.override;
67692
67825
  }
67693
67826
  const version2 = opts.version ?? FRPC_VERSION;
67694
67827
  const platform = opts.platform ?? detectPlatform();
67695
- const binDir = import_node_path54.default.join(opts.dataDir, "bin");
67696
- import_node_fs49.default.mkdirSync(binDir, { recursive: true });
67828
+ const binDir = import_node_path55.default.join(opts.dataDir, "bin");
67829
+ import_node_fs50.default.mkdirSync(binDir, { recursive: true });
67697
67830
  cleanupStaleArtifacts(binDir);
67698
- const stableBin = import_node_path54.default.join(binDir, "frpc");
67699
- if (import_node_fs49.default.existsSync(stableBin)) return stableBin;
67831
+ const stableBin = import_node_path55.default.join(binDir, "frpc");
67832
+ if (import_node_fs50.default.existsSync(stableBin)) return stableBin;
67700
67833
  const partialBin = `${stableBin}.partial`;
67701
- const tarballPath = import_node_path54.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
67834
+ const tarballPath = import_node_path55.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
67702
67835
  try {
67703
67836
  const url = frpcDownloadUrl(version2, platform);
67704
67837
  await downloadToFile(url, tarballPath, opts.fetchImpl);
@@ -67707,8 +67840,8 @@ async function ensureFrpcBinary(opts) {
67707
67840
  } else {
67708
67841
  await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
67709
67842
  }
67710
- import_node_fs49.default.chmodSync(partialBin, 493);
67711
- import_node_fs49.default.renameSync(partialBin, stableBin);
67843
+ import_node_fs50.default.chmodSync(partialBin, 493);
67844
+ import_node_fs50.default.renameSync(partialBin, stableBin);
67712
67845
  } finally {
67713
67846
  safeUnlink(tarballPath);
67714
67847
  safeUnlink(partialBin);
@@ -67718,15 +67851,15 @@ async function ensureFrpcBinary(opts) {
67718
67851
  function cleanupStaleArtifacts(binDir) {
67719
67852
  let entries;
67720
67853
  try {
67721
- entries = import_node_fs49.default.readdirSync(binDir);
67854
+ entries = import_node_fs50.default.readdirSync(binDir);
67722
67855
  } catch {
67723
67856
  return;
67724
67857
  }
67725
67858
  for (const name of entries) {
67726
67859
  if (name.endsWith(".partial") || name.startsWith("extract-")) {
67727
- const full = import_node_path54.default.join(binDir, name);
67860
+ const full = import_node_path55.default.join(binDir, name);
67728
67861
  try {
67729
- import_node_fs49.default.rmSync(full, { recursive: true, force: true });
67862
+ import_node_fs50.default.rmSync(full, { recursive: true, force: true });
67730
67863
  } catch {
67731
67864
  }
67732
67865
  }
@@ -67734,7 +67867,7 @@ function cleanupStaleArtifacts(binDir) {
67734
67867
  }
67735
67868
  function safeUnlink(p3) {
67736
67869
  try {
67737
- import_node_fs49.default.unlinkSync(p3);
67870
+ import_node_fs50.default.unlinkSync(p3);
67738
67871
  } catch {
67739
67872
  }
67740
67873
  }
@@ -67745,13 +67878,13 @@ async function downloadToFile(url, dest, fetchImpl) {
67745
67878
  if (!res.ok || !res.body) {
67746
67879
  throw new Error(`download failed: ${res.status} ${res.statusText}`);
67747
67880
  }
67748
- const out = import_node_fs49.default.createWriteStream(dest);
67749
- const nodeStream = import_node_stream3.Readable.fromWeb(res.body);
67750
- await (0, import_promises9.pipeline)(nodeStream, out);
67881
+ const out = import_node_fs50.default.createWriteStream(dest);
67882
+ const nodeStream = import_node_stream4.Readable.fromWeb(res.body);
67883
+ await (0, import_promises10.pipeline)(nodeStream, out);
67751
67884
  }
67752
67885
  async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
67753
- const work = import_node_path54.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
67754
- import_node_fs49.default.mkdirSync(work, { recursive: true });
67886
+ const work = import_node_path55.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
67887
+ import_node_fs50.default.mkdirSync(work, { recursive: true });
67755
67888
  try {
67756
67889
  await new Promise((resolve9, reject) => {
67757
67890
  const proc = (0, import_node_child_process14.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
@@ -67759,32 +67892,32 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
67759
67892
  proc.on("exit", (code) => code === 0 ? resolve9() : reject(new Error(`tar exited ${code}`)));
67760
67893
  });
67761
67894
  const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
67762
- const src = import_node_path54.default.join(work, dirName, "frpc");
67763
- if (!import_node_fs49.default.existsSync(src)) {
67895
+ const src = import_node_path55.default.join(work, dirName, "frpc");
67896
+ if (!import_node_fs50.default.existsSync(src)) {
67764
67897
  throw new Error(`frpc not found inside tarball at ${src}`);
67765
67898
  }
67766
- import_node_fs49.default.copyFileSync(src, destBin);
67899
+ import_node_fs50.default.copyFileSync(src, destBin);
67767
67900
  } finally {
67768
- import_node_fs49.default.rmSync(work, { recursive: true, force: true });
67901
+ import_node_fs50.default.rmSync(work, { recursive: true, force: true });
67769
67902
  }
67770
67903
  }
67771
67904
 
67772
67905
  // src/tunnel/frpc-process.ts
67773
- var import_node_fs50 = __toESM(require("fs"), 1);
67774
- var import_node_path55 = __toESM(require("path"), 1);
67906
+ var import_node_fs51 = __toESM(require("fs"), 1);
67907
+ var import_node_path56 = __toESM(require("path"), 1);
67775
67908
  var import_node_child_process15 = require("child_process");
67776
67909
  function frpcPidFilePath(dataDir) {
67777
- return import_node_path55.default.join(dataDir, "frpc.pid");
67910
+ return import_node_path56.default.join(dataDir, "frpc.pid");
67778
67911
  }
67779
67912
  function writeFrpcPid(dataDir, pid) {
67780
67913
  try {
67781
- import_node_fs50.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
67914
+ import_node_fs51.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
67782
67915
  } catch {
67783
67916
  }
67784
67917
  }
67785
67918
  function clearFrpcPid(dataDir) {
67786
67919
  try {
67787
- import_node_fs50.default.unlinkSync(frpcPidFilePath(dataDir));
67920
+ import_node_fs51.default.unlinkSync(frpcPidFilePath(dataDir));
67788
67921
  } catch {
67789
67922
  }
67790
67923
  }
@@ -67800,7 +67933,7 @@ function defaultIsPidAlive(pid) {
67800
67933
  }
67801
67934
  function defaultReadPidFile(file) {
67802
67935
  try {
67803
- return import_node_fs50.default.readFileSync(file, "utf8");
67936
+ return import_node_fs51.default.readFileSync(file, "utf8");
67804
67937
  } catch {
67805
67938
  return null;
67806
67939
  }
@@ -67816,7 +67949,7 @@ function defaultSleep2(ms) {
67816
67949
  }
67817
67950
  async function killStaleFrpc(deps) {
67818
67951
  const pidFile = frpcPidFilePath(deps.dataDir);
67819
- const tomlPath = import_node_path55.default.join(deps.dataDir, "frpc.toml");
67952
+ const tomlPath = import_node_path56.default.join(deps.dataDir, "frpc.toml");
67820
67953
  const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
67821
67954
  const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
67822
67955
  const killPid = deps.killPidImpl ?? defaultKillPid;
@@ -67840,7 +67973,7 @@ async function killStaleFrpc(deps) {
67840
67973
  }
67841
67974
  if (victims.size === 0) {
67842
67975
  try {
67843
- import_node_fs50.default.unlinkSync(pidFile);
67976
+ import_node_fs51.default.unlinkSync(pidFile);
67844
67977
  } catch {
67845
67978
  }
67846
67979
  return;
@@ -67851,7 +67984,7 @@ async function killStaleFrpc(deps) {
67851
67984
  }
67852
67985
  await sleep2(deps.reapWaitMs ?? 300);
67853
67986
  try {
67854
- import_node_fs50.default.unlinkSync(pidFile);
67987
+ import_node_fs51.default.unlinkSync(pidFile);
67855
67988
  } catch {
67856
67989
  }
67857
67990
  }
@@ -67888,7 +68021,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
67888
68021
  var TunnelManager = class {
67889
68022
  constructor(deps) {
67890
68023
  this.deps = deps;
67891
- this.store = deps.store ?? new TunnelStore(import_node_path56.default.join(deps.dataDir, "tunnel.json"));
68024
+ this.store = deps.store ?? new TunnelStore(import_node_path57.default.join(deps.dataDir, "tunnel.json"));
67892
68025
  this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
67893
68026
  this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
67894
68027
  }
@@ -68015,8 +68148,8 @@ var TunnelManager = class {
68015
68148
  dataDir: this.deps.dataDir,
68016
68149
  override: this.deps.frpcBinaryOverride ?? void 0
68017
68150
  });
68018
- const tomlPath = import_node_path56.default.join(this.deps.dataDir, "frpc.toml");
68019
- const proxyName = `clawd-${t2.subdomain}-${localPort}-${import_node_crypto15.default.randomBytes(3).toString("hex")}`;
68151
+ const tomlPath = import_node_path57.default.join(this.deps.dataDir, "frpc.toml");
68152
+ const proxyName = `clawd-${t2.subdomain}-${localPort}-${import_node_crypto16.default.randomBytes(3).toString("hex")}`;
68020
68153
  const toml = buildFrpcToml({
68021
68154
  serverAddr: t2.frpsHost,
68022
68155
  serverPort: t2.frpsPort,
@@ -68026,14 +68159,14 @@ var TunnelManager = class {
68026
68159
  localPort,
68027
68160
  logLevel: "info"
68028
68161
  });
68029
- await import_node_fs51.default.promises.writeFile(tomlPath, toml, { mode: 384 });
68162
+ await import_node_fs52.default.promises.writeFile(tomlPath, toml, { mode: 384 });
68030
68163
  const proc = (this.deps.spawnImpl ?? import_node_child_process16.spawn)(frpcBin, ["-c", tomlPath], {
68031
68164
  stdio: ["ignore", "pipe", "pipe"]
68032
68165
  });
68033
- const logDir = import_node_path56.default.join(this.deps.dataDir, "log");
68034
- import_node_fs51.default.mkdirSync(logDir, { recursive: true });
68035
- const logFilePath = import_node_path56.default.join(logDir, "frpc.log");
68036
- const logStream = import_node_fs51.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
68166
+ const logDir = import_node_path57.default.join(this.deps.dataDir, "log");
68167
+ import_node_fs52.default.mkdirSync(logDir, { recursive: true });
68168
+ const logFilePath = import_node_path57.default.join(logDir, "frpc.log");
68169
+ const logStream = import_node_fs52.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
68037
68170
  logStream.on("error", () => {
68038
68171
  });
68039
68172
  const tee = (chunk) => {
@@ -68115,28 +68248,28 @@ async function waitForFrpcReady(proc, timeoutMs) {
68115
68248
  }
68116
68249
 
68117
68250
  // src/tunnel/device-key.ts
68118
- var import_node_os19 = __toESM(require("os"), 1);
68119
- var import_node_path57 = __toESM(require("path"), 1);
68120
- var import_node_crypto16 = __toESM(require("crypto"), 1);
68251
+ var import_node_os20 = __toESM(require("os"), 1);
68252
+ var import_node_path58 = __toESM(require("path"), 1);
68253
+ var import_node_crypto17 = __toESM(require("crypto"), 1);
68121
68254
  var DERIVE_SALT = "clawd-tunnel-device-v1";
68122
68255
  function deriveStableDeviceKey(opts = {}) {
68123
- const hostname = opts.hostname ?? import_node_os19.default.hostname();
68124
- const uid = opts.uid ?? (typeof import_node_os19.default.userInfo === "function" ? import_node_os19.default.userInfo().uid : 0);
68125
- const home = opts.home ?? import_node_os19.default.homedir();
68126
- const defaultDataDir = import_node_path57.default.resolve(import_node_path57.default.join(home, ".clawd"));
68127
- const normalizedDataDir = opts.dataDir ? import_node_path57.default.resolve(opts.dataDir) : null;
68256
+ const hostname = opts.hostname ?? import_node_os20.default.hostname();
68257
+ const uid = opts.uid ?? (typeof import_node_os20.default.userInfo === "function" ? import_node_os20.default.userInfo().uid : 0);
68258
+ const home = opts.home ?? import_node_os20.default.homedir();
68259
+ const defaultDataDir = import_node_path58.default.resolve(import_node_path58.default.join(home, ".clawd"));
68260
+ const normalizedDataDir = opts.dataDir ? import_node_path58.default.resolve(opts.dataDir) : null;
68128
68261
  const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
68129
68262
  const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
68130
- return import_node_crypto16.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
68263
+ return import_node_crypto17.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
68131
68264
  }
68132
68265
 
68133
68266
  // src/auth-store.ts
68134
- var import_node_fs52 = __toESM(require("fs"), 1);
68135
- var import_node_path58 = __toESM(require("path"), 1);
68136
- var import_node_crypto17 = __toESM(require("crypto"), 1);
68267
+ var import_node_fs53 = __toESM(require("fs"), 1);
68268
+ var import_node_path59 = __toESM(require("path"), 1);
68269
+ var import_node_crypto18 = __toESM(require("crypto"), 1);
68137
68270
  var AUTH_FILE_NAME = "auth.json";
68138
68271
  function authFilePath(dataDir) {
68139
- return import_node_path58.default.join(dataDir, AUTH_FILE_NAME);
68272
+ return import_node_path59.default.join(dataDir, AUTH_FILE_NAME);
68140
68273
  }
68141
68274
  function loadOrCreateAuthFile(opts) {
68142
68275
  const file = authFilePath(opts.dataDir);
@@ -68170,14 +68303,14 @@ function loadOrCreateTunnelDeviceKey(opts) {
68170
68303
  return tunnelDeviceKey;
68171
68304
  }
68172
68305
  function defaultGenerateToken() {
68173
- return import_node_crypto17.default.randomBytes(32).toString("base64url");
68306
+ return import_node_crypto18.default.randomBytes(32).toString("base64url");
68174
68307
  }
68175
68308
  function defaultGenerateOwnerPrincipalId() {
68176
- return `owner-${import_node_crypto17.default.randomUUID()}`;
68309
+ return `owner-${import_node_crypto18.default.randomUUID()}`;
68177
68310
  }
68178
68311
  function readAuthFile(file) {
68179
68312
  try {
68180
- const raw = import_node_fs52.default.readFileSync(file, "utf8");
68313
+ const raw = import_node_fs53.default.readFileSync(file, "utf8");
68181
68314
  const parsed = JSON.parse(raw);
68182
68315
  if (typeof parsed?.token !== "string" || parsed.token.length === 0) {
68183
68316
  return null;
@@ -68198,26 +68331,26 @@ function readAuthFile(file) {
68198
68331
  }
68199
68332
  }
68200
68333
  function writeAuthFile(file, content) {
68201
- import_node_fs52.default.mkdirSync(import_node_path58.default.dirname(file), { recursive: true });
68202
- import_node_fs52.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
68334
+ import_node_fs53.default.mkdirSync(import_node_path59.default.dirname(file), { recursive: true });
68335
+ import_node_fs53.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
68203
68336
  try {
68204
- import_node_fs52.default.chmodSync(file, 384);
68337
+ import_node_fs53.default.chmodSync(file, 384);
68205
68338
  } catch {
68206
68339
  }
68207
68340
  }
68208
68341
 
68209
68342
  // src/owner-profile.ts
68210
- var import_node_fs53 = __toESM(require("fs"), 1);
68211
- var import_node_os20 = __toESM(require("os"), 1);
68212
- var import_node_path59 = __toESM(require("path"), 1);
68343
+ var import_node_fs54 = __toESM(require("fs"), 1);
68344
+ var import_node_os21 = __toESM(require("os"), 1);
68345
+ var import_node_path60 = __toESM(require("path"), 1);
68213
68346
  var PROFILE_FILENAME = "profile.json";
68214
68347
  function profilePath(dataDir) {
68215
- return import_node_path59.default.join(dataDir, PROFILE_FILENAME);
68348
+ return import_node_path60.default.join(dataDir, PROFILE_FILENAME);
68216
68349
  }
68217
68350
  function loadOwnerProfile(dataDir) {
68218
68351
  let raw;
68219
68352
  try {
68220
- raw = import_node_fs53.default.readFileSync(profilePath(dataDir), "utf8");
68353
+ raw = import_node_fs54.default.readFileSync(profilePath(dataDir), "utf8");
68221
68354
  } catch {
68222
68355
  return {};
68223
68356
  }
@@ -68233,11 +68366,11 @@ function loadOwnerProfile(dataDir) {
68233
68366
  }
68234
68367
  function patchOwnerProfile(dataDir, patch) {
68235
68368
  const merged = { ...loadOwnerProfile(dataDir), ...patch };
68236
- import_node_fs53.default.writeFileSync(profilePath(dataDir), JSON.stringify(merged, null, 2), { encoding: "utf8", mode: 384 });
68369
+ import_node_fs54.default.writeFileSync(profilePath(dataDir), JSON.stringify(merged, null, 2), { encoding: "utf8", mode: 384 });
68237
68370
  return merged;
68238
68371
  }
68239
68372
  function loadOwnerDisplayName(dataDir) {
68240
- const fallback = import_node_os20.default.userInfo().username;
68373
+ const fallback = import_node_os21.default.userInfo().username;
68241
68374
  const displayName = loadOwnerProfile(dataDir).displayName;
68242
68375
  if (typeof displayName !== "string" || displayName.length === 0) {
68243
68376
  if (displayName !== void 0) {
@@ -68249,18 +68382,18 @@ function loadOwnerDisplayName(dataDir) {
68249
68382
  }
68250
68383
 
68251
68384
  // src/feishu-auth/owner-identity-store.ts
68252
- var import_node_fs54 = __toESM(require("fs"), 1);
68253
- var import_node_path60 = __toESM(require("path"), 1);
68385
+ var import_node_fs55 = __toESM(require("fs"), 1);
68386
+ var import_node_path61 = __toESM(require("path"), 1);
68254
68387
  var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
68255
68388
  var OwnerIdentityStore = class {
68256
68389
  file;
68257
68390
  constructor(dataDir) {
68258
- this.file = import_node_path60.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
68391
+ this.file = import_node_path61.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
68259
68392
  }
68260
68393
  read() {
68261
68394
  let raw;
68262
68395
  try {
68263
- raw = import_node_fs54.default.readFileSync(this.file, "utf8");
68396
+ raw = import_node_fs55.default.readFileSync(this.file, "utf8");
68264
68397
  } catch {
68265
68398
  return null;
68266
68399
  }
@@ -68287,16 +68420,16 @@ var OwnerIdentityStore = class {
68287
68420
  };
68288
68421
  }
68289
68422
  write(record4) {
68290
- import_node_fs54.default.mkdirSync(import_node_path60.default.dirname(this.file), { recursive: true });
68291
- import_node_fs54.default.writeFileSync(this.file, JSON.stringify(record4, null, 2), { mode: 384 });
68423
+ import_node_fs55.default.mkdirSync(import_node_path61.default.dirname(this.file), { recursive: true });
68424
+ import_node_fs55.default.writeFileSync(this.file, JSON.stringify(record4, null, 2), { mode: 384 });
68292
68425
  try {
68293
- import_node_fs54.default.chmodSync(this.file, 384);
68426
+ import_node_fs55.default.chmodSync(this.file, 384);
68294
68427
  } catch {
68295
68428
  }
68296
68429
  }
68297
68430
  clear() {
68298
68431
  try {
68299
- import_node_fs54.default.unlinkSync(this.file);
68432
+ import_node_fs55.default.unlinkSync(this.file);
68300
68433
  } catch (err) {
68301
68434
  const code = err?.code;
68302
68435
  if (code !== "ENOENT") throw err;
@@ -68305,7 +68438,7 @@ var OwnerIdentityStore = class {
68305
68438
  };
68306
68439
 
68307
68440
  // src/feishu-auth/login-flow.ts
68308
- var import_node_crypto18 = __toESM(require("crypto"), 1);
68441
+ var import_node_crypto19 = __toESM(require("crypto"), 1);
68309
68442
  var STATE_TTL_MS = 5 * 60 * 1e3;
68310
68443
  var LoginFlow = class {
68311
68444
  constructor(deps) {
@@ -68314,7 +68447,7 @@ var LoginFlow = class {
68314
68447
  deps;
68315
68448
  pendingStates = /* @__PURE__ */ new Map();
68316
68449
  start() {
68317
- const state = import_node_crypto18.default.randomBytes(16).toString("base64url");
68450
+ const state = import_node_crypto19.default.randomBytes(16).toString("base64url");
68318
68451
  const now = (this.deps.now ?? Date.now)();
68319
68452
  this.pendingStates.set(state, now);
68320
68453
  this.gcExpired(now);
@@ -68792,8 +68925,8 @@ function verifyConnectToken(args) {
68792
68925
  }
68793
68926
 
68794
68927
  // src/feishu-auth/server-key.ts
68795
- var fs71 = __toESM(require("fs"), 1);
68796
- var path73 = __toESM(require("path"), 1);
68928
+ var fs72 = __toESM(require("fs"), 1);
68929
+ var path74 = __toESM(require("path"), 1);
68797
68930
  var FILE_NAME2 = "server-signing-key.json";
68798
68931
  var ServerKeyStore = class {
68799
68932
  constructor(dataDir) {
@@ -68801,12 +68934,12 @@ var ServerKeyStore = class {
68801
68934
  }
68802
68935
  dataDir;
68803
68936
  filePath() {
68804
- return path73.join(this.dataDir, FILE_NAME2);
68937
+ return path74.join(this.dataDir, FILE_NAME2);
68805
68938
  }
68806
68939
  /** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
68807
68940
  read() {
68808
68941
  try {
68809
- const raw = fs71.readFileSync(this.filePath(), "utf8");
68942
+ const raw = fs72.readFileSync(this.filePath(), "utf8");
68810
68943
  const parsed = JSON.parse(raw);
68811
68944
  if (typeof parsed.publicKeyPem === "string" && parsed.publicKeyPem.includes("PUBLIC KEY")) {
68812
68945
  return parsed.publicKeyPem;
@@ -68821,12 +68954,12 @@ var ServerKeyStore = class {
68821
68954
  publicKeyPem,
68822
68955
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
68823
68956
  };
68824
- fs71.mkdirSync(this.dataDir, { recursive: true });
68825
- fs71.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
68957
+ fs72.mkdirSync(this.dataDir, { recursive: true });
68958
+ fs72.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
68826
68959
  }
68827
68960
  clear() {
68828
68961
  try {
68829
- fs71.unlinkSync(this.filePath());
68962
+ fs72.unlinkSync(this.filePath());
68830
68963
  } catch {
68831
68964
  }
68832
68965
  }
@@ -68836,19 +68969,19 @@ var ServerKeyStore = class {
68836
68969
  init_protocol();
68837
68970
 
68838
68971
  // src/handlers/index.ts
68839
- var import_node_path74 = __toESM(require("path"), 1);
68972
+ var import_node_path75 = __toESM(require("path"), 1);
68840
68973
 
68841
68974
  // src/handlers/session.ts
68842
68975
  init_protocol();
68843
68976
 
68844
68977
  // src/session/fork.ts
68845
- var import_node_fs55 = __toESM(require("fs"), 1);
68846
- var import_node_os21 = __toESM(require("os"), 1);
68847
- var import_node_path61 = __toESM(require("path"), 1);
68848
- var import_node_crypto19 = require("crypto");
68978
+ var import_node_fs56 = __toESM(require("fs"), 1);
68979
+ var import_node_os22 = __toESM(require("os"), 1);
68980
+ var import_node_path62 = __toESM(require("path"), 1);
68981
+ var import_node_crypto20 = require("crypto");
68849
68982
  init_claude_history();
68850
68983
  function readJsonlEntries(file) {
68851
- const raw = import_node_fs55.default.readFileSync(file, "utf8");
68984
+ const raw = import_node_fs56.default.readFileSync(file, "utf8");
68852
68985
  const out = [];
68853
68986
  for (const line of raw.split("\n")) {
68854
68987
  const t2 = line.trim();
@@ -68861,19 +68994,19 @@ function readJsonlEntries(file) {
68861
68994
  return out;
68862
68995
  }
68863
68996
  function forkSession(input) {
68864
- const baseDir = input.baseDir ?? import_node_path61.default.join(import_node_os21.default.homedir(), ".claude");
68865
- let projectDir = import_node_path61.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
68866
- let sourceFile = import_node_path61.default.join(projectDir, `${input.toolSessionId}.jsonl`);
68867
- if (!import_node_fs55.default.existsSync(sourceFile)) {
68997
+ const baseDir = input.baseDir ?? import_node_path62.default.join(import_node_os22.default.homedir(), ".claude");
68998
+ let projectDir = import_node_path62.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
68999
+ let sourceFile = import_node_path62.default.join(projectDir, `${input.toolSessionId}.jsonl`);
69000
+ if (!import_node_fs56.default.existsSync(sourceFile)) {
68868
69001
  const found = findTranscriptByToolSessionId(
68869
- import_node_path61.default.join(baseDir, "projects"),
69002
+ import_node_path62.default.join(baseDir, "projects"),
68870
69003
  input.toolSessionId
68871
69004
  );
68872
69005
  if (!found) {
68873
69006
  throw new Error(`fork: source transcript not found: ${sourceFile}`);
68874
69007
  }
68875
69008
  sourceFile = found;
68876
- projectDir = import_node_path61.default.dirname(found);
69009
+ projectDir = import_node_path62.default.dirname(found);
68877
69010
  }
68878
69011
  const entries = readJsonlEntries(sourceFile);
68879
69012
  const mainEntries = entries.filter((e) => e.isSidechain !== true);
@@ -68882,7 +69015,7 @@ function forkSession(input) {
68882
69015
  throw new Error(`fork: messageUuid not found in transcript: ${input.messageUuid}`);
68883
69016
  }
68884
69017
  const sliced = mainEntries.slice(0, targetIdx + 1);
68885
- const forkedToolSessionId = (0, import_node_crypto19.randomUUID)();
69018
+ const forkedToolSessionId = (0, import_node_crypto20.randomUUID)();
68886
69019
  let parentUuid = null;
68887
69020
  const forkedLines = [];
68888
69021
  for (const entry of sliced) {
@@ -68902,27 +69035,27 @@ function forkSession(input) {
68902
69035
  }
68903
69036
  forkedLines.push(JSON.stringify(forked));
68904
69037
  }
68905
- const outDir = input.targetCwd ? import_node_path61.default.join(baseDir, "projects", cwdToHashDir(input.targetCwd)) : projectDir;
68906
- const forkedFilePath = import_node_path61.default.join(outDir, `${forkedToolSessionId}.jsonl`);
68907
- import_node_fs55.default.mkdirSync(outDir, { recursive: true });
68908
- import_node_fs55.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
69038
+ const outDir = input.targetCwd ? import_node_path62.default.join(baseDir, "projects", cwdToHashDir(input.targetCwd)) : projectDir;
69039
+ const forkedFilePath = import_node_path62.default.join(outDir, `${forkedToolSessionId}.jsonl`);
69040
+ import_node_fs56.default.mkdirSync(outDir, { recursive: true });
69041
+ import_node_fs56.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
68909
69042
  return { forkedToolSessionId, forkedFilePath };
68910
69043
  }
68911
69044
 
68912
69045
  // src/session/external-scan.ts
68913
- var import_node_fs56 = __toESM(require("fs"), 1);
68914
- var import_promises10 = __toESM(require("fs/promises"), 1);
68915
- var import_node_os22 = __toESM(require("os"), 1);
68916
- var import_node_path62 = __toESM(require("path"), 1);
69046
+ var import_node_fs57 = __toESM(require("fs"), 1);
69047
+ var import_promises11 = __toESM(require("fs/promises"), 1);
69048
+ var import_node_os23 = __toESM(require("os"), 1);
69049
+ var import_node_path63 = __toESM(require("path"), 1);
68917
69050
  var import_node_module = require("module");
68918
69051
  var import_node_child_process17 = require("child_process");
68919
69052
  var import_meta6 = {};
68920
69053
  function defaultRoots() {
68921
- const home = import_node_os22.default.homedir();
69054
+ const home = import_node_os23.default.homedir();
68922
69055
  return {
68923
- claudeProjectsDir: import_node_path62.default.join(home, ".claude", "projects"),
68924
- codexDir: import_node_path62.default.join(home, ".codex"),
68925
- clawdDir: import_node_path62.default.join(home, ".clawd")
69056
+ claudeProjectsDir: import_node_path63.default.join(home, ".claude", "projects"),
69057
+ codexDir: import_node_path63.default.join(home, ".codex"),
69058
+ clawdDir: import_node_path63.default.join(home, ".clawd")
68926
69059
  };
68927
69060
  }
68928
69061
  function width(s2) {
@@ -68950,7 +69083,7 @@ function toMs(v3) {
68950
69083
  async function* jsonLines(file) {
68951
69084
  let raw;
68952
69085
  try {
68953
- raw = await import_promises10.default.readFile(file, "utf8");
69086
+ raw = await import_promises11.default.readFile(file, "utf8");
68954
69087
  } catch {
68955
69088
  return;
68956
69089
  }
@@ -68973,7 +69106,7 @@ function userText(msg) {
68973
69106
  }
68974
69107
  function isDir2(p3) {
68975
69108
  try {
68976
- return import_node_fs56.default.statSync(p3).isDirectory();
69109
+ return import_node_fs57.default.statSync(p3).isDirectory();
68977
69110
  } catch {
68978
69111
  return false;
68979
69112
  }
@@ -68982,7 +69115,7 @@ async function scanClaude(roots) {
68982
69115
  const out = [];
68983
69116
  let dirs;
68984
69117
  try {
68985
- dirs = import_node_fs56.default.readdirSync(roots.claudeProjectsDir, { withFileTypes: true });
69118
+ dirs = import_node_fs57.default.readdirSync(roots.claudeProjectsDir, { withFileTypes: true });
68986
69119
  } catch {
68987
69120
  return out;
68988
69121
  }
@@ -68990,16 +69123,16 @@ async function scanClaude(roots) {
68990
69123
  if (!d2.isDirectory()) continue;
68991
69124
  let files;
68992
69125
  try {
68993
- files = import_node_fs56.default.readdirSync(import_node_path62.default.join(roots.claudeProjectsDir, d2.name));
69126
+ files = import_node_fs57.default.readdirSync(import_node_path63.default.join(roots.claudeProjectsDir, d2.name));
68994
69127
  } catch {
68995
69128
  continue;
68996
69129
  }
68997
69130
  for (const name of files) {
68998
69131
  if (!name.endsWith(".jsonl")) continue;
68999
- const file = import_node_path62.default.join(roots.claudeProjectsDir, d2.name, name);
69132
+ const file = import_node_path63.default.join(roots.claudeProjectsDir, d2.name, name);
69000
69133
  let st2;
69001
69134
  try {
69002
- st2 = import_node_fs56.default.statSync(file);
69135
+ st2 = import_node_fs57.default.statSync(file);
69003
69136
  } catch {
69004
69137
  continue;
69005
69138
  }
@@ -69052,7 +69185,7 @@ async function scanClaude(roots) {
69052
69185
  return out;
69053
69186
  }
69054
69187
  async function countCodexTurns(rolloutPath) {
69055
- if (!rolloutPath || !import_node_fs56.default.existsSync(rolloutPath)) return { turns: 0, first: "" };
69188
+ if (!rolloutPath || !import_node_fs57.default.existsSync(rolloutPath)) return { turns: 0, first: "" };
69056
69189
  let turns = 0;
69057
69190
  let first = "";
69058
69191
  for await (const rec6 of jsonLines(rolloutPath)) {
@@ -69126,7 +69259,7 @@ async function codexFromRows(rows) {
69126
69259
  async function scanCodex(roots) {
69127
69260
  let dbs = [];
69128
69261
  try {
69129
- dbs = import_node_fs56.default.readdirSync(roots.codexDir).filter((n2) => /^state_.*\.sqlite$/.test(n2)).sort().map((n2) => import_node_path62.default.join(roots.codexDir, n2));
69262
+ dbs = import_node_fs57.default.readdirSync(roots.codexDir).filter((n2) => /^state_.*\.sqlite$/.test(n2)).sort().map((n2) => import_node_path63.default.join(roots.codexDir, n2));
69130
69263
  } catch {
69131
69264
  }
69132
69265
  if (!dbs.length) return [];
@@ -69135,14 +69268,14 @@ async function scanCodex(roots) {
69135
69268
  }
69136
69269
  async function scanExternalSessions(rootsIn) {
69137
69270
  const roots = { ...defaultRoots(), ...rootsIn };
69138
- const personaRoot = import_node_path62.default.join(roots.clawdDir, "personas");
69271
+ const personaRoot = import_node_path63.default.join(roots.clawdDir, "personas");
69139
69272
  const all = [...await scanClaude(roots), ...await scanCodex(roots)];
69140
69273
  const out = [];
69141
69274
  for (const c2 of all) {
69142
69275
  if (c2.skip) continue;
69143
69276
  if (c2.turns < 1) continue;
69144
69277
  if (!c2.cwd || !isDir2(c2.cwd)) continue;
69145
- if (c2.cwd === roots.clawdDir || c2.cwd === personaRoot || c2.cwd.startsWith(personaRoot + import_node_path62.default.sep) || c2.cwd.startsWith(roots.clawdDir + import_node_path62.default.sep)) {
69278
+ if (c2.cwd === roots.clawdDir || c2.cwd === personaRoot || c2.cwd.startsWith(personaRoot + import_node_path63.default.sep) || c2.cwd.startsWith(roots.clawdDir + import_node_path63.default.sep)) {
69146
69279
  continue;
69147
69280
  }
69148
69281
  out.push({
@@ -69159,13 +69292,13 @@ async function scanExternalSessions(rootsIn) {
69159
69292
  }
69160
69293
 
69161
69294
  // src/session/import-ledger.ts
69162
- var import_node_fs57 = __toESM(require("fs"), 1);
69163
- var import_node_path63 = __toESM(require("path"), 1);
69295
+ var import_node_fs58 = __toESM(require("fs"), 1);
69296
+ var import_node_path64 = __toESM(require("path"), 1);
69164
69297
  var LEDGER_FILENAME = "session-import-ledger.json";
69165
69298
  function readImportLedger(dataDir) {
69166
69299
  try {
69167
69300
  const parsed = JSON.parse(
69168
- import_node_fs57.default.readFileSync(import_node_path63.default.join(dataDir, LEDGER_FILENAME), "utf8")
69301
+ import_node_fs58.default.readFileSync(import_node_path64.default.join(dataDir, LEDGER_FILENAME), "utf8")
69169
69302
  );
69170
69303
  return Array.isArray(parsed) ? parsed : [];
69171
69304
  } catch {
@@ -69173,10 +69306,10 @@ function readImportLedger(dataDir) {
69173
69306
  }
69174
69307
  }
69175
69308
  function appendImportLedger(dataDir, entry) {
69176
- const file = import_node_path63.default.join(dataDir, LEDGER_FILENAME);
69309
+ const file = import_node_path64.default.join(dataDir, LEDGER_FILENAME);
69177
69310
  const entries = readImportLedger(dataDir);
69178
69311
  entries.push(entry);
69179
- import_node_fs57.default.writeFileSync(file, JSON.stringify(entries, null, 2), { encoding: "utf8", mode: 384 });
69312
+ import_node_fs58.default.writeFileSync(file, JSON.stringify(entries, null, 2), { encoding: "utf8", mode: 384 });
69180
69313
  }
69181
69314
 
69182
69315
  // src/handlers/session.ts
@@ -69709,7 +69842,7 @@ function buildPermissionHandlers(deps) {
69709
69842
  }
69710
69843
 
69711
69844
  // src/handlers/history.ts
69712
- var path78 = __toESM(require("path"), 1);
69845
+ var path79 = __toESM(require("path"), 1);
69713
69846
  init_protocol();
69714
69847
 
69715
69848
  // src/session/recent-dirs.ts
@@ -69727,7 +69860,7 @@ function listRecentDirs(store, limit = 50) {
69727
69860
  }
69728
69861
 
69729
69862
  // src/permission/persona-paths.ts
69730
- var path77 = __toESM(require("path"), 1);
69863
+ var path78 = __toESM(require("path"), 1);
69731
69864
  function getAllowedPersonaIds(grants, action) {
69732
69865
  const ids = /* @__PURE__ */ new Set();
69733
69866
  for (const g3 of grants) {
@@ -69740,42 +69873,42 @@ function getAllowedPersonaIds(grants, action) {
69740
69873
  return ids;
69741
69874
  }
69742
69875
  function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
69743
- const target = path77.resolve(absPath);
69876
+ const target = path78.resolve(absPath);
69744
69877
  if (userWorkDir) {
69745
- const u2 = path77.resolve(userWorkDir);
69746
- const usep = u2.endsWith(path77.sep) ? "" : path77.sep;
69878
+ const u2 = path78.resolve(userWorkDir);
69879
+ const usep = u2.endsWith(path78.sep) ? "" : path78.sep;
69747
69880
  if (target === u2 || target.startsWith(u2 + usep)) return true;
69748
69881
  }
69749
- const root = path77.resolve(personaRoot);
69750
- const sep4 = root.endsWith(path77.sep) ? "" : path77.sep;
69882
+ const root = path78.resolve(personaRoot);
69883
+ const sep4 = root.endsWith(path78.sep) ? "" : path78.sep;
69751
69884
  if (!target.startsWith(root + sep4)) return false;
69752
- const rel = path77.relative(root, target);
69885
+ const rel = path78.relative(root, target);
69753
69886
  if (!rel || rel.startsWith("..")) return false;
69754
- const personaId2 = rel.split(path77.sep)[0];
69887
+ const personaId2 = rel.split(path78.sep)[0];
69755
69888
  if (!personaId2) return false;
69756
69889
  const allowed = getAllowedPersonaIds(grants, action);
69757
69890
  if (allowed === "*") return true;
69758
69891
  return allowed.has(personaId2);
69759
69892
  }
69760
69893
  function personaIdFromPath(absPath, personaRoot) {
69761
- const root = path77.resolve(personaRoot);
69762
- const target = path77.resolve(absPath);
69763
- const sep4 = root.endsWith(path77.sep) ? "" : path77.sep;
69894
+ const root = path78.resolve(personaRoot);
69895
+ const target = path78.resolve(absPath);
69896
+ const sep4 = root.endsWith(path78.sep) ? "" : path78.sep;
69764
69897
  if (!target.startsWith(root + sep4)) return null;
69765
- const rel = path77.relative(root, target);
69898
+ const rel = path78.relative(root, target);
69766
69899
  if (!rel || rel.startsWith("..")) return null;
69767
- const id = rel.split(path77.sep)[0];
69900
+ const id = rel.split(path78.sep)[0];
69768
69901
  return id || null;
69769
69902
  }
69770
69903
  function isPathWithin(dir, absPath) {
69771
- const d2 = path77.resolve(dir);
69772
- const t2 = path77.resolve(absPath);
69773
- const sep4 = d2.endsWith(path77.sep) ? "" : path77.sep;
69904
+ const d2 = path78.resolve(dir);
69905
+ const t2 = path78.resolve(absPath);
69906
+ const sep4 = d2.endsWith(path78.sep) ? "" : path78.sep;
69774
69907
  return t2 === d2 || t2.startsWith(d2 + sep4);
69775
69908
  }
69776
69909
  function isPathInGuestBoundary(personaRoot, personaId2, userWorkDir, absPath) {
69777
69910
  if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
69778
- return personaIdFromPath(path77.resolve(absPath), personaRoot) === personaId2;
69911
+ return personaIdFromPath(path78.resolve(absPath), personaRoot) === personaId2;
69779
69912
  }
69780
69913
 
69781
69914
  // src/handlers/history.ts
@@ -69828,7 +69961,7 @@ function buildHistoryHandlers(deps) {
69828
69961
  if (!pid) return false;
69829
69962
  return isGuestPathAllowed(
69830
69963
  ctx.grants,
69831
- path78.join(personaRoot, pid),
69964
+ path79.join(personaRoot, pid),
69832
69965
  personaRoot,
69833
69966
  "read",
69834
69967
  userWorkDir
@@ -69840,7 +69973,7 @@ function buildHistoryHandlers(deps) {
69840
69973
  };
69841
69974
  const list = async (frame, _client, ctx) => {
69842
69975
  const args = HistoryListArgs.parse(frame);
69843
- assertGuestPath(ctx, path78.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
69976
+ assertGuestPath(ctx, path79.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
69844
69977
  const sessions = await history.listSessions(args);
69845
69978
  return { response: { type: "history:list", sessions } };
69846
69979
  };
@@ -69888,14 +70021,14 @@ function buildHistoryHandlers(deps) {
69888
70021
  };
69889
70022
  const subagents = async (frame, _client, ctx) => {
69890
70023
  const args = HistorySubagentsArgs.parse(frame);
69891
- assertGuestPath(ctx, path78.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
70024
+ assertGuestPath(ctx, path79.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
69892
70025
  assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagents");
69893
70026
  const subs = await historyReaderForToolSession(args.toolSessionId).listSubagents(args);
69894
70027
  return { response: { type: "history:subagents", subagents: subs } };
69895
70028
  };
69896
70029
  const subagentRead = async (frame, _client, ctx) => {
69897
70030
  const args = HistorySubagentReadArgs.parse(frame);
69898
- assertGuestPath(ctx, path78.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
70031
+ assertGuestPath(ctx, path79.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
69899
70032
  assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagent-read");
69900
70033
  const res = await historyReaderForToolSession(args.toolSessionId).readSubagent(args);
69901
70034
  return { response: { type: "history:subagent-read", ...res } };
@@ -69905,7 +70038,7 @@ function buildHistoryHandlers(deps) {
69905
70038
  if (ctx?.principal.kind === "guest" && personaRoot) {
69906
70039
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
69907
70040
  const filtered = dirs.filter(
69908
- (d2) => isGuestPathAllowed(ctx.grants, path78.resolve(d2.cwd), personaRoot, "read", userWorkDir)
70041
+ (d2) => isGuestPathAllowed(ctx.grants, path79.resolve(d2.cwd), personaRoot, "read", userWorkDir)
69909
70042
  );
69910
70043
  return { response: { type: "history:recentDirs", dirs: filtered } };
69911
70044
  }
@@ -69922,17 +70055,17 @@ function buildHistoryHandlers(deps) {
69922
70055
  }
69923
70056
 
69924
70057
  // src/handlers/projects.ts
69925
- var fs75 = __toESM(require("fs"), 1);
69926
- var os24 = __toESM(require("os"), 1);
69927
- var path79 = __toESM(require("path"), 1);
70058
+ var fs76 = __toESM(require("fs"), 1);
70059
+ var os25 = __toESM(require("os"), 1);
70060
+ var path80 = __toESM(require("path"), 1);
69928
70061
  var import_node_child_process18 = require("child_process");
69929
70062
  init_protocol();
69930
- var DEFAULT_PROJECTS_ROOT = path79.join(os24.homedir(), "Documents", "ChatGPT");
70063
+ var DEFAULT_PROJECTS_ROOT = path80.join(os25.homedir(), "Documents", "ChatGPT");
69931
70064
  function allocateDir(root, name) {
69932
- let candidate = path79.join(root, name);
70065
+ let candidate = path80.join(root, name);
69933
70066
  let n2 = 2;
69934
- while (fs75.existsSync(candidate)) {
69935
- candidate = path79.join(root, `${name} ${n2}`);
70067
+ while (fs76.existsSync(candidate)) {
70068
+ candidate = path80.join(root, `${name} ${n2}`);
69936
70069
  n2 += 1;
69937
70070
  }
69938
70071
  return candidate;
@@ -69960,7 +70093,7 @@ function buildProjectHandlers(deps) {
69960
70093
  throw new ClawdError(ERROR_CODES.INVALID_CWD, "project:reveal \u4EC5\u652F\u6301 macOS");
69961
70094
  }
69962
70095
  try {
69963
- if (!fs75.statSync(args.path).isDirectory()) throw new Error("not dir");
70096
+ if (!fs76.statSync(args.path).isDirectory()) throw new Error("not dir");
69964
70097
  } catch {
69965
70098
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
69966
70099
  }
@@ -69976,7 +70109,7 @@ function buildProjectHandlers(deps) {
69976
70109
  let target;
69977
70110
  if (args.path) {
69978
70111
  try {
69979
- if (!fs75.statSync(args.path).isDirectory()) throw new Error("not dir");
70112
+ if (!fs76.statSync(args.path).isDirectory()) throw new Error("not dir");
69980
70113
  } catch {
69981
70114
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
69982
70115
  }
@@ -69984,15 +70117,15 @@ function buildProjectHandlers(deps) {
69984
70117
  } else {
69985
70118
  const name = args.name;
69986
70119
  try {
69987
- fs75.mkdirSync(root, { recursive: true });
70120
+ fs76.mkdirSync(root, { recursive: true });
69988
70121
  target = allocateDir(root, name);
69989
- fs75.mkdirSync(target);
70122
+ fs76.mkdirSync(target);
69990
70123
  } catch (err) {
69991
70124
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `\u521B\u5EFA\u9879\u76EE\u76EE\u5F55\u5931\u8D25: ${String(err)}`);
69992
70125
  }
69993
70126
  const git2 = (0, import_node_child_process18.spawnSync)("git", ["init"], { cwd: target, stdio: "ignore" });
69994
70127
  if (git2.status !== 0) {
69995
- fs75.rmSync(target, { recursive: true, force: true });
70128
+ fs76.rmSync(target, { recursive: true, force: true });
69996
70129
  throw new ClawdError(
69997
70130
  ERROR_CODES.INVALID_CWD,
69998
70131
  `git init \u5931\u8D25\uFF08${git2.error ? String(git2.error) : `exit ${git2.status}`}\uFF09: ${target}`
@@ -70017,9 +70150,9 @@ function buildProjectHandlers(deps) {
70017
70150
  }
70018
70151
 
70019
70152
  // src/handlers/workspace.ts
70020
- var path80 = __toESM(require("path"), 1);
70153
+ var path81 = __toESM(require("path"), 1);
70021
70154
  init_protocol();
70022
- var os25 = __toESM(require("os"), 1);
70155
+ var os26 = __toESM(require("os"), 1);
70023
70156
  init_protocol();
70024
70157
  init_protocol();
70025
70158
  function buildEnabledPluginNames(personaManager, personaId2) {
@@ -70059,23 +70192,23 @@ function buildWorkspaceHandlers(deps) {
70059
70192
  const list = async (frame, _client, ctx) => {
70060
70193
  const args = WorkspaceListArgs.parse(frame);
70061
70194
  const isGuest = ctx?.principal.kind === "guest";
70062
- const fallbackCwd = isGuest && personaRoot ? personaRoot : os25.homedir();
70063
- const resolvedCwd = path80.resolve(args.cwd ?? fallbackCwd);
70064
- const target = args.path ? path80.resolve(resolvedCwd, args.path) : resolvedCwd;
70195
+ const fallbackCwd = isGuest && personaRoot ? personaRoot : os26.homedir();
70196
+ const resolvedCwd = path81.resolve(args.cwd ?? fallbackCwd);
70197
+ const target = args.path ? path81.resolve(resolvedCwd, args.path) : resolvedCwd;
70065
70198
  assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
70066
70199
  const res = workspace.list({ ...args, cwd: resolvedCwd });
70067
70200
  return { response: { type: "workspace:list", ...res } };
70068
70201
  };
70069
70202
  const read = async (frame, _client, ctx) => {
70070
70203
  const args = WorkspaceReadArgs.parse(frame);
70071
- const target = path80.isAbsolute(args.path) ? path80.resolve(args.path) : path80.resolve(args.cwd, args.path);
70204
+ const target = path81.isAbsolute(args.path) ? path81.resolve(args.path) : path81.resolve(args.cwd, args.path);
70072
70205
  assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
70073
70206
  const res = workspace.read(args);
70074
70207
  return { response: { type: "workspace:read", ...res } };
70075
70208
  };
70076
70209
  const skillsList = async (frame, _client, ctx) => {
70077
70210
  const args = SkillsListArgs.parse(frame);
70078
- const cwdAbs = path80.resolve(args.cwd);
70211
+ const cwdAbs = path81.resolve(args.cwd);
70079
70212
  assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
70080
70213
  const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
70081
70214
  if (ctx?.principal.kind === "guest" && personaRoot) {
@@ -70087,7 +70220,7 @@ function buildWorkspaceHandlers(deps) {
70087
70220
  };
70088
70221
  const agentsList = async (frame, _client, ctx) => {
70089
70222
  const args = AgentsListArgs.parse(frame);
70090
- const cwdAbs = path80.resolve(args.cwd);
70223
+ const cwdAbs = path81.resolve(args.cwd);
70091
70224
  assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
70092
70225
  if (isCodexFamily(args.tool) || isPiFamily(args.tool)) {
70093
70226
  return { response: { type: "agents:list", agents: [] } };
@@ -70109,20 +70242,20 @@ function buildWorkspaceHandlers(deps) {
70109
70242
  }
70110
70243
 
70111
70244
  // src/handlers/git.ts
70112
- var path82 = __toESM(require("path"), 1);
70245
+ var path83 = __toESM(require("path"), 1);
70113
70246
  init_protocol();
70114
70247
  init_protocol();
70115
70248
 
70116
70249
  // src/workspace/git.ts
70117
70250
  var import_node_child_process19 = require("child_process");
70118
- var import_node_fs58 = __toESM(require("fs"), 1);
70119
- var import_node_path64 = __toESM(require("path"), 1);
70251
+ var import_node_fs59 = __toESM(require("fs"), 1);
70252
+ var import_node_path65 = __toESM(require("path"), 1);
70120
70253
  var import_node_util2 = require("util");
70121
70254
  var pexec = (0, import_node_util2.promisify)(import_node_child_process19.execFile);
70122
70255
  function normalizePath(p3) {
70123
- const resolved = import_node_path64.default.resolve(p3);
70256
+ const resolved = import_node_path65.default.resolve(p3);
70124
70257
  try {
70125
- return import_node_fs58.default.realpathSync(resolved);
70258
+ return import_node_fs59.default.realpathSync(resolved);
70126
70259
  } catch {
70127
70260
  return resolved;
70128
70261
  }
@@ -70196,7 +70329,7 @@ async function listGitBranches(cwd) {
70196
70329
  function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
70197
70330
  if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
70198
70331
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
70199
- if (!isGuestPathAllowed(ctx.grants, path82.resolve(cwd), personaRoot, "read", userWorkDir)) {
70332
+ if (!isGuestPathAllowed(ctx.grants, path83.resolve(cwd), personaRoot, "read", userWorkDir)) {
70200
70333
  throw new ClawdError(
70201
70334
  ERROR_CODES.UNAUTHORIZED,
70202
70335
  `guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
@@ -70453,12 +70586,12 @@ async function queryCodexAccount(deps = {}) {
70453
70586
  }
70454
70587
 
70455
70588
  // src/tools/pi-account.ts
70456
- var import_node_fs59 = __toESM(require("fs"), 1);
70457
- var import_node_path65 = __toESM(require("path"), 1);
70589
+ var import_node_fs60 = __toESM(require("fs"), 1);
70590
+ var import_node_path66 = __toESM(require("path"), 1);
70458
70591
  function readPiCredentials(agentDir) {
70459
70592
  let raw;
70460
70593
  try {
70461
- raw = JSON.parse(import_node_fs59.default.readFileSync(import_node_path65.default.join(agentDir, "auth.json"), "utf8"));
70594
+ raw = JSON.parse(import_node_fs60.default.readFileSync(import_node_path66.default.join(agentDir, "auth.json"), "utf8"));
70462
70595
  } catch {
70463
70596
  return {};
70464
70597
  }
@@ -71140,7 +71273,7 @@ function buildCloudVolumeHandlers(deps) {
71140
71273
  }
71141
71274
 
71142
71275
  // src/handlers/meta.ts
71143
- var import_node_os23 = __toESM(require("os"), 1);
71276
+ var import_node_os24 = __toESM(require("os"), 1);
71144
71277
  init_protocol();
71145
71278
 
71146
71279
  // src/handlers/method-grants.ts
@@ -71450,21 +71583,21 @@ function computeMethodAccess(args) {
71450
71583
  }
71451
71584
 
71452
71585
  // src/version.ts
71453
- var version = "0.2.574".length > 0 ? "0.2.574" : "dev";
71586
+ var version = "0.2.576".length > 0 ? "0.2.576" : "dev";
71454
71587
 
71455
71588
  // src/cli-probe/probe.ts
71456
- var fs78 = __toESM(require("fs"), 1);
71457
- var path84 = __toESM(require("path"), 1);
71589
+ var fs79 = __toESM(require("fs"), 1);
71590
+ var path85 = __toESM(require("path"), 1);
71458
71591
  var PKG_NAME = "@clawos-dev/clawd";
71459
71592
  var BIN_NAME = "clawd";
71460
71593
  var MAX_PARENT_HOPS = 5;
71461
71594
  function probeGlobalCli(pathEnv) {
71462
71595
  if (!pathEnv) return null;
71463
- for (const dir of pathEnv.split(path84.delimiter)) {
71596
+ for (const dir of pathEnv.split(path85.delimiter)) {
71464
71597
  if (!dir) continue;
71465
71598
  let real;
71466
71599
  try {
71467
- real = fs78.realpathSync(path84.join(dir, BIN_NAME));
71600
+ real = fs79.realpathSync(path85.join(dir, BIN_NAME));
71468
71601
  } catch {
71469
71602
  continue;
71470
71603
  }
@@ -71474,15 +71607,15 @@ function probeGlobalCli(pathEnv) {
71474
71607
  return null;
71475
71608
  }
71476
71609
  function readOwnPackageVersion(entryPath) {
71477
- let dir = path84.dirname(entryPath);
71610
+ let dir = path85.dirname(entryPath);
71478
71611
  for (let i2 = 0; i2 < MAX_PARENT_HOPS; i2++) {
71479
71612
  try {
71480
- const raw = fs78.readFileSync(path84.join(dir, "package.json"), "utf8");
71613
+ const raw = fs79.readFileSync(path85.join(dir, "package.json"), "utf8");
71481
71614
  const pkg = JSON.parse(raw);
71482
71615
  if (pkg.name !== PKG_NAME) return null;
71483
71616
  return typeof pkg.version === "string" && pkg.version ? pkg.version : null;
71484
71617
  } catch {
71485
- const parent = path84.dirname(dir);
71618
+ const parent = path85.dirname(dir);
71486
71619
  if (parent === dir) return null;
71487
71620
  dir = parent;
71488
71621
  }
@@ -71518,7 +71651,7 @@ function buildReadyFrame(deps, client) {
71518
71651
  return {
71519
71652
  version,
71520
71653
  protocolVersion: PROTOCOL_VERSION,
71521
- hostname: import_node_os23.default.hostname(),
71654
+ hostname: import_node_os24.default.hostname(),
71522
71655
  os: process.platform,
71523
71656
  tools,
71524
71657
  runningSessions: info.runningSessions,
@@ -71658,7 +71791,7 @@ function buildPersonaHandlers(deps) {
71658
71791
  }
71659
71792
 
71660
71793
  // src/handlers/attachment.ts
71661
- var import_node_path66 = __toESM(require("path"), 1);
71794
+ var import_node_path67 = __toESM(require("path"), 1);
71662
71795
  init_protocol();
71663
71796
  init_protocol();
71664
71797
  function assertGuestAttachmentPath(ctx, absPath, personaRoot, method, usersRoot) {
@@ -71737,12 +71870,12 @@ function buildAttachmentHandlers(deps) {
71737
71870
  `session ${args.sessionId} scope unresolved`
71738
71871
  );
71739
71872
  }
71740
- const cwdAbs = import_node_path66.default.resolve(sessionFile.cwd);
71741
- const candidateAbs = import_node_path66.default.isAbsolute(args.relPath) ? import_node_path66.default.resolve(args.relPath) : import_node_path66.default.resolve(cwdAbs, args.relPath);
71873
+ const cwdAbs = import_node_path67.default.resolve(sessionFile.cwd);
71874
+ const candidateAbs = import_node_path67.default.isAbsolute(args.relPath) ? import_node_path67.default.resolve(args.relPath) : import_node_path67.default.resolve(cwdAbs, args.relPath);
71742
71875
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
71743
71876
  const entries = deps.groupFileStore.list(scope, args.sessionId);
71744
71877
  const entry = entries.find((e) => {
71745
- const storedAbs = import_node_path66.default.isAbsolute(e.relPath) ? import_node_path66.default.resolve(e.relPath) : import_node_path66.default.resolve(cwdAbs, e.relPath);
71878
+ const storedAbs = import_node_path67.default.isAbsolute(e.relPath) ? import_node_path67.default.resolve(e.relPath) : import_node_path67.default.resolve(cwdAbs, e.relPath);
71746
71879
  return storedAbs === candidateAbs && !e.stale;
71747
71880
  });
71748
71881
  if (!entry) {
@@ -71766,7 +71899,7 @@ function buildAttachmentHandlers(deps) {
71766
71899
  if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
71767
71900
  const f2 = deps.sessionStore.read(sessionId);
71768
71901
  if (!f2) return;
71769
- assertGuestAttachmentPath(ctx, import_node_path66.default.resolve(f2.cwd), deps.personaRoot, method, deps.usersRoot);
71902
+ assertGuestAttachmentPath(ctx, import_node_path67.default.resolve(f2.cwd), deps.personaRoot, method, deps.usersRoot);
71770
71903
  }
71771
71904
  const groupAdd = async (frame, _client, ctx) => {
71772
71905
  if (!deps.groupFileStore || !deps.getSessionScope) {
@@ -71781,8 +71914,8 @@ function buildAttachmentHandlers(deps) {
71781
71914
  if (!scope) {
71782
71915
  throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
71783
71916
  }
71784
- const cwdAbs = import_node_path66.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
71785
- const candidateAbs = import_node_path66.default.isAbsolute(args.relPath) ? import_node_path66.default.resolve(args.relPath) : import_node_path66.default.resolve(cwdAbs, args.relPath);
71917
+ const cwdAbs = import_node_path67.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
71918
+ const candidateAbs = import_node_path67.default.isAbsolute(args.relPath) ? import_node_path67.default.resolve(args.relPath) : import_node_path67.default.resolve(cwdAbs, args.relPath);
71786
71919
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
71787
71920
  const from = args.origin === "agent" ? "agent" : ctx?.principal.kind === "owner" ? "owner" : "agent";
71788
71921
  const size = 0;
@@ -71840,21 +71973,21 @@ function buildAttachmentHandlers(deps) {
71840
71973
  }
71841
71974
 
71842
71975
  // src/handlers/extension.ts
71843
- var import_promises14 = __toESM(require("fs/promises"), 1);
71844
- var import_node_path71 = __toESM(require("path"), 1);
71976
+ var import_promises15 = __toESM(require("fs/promises"), 1);
71977
+ var import_node_path72 = __toESM(require("path"), 1);
71845
71978
  init_protocol();
71846
71979
 
71847
71980
  // src/extension/bundle-zip.ts
71848
- var import_promises11 = __toESM(require("fs/promises"), 1);
71849
- var import_node_path67 = __toESM(require("path"), 1);
71850
- var import_node_crypto20 = __toESM(require("crypto"), 1);
71981
+ var import_promises12 = __toESM(require("fs/promises"), 1);
71982
+ var import_node_path68 = __toESM(require("path"), 1);
71983
+ var import_node_crypto21 = __toESM(require("crypto"), 1);
71851
71984
  var import_jszip2 = __toESM(require_lib3(), 1);
71852
71985
  async function bundleExtensionDir(dir) {
71853
71986
  const entries = await listFilesSorted(dir);
71854
71987
  const zip = new import_jszip2.default();
71855
71988
  for (const rel of entries) {
71856
- const abs = import_node_path67.default.join(dir, rel);
71857
- const content = await import_promises11.default.readFile(abs);
71989
+ const abs = import_node_path68.default.join(dir, rel);
71990
+ const content = await import_promises12.default.readFile(abs);
71858
71991
  zip.file(rel, content, { date: FIXED_DATE });
71859
71992
  }
71860
71993
  const buffer = await zip.generateAsync({
@@ -71862,7 +71995,7 @@ async function bundleExtensionDir(dir) {
71862
71995
  compression: "DEFLATE",
71863
71996
  compressionOptions: { level: 6 }
71864
71997
  });
71865
- const sha256 = import_node_crypto20.default.createHash("sha256").update(buffer).digest("hex");
71998
+ const sha256 = import_node_crypto21.default.createHash("sha256").update(buffer).digest("hex");
71866
71999
  return { buffer, sha256 };
71867
72000
  }
71868
72001
  var FIXED_DATE = /* @__PURE__ */ new Date("2020-01-01T00:00:00.000Z");
@@ -71874,8 +72007,8 @@ async function listFilesSorted(rootDir) {
71874
72007
  return out;
71875
72008
  }
71876
72009
  async function walk(absRoot, relPrefix, out) {
71877
- const dirAbs = import_node_path67.default.join(absRoot, relPrefix);
71878
- const entries = await import_promises11.default.readdir(dirAbs, { withFileTypes: true });
72010
+ const dirAbs = import_node_path68.default.join(absRoot, relPrefix);
72011
+ const entries = await import_promises12.default.readdir(dirAbs, { withFileTypes: true });
71879
72012
  for (const e of entries) {
71880
72013
  if (IGNORE_BASENAMES.has(e.name)) continue;
71881
72014
  const rel = relPrefix ? `${relPrefix}/${e.name}` : e.name;
@@ -71927,26 +72060,26 @@ function computePublishCheck(args) {
71927
72060
  }
71928
72061
 
71929
72062
  // src/extension/install-flow.ts
71930
- var import_promises12 = __toESM(require("fs/promises"), 1);
71931
- var import_node_path69 = __toESM(require("path"), 1);
71932
- var import_node_os25 = __toESM(require("os"), 1);
71933
- var import_node_crypto21 = __toESM(require("crypto"), 1);
72063
+ var import_promises13 = __toESM(require("fs/promises"), 1);
72064
+ var import_node_path70 = __toESM(require("path"), 1);
72065
+ var import_node_os26 = __toESM(require("os"), 1);
72066
+ var import_node_crypto22 = __toESM(require("crypto"), 1);
71934
72067
  var import_jszip3 = __toESM(require_lib3(), 1);
71935
72068
 
71936
72069
  // src/extension/paths.ts
71937
- var import_node_os24 = __toESM(require("os"), 1);
71938
- var import_node_path68 = __toESM(require("path"), 1);
72070
+ var import_node_os25 = __toESM(require("os"), 1);
72071
+ var import_node_path69 = __toESM(require("path"), 1);
71939
72072
  function clawdHomeRoot(override) {
71940
- return override ?? process.env.CLAWD_HOME ?? import_node_path68.default.join(import_node_os24.default.homedir(), ".clawd");
72073
+ return override ?? process.env.CLAWD_HOME ?? import_node_path69.default.join(import_node_os25.default.homedir(), ".clawd");
71941
72074
  }
71942
72075
  function extensionsRoot(override) {
71943
- return import_node_path68.default.join(clawdHomeRoot(override), "extensions");
72076
+ return import_node_path69.default.join(clawdHomeRoot(override), "extensions");
71944
72077
  }
71945
72078
  function publishedChannelsFile(override) {
71946
- return import_node_path68.default.join(clawdHomeRoot(override), "extensions-published.json");
72079
+ return import_node_path69.default.join(clawdHomeRoot(override), "extensions-published.json");
71947
72080
  }
71948
72081
  function bundleCacheRoot(override) {
71949
- return import_node_path68.default.join(clawdHomeRoot(override), "extension-bundles");
72082
+ return import_node_path69.default.join(clawdHomeRoot(override), "extension-bundles");
71950
72083
  }
71951
72084
 
71952
72085
  // src/extension/install-flow.ts
@@ -71959,7 +72092,7 @@ var InstallError = class extends Error {
71959
72092
  };
71960
72093
  async function installFromChannel(args, deps) {
71961
72094
  const { channelRef, snapshotHash, bundleZip } = args;
71962
- const computed = import_node_crypto21.default.createHash("sha256").update(bundleZip).digest("hex");
72095
+ const computed = import_node_crypto22.default.createHash("sha256").update(bundleZip).digest("hex");
71963
72096
  if (computed !== snapshotHash) {
71964
72097
  throw new InstallError(
71965
72098
  "HASH_MISMATCH",
@@ -71973,7 +72106,7 @@ async function installFromChannel(args, deps) {
71973
72106
  throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
71974
72107
  }
71975
72108
  for (const name of Object.keys(zip.files)) {
71976
- if (name.includes("..") || name.startsWith("/") || import_node_path69.default.isAbsolute(name)) {
72109
+ if (name.includes("..") || name.startsWith("/") || import_node_path70.default.isAbsolute(name)) {
71977
72110
  throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
71978
72111
  }
71979
72112
  }
@@ -72005,10 +72138,10 @@ async function installFromChannel(args, deps) {
72005
72138
  );
72006
72139
  }
72007
72140
  const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
72008
- const destDir = import_node_path69.default.join(deps.extensionsRoot, localExtId);
72141
+ const destDir = import_node_path70.default.join(deps.extensionsRoot, localExtId);
72009
72142
  let destExists = false;
72010
72143
  try {
72011
- await import_promises12.default.access(destDir);
72144
+ await import_promises13.default.access(destDir);
72012
72145
  destExists = true;
72013
72146
  } catch {
72014
72147
  }
@@ -72018,28 +72151,28 @@ async function installFromChannel(args, deps) {
72018
72151
  `extension ${localExtId} already installed locally (from owner ${channelRef.ownerPrincipalId})`
72019
72152
  );
72020
72153
  }
72021
- const stage = await import_promises12.default.mkdtemp(
72022
- import_node_path69.default.join(import_node_os25.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
72154
+ const stage = await import_promises13.default.mkdtemp(
72155
+ import_node_path70.default.join(import_node_os26.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
72023
72156
  );
72024
72157
  try {
72025
72158
  for (const [name, entry] of Object.entries(zip.files)) {
72026
- const dest = import_node_path69.default.join(stage, name);
72159
+ const dest = import_node_path70.default.join(stage, name);
72027
72160
  if (entry.dir) {
72028
- await import_promises12.default.mkdir(dest, { recursive: true });
72161
+ await import_promises13.default.mkdir(dest, { recursive: true });
72029
72162
  continue;
72030
72163
  }
72031
- await import_promises12.default.mkdir(import_node_path69.default.dirname(dest), { recursive: true });
72164
+ await import_promises13.default.mkdir(import_node_path70.default.dirname(dest), { recursive: true });
72032
72165
  if (name === "manifest.json") {
72033
72166
  const rewritten = { ...parsed.data, id: localExtId };
72034
- await import_promises12.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
72167
+ await import_promises13.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
72035
72168
  } else {
72036
- await import_promises12.default.writeFile(dest, await entry.async("nodebuffer"));
72169
+ await import_promises13.default.writeFile(dest, await entry.async("nodebuffer"));
72037
72170
  }
72038
72171
  }
72039
- await import_promises12.default.mkdir(deps.extensionsRoot, { recursive: true });
72040
- await import_promises12.default.rename(stage, destDir);
72172
+ await import_promises13.default.mkdir(deps.extensionsRoot, { recursive: true });
72173
+ await import_promises13.default.rename(stage, destDir);
72041
72174
  } catch (e) {
72042
- await import_promises12.default.rm(stage, { recursive: true, force: true }).catch(() => {
72175
+ await import_promises13.default.rm(stage, { recursive: true, force: true }).catch(() => {
72043
72176
  });
72044
72177
  throw e;
72045
72178
  }
@@ -72048,10 +72181,10 @@ async function installFromChannel(args, deps) {
72048
72181
  }
72049
72182
 
72050
72183
  // src/extension/update-flow.ts
72051
- var import_promises13 = __toESM(require("fs/promises"), 1);
72052
- var import_node_path70 = __toESM(require("path"), 1);
72053
- var import_node_os26 = __toESM(require("os"), 1);
72054
- var import_node_crypto22 = __toESM(require("crypto"), 1);
72184
+ var import_promises14 = __toESM(require("fs/promises"), 1);
72185
+ var import_node_path71 = __toESM(require("path"), 1);
72186
+ var import_node_os27 = __toESM(require("os"), 1);
72187
+ var import_node_crypto23 = __toESM(require("crypto"), 1);
72055
72188
  var import_jszip4 = __toESM(require_lib3(), 1);
72056
72189
  var UpdateError = class extends Error {
72057
72190
  constructor(code, message) {
@@ -72066,11 +72199,11 @@ async function updateFromChannel(args, deps) {
72066
72199
  channelRef.extId,
72067
72200
  channelRef.ownerPrincipalId
72068
72201
  );
72069
- const liveDir = import_node_path70.default.join(deps.extensionsRoot, localExtId);
72202
+ const liveDir = import_node_path71.default.join(deps.extensionsRoot, localExtId);
72070
72203
  const prevDir = `${liveDir}.prev`;
72071
72204
  let existingVersion;
72072
72205
  try {
72073
- const raw = await import_promises13.default.readFile(import_node_path70.default.join(liveDir, "manifest.json"), "utf8");
72206
+ const raw = await import_promises14.default.readFile(import_node_path71.default.join(liveDir, "manifest.json"), "utf8");
72074
72207
  const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
72075
72208
  if (!parsed2.success) {
72076
72209
  throw new UpdateError(
@@ -72089,7 +72222,7 @@ async function updateFromChannel(args, deps) {
72089
72222
  if (e instanceof UpdateError) throw e;
72090
72223
  throw e;
72091
72224
  }
72092
- const computed = import_node_crypto22.default.createHash("sha256").update(bundleZip).digest("hex");
72225
+ const computed = import_node_crypto23.default.createHash("sha256").update(bundleZip).digest("hex");
72093
72226
  if (computed !== snapshotHash) {
72094
72227
  throw new UpdateError(
72095
72228
  "HASH_MISMATCH",
@@ -72103,7 +72236,7 @@ async function updateFromChannel(args, deps) {
72103
72236
  throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
72104
72237
  }
72105
72238
  for (const name of Object.keys(zip.files)) {
72106
- if (name.includes("..") || name.startsWith("/") || import_node_path70.default.isAbsolute(name)) {
72239
+ if (name.includes("..") || name.startsWith("/") || import_node_path71.default.isAbsolute(name)) {
72107
72240
  throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
72108
72241
  }
72109
72242
  }
@@ -72135,31 +72268,31 @@ async function updateFromChannel(args, deps) {
72135
72268
  );
72136
72269
  }
72137
72270
  await deps.runtime.close(localExtId);
72138
- await import_promises13.default.rm(prevDir, { recursive: true, force: true });
72139
- await import_promises13.default.rename(liveDir, prevDir);
72140
- const stage = await import_promises13.default.mkdtemp(
72141
- import_node_path70.default.join(import_node_os26.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
72271
+ await import_promises14.default.rm(prevDir, { recursive: true, force: true });
72272
+ await import_promises14.default.rename(liveDir, prevDir);
72273
+ const stage = await import_promises14.default.mkdtemp(
72274
+ import_node_path71.default.join(import_node_os27.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
72142
72275
  );
72143
72276
  try {
72144
72277
  for (const [name, entry] of Object.entries(zip.files)) {
72145
- const dest = import_node_path70.default.join(stage, name);
72278
+ const dest = import_node_path71.default.join(stage, name);
72146
72279
  if (entry.dir) {
72147
- await import_promises13.default.mkdir(dest, { recursive: true });
72280
+ await import_promises14.default.mkdir(dest, { recursive: true });
72148
72281
  continue;
72149
72282
  }
72150
- await import_promises13.default.mkdir(import_node_path70.default.dirname(dest), { recursive: true });
72283
+ await import_promises14.default.mkdir(import_node_path71.default.dirname(dest), { recursive: true });
72151
72284
  if (name === "manifest.json") {
72152
72285
  const rewritten = { ...parsed.data, id: localExtId };
72153
- await import_promises13.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
72286
+ await import_promises14.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
72154
72287
  } else {
72155
- await import_promises13.default.writeFile(dest, await entry.async("nodebuffer"));
72288
+ await import_promises14.default.writeFile(dest, await entry.async("nodebuffer"));
72156
72289
  }
72157
72290
  }
72158
- await import_promises13.default.rename(stage, liveDir);
72291
+ await import_promises14.default.rename(stage, liveDir);
72159
72292
  } catch (e) {
72160
- await import_promises13.default.rm(stage, { recursive: true, force: true }).catch(() => {
72293
+ await import_promises14.default.rm(stage, { recursive: true, force: true }).catch(() => {
72161
72294
  });
72162
- await import_promises13.default.rename(prevDir, liveDir).catch(() => {
72295
+ await import_promises14.default.rename(prevDir, liveDir).catch(() => {
72163
72296
  });
72164
72297
  await deps.runtime.open(localExtId).catch(() => {
72165
72298
  });
@@ -72181,7 +72314,7 @@ async function updateFromChannel(args, deps) {
72181
72314
  reason: e.message
72182
72315
  };
72183
72316
  }
72184
- await import_promises13.default.rm(prevDir, { recursive: true, force: true });
72317
+ await import_promises14.default.rm(prevDir, { recursive: true, force: true });
72185
72318
  return {
72186
72319
  kind: "updated",
72187
72320
  extId: localExtId,
@@ -72189,9 +72322,9 @@ async function updateFromChannel(args, deps) {
72189
72322
  };
72190
72323
  }
72191
72324
  async function rollback(deps, localExtId, liveDir, prevDir) {
72192
- await import_promises13.default.rm(liveDir, { recursive: true, force: true }).catch(() => {
72325
+ await import_promises14.default.rm(liveDir, { recursive: true, force: true }).catch(() => {
72193
72326
  });
72194
- await import_promises13.default.rename(prevDir, liveDir).catch(() => {
72327
+ await import_promises14.default.rename(prevDir, liveDir).catch(() => {
72195
72328
  });
72196
72329
  await deps.runtime.open(localExtId).catch(() => {
72197
72330
  });
@@ -72214,18 +72347,18 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
72214
72347
  );
72215
72348
  }
72216
72349
  }
72217
- const manifestPath = import_node_path71.default.join(root, extId, "manifest.json");
72350
+ const manifestPath = import_node_path72.default.join(root, extId, "manifest.json");
72218
72351
  const manifest = await readManifest(root, extId);
72219
72352
  const next = { ...manifest, version: newVersion };
72220
72353
  const tmp = `${manifestPath}.tmp`;
72221
- await import_promises14.default.writeFile(tmp, JSON.stringify(next, null, 2));
72222
- await import_promises14.default.rename(tmp, manifestPath);
72354
+ await import_promises15.default.writeFile(tmp, JSON.stringify(next, null, 2));
72355
+ await import_promises15.default.rename(tmp, manifestPath);
72223
72356
  }
72224
72357
  async function readManifest(root, extId) {
72225
- const file = import_node_path71.default.join(root, extId, "manifest.json");
72358
+ const file = import_node_path72.default.join(root, extId, "manifest.json");
72226
72359
  let raw;
72227
72360
  try {
72228
- raw = await import_promises14.default.readFile(file, "utf8");
72361
+ raw = await import_promises15.default.readFile(file, "utf8");
72229
72362
  } catch (e) {
72230
72363
  if (e.code === "ENOENT") {
72231
72364
  throw new ClawdError(ERROR_CODES.INVALID_PARAM, `extension ${extId} not installed`);
@@ -72306,7 +72439,7 @@ function buildExtensionHandlers(deps) {
72306
72439
  };
72307
72440
  async function buildSnapshotMeta(extId) {
72308
72441
  const manifest = await readManifest(deps.root, extId);
72309
- const { sha256, buffer } = await bundleExtensionDir(import_node_path71.default.join(deps.root, extId));
72442
+ const { sha256, buffer } = await bundleExtensionDir(import_node_path72.default.join(deps.root, extId));
72310
72443
  return { manifest, contentHash: sha256, buffer };
72311
72444
  }
72312
72445
  const publish = async (frame, _client, ctx) => {
@@ -72811,7 +72944,7 @@ function buildTopicHandlers(deps) {
72811
72944
  init_protocol();
72812
72945
 
72813
72946
  // src/channel/authority.ts
72814
- var import_promises15 = __toESM(require("fs/promises"), 1);
72947
+ var import_promises16 = __toESM(require("fs/promises"), 1);
72815
72948
  init_protocol();
72816
72949
  var DEFAULT_AUTHORITY_RULES = [
72817
72950
  { id: "outbound-message", desc: "\u4EE5\u8001\u677F\u540D\u4E49\u7ED9\u5176\u4ED6\u4EBA\u53D1\u6D88\u606F\uFF08IM/\u90AE\u4EF6\uFF09", action: "ask" },
@@ -72829,7 +72962,7 @@ async function resolveAuthority(args) {
72829
72962
  let source;
72830
72963
  let raw = null;
72831
72964
  try {
72832
- raw = await import_promises15.default.readFile(args.tablePath, "utf8");
72965
+ raw = await import_promises16.default.readFile(args.tablePath, "utf8");
72833
72966
  } catch (e) {
72834
72967
  if (e.code !== "ENOENT") {
72835
72968
  return askBecause(`\u6388\u6743\u8BBE\u5B9A\u8BFB\u4E0D\u51FA\u6765\uFF08${args.tablePath}\uFF09\uFF1A${e.message}`);
@@ -73133,12 +73266,12 @@ function buildVisitorHandlers(deps) {
73133
73266
  }
73134
73267
 
73135
73268
  // src/extension/registry.ts
73136
- var import_promises16 = __toESM(require("fs/promises"), 1);
73137
- var import_node_path72 = __toESM(require("path"), 1);
73269
+ var import_promises17 = __toESM(require("fs/promises"), 1);
73270
+ var import_node_path73 = __toESM(require("path"), 1);
73138
73271
  async function loadAll(root) {
73139
73272
  let entries;
73140
73273
  try {
73141
- entries = await import_promises16.default.readdir(root, { withFileTypes: true });
73274
+ entries = await import_promises17.default.readdir(root, { withFileTypes: true });
73142
73275
  } catch (e) {
73143
73276
  if (e.code === "ENOENT") return [];
73144
73277
  throw e;
@@ -73147,16 +73280,16 @@ async function loadAll(root) {
73147
73280
  for (const ent of entries) {
73148
73281
  if (!ent.isDirectory()) continue;
73149
73282
  if (ent.name.startsWith(".")) continue;
73150
- records.push(await loadOne(import_node_path72.default.join(root, ent.name), ent.name));
73283
+ records.push(await loadOne(import_node_path73.default.join(root, ent.name), ent.name));
73151
73284
  }
73152
73285
  records.sort((a2, b3) => a2.extId < b3.extId ? -1 : a2.extId > b3.extId ? 1 : 0);
73153
73286
  return records;
73154
73287
  }
73155
73288
  async function loadOne(dir, dirName) {
73156
- const manifestPath = import_node_path72.default.join(dir, "manifest.json");
73289
+ const manifestPath = import_node_path73.default.join(dir, "manifest.json");
73157
73290
  let raw;
73158
73291
  try {
73159
- raw = await import_promises16.default.readFile(manifestPath, "utf8");
73292
+ raw = await import_promises17.default.readFile(manifestPath, "utf8");
73160
73293
  } catch {
73161
73294
  return {
73162
73295
  extId: dirName,
@@ -73197,8 +73330,8 @@ async function loadOne(dir, dirName) {
73197
73330
  }
73198
73331
 
73199
73332
  // src/extension/uninstall.ts
73200
- var import_promises17 = __toESM(require("fs/promises"), 1);
73201
- var import_node_path73 = __toESM(require("path"), 1);
73333
+ var import_promises18 = __toESM(require("fs/promises"), 1);
73334
+ var import_node_path74 = __toESM(require("path"), 1);
73202
73335
  var UninstallError = class extends Error {
73203
73336
  constructor(code, message) {
73204
73337
  super(message);
@@ -73207,32 +73340,32 @@ var UninstallError = class extends Error {
73207
73340
  code;
73208
73341
  };
73209
73342
  async function uninstall(deps) {
73210
- const dir = import_node_path73.default.join(deps.root, deps.extId);
73343
+ const dir = import_node_path74.default.join(deps.root, deps.extId);
73211
73344
  try {
73212
- await import_promises17.default.access(dir);
73345
+ await import_promises18.default.access(dir);
73213
73346
  } catch {
73214
73347
  throw new UninstallError("NOT_FOUND", `extension ${deps.extId} not installed`);
73215
73348
  }
73216
73349
  await deps.runtime.close(deps.extId);
73217
- await import_promises17.default.rm(dir, { recursive: true, force: true });
73350
+ await import_promises18.default.rm(dir, { recursive: true, force: true });
73218
73351
  }
73219
73352
 
73220
73353
  // src/handlers/index.ts
73221
- var import_node_crypto23 = require("crypto");
73354
+ var import_node_crypto24 = require("crypto");
73222
73355
 
73223
73356
  // src/handlers/peer-exec.ts
73224
73357
  init_protocol();
73225
73358
 
73226
73359
  // src/peer-ops/run-command.ts
73227
73360
  var import_node_child_process23 = require("child_process");
73228
- var import_node_os27 = __toESM(require("os"), 1);
73361
+ var import_node_os28 = __toESM(require("os"), 1);
73229
73362
  var DEFAULT_TIMEOUT_MS6 = 3e4;
73230
73363
  var MAX_TIMEOUT_MS = 3e5;
73231
73364
  var MAX_OUTPUT_BYTES = 1048576;
73232
73365
  function runCommand2(command, opts = {}) {
73233
73366
  const timeoutMs = Math.min(opts.timeoutMs ?? DEFAULT_TIMEOUT_MS6, MAX_TIMEOUT_MS);
73234
73367
  return new Promise((resolve9) => {
73235
- const child = (0, import_node_child_process23.spawn)("bash", ["-c", command], { cwd: import_node_os27.default.homedir() });
73368
+ const child = (0, import_node_child_process23.spawn)("bash", ["-c", command], { cwd: import_node_os28.default.homedir() });
73236
73369
  const out = [];
73237
73370
  const err = [];
73238
73371
  let outBytes = 0;
@@ -73373,7 +73506,7 @@ function buildMethodHandlers(deps) {
73373
73506
  const c2 = deps.contactStore.get(deviceId);
73374
73507
  return c2 ? { deviceId: c2.deviceId, remoteUrl: c2.remoteUrl, connectToken: c2.connectToken } : null;
73375
73508
  },
73376
- genId: () => (0, import_node_crypto23.randomUUID)(),
73509
+ genId: () => (0, import_node_crypto24.randomUUID)(),
73377
73510
  now: () => Date.now(),
73378
73511
  forwardInboxPostToPeer,
73379
73512
  logger: deps.logger
@@ -73422,7 +73555,7 @@ function buildMethodHandlers(deps) {
73422
73555
  broadcast: deps.broadcastToOwners
73423
73556
  }),
73424
73557
  ...buildMasterHandlers({
73425
- authorityTablePath: import_node_path74.default.join(deps.masterDataDir, "master-authority.json")
73558
+ authorityTablePath: import_node_path75.default.join(deps.masterDataDir, "master-authority.json")
73426
73559
  }),
73427
73560
  ...buildTopicHandlers({
73428
73561
  topicStore: deps.topicStore,
@@ -73565,8 +73698,8 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
73565
73698
 
73566
73699
  // src/extension/runtime.ts
73567
73700
  var import_node_child_process24 = require("child_process");
73568
- var import_node_path75 = __toESM(require("path"), 1);
73569
- var import_promises18 = require("timers/promises");
73701
+ var import_node_path76 = __toESM(require("path"), 1);
73702
+ var import_promises19 = require("timers/promises");
73570
73703
 
73571
73704
  // src/extension/port-allocator.ts
73572
73705
  var import_node_net = __toESM(require("net"), 1);
@@ -73666,7 +73799,7 @@ var Runtime = class {
73666
73799
  /\$CLAWOS_EXT_PORT/g,
73667
73800
  String(port)
73668
73801
  );
73669
- const dir = import_node_path75.default.join(this.root, extId);
73802
+ const dir = import_node_path76.default.join(this.root, extId);
73670
73803
  const env = {
73671
73804
  ...process.env,
73672
73805
  CLAWOS_EXT_PORT: String(port),
@@ -73742,7 +73875,7 @@ ${handle.stderrTail}`
73742
73875
  if (res.ok) return;
73743
73876
  } catch {
73744
73877
  }
73745
- await (0, import_promises18.setTimeout)(this.healthzIntervalMs);
73878
+ await (0, import_promises19.setTimeout)(this.healthzIntervalMs);
73746
73879
  }
73747
73880
  throw new RuntimeError(
73748
73881
  "HEALTHZ_FAILED",
@@ -73767,7 +73900,7 @@ ${handle.stderrTail}`
73767
73900
  };
73768
73901
  killGroup("SIGTERM");
73769
73902
  const exited = new Promise((resolve9) => child.once("exit", () => resolve9()));
73770
- const timed = (0, import_promises18.setTimeout)(5e3).then(() => "timeout");
73903
+ const timed = (0, import_promises19.setTimeout)(5e3).then(() => "timeout");
73771
73904
  const winner = await Promise.race([exited.then(() => "exited"), timed]);
73772
73905
  if (winner === "timeout" && child.exitCode === null) {
73773
73906
  killGroup("SIGKILL");
@@ -73777,8 +73910,8 @@ ${handle.stderrTail}`
73777
73910
  };
73778
73911
 
73779
73912
  // src/extension/published-channels.ts
73780
- var import_promises19 = __toESM(require("fs/promises"), 1);
73781
- var import_node_path76 = __toESM(require("path"), 1);
73913
+ var import_promises20 = __toESM(require("fs/promises"), 1);
73914
+ var import_node_path77 = __toESM(require("path"), 1);
73782
73915
  init_zod();
73783
73916
  var PublishedChannelsError = class extends Error {
73784
73917
  constructor(code, message) {
@@ -73808,7 +73941,7 @@ var PublishedChannelStore = class {
73808
73941
  this.channels.clear();
73809
73942
  let raw;
73810
73943
  try {
73811
- raw = await import_promises19.default.readFile(this.filePath, "utf8");
73944
+ raw = await import_promises20.default.readFile(this.filePath, "utf8");
73812
73945
  } catch (e) {
73813
73946
  if (e.code === "ENOENT") {
73814
73947
  this.loaded = true;
@@ -73877,15 +74010,15 @@ var PublishedChannelStore = class {
73877
74010
  )
73878
74011
  };
73879
74012
  const tmp = `${this.filePath}.tmp`;
73880
- await import_promises19.default.mkdir(import_node_path76.default.dirname(this.filePath), { recursive: true });
73881
- await import_promises19.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
73882
- await import_promises19.default.rename(tmp, this.filePath);
74013
+ await import_promises20.default.mkdir(import_node_path77.default.dirname(this.filePath), { recursive: true });
74014
+ await import_promises20.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
74015
+ await import_promises20.default.rename(tmp, this.filePath);
73883
74016
  }
73884
74017
  };
73885
74018
 
73886
74019
  // src/extension/bundle-cache.ts
73887
- var import_promises20 = __toESM(require("fs/promises"), 1);
73888
- var import_node_path77 = __toESM(require("path"), 1);
74020
+ var import_promises21 = __toESM(require("fs/promises"), 1);
74021
+ var import_node_path78 = __toESM(require("path"), 1);
73889
74022
  var BundleCache = class {
73890
74023
  constructor(rootDir) {
73891
74024
  this.rootDir = rootDir;
@@ -73893,17 +74026,17 @@ var BundleCache = class {
73893
74026
  rootDir;
73894
74027
  /** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
73895
74028
  async write(snapshotHash, buffer) {
73896
- await import_promises20.default.mkdir(this.rootDir, { recursive: true });
73897
- const file = import_node_path77.default.join(this.rootDir, `${snapshotHash}.zip`);
74029
+ await import_promises21.default.mkdir(this.rootDir, { recursive: true });
74030
+ const file = import_node_path78.default.join(this.rootDir, `${snapshotHash}.zip`);
73898
74031
  const tmp = `${file}.tmp`;
73899
- await import_promises20.default.writeFile(tmp, buffer, { mode: 384 });
73900
- await import_promises20.default.rename(tmp, file);
74032
+ await import_promises21.default.writeFile(tmp, buffer, { mode: 384 });
74033
+ await import_promises21.default.rename(tmp, file);
73901
74034
  }
73902
74035
  /** Returns the bundle bytes, or null when the file doesn't exist. */
73903
74036
  async read(snapshotHash) {
73904
- const file = import_node_path77.default.join(this.rootDir, `${snapshotHash}.zip`);
74037
+ const file = import_node_path78.default.join(this.rootDir, `${snapshotHash}.zip`);
73905
74038
  try {
73906
- return await import_promises20.default.readFile(file);
74039
+ return await import_promises21.default.readFile(file);
73907
74040
  } catch (e) {
73908
74041
  if (e.code === "ENOENT") return null;
73909
74042
  throw e;
@@ -73911,8 +74044,8 @@ var BundleCache = class {
73911
74044
  }
73912
74045
  /** Idempotent — missing file is not an error. */
73913
74046
  async delete(snapshotHash) {
73914
- const file = import_node_path77.default.join(this.rootDir, `${snapshotHash}.zip`);
73915
- await import_promises20.default.rm(file, { force: true });
74047
+ const file = import_node_path78.default.join(this.rootDir, `${snapshotHash}.zip`);
74048
+ await import_promises21.default.rm(file, { force: true });
73916
74049
  }
73917
74050
  };
73918
74051
 
@@ -73932,26 +74065,26 @@ async function startDaemon(config) {
73932
74065
  },
73933
74066
  source: "daemon",
73934
74067
  sampling: logShippingCfg.sampling,
73935
- homeDir: import_node_os28.default.homedir()
74068
+ homeDir: import_node_os29.default.homedir()
73936
74069
  });
73937
- const logDir = import_node_path78.default.join(config.dataDir, "log");
73938
- import_node_fs60.default.mkdirSync(logDir, { recursive: true });
74070
+ const logDir = import_node_path79.default.join(config.dataDir, "log");
74071
+ import_node_fs61.default.mkdirSync(logDir, { recursive: true });
73939
74072
  const logger = createLogger({
73940
74073
  level: config.logLevel,
73941
- file: import_node_path78.default.join(logDir, "clawd.log"),
74074
+ file: import_node_path79.default.join(logDir, "clawd.log"),
73942
74075
  logClient
73943
74076
  });
73944
74077
  logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
73945
74078
  const screenIdleProbeLogger = createFileOnlyLogger({
73946
- file: import_node_path78.default.join(logDir, "screen-idle-probe.log"),
74079
+ file: import_node_path79.default.join(logDir, "screen-idle-probe.log"),
73947
74080
  level: "debug"
73948
74081
  });
73949
74082
  logger.info("screen-idle probe logger enabled", {
73950
- file: import_node_path78.default.join(logDir, "screen-idle-probe.log")
74083
+ file: import_node_path79.default.join(logDir, "screen-idle-probe.log")
73951
74084
  });
73952
74085
  const CAP_TARGETS = [
73953
- import_node_path78.default.join(logDir, "clawd.log"),
73954
- import_node_path78.default.join(logDir, "screen-idle-probe.log")
74086
+ import_node_path79.default.join(logDir, "clawd.log"),
74087
+ import_node_path79.default.join(logDir, "screen-idle-probe.log")
73955
74088
  ];
73956
74089
  const LOG_CAP_MAX_BYTES = 10 * 1024 * 1024;
73957
74090
  const LOG_CAP_KEEP_BYTES = 5 * 1024 * 1024;
@@ -74073,8 +74206,8 @@ async function startDaemon(config) {
74073
74206
  const agents = new AgentsScanner();
74074
74207
  const history = new ClaudeHistoryReader();
74075
74208
  let transport = null;
74076
- const personaStore = new PersonaStore(import_node_path78.default.join(config.dataDir, "personas"));
74077
- const usersRoot = import_node_path78.default.join(config.dataDir, "users");
74209
+ const personaStore = new PersonaStore(import_node_path79.default.join(config.dataDir, "personas"));
74210
+ const usersRoot = import_node_path79.default.join(config.dataDir, "users");
74078
74211
  const defaultsRoot = findDefaultsRoot(logger);
74079
74212
  if (defaultsRoot) {
74080
74213
  seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
@@ -74091,7 +74224,7 @@ async function startDaemon(config) {
74091
74224
  retirePersonaBuilder({ store: personaStore, logger });
74092
74225
  const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
74093
74226
  const dispatchStore = createDispatchStore({
74094
- filePath: import_node_path78.default.join(config.dataDir, "dispatch.json"),
74227
+ filePath: import_node_path79.default.join(config.dataDir, "dispatch.json"),
74095
74228
  now: () => Date.now(),
74096
74229
  onFlushError: (err) => logger.error("dispatch store flush failed", {
74097
74230
  reason: err instanceof Error ? err.message : String(err)
@@ -74100,18 +74233,18 @@ async function startDaemon(config) {
74100
74233
  await dispatchStore.load();
74101
74234
  dispatchStore.markInterruptedAsFailed((/* @__PURE__ */ new Date()).toISOString());
74102
74235
  const channelStore = createChannelStore({
74103
- filePath: import_node_path78.default.join(config.dataDir, "channels.json"),
74236
+ filePath: import_node_path79.default.join(config.dataDir, "channels.json"),
74104
74237
  now: () => Date.now(),
74105
- genId: () => `ch-${(0, import_node_crypto24.randomUUID)().slice(0, 8)}`,
74238
+ genId: () => `ch-${(0, import_node_crypto25.randomUUID)().slice(0, 8)}`,
74106
74239
  onFlushError: (err) => logger.error("channel store flush failed", {
74107
74240
  reason: err instanceof Error ? err.message : String(err)
74108
74241
  })
74109
74242
  });
74110
74243
  await channelStore.load();
74111
74244
  const topicStore = createTopicStore({
74112
- filePath: import_node_path78.default.join(config.dataDir, "topics.json"),
74245
+ filePath: import_node_path79.default.join(config.dataDir, "topics.json"),
74113
74246
  now: () => Date.now(),
74114
- genId: () => `tp-${(0, import_node_crypto24.randomUUID)().slice(0, 8)}`,
74247
+ genId: () => `tp-${(0, import_node_crypto25.randomUUID)().slice(0, 8)}`,
74115
74248
  onFlushError: (err) => logger.error("topic store flush failed", {
74116
74249
  reason: err instanceof Error ? err.message : String(err)
74117
74250
  })
@@ -74119,7 +74252,7 @@ async function startDaemon(config) {
74119
74252
  await topicStore.load();
74120
74253
  let deliverPendingRef;
74121
74254
  const personaDispatchManager = new PersonaDispatchManager({
74122
- genId: () => (0, import_node_crypto24.randomUUID)(),
74255
+ genId: () => (0, import_node_crypto25.randomUUID)(),
74123
74256
  store: dispatchStore,
74124
74257
  now: () => Date.now(),
74125
74258
  onCompleted: (sid) => deliverPendingRef?.(sid),
@@ -74136,12 +74269,12 @@ async function startDaemon(config) {
74136
74269
  });
74137
74270
  }
74138
74271
  });
74139
- const here = typeof __dirname === "string" ? __dirname : import_node_path78.default.dirname((0, import_node_url5.fileURLToPath)(import_meta9.url));
74272
+ const here = typeof __dirname === "string" ? __dirname : import_node_path79.default.dirname((0, import_node_url5.fileURLToPath)(import_meta9.url));
74140
74273
  const mcpConfigs = [];
74141
74274
  const secretsBundleRoot = findSecretsBundleRoot(logger);
74142
- const localSecretsDir = import_node_path78.default.join(config.dataDir, LOCAL_SECRETS_DIRNAME);
74275
+ const localSecretsDir = import_node_path79.default.join(config.dataDir, LOCAL_SECRETS_DIRNAME);
74143
74276
  const readSecrets = () => readSecretTable({ bundleRoot: secretsBundleRoot, overrideDir: localSecretsDir, logger });
74144
- const githubTokenFile = import_node_path78.default.join(localSecretsDir, GITHUB_TOKEN_FILE);
74277
+ const githubTokenFile = import_node_path79.default.join(localSecretsDir, GITHUB_TOKEN_FILE);
74145
74278
  const githubIdentity = createGithubIdentity({
74146
74279
  resolve: () => resolveGithubAuth({ exec: runCommand, fileToken: () => readEnvFileVar(githubTokenFile, GITHUB_TOKEN_VAR) }),
74147
74280
  store: (token) => storeGithubAuth({
@@ -74179,22 +74312,22 @@ async function startDaemon(config) {
74179
74312
  void githubIdentity.refresh();
74180
74313
  return renderPersonaMcpSecrets({
74181
74314
  personaId: personaId2,
74182
- personaDir: import_node_path78.default.join(config.dataDir, "personas", personaId2),
74315
+ personaDir: import_node_path79.default.join(config.dataDir, "personas", personaId2),
74183
74316
  secrets,
74184
- outDir: import_node_path78.default.join(config.dataDir, "persona-mcp"),
74317
+ outDir: import_node_path79.default.join(config.dataDir, "persona-mcp"),
74185
74318
  logger
74186
74319
  });
74187
74320
  };
74188
74321
  const mcpDaemonUrl = `http://127.0.0.1:${config.port}`;
74189
74322
  const dispatchServerCandidates = [
74190
- import_node_path78.default.join(here, "dispatch", "mcp-server.cjs"),
74323
+ import_node_path79.default.join(here, "dispatch", "mcp-server.cjs"),
74191
74324
  // 生产 dist/index → dist/dispatch/mcp-server.cjs
74192
- import_node_path78.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
74325
+ import_node_path79.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
74193
74326
  // dev tsx src/index → ../dist/dispatch/mcp-server.cjs
74194
74327
  ];
74195
- const dispatchServerScriptPath = dispatchServerCandidates.find((p3) => import_node_fs60.default.existsSync(p3));
74328
+ const dispatchServerScriptPath = dispatchServerCandidates.find((p3) => import_node_fs61.default.existsSync(p3));
74196
74329
  if (dispatchServerScriptPath) {
74197
- const dispatchLogPath = import_node_path78.default.join(logDir, "dispatch-mcp-server.log");
74330
+ const dispatchLogPath = import_node_path79.default.join(logDir, "dispatch-mcp-server.log");
74198
74331
  const dispatchCfgPath = writeDispatchMcpConfig({
74199
74332
  dataDir: config.dataDir,
74200
74333
  serverScriptPath: dispatchServerScriptPath,
@@ -74214,12 +74347,12 @@ async function startDaemon(config) {
74214
74347
  });
74215
74348
  }
74216
74349
  const ticketServerCandidates = [
74217
- import_node_path78.default.join(here, "ticket", "mcp-server.cjs"),
74218
- import_node_path78.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
74350
+ import_node_path79.default.join(here, "ticket", "mcp-server.cjs"),
74351
+ import_node_path79.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
74219
74352
  ];
74220
- const ticketServerScriptPath = ticketServerCandidates.find((p3) => import_node_fs60.default.existsSync(p3));
74353
+ const ticketServerScriptPath = ticketServerCandidates.find((p3) => import_node_fs61.default.existsSync(p3));
74221
74354
  if (ticketServerScriptPath) {
74222
- const ticketLogPath = import_node_path78.default.join(logDir, "ticket-mcp-server.log");
74355
+ const ticketLogPath = import_node_path79.default.join(logDir, "ticket-mcp-server.log");
74223
74356
  const ticketCfgPath = writeTicketMcpConfig({
74224
74357
  dataDir: config.dataDir,
74225
74358
  serverScriptPath: ticketServerScriptPath,
@@ -74241,12 +74374,12 @@ async function startDaemon(config) {
74241
74374
  });
74242
74375
  }
74243
74376
  const shiftServerCandidates = [
74244
- import_node_path78.default.join(here, "shift", "mcp-server.cjs"),
74245
- import_node_path78.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
74377
+ import_node_path79.default.join(here, "shift", "mcp-server.cjs"),
74378
+ import_node_path79.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
74246
74379
  ];
74247
- const shiftServerScriptPath = shiftServerCandidates.find((p3) => import_node_fs60.default.existsSync(p3));
74380
+ const shiftServerScriptPath = shiftServerCandidates.find((p3) => import_node_fs61.default.existsSync(p3));
74248
74381
  if (shiftServerScriptPath) {
74249
- const shiftLogPath = import_node_path78.default.join(logDir, "shift-mcp-server.log");
74382
+ const shiftLogPath = import_node_path79.default.join(logDir, "shift-mcp-server.log");
74250
74383
  const shiftCfgPath = await writeShiftMcpConfig({
74251
74384
  dataDir: config.dataDir,
74252
74385
  serverScriptPath: shiftServerScriptPath,
@@ -74267,12 +74400,12 @@ async function startDaemon(config) {
74267
74400
  );
74268
74401
  }
74269
74402
  const inboxServerCandidates = [
74270
- import_node_path78.default.join(here, "inbox", "mcp-server.cjs"),
74271
- import_node_path78.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
74403
+ import_node_path79.default.join(here, "inbox", "mcp-server.cjs"),
74404
+ import_node_path79.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
74272
74405
  ];
74273
- const inboxServerScriptPath = inboxServerCandidates.find((p3) => import_node_fs60.default.existsSync(p3));
74406
+ const inboxServerScriptPath = inboxServerCandidates.find((p3) => import_node_fs61.default.existsSync(p3));
74274
74407
  if (inboxServerScriptPath) {
74275
- const inboxLogPath = import_node_path78.default.join(logDir, "inbox-mcp-server.log");
74408
+ const inboxLogPath = import_node_path79.default.join(logDir, "inbox-mcp-server.log");
74276
74409
  const inboxCfgPath = await writeInboxMcpConfig({
74277
74410
  dataDir: config.dataDir,
74278
74411
  serverScriptPath: inboxServerScriptPath,
@@ -74293,10 +74426,10 @@ async function startDaemon(config) {
74293
74426
  );
74294
74427
  }
74295
74428
  const peerOpsServerCandidates = [
74296
- import_node_path78.default.join(here, "peer-ops", "mcp-server.cjs"),
74297
- import_node_path78.default.join(here, "..", "dist", "peer-ops", "mcp-server.cjs")
74429
+ import_node_path79.default.join(here, "peer-ops", "mcp-server.cjs"),
74430
+ import_node_path79.default.join(here, "..", "dist", "peer-ops", "mcp-server.cjs")
74298
74431
  ];
74299
- const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) => import_node_fs60.default.existsSync(p3));
74432
+ const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) => import_node_fs61.default.existsSync(p3));
74300
74433
  if (peerOpsServerScriptPath) {
74301
74434
  const peerOpsCfgPath = writePeerOpsMcpConfig({
74302
74435
  dataDir: config.dataDir,
@@ -74316,12 +74449,12 @@ async function startDaemon(config) {
74316
74449
  );
74317
74450
  }
74318
74451
  const rpcToolServerCandidates = [
74319
- import_node_path78.default.join(here, "rpc-tool", "mcp-server.cjs"),
74320
- import_node_path78.default.join(here, "..", "dist", "rpc-tool", "mcp-server.cjs")
74452
+ import_node_path79.default.join(here, "rpc-tool", "mcp-server.cjs"),
74453
+ import_node_path79.default.join(here, "..", "dist", "rpc-tool", "mcp-server.cjs")
74321
74454
  ];
74322
- const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) => import_node_fs60.default.existsSync(p3));
74455
+ const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) => import_node_fs61.default.existsSync(p3));
74323
74456
  if (rpcToolServerScriptPath) {
74324
- const rpcToolLogPath = import_node_path78.default.join(logDir, "rpc-tool-mcp-server.log");
74457
+ const rpcToolLogPath = import_node_path79.default.join(logDir, "rpc-tool-mcp-server.log");
74325
74458
  const rpcToolCfgPath = writeRpcToolMcpConfig({
74326
74459
  dataDir: config.dataDir,
74327
74460
  serverScriptPath: rpcToolServerScriptPath,
@@ -74342,7 +74475,7 @@ async function startDaemon(config) {
74342
74475
  );
74343
74476
  }
74344
74477
  const shiftStore = createShiftStore({
74345
- filePath: import_node_path78.default.join(config.dataDir, "shift.json"),
74478
+ filePath: import_node_path79.default.join(config.dataDir, "shift.json"),
74346
74479
  ownerIdProvider: () => ownerPrincipalId,
74347
74480
  now: () => Date.now()
74348
74481
  });
@@ -74364,7 +74497,7 @@ async function startDaemon(config) {
74364
74497
  getAdapter,
74365
74498
  historyReader: history,
74366
74499
  dataDir: config.dataDir,
74367
- personaRoot: import_node_path78.default.join(config.dataDir, "personas"),
74500
+ personaRoot: import_node_path79.default.join(config.dataDir, "personas"),
74368
74501
  // dispatch / shift 自动化 spawn 按 persona 绑定 tool 起 B session(codex persona 用 codex)。
74369
74502
  // personaRegistry 声明在 manager 之后(同作用域 const,调用时机在启动完成后,无 TDZ 风险)。
74370
74503
  getPersonaDefaults: (personaId2) => personaRegistry.get(personaId2),
@@ -74421,10 +74554,10 @@ async function startDaemon(config) {
74421
74554
  // 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
74422
74555
  attachmentGroup: {
74423
74556
  onFileEdit: (input) => {
74424
- const absPath = import_node_path78.default.isAbsolute(input.relPath) ? input.relPath : import_node_path78.default.join(input.cwd, input.relPath);
74557
+ const absPath = import_node_path79.default.isAbsolute(input.relPath) ? input.relPath : import_node_path79.default.join(input.cwd, input.relPath);
74425
74558
  let size = 0;
74426
74559
  try {
74427
- size = import_node_fs60.default.statSync(absPath).size;
74560
+ size = import_node_fs61.default.statSync(absPath).size;
74428
74561
  } catch (err) {
74429
74562
  logger.warn("attachment.onFileEdit stat failed", {
74430
74563
  sessionId: input.sessionId,
@@ -74465,9 +74598,9 @@ async function startDaemon(config) {
74465
74598
  logger.info("projects.seed-dropped", { dropped: droppedSeed.dropped, backup: droppedSeed.backup });
74466
74599
  }
74467
74600
  const projectsStore = new ProjectsStore({
74468
- file: import_node_path78.default.join(config.dataDir, "projects.json"),
74601
+ file: import_node_path79.default.join(config.dataDir, "projects.json"),
74469
74602
  clawdDir: config.dataDir,
74470
- codexStateFile: import_node_path78.default.join(import_node_os28.default.homedir(), ".codex", ".codex-global-state.json"),
74603
+ codexStateFile: import_node_path79.default.join(import_node_os29.default.homedir(), ".codex", ".codex-global-state.json"),
74471
74604
  logger
74472
74605
  });
74473
74606
  const observer = new SessionObserver({
@@ -74532,13 +74665,13 @@ async function startDaemon(config) {
74532
74665
  logger
74533
74666
  });
74534
74667
  registerAdapter("claude", claudeAdapter);
74535
- const codexIsolatedHome = import_node_path78.default.join(config.dataDir, "codex-home");
74668
+ const codexIsolatedHome = import_node_path79.default.join(config.dataDir, "codex-home");
74536
74669
  try {
74537
- import_node_fs60.default.mkdirSync(codexIsolatedHome, { recursive: true });
74670
+ import_node_fs61.default.mkdirSync(codexIsolatedHome, { recursive: true });
74538
74671
  for (const f2 of ["auth.json", "config.toml"]) {
74539
- const link = import_node_path78.default.join(codexIsolatedHome, f2);
74540
- const target = import_node_path78.default.join(import_node_os28.default.homedir(), ".codex", f2);
74541
- if (!import_node_fs60.default.existsSync(link) && import_node_fs60.default.existsSync(target)) import_node_fs60.default.symlinkSync(target, link);
74672
+ const link = import_node_path79.default.join(codexIsolatedHome, f2);
74673
+ const target = import_node_path79.default.join(import_node_os29.default.homedir(), ".codex", f2);
74674
+ if (!import_node_fs61.default.existsSync(link) && import_node_fs61.default.existsSync(target)) import_node_fs61.default.symlinkSync(target, link);
74542
74675
  }
74543
74676
  } catch (err) {
74544
74677
  logger.warn("codex isolated home setup failed", { err: String(err) });
@@ -74549,17 +74682,17 @@ async function startDaemon(config) {
74549
74682
  logger,
74550
74683
  historyReader: new CodexHistoryReader({
74551
74684
  roots: codexRolloutRoots(config.dataDir),
74552
- sharedHome: import_node_path78.default.join(import_node_os28.default.homedir(), ".codex"),
74685
+ sharedHome: import_node_path79.default.join(import_node_os29.default.homedir(), ".codex"),
74553
74686
  logger
74554
74687
  }),
74555
74688
  // projectPaths 每次调用现取 —— 用户新建 project 后立即生效,不用重启 daemon
74556
74689
  codexHomeFor: (cwd) => resolveCodexHome({
74557
74690
  cwd,
74558
- personaRoot: import_node_path78.default.join(config.dataDir, "personas"),
74691
+ personaRoot: import_node_path79.default.join(config.dataDir, "personas"),
74559
74692
  // 必须用 listMerged(Codex registry ∪ 叠加层):只用本地 list() 的话,用户在
74560
74693
  // Codex 里建的 project 不在表里,在它下面开的会话会被误判成隔离 → Codex 侧看不到
74561
74694
  projectPaths: projectsStore.listMerged().map((x2) => x2.path),
74562
- sharedHome: import_node_path78.default.join(import_node_os28.default.homedir(), ".codex"),
74695
+ sharedHome: import_node_path79.default.join(import_node_os29.default.homedir(), ".codex"),
74563
74696
  isolatedHome: codexIsolatedHome
74564
74697
  }),
74565
74698
  // 附件图片验签:与 http-router /files 路由同一把 secret
@@ -74584,10 +74717,10 @@ async function startDaemon(config) {
74584
74717
  );
74585
74718
  registerAdapter(PI_CLOUD_TOOL_ID, new CloudPiAdapter({ client: cloudGateway, history: cloudHistorySource, logger }));
74586
74719
  const piMcpBridgeCandidates = [
74587
- import_node_path78.default.join(here, "pi-mcp-bridge", "extension.cjs"),
74588
- import_node_path78.default.join(here, "..", "dist", "pi-mcp-bridge", "extension.cjs")
74720
+ import_node_path79.default.join(here, "pi-mcp-bridge", "extension.cjs"),
74721
+ import_node_path79.default.join(here, "..", "dist", "pi-mcp-bridge", "extension.cjs")
74589
74722
  ];
74590
- const piMcpBridgePath = piMcpBridgeCandidates.find((p3) => import_node_fs60.default.existsSync(p3));
74723
+ const piMcpBridgePath = piMcpBridgeCandidates.find((p3) => import_node_fs61.default.existsSync(p3));
74591
74724
  if (piMcpBridgePath) {
74592
74725
  logger.info("pi-mcp-bridge extension resolved", { path: piMcpBridgePath });
74593
74726
  } else {
@@ -74882,11 +75015,11 @@ async function startDaemon(config) {
74882
75015
  // 'persona/<pid>/owner',default 走 'default'。
74883
75016
  getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
74884
75017
  // guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
74885
- personaRoot: import_node_path78.default.join(config.dataDir, "personas"),
75018
+ personaRoot: import_node_path79.default.join(config.dataDir, "personas"),
74886
75019
  usersRoot
74887
75020
  },
74888
75021
  // workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
74889
- personaRoot: import_node_path78.default.join(config.dataDir, "personas"),
75022
+ personaRoot: import_node_path79.default.join(config.dataDir, "personas"),
74890
75023
  // v2 多人 persona 隔离:handler 派生 guest user-dir 放行
74891
75024
  usersRoot,
74892
75025
  // v2 Phase 6: whoami handler 装在 owner principal.displayName + persona 解析
@@ -75027,7 +75160,7 @@ async function startDaemon(config) {
75027
75160
  sourceSessionId: args.sourceSessionId
75028
75161
  });
75029
75162
  const sourceFile = manager.findOwnedSession(args.sourceSessionId);
75030
- const sourceJsonlPath = resolveSourceJsonlPath(sourceFile, import_node_os28.default.homedir());
75163
+ const sourceJsonlPath = resolveSourceJsonlPath(sourceFile, import_node_os29.default.homedir());
75031
75164
  logger.info("dispatch.spawnB.source-resolved", {
75032
75165
  dispatchId: args.dispatchId,
75033
75166
  sourceJsonlPath,
@@ -75119,6 +75252,9 @@ async function startDaemon(config) {
75119
75252
  }
75120
75253
  return probeLocalVersion(runCommand, pkg);
75121
75254
  },
75255
+ fetchArtifact: downloadArtifact(runCommand),
75256
+ // apt 条目的 version 按 Debian 12 仓库定(不是本机):一次出网查 madison,只要元数据不下载
75257
+ debianPackage: lookupDebianPackage(),
75122
75258
  githubIdentity,
75123
75259
  githubApi: (token) => createGithubApi({ token }),
75124
75260
  org: PERSONA_REPO_ORG,
@@ -75164,7 +75300,7 @@ async function startDaemon(config) {
75164
75300
  });
75165
75301
  shiftScheduler.start();
75166
75302
  logger.info("shift scheduler started", { shiftCount: shiftStore.list().length });
75167
- const larkBotStore = createLarkBotBindingStore(import_node_path78.default.join(config.dataDir, "personas"));
75303
+ const larkBotStore = createLarkBotBindingStore(import_node_path79.default.join(config.dataDir, "personas"));
75168
75304
  const larkBotCloud = createLarkBotCloudClient({
75169
75305
  api: config.clawosApi ?? DEFAULT_CLAWOS_API,
75170
75306
  getLoginPass: () => ownerIdentityStore.read()?.loginPass ?? null
@@ -75176,7 +75312,7 @@ async function startDaemon(config) {
75176
75312
  store: larkBotStore,
75177
75313
  fetchResource: (appId, messageId, fileKey, maxBytes, type) => larkBotCloud.fetchResource(appId, messageId, fileKey, maxBytes, type),
75178
75314
  // 图片落 guest userWorkDir 下(capId = lark-<chat_id>):CC 经 --add-dir + allowRead carve 可 Read
75179
- mediaRootFor: (chatId) => import_node_path78.default.join(deriveUserWorkDir(`lark-${chatId}`, usersRoot), "lark-media"),
75315
+ mediaRootFor: (chatId) => import_node_path79.default.join(deriveUserWorkDir(`lark-${chatId}`, usersRoot), "lark-media"),
75180
75316
  isShuttingDown: () => larkDraining,
75181
75317
  logger: {
75182
75318
  warn: (msg) => logger.warn(msg),
@@ -75460,8 +75596,8 @@ async function startDaemon(config) {
75460
75596
  const lines = [
75461
75597
  `Tunnel: ${r2.url}`,
75462
75598
  ...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
75463
- `Frpc config: ${import_node_path78.default.join(config.dataDir, "frpc.toml")}`,
75464
- `Frpc log: ${import_node_path78.default.join(logDir, "frpc.log")}`
75599
+ `Frpc config: ${import_node_path79.default.join(config.dataDir, "frpc.toml")}`,
75600
+ `Frpc log: ${import_node_path79.default.join(logDir, "frpc.log")}`
75465
75601
  ];
75466
75602
  const width2 = Math.max(...lines.map((l2) => l2.length));
75467
75603
  const bar = "\u2550".repeat(width2 + 4);
@@ -75474,8 +75610,8 @@ ${bar}
75474
75610
 
75475
75611
  `);
75476
75612
  try {
75477
- const connectPath = import_node_path78.default.join(config.dataDir, "connect.txt");
75478
- import_node_fs60.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
75613
+ const connectPath = import_node_path79.default.join(config.dataDir, "connect.txt");
75614
+ import_node_fs61.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
75479
75615
  } catch {
75480
75616
  }
75481
75617
  } catch (err) {
@@ -75573,9 +75709,9 @@ ${bar}
75573
75709
  };
75574
75710
  }
75575
75711
  function migrateDropPersonsDir(dataDir) {
75576
- const dir = import_node_path78.default.join(dataDir, "persons");
75712
+ const dir = import_node_path79.default.join(dataDir, "persons");
75577
75713
  try {
75578
- import_node_fs60.default.rmSync(dir, { recursive: true, force: true });
75714
+ import_node_fs61.default.rmSync(dir, { recursive: true, force: true });
75579
75715
  } catch {
75580
75716
  }
75581
75717
  }