@clawos-dev/clawd 0.2.485 → 0.2.487

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: path97, errorMaps, issueData } = params;
454
- const fullPath = [...path97, ...issueData.path || []];
453
+ const { data, path: path98, errorMaps, issueData } = params;
454
+ const fullPath = [...path98, ...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, path97, key) {
765
+ constructor(parent, value, path98, key) {
766
766
  this._cachedPath = [];
767
767
  this.parent = parent;
768
768
  this.data = value;
769
- this._path = path97;
769
+ this._path = path98;
770
770
  this._key = key;
771
771
  }
772
772
  get path() {
@@ -6027,6 +6027,9 @@ function isScanFresh(scan, repo2) {
6027
6027
  if (scan.status !== "done") return false;
6028
6028
  return scan.head === repo2.head && !repo2.dirty;
6029
6029
  }
6030
+ function cloudEngineOk(tool) {
6031
+ return (tool || "claude") === "codex";
6032
+ }
6030
6033
  function repoSlug(url) {
6031
6034
  return url.trim().replace(/^git@[^:]+:/, "").replace(/^https?:\/\/[^/]+\//, "").replace(/\.git$/, "");
6032
6035
  }
@@ -7603,7 +7606,12 @@ var init_schemas = __esm({
7603
7606
  // 缺省 = 该 tool 的 effort 与模型无关(claude 即此情形),消费方回落到 configSchema 里
7604
7607
  // name==='effort' 那条字段的 options。
7605
7608
  efforts: external_exports.array(SelectOptionSchema).optional(),
7606
- defaultEffort: external_exports.string().optional()
7609
+ defaultEffort: external_exports.string().optional(),
7610
+ // 下拉分组标题(codex:模型家族名 GPT / Gemini / Claude…,由 daemon 从 model id 派生)。
7611
+ // 缺省 = 该 tool 的模型不分组(claude 即此情形),消费方平铺渲染、不出标题。
7612
+ // 全表只落在一个家族时 daemon 也不填——一个横跨全表的标题没有信息量。
7613
+ // 消费方假定同 group 的条目已连续排好(排序在 daemon 侧,见 codex-model-list.mergeProviderModels)。
7614
+ group: external_exports.string().optional()
7607
7615
  });
7608
7616
  ModeInfoSchema = external_exports.object({
7609
7617
  id: external_exports.string().min(1),
@@ -9919,8 +9927,8 @@ var require_req = __commonJS({
9919
9927
  if (req.originalUrl) {
9920
9928
  _req.url = req.originalUrl;
9921
9929
  } else {
9922
- const path97 = req.path;
9923
- _req.url = typeof path97 === "string" ? path97 : req.url ? req.url.path || req.url : void 0;
9930
+ const path98 = req.path;
9931
+ _req.url = typeof path98 === "string" ? path98 : req.url ? req.url.path || req.url : void 0;
9924
9932
  }
9925
9933
  if (req.query) {
9926
9934
  _req.query = req.query;
@@ -10085,14 +10093,14 @@ var require_redact = __commonJS({
10085
10093
  }
10086
10094
  return obj;
10087
10095
  }
10088
- function parsePath(path97) {
10096
+ function parsePath(path98) {
10089
10097
  const parts = [];
10090
10098
  let current = "";
10091
10099
  let inBrackets = false;
10092
10100
  let inQuotes = false;
10093
10101
  let quoteChar = "";
10094
- for (let i = 0; i < path97.length; i++) {
10095
- const char = path97[i];
10102
+ for (let i = 0; i < path98.length; i++) {
10103
+ const char = path98[i];
10096
10104
  if (!inBrackets && char === ".") {
10097
10105
  if (current) {
10098
10106
  parts.push(current);
@@ -10223,10 +10231,10 @@ var require_redact = __commonJS({
10223
10231
  return current;
10224
10232
  }
10225
10233
  function redactPaths(obj, paths, censor, remove = false) {
10226
- for (const path97 of paths) {
10227
- const parts = parsePath(path97);
10234
+ for (const path98 of paths) {
10235
+ const parts = parsePath(path98);
10228
10236
  if (parts.includes("*")) {
10229
- redactWildcardPath(obj, parts, censor, path97, remove);
10237
+ redactWildcardPath(obj, parts, censor, path98, remove);
10230
10238
  } else {
10231
10239
  if (remove) {
10232
10240
  removeKey(obj, parts);
@@ -10311,8 +10319,8 @@ var require_redact = __commonJS({
10311
10319
  }
10312
10320
  } else {
10313
10321
  if (afterWildcard.includes("*")) {
10314
- const wrappedCensor = typeof censor === "function" ? (value, path97) => {
10315
- const fullPath = [...pathArray.slice(0, pathLength), ...path97];
10322
+ const wrappedCensor = typeof censor === "function" ? (value, path98) => {
10323
+ const fullPath = [...pathArray.slice(0, pathLength), ...path98];
10316
10324
  return censor(value, fullPath);
10317
10325
  } : censor;
10318
10326
  redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
@@ -10347,8 +10355,8 @@ var require_redact = __commonJS({
10347
10355
  return null;
10348
10356
  }
10349
10357
  const pathStructure = /* @__PURE__ */ new Map();
10350
- for (const path97 of pathsToClone) {
10351
- const parts = parsePath(path97);
10358
+ for (const path98 of pathsToClone) {
10359
+ const parts = parsePath(path98);
10352
10360
  let current = pathStructure;
10353
10361
  for (let i = 0; i < parts.length; i++) {
10354
10362
  const part = parts[i];
@@ -10400,24 +10408,24 @@ var require_redact = __commonJS({
10400
10408
  }
10401
10409
  return cloneSelectively(obj, pathStructure);
10402
10410
  }
10403
- function validatePath(path97) {
10404
- if (typeof path97 !== "string") {
10411
+ function validatePath(path98) {
10412
+ if (typeof path98 !== "string") {
10405
10413
  throw new Error("Paths must be (non-empty) strings");
10406
10414
  }
10407
- if (path97 === "") {
10415
+ if (path98 === "") {
10408
10416
  throw new Error("Invalid redaction path ()");
10409
10417
  }
10410
- if (path97.includes("..")) {
10411
- throw new Error(`Invalid redaction path (${path97})`);
10418
+ if (path98.includes("..")) {
10419
+ throw new Error(`Invalid redaction path (${path98})`);
10412
10420
  }
10413
- if (path97.includes(",")) {
10414
- throw new Error(`Invalid redaction path (${path97})`);
10421
+ if (path98.includes(",")) {
10422
+ throw new Error(`Invalid redaction path (${path98})`);
10415
10423
  }
10416
10424
  let bracketCount = 0;
10417
10425
  let inQuotes = false;
10418
10426
  let quoteChar = "";
10419
- for (let i = 0; i < path97.length; i++) {
10420
- const char = path97[i];
10427
+ for (let i = 0; i < path98.length; i++) {
10428
+ const char = path98[i];
10421
10429
  if ((char === '"' || char === "'") && bracketCount > 0) {
10422
10430
  if (!inQuotes) {
10423
10431
  inQuotes = true;
@@ -10431,20 +10439,20 @@ var require_redact = __commonJS({
10431
10439
  } else if (char === "]" && !inQuotes) {
10432
10440
  bracketCount--;
10433
10441
  if (bracketCount < 0) {
10434
- throw new Error(`Invalid redaction path (${path97})`);
10442
+ throw new Error(`Invalid redaction path (${path98})`);
10435
10443
  }
10436
10444
  }
10437
10445
  }
10438
10446
  if (bracketCount !== 0) {
10439
- throw new Error(`Invalid redaction path (${path97})`);
10447
+ throw new Error(`Invalid redaction path (${path98})`);
10440
10448
  }
10441
10449
  }
10442
10450
  function validatePaths(paths) {
10443
10451
  if (!Array.isArray(paths)) {
10444
10452
  throw new TypeError("paths must be an array");
10445
10453
  }
10446
- for (const path97 of paths) {
10447
- validatePath(path97);
10454
+ for (const path98 of paths) {
10455
+ validatePath(path98);
10448
10456
  }
10449
10457
  }
10450
10458
  function slowRedact(options = {}) {
@@ -10612,8 +10620,8 @@ var require_redaction = __commonJS({
10612
10620
  if (shape[k2] === null) {
10613
10621
  o[k2] = (value) => topCensor(value, [k2]);
10614
10622
  } else {
10615
- const wrappedCensor = typeof censor === "function" ? (value, path97) => {
10616
- return censor(value, [k2, ...path97]);
10623
+ const wrappedCensor = typeof censor === "function" ? (value, path98) => {
10624
+ return censor(value, [k2, ...path98]);
10617
10625
  } : censor;
10618
10626
  o[k2] = Redact({
10619
10627
  paths: shape[k2],
@@ -10831,10 +10839,10 @@ var require_atomic_sleep = __commonJS({
10831
10839
  var require_sonic_boom = __commonJS({
10832
10840
  "../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
10833
10841
  "use strict";
10834
- var fs85 = require("fs");
10842
+ var fs86 = require("fs");
10835
10843
  var EventEmitter3 = require("events");
10836
10844
  var inherits = require("util").inherits;
10837
- var path97 = require("path");
10845
+ var path98 = require("path");
10838
10846
  var sleep2 = require_atomic_sleep();
10839
10847
  var assert = require("assert");
10840
10848
  var BUSY_WRITE_TIMEOUT = 100;
@@ -10888,20 +10896,20 @@ var require_sonic_boom = __commonJS({
10888
10896
  const mode = sonic.mode;
10889
10897
  if (sonic.sync) {
10890
10898
  try {
10891
- if (sonic.mkdir) fs85.mkdirSync(path97.dirname(file), { recursive: true });
10892
- const fd = fs85.openSync(file, flags, mode);
10899
+ if (sonic.mkdir) fs86.mkdirSync(path98.dirname(file), { recursive: true });
10900
+ const fd = fs86.openSync(file, flags, mode);
10893
10901
  fileOpened(null, fd);
10894
10902
  } catch (err) {
10895
10903
  fileOpened(err);
10896
10904
  throw err;
10897
10905
  }
10898
10906
  } else if (sonic.mkdir) {
10899
- fs85.mkdir(path97.dirname(file), { recursive: true }, (err) => {
10907
+ fs86.mkdir(path98.dirname(file), { recursive: true }, (err) => {
10900
10908
  if (err) return fileOpened(err);
10901
- fs85.open(file, flags, mode, fileOpened);
10909
+ fs86.open(file, flags, mode, fileOpened);
10902
10910
  });
10903
10911
  } else {
10904
- fs85.open(file, flags, mode, fileOpened);
10912
+ fs86.open(file, flags, mode, fileOpened);
10905
10913
  }
10906
10914
  }
10907
10915
  function SonicBoom(opts) {
@@ -10942,8 +10950,8 @@ var require_sonic_boom = __commonJS({
10942
10950
  this.flush = flushBuffer;
10943
10951
  this.flushSync = flushBufferSync;
10944
10952
  this._actualWrite = actualWriteBuffer;
10945
- fsWriteSync = () => fs85.writeSync(this.fd, this._writingBuf);
10946
- fsWrite = () => fs85.write(this.fd, this._writingBuf, this.release);
10953
+ fsWriteSync = () => fs86.writeSync(this.fd, this._writingBuf);
10954
+ fsWrite = () => fs86.write(this.fd, this._writingBuf, this.release);
10947
10955
  } else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
10948
10956
  this._writingBuf = "";
10949
10957
  this.write = write;
@@ -10952,15 +10960,15 @@ var require_sonic_boom = __commonJS({
10952
10960
  this._actualWrite = actualWrite;
10953
10961
  fsWriteSync = () => {
10954
10962
  if (Buffer.isBuffer(this._writingBuf)) {
10955
- return fs85.writeSync(this.fd, this._writingBuf);
10963
+ return fs86.writeSync(this.fd, this._writingBuf);
10956
10964
  }
10957
- return fs85.writeSync(this.fd, this._writingBuf, "utf8");
10965
+ return fs86.writeSync(this.fd, this._writingBuf, "utf8");
10958
10966
  };
10959
10967
  fsWrite = () => {
10960
10968
  if (Buffer.isBuffer(this._writingBuf)) {
10961
- return fs85.write(this.fd, this._writingBuf, this.release);
10969
+ return fs86.write(this.fd, this._writingBuf, this.release);
10962
10970
  }
10963
- return fs85.write(this.fd, this._writingBuf, "utf8", this.release);
10971
+ return fs86.write(this.fd, this._writingBuf, "utf8", this.release);
10964
10972
  };
10965
10973
  } else {
10966
10974
  throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
@@ -11017,7 +11025,7 @@ var require_sonic_boom = __commonJS({
11017
11025
  }
11018
11026
  }
11019
11027
  if (this._fsync) {
11020
- fs85.fsyncSync(this.fd);
11028
+ fs86.fsyncSync(this.fd);
11021
11029
  }
11022
11030
  const len = this._len;
11023
11031
  if (this._reopening) {
@@ -11131,7 +11139,7 @@ var require_sonic_boom = __commonJS({
11131
11139
  const onDrain = () => {
11132
11140
  if (!this._fsync) {
11133
11141
  try {
11134
- fs85.fsync(this.fd, (err) => {
11142
+ fs86.fsync(this.fd, (err) => {
11135
11143
  this._flushPending = false;
11136
11144
  cb(err);
11137
11145
  });
@@ -11233,7 +11241,7 @@ var require_sonic_boom = __commonJS({
11233
11241
  const fd = this.fd;
11234
11242
  this.once("ready", () => {
11235
11243
  if (fd !== this.fd) {
11236
- fs85.close(fd, (err) => {
11244
+ fs86.close(fd, (err) => {
11237
11245
  if (err) {
11238
11246
  return this.emit("error", err);
11239
11247
  }
@@ -11282,7 +11290,7 @@ var require_sonic_boom = __commonJS({
11282
11290
  buf = this._bufs[0];
11283
11291
  }
11284
11292
  try {
11285
- const n = Buffer.isBuffer(buf) ? fs85.writeSync(this.fd, buf) : fs85.writeSync(this.fd, buf, "utf8");
11293
+ const n = Buffer.isBuffer(buf) ? fs86.writeSync(this.fd, buf) : fs86.writeSync(this.fd, buf, "utf8");
11286
11294
  const releasedBufObj = releaseWritingBuf(buf, this._len, n);
11287
11295
  buf = releasedBufObj.writingBuf;
11288
11296
  this._len = releasedBufObj.len;
@@ -11298,7 +11306,7 @@ var require_sonic_boom = __commonJS({
11298
11306
  }
11299
11307
  }
11300
11308
  try {
11301
- fs85.fsyncSync(this.fd);
11309
+ fs86.fsyncSync(this.fd);
11302
11310
  } catch {
11303
11311
  }
11304
11312
  }
@@ -11319,7 +11327,7 @@ var require_sonic_boom = __commonJS({
11319
11327
  buf = mergeBuf(this._bufs[0], this._lens[0]);
11320
11328
  }
11321
11329
  try {
11322
- const n = fs85.writeSync(this.fd, buf);
11330
+ const n = fs86.writeSync(this.fd, buf);
11323
11331
  buf = buf.subarray(n);
11324
11332
  this._len = Math.max(this._len - n, 0);
11325
11333
  if (buf.length <= 0) {
@@ -11347,13 +11355,13 @@ var require_sonic_boom = __commonJS({
11347
11355
  this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
11348
11356
  if (this.sync) {
11349
11357
  try {
11350
- const written = Buffer.isBuffer(this._writingBuf) ? fs85.writeSync(this.fd, this._writingBuf) : fs85.writeSync(this.fd, this._writingBuf, "utf8");
11358
+ const written = Buffer.isBuffer(this._writingBuf) ? fs86.writeSync(this.fd, this._writingBuf) : fs86.writeSync(this.fd, this._writingBuf, "utf8");
11351
11359
  release2(null, written);
11352
11360
  } catch (err) {
11353
11361
  release2(err);
11354
11362
  }
11355
11363
  } else {
11356
- fs85.write(this.fd, this._writingBuf, release2);
11364
+ fs86.write(this.fd, this._writingBuf, release2);
11357
11365
  }
11358
11366
  }
11359
11367
  function actualWriteBuffer() {
@@ -11362,7 +11370,7 @@ var require_sonic_boom = __commonJS({
11362
11370
  this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
11363
11371
  if (this.sync) {
11364
11372
  try {
11365
- const written = fs85.writeSync(this.fd, this._writingBuf);
11373
+ const written = fs86.writeSync(this.fd, this._writingBuf);
11366
11374
  release2(null, written);
11367
11375
  } catch (err) {
11368
11376
  release2(err);
@@ -11371,7 +11379,7 @@ var require_sonic_boom = __commonJS({
11371
11379
  if (kCopyBuffer) {
11372
11380
  this._writingBuf = Buffer.from(this._writingBuf);
11373
11381
  }
11374
- fs85.write(this.fd, this._writingBuf, release2);
11382
+ fs86.write(this.fd, this._writingBuf, release2);
11375
11383
  }
11376
11384
  }
11377
11385
  function actualClose(sonic) {
@@ -11387,12 +11395,12 @@ var require_sonic_boom = __commonJS({
11387
11395
  sonic._lens = [];
11388
11396
  assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
11389
11397
  try {
11390
- fs85.fsync(sonic.fd, closeWrapped);
11398
+ fs86.fsync(sonic.fd, closeWrapped);
11391
11399
  } catch {
11392
11400
  }
11393
11401
  function closeWrapped() {
11394
11402
  if (sonic.fd !== 1 && sonic.fd !== 2) {
11395
- fs85.close(sonic.fd, done);
11403
+ fs86.close(sonic.fd, done);
11396
11404
  } else {
11397
11405
  done();
11398
11406
  }
@@ -13756,7 +13764,7 @@ var require_multistream = __commonJS({
13756
13764
  var require_pino = __commonJS({
13757
13765
  "../node_modules/.pnpm/pino@9.14.0/node_modules/pino/pino.js"(exports2, module2) {
13758
13766
  "use strict";
13759
- var os31 = require("os");
13767
+ var os32 = require("os");
13760
13768
  var stdSerializers = require_pino_std_serializers();
13761
13769
  var caller = require_caller();
13762
13770
  var redaction = require_redaction();
@@ -13803,7 +13811,7 @@ var require_pino = __commonJS({
13803
13811
  } = symbols;
13804
13812
  var { epochTime, nullTime } = time;
13805
13813
  var { pid } = process;
13806
- var hostname = os31.hostname();
13814
+ var hostname = os32.hostname();
13807
13815
  var defaultErrorSerializer = stdSerializers.err;
13808
13816
  var defaultOptions2 = {
13809
13817
  level: "info",
@@ -14527,11 +14535,11 @@ var init_lib = __esm({
14527
14535
  }
14528
14536
  }
14529
14537
  },
14530
- addToPath: function addToPath(path97, added, removed, oldPosInc, options) {
14531
- var last = path97.lastComponent;
14538
+ addToPath: function addToPath(path98, added, removed, oldPosInc, options) {
14539
+ var last = path98.lastComponent;
14532
14540
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
14533
14541
  return {
14534
- oldPos: path97.oldPos + oldPosInc,
14542
+ oldPos: path98.oldPos + oldPosInc,
14535
14543
  lastComponent: {
14536
14544
  count: last.count + 1,
14537
14545
  added,
@@ -14541,7 +14549,7 @@ var init_lib = __esm({
14541
14549
  };
14542
14550
  } else {
14543
14551
  return {
14544
- oldPos: path97.oldPos + oldPosInc,
14552
+ oldPos: path98.oldPos + oldPosInc,
14545
14553
  lastComponent: {
14546
14554
  count: 1,
14547
14555
  added,
@@ -15123,10 +15131,10 @@ function attachmentToHistoryMessage(o, ts) {
15123
15131
  const memories = raw.map((m2) => {
15124
15132
  if (!m2 || typeof m2 !== "object") return null;
15125
15133
  const rec4 = m2;
15126
- const path97 = typeof rec4.path === "string" ? rec4.path : null;
15134
+ const path98 = typeof rec4.path === "string" ? rec4.path : null;
15127
15135
  const content = typeof rec4.content === "string" ? rec4.content : null;
15128
- if (!path97 || content == null) return null;
15129
- const entry = { path: path97, content };
15136
+ if (!path98 || content == null) return null;
15137
+ const entry = { path: path98, content };
15130
15138
  if (typeof rec4.mtimeMs === "number") entry.mtimeMs = rec4.mtimeMs;
15131
15139
  return entry;
15132
15140
  }).filter((m2) => m2 !== null);
@@ -15992,10 +16000,10 @@ function parseAttachment(obj) {
15992
16000
  const memories = raw.map((m2) => {
15993
16001
  if (!m2 || typeof m2 !== "object") return null;
15994
16002
  const rec4 = m2;
15995
- const path97 = typeof rec4.path === "string" ? rec4.path : null;
16003
+ const path98 = typeof rec4.path === "string" ? rec4.path : null;
15996
16004
  const content = typeof rec4.content === "string" ? rec4.content : null;
15997
- if (!path97 || content == null) return null;
15998
- const out = { path: path97, content };
16005
+ if (!path98 || content == null) return null;
16006
+ const out = { path: path98, content };
15999
16007
  if (typeof rec4.mtimeMs === "number") out.mtimeMs = rec4.mtimeMs;
16000
16008
  return out;
16001
16009
  }).filter((m2) => m2 !== null);
@@ -36969,8 +36977,8 @@ var require_utils = __commonJS({
36969
36977
  var result = transform[inputType][outputType](input);
36970
36978
  return result;
36971
36979
  };
36972
- exports2.resolve = function(path97) {
36973
- var parts = path97.split("/");
36980
+ exports2.resolve = function(path98) {
36981
+ var parts = path98.split("/");
36974
36982
  var result = [];
36975
36983
  for (var index = 0; index < parts.length; index++) {
36976
36984
  var part = parts[index];
@@ -42823,18 +42831,18 @@ var require_object = __commonJS({
42823
42831
  var object = new ZipObject(name, zipObjectContent, o);
42824
42832
  this.files[name] = object;
42825
42833
  };
42826
- var parentFolder = function(path97) {
42827
- if (path97.slice(-1) === "/") {
42828
- path97 = path97.substring(0, path97.length - 1);
42834
+ var parentFolder = function(path98) {
42835
+ if (path98.slice(-1) === "/") {
42836
+ path98 = path98.substring(0, path98.length - 1);
42829
42837
  }
42830
- var lastSlash = path97.lastIndexOf("/");
42831
- return lastSlash > 0 ? path97.substring(0, lastSlash) : "";
42838
+ var lastSlash = path98.lastIndexOf("/");
42839
+ return lastSlash > 0 ? path98.substring(0, lastSlash) : "";
42832
42840
  };
42833
- var forceTrailingSlash = function(path97) {
42834
- if (path97.slice(-1) !== "/") {
42835
- path97 += "/";
42841
+ var forceTrailingSlash = function(path98) {
42842
+ if (path98.slice(-1) !== "/") {
42843
+ path98 += "/";
42836
42844
  }
42837
- return path97;
42845
+ return path98;
42838
42846
  };
42839
42847
  var folderAdd = function(name, createFolders) {
42840
42848
  createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
@@ -43836,7 +43844,7 @@ var require_lib3 = __commonJS({
43836
43844
  // src/run-case/recorder.ts
43837
43845
  function startRunCaseRecorder(opts) {
43838
43846
  const now = opts.now ?? Date.now;
43839
- const dir = import_node_path79.default.dirname(opts.recordPath);
43847
+ const dir = import_node_path80.default.dirname(opts.recordPath);
43840
43848
  let stream = null;
43841
43849
  let closing = false;
43842
43850
  let closedSettled = false;
@@ -43850,8 +43858,8 @@ function startRunCaseRecorder(opts) {
43850
43858
  });
43851
43859
  const ensureStream = () => {
43852
43860
  if (stream) return stream;
43853
- import_node_fs57.default.mkdirSync(dir, { recursive: true });
43854
- stream = import_node_fs57.default.createWriteStream(opts.recordPath, { flags: "a" });
43861
+ import_node_fs58.default.mkdirSync(dir, { recursive: true });
43862
+ stream = import_node_fs58.default.createWriteStream(opts.recordPath, { flags: "a" });
43855
43863
  stream.on("close", () => closedResolve());
43856
43864
  return stream;
43857
43865
  };
@@ -43876,12 +43884,12 @@ function startRunCaseRecorder(opts) {
43876
43884
  };
43877
43885
  return { tap, close, closed };
43878
43886
  }
43879
- var import_node_fs57, import_node_path79;
43887
+ var import_node_fs58, import_node_path80;
43880
43888
  var init_recorder = __esm({
43881
43889
  "src/run-case/recorder.ts"() {
43882
43890
  "use strict";
43883
- import_node_fs57 = __toESM(require("fs"), 1);
43884
- import_node_path79 = __toESM(require("path"), 1);
43891
+ import_node_fs58 = __toESM(require("fs"), 1);
43892
+ import_node_path80 = __toESM(require("path"), 1);
43885
43893
  }
43886
43894
  });
43887
43895
 
@@ -43924,7 +43932,7 @@ var init_wire = __esm({
43924
43932
  // src/run-case/controller.ts
43925
43933
  async function runController(opts) {
43926
43934
  const now = opts.now ?? Date.now;
43927
- const cwd = opts.cwd ?? (0, import_node_fs58.mkdtempSync)(import_node_path80.default.join(import_node_os27.default.tmpdir(), "clawd-runcase-"));
43935
+ const cwd = opts.cwd ?? (0, import_node_fs59.mkdtempSync)(import_node_path81.default.join(import_node_os28.default.tmpdir(), "clawd-runcase-"));
43928
43936
  const ownsCwd = opts.cwd === void 0;
43929
43937
  const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
43930
43938
  const spawnCtx = { cwd };
@@ -44085,19 +44093,19 @@ async function runController(opts) {
44085
44093
  if (sigintHandler) process.off("SIGINT", sigintHandler);
44086
44094
  if (ownsCwd) {
44087
44095
  try {
44088
- (0, import_node_fs58.rmSync)(cwd, { recursive: true, force: true });
44096
+ (0, import_node_fs59.rmSync)(cwd, { recursive: true, force: true });
44089
44097
  } catch {
44090
44098
  }
44091
44099
  }
44092
44100
  return exitCode ?? 0;
44093
44101
  }
44094
- var import_node_fs58, import_node_os27, import_node_path80;
44102
+ var import_node_fs59, import_node_os28, import_node_path81;
44095
44103
  var init_controller = __esm({
44096
44104
  "src/run-case/controller.ts"() {
44097
44105
  "use strict";
44098
- import_node_fs58 = require("fs");
44099
- import_node_os27 = __toESM(require("os"), 1);
44100
- import_node_path80 = __toESM(require("path"), 1);
44106
+ import_node_fs59 = require("fs");
44107
+ import_node_os28 = __toESM(require("os"), 1);
44108
+ import_node_path81 = __toESM(require("path"), 1);
44101
44109
  init_claude();
44102
44110
  init_stdout_splitter();
44103
44111
  init_permission_stdio();
@@ -44372,9 +44380,9 @@ Env (advanced):
44372
44380
  `;
44373
44381
 
44374
44382
  // src/index.ts
44375
- var import_node_path78 = __toESM(require("path"), 1);
44376
- var import_node_fs56 = __toESM(require("fs"), 1);
44377
- var import_node_os26 = __toESM(require("os"), 1);
44383
+ var import_node_path79 = __toESM(require("path"), 1);
44384
+ var import_node_fs57 = __toESM(require("fs"), 1);
44385
+ var import_node_os27 = __toESM(require("os"), 1);
44378
44386
  var import_node_crypto22 = require("crypto");
44379
44387
  var import_node_url5 = require("url");
44380
44388
 
@@ -51157,7 +51165,7 @@ init_claude();
51157
51165
 
51158
51166
  // src/tools/codex.ts
51159
51167
  var import_node_child_process6 = require("child_process");
51160
- var import_node_fs19 = __toESM(require("fs"), 1);
51168
+ var import_node_fs20 = __toESM(require("fs"), 1);
51161
51169
 
51162
51170
  // src/tools/codex-session.ts
51163
51171
  var import_node_child_process4 = require("child_process");
@@ -51630,8 +51638,8 @@ function turnStartInput(text) {
51630
51638
  const items = [];
51631
51639
  let leftover = text;
51632
51640
  for (const m2 of text.matchAll(SKILL_RE)) {
51633
- const [marker, name, path97] = m2;
51634
- items.push({ type: "skill", name, path: path97 });
51641
+ const [marker, name, path98] = m2;
51642
+ items.push({ type: "skill", name, path: path98 });
51635
51643
  leftover = leftover.replace(marker, "");
51636
51644
  }
51637
51645
  for (const m2 of text.matchAll(ATTACHMENT_RE2)) {
@@ -52020,6 +52028,105 @@ function mapModelList(raw) {
52020
52028
  }
52021
52029
  return models;
52022
52030
  }
52031
+ function modelFamily(id) {
52032
+ const head = (id.split("-")[0] || id).toLowerCase();
52033
+ if (head === "gpt") return "GPT";
52034
+ return head.charAt(0).toUpperCase() + head.slice(1);
52035
+ }
52036
+ function familyRank(family) {
52037
+ return family === "GPT" ? 0 : 1;
52038
+ }
52039
+ function mergeProviderModels(native, provider) {
52040
+ const nativeOrder = new Map(native.map((m2, i) => [m2.id, i]));
52041
+ const extras = provider.filter((p2) => !nativeOrder.has(p2.id)).map((p2) => ({ id: p2.id, label: p2.id, contextWindowSize: CODEX_CONTEXT_WINDOW }));
52042
+ const sorted = [...native, ...extras].sort((a, b2) => {
52043
+ const fa = modelFamily(a.id);
52044
+ const fb = modelFamily(b2.id);
52045
+ if (fa !== fb) return familyRank(fa) - familyRank(fb) || fa.localeCompare(fb);
52046
+ const ia = nativeOrder.get(a.id);
52047
+ const ib = nativeOrder.get(b2.id);
52048
+ if (ia !== void 0 && ib !== void 0) return ia - ib;
52049
+ if (ia !== void 0) return -1;
52050
+ if (ib !== void 0) return 1;
52051
+ return a.id.localeCompare(b2.id);
52052
+ });
52053
+ if (new Set(sorted.map((m2) => modelFamily(m2.id))).size <= 1) return sorted;
52054
+ return sorted.map((m2) => ({ ...m2, group: modelFamily(m2.id) }));
52055
+ }
52056
+
52057
+ // src/tools/codex-provider-models.ts
52058
+ var import_node_fs19 = __toESM(require("fs"), 1);
52059
+ var import_node_os7 = __toESM(require("os"), 1);
52060
+ var import_node_path18 = __toESM(require("path"), 1);
52061
+ var PROVIDER_FETCH_TIMEOUT_MS = 3e3;
52062
+ function asRecord(v2) {
52063
+ return v2 && typeof v2 === "object" && !Array.isArray(v2) ? v2 : null;
52064
+ }
52065
+ function readAuthKey(codexHome) {
52066
+ try {
52067
+ const raw = JSON.parse(import_node_fs19.default.readFileSync(import_node_path18.default.join(codexHome, "auth.json"), "utf8"));
52068
+ const key = asRecord(raw)?.OPENAI_API_KEY;
52069
+ return typeof key === "string" && key ? key : void 0;
52070
+ } catch {
52071
+ return void 0;
52072
+ }
52073
+ }
52074
+ function resolveProviderEndpoint(rawConfig, deps = {}) {
52075
+ const config = asRecord(asRecord(rawConfig)?.config);
52076
+ if (!config) return null;
52077
+ const name = config.model_provider;
52078
+ if (typeof name !== "string" || !name) return null;
52079
+ const entry = asRecord(asRecord(config.model_providers)?.[name]);
52080
+ if (!entry) return null;
52081
+ const baseUrl = entry.base_url;
52082
+ if (typeof baseUrl !== "string" || !baseUrl) return null;
52083
+ const env = deps.env ?? process.env;
52084
+ const codexHome = deps.codexHome ?? env.CODEX_HOME ?? import_node_path18.default.join(import_node_os7.default.homedir(), ".codex");
52085
+ const envKey = typeof entry.env_key === "string" && entry.env_key ? entry.env_key : null;
52086
+ const token = envKey ? env[envKey] : readAuthKey(codexHome);
52087
+ if (!token) {
52088
+ deps.logger?.warn?.(
52089
+ envKey ? `provider "${name}": env_key ${envKey} is not set in the daemon process, sending unauthenticated` : `provider "${name}": no OPENAI_API_KEY in ${codexHome}/auth.json, sending unauthenticated`
52090
+ );
52091
+ }
52092
+ return {
52093
+ baseUrl,
52094
+ headers: {
52095
+ Accept: "application/json",
52096
+ ...token ? { Authorization: `Bearer ${token}` } : {}
52097
+ }
52098
+ };
52099
+ }
52100
+ async function fetchProviderModels(endpoint, deps = {}) {
52101
+ const fetchImpl = deps.fetchImpl ?? fetch;
52102
+ const controller = new AbortController();
52103
+ const timer = setTimeout(() => controller.abort(), deps.timeoutMs ?? PROVIDER_FETCH_TIMEOUT_MS);
52104
+ const url = `${endpoint.baseUrl.replace(/\/$/, "")}/models`;
52105
+ try {
52106
+ const res = await fetchImpl(url, { headers: endpoint.headers, signal: controller.signal });
52107
+ if (!res.ok) {
52108
+ deps.logger?.warn?.(`provider model list failed: HTTP ${res.status} from ${url}`);
52109
+ return [];
52110
+ }
52111
+ const data = asRecord(await res.json())?.data;
52112
+ if (!Array.isArray(data)) {
52113
+ deps.logger?.warn?.(`provider model list: \`data\` is not an array (${url})`);
52114
+ return [];
52115
+ }
52116
+ const out = [];
52117
+ for (const item of data) {
52118
+ const e = asRecord(item);
52119
+ if (!e || typeof e.id !== "string" || !e.id) continue;
52120
+ out.push({ id: e.id, ...typeof e.owned_by === "string" ? { ownedBy: e.owned_by } : {} });
52121
+ }
52122
+ return out;
52123
+ } catch (err) {
52124
+ deps.logger?.warn?.(`provider model list failed: ${err.message}`);
52125
+ return [];
52126
+ } finally {
52127
+ clearTimeout(timer);
52128
+ }
52129
+ }
52023
52130
 
52024
52131
  // src/tools/codex.ts
52025
52132
  init_claude();
@@ -52084,14 +52191,13 @@ function buildCapabilities(models) {
52084
52191
  function sanitizeCodexModel(model) {
52085
52192
  if (model === void 0) return void 0;
52086
52193
  if (CLAUDE_MODEL_IDS.includes(model)) return void 0;
52087
- if (model.startsWith("claude-")) return void 0;
52088
52194
  return model;
52089
52195
  }
52090
52196
  async function probeCodex(env = process.env) {
52091
- if (env.CODEX_BIN && import_node_fs19.default.existsSync(env.CODEX_BIN)) return { available: true, path: env.CODEX_BIN };
52197
+ if (env.CODEX_BIN && import_node_fs20.default.existsSync(env.CODEX_BIN)) return { available: true, path: env.CODEX_BIN };
52092
52198
  try {
52093
52199
  const out = (0, import_node_child_process6.execFileSync)("which", ["codex"], { encoding: "utf8" }).trim();
52094
- if (out && import_node_fs19.default.existsSync(out)) return { available: true, path: out };
52200
+ if (out && import_node_fs20.default.existsSync(out)) return { available: true, path: out };
52095
52201
  } catch {
52096
52202
  }
52097
52203
  return { available: false };
@@ -52104,6 +52210,8 @@ var CodexAdapter = class {
52104
52210
  logger;
52105
52211
  probeOverride;
52106
52212
  queryOverride;
52213
+ configQueryOverride;
52214
+ fetchImpl;
52107
52215
  /** CODEX_HOME 归属解析(spec 2026-08-18-codex-project-alignment §3.1),由 index.ts 注入 */
52108
52216
  codexHomeFor;
52109
52217
  // capabilities 的进程级 memo。**回落结果同样被缓存**——否则 codex 没装时每次开弹窗都
@@ -52115,6 +52223,8 @@ var CodexAdapter = class {
52115
52223
  this.probeOverride = opts.probeOverride;
52116
52224
  this.historyReader = opts.historyReader;
52117
52225
  this.queryOverride = opts.queryOverride;
52226
+ this.configQueryOverride = opts.configQueryOverride;
52227
+ this.fetchImpl = opts.fetchImpl;
52118
52228
  this.codexHomeFor = opts.codexHomeFor;
52119
52229
  }
52120
52230
  async probe() {
@@ -52127,14 +52237,46 @@ var CodexAdapter = class {
52127
52237
  return this.capsPromise;
52128
52238
  }
52129
52239
  async loadCapabilities() {
52240
+ const [native, providerModels] = await Promise.all([
52241
+ this.loadNativeModels(),
52242
+ this.loadProviderModels()
52243
+ ]);
52244
+ if (native.length === 0 && providerModels.length === 0) {
52245
+ return buildCapabilities([CODEX_DEFAULT_MODEL_ENTRY]);
52246
+ }
52247
+ const base = native.length > 0 ? [] : [CODEX_DEFAULT_MODEL_ENTRY];
52248
+ return buildCapabilities([...base, ...mergeProviderModels(native, providerModels)]);
52249
+ }
52250
+ /** codex 内置型号表。失败返回 [],由 loadCapabilities 决定怎么降级 */
52251
+ async loadNativeModels() {
52130
52252
  try {
52131
52253
  const raw = this.queryOverride ? await this.queryOverride() : await queryCodexAppServer(process.cwd(), "model/list", {});
52132
- return buildCapabilities(mapModelList(raw));
52254
+ return mapModelList(raw);
52133
52255
  } catch (err) {
52134
- this.logger?.warn?.(
52135
- `codex model/list failed, falling back to config.toml default only: ${err.message}`
52136
- );
52137
- return buildCapabilities([CODEX_DEFAULT_MODEL_ENTRY]);
52256
+ this.logger?.warn?.(`codex model/list failed: ${err.message}`);
52257
+ return [];
52258
+ }
52259
+ }
52260
+ /**
52261
+ * provider 订阅侧全集。未配自定义 provider(官方用户)或任何失败都返回 []。
52262
+ * 见 codex-provider-models.ts —— model/list 只报 codex 内置型号,代理转发的模型全靠这里。
52263
+ */
52264
+ async loadProviderModels() {
52265
+ try {
52266
+ const raw = this.configQueryOverride ? await this.configQueryOverride() : await queryCodexAppServer(process.cwd(), "config/read", {}, {
52267
+ timeoutMs: PROVIDER_FETCH_TIMEOUT_MS
52268
+ });
52269
+ const endpoint = resolveProviderEndpoint(raw, {
52270
+ ...this.logger ? { logger: this.logger } : {}
52271
+ });
52272
+ if (!endpoint) return [];
52273
+ return await fetchProviderModels(endpoint, {
52274
+ ...this.fetchImpl ? { fetchImpl: this.fetchImpl } : {},
52275
+ ...this.logger ? { logger: this.logger } : {}
52276
+ });
52277
+ } catch (err) {
52278
+ this.logger?.warn?.(`codex provider model list failed: ${err.message}`);
52279
+ return [];
52138
52280
  }
52139
52281
  }
52140
52282
  // 纯函数、无 IO。所有 codex 模型共用同一静态窗口值(model/list 不给 contextWindow),
@@ -52164,9 +52306,9 @@ var CodexAdapter = class {
52164
52306
 
52165
52307
  // src/tools/claude-tui.ts
52166
52308
  var import_node_crypto5 = require("crypto");
52167
- var import_node_fs20 = __toESM(require("fs"), 1);
52168
- var import_node_os7 = __toESM(require("os"), 1);
52169
- var import_node_path18 = __toESM(require("path"), 1);
52309
+ var import_node_fs21 = __toESM(require("fs"), 1);
52310
+ var import_node_os8 = __toESM(require("os"), 1);
52311
+ var import_node_path19 = __toESM(require("path"), 1);
52170
52312
  var import_headless = __toESM(require_xterm_headless(), 1);
52171
52313
 
52172
52314
  // ../node_modules/.pnpm/@xterm+addon-serialize@0.14.0/node_modules/@xterm/addon-serialize/lib/addon-serialize.mjs
@@ -53391,10 +53533,10 @@ function buildTuiSpawnArgs(ctx, isResume = false) {
53391
53533
  }
53392
53534
  function jsonlExistsForCtx(ctx) {
53393
53535
  if (!ctx.toolSessionId) return false;
53394
- const home = import_node_os7.default.homedir();
53395
- const file = import_node_path18.default.join(home, ".claude", "projects", cwdToHashDir(ctx.cwd), `${ctx.toolSessionId}.jsonl`);
53536
+ const home = import_node_os8.default.homedir();
53537
+ const file = import_node_path19.default.join(home, ".claude", "projects", cwdToHashDir(ctx.cwd), `${ctx.toolSessionId}.jsonl`);
53396
53538
  try {
53397
- return import_node_fs20.default.statSync(file).isFile();
53539
+ return import_node_fs21.default.statSync(file).isFile();
53398
53540
  } catch {
53399
53541
  return false;
53400
53542
  }
@@ -53478,7 +53620,7 @@ var PersonaDispatchManager = class {
53478
53620
 
53479
53621
  // src/dispatch/store.ts
53480
53622
  var import_promises = __toESM(require("fs/promises"), 1);
53481
- var import_node_path19 = __toESM(require("path"), 1);
53623
+ var import_node_path20 = __toESM(require("path"), 1);
53482
53624
 
53483
53625
  // src/shift/constants.ts
53484
53626
  var MAX_RUNS_PER_SHIFT = 30;
@@ -53516,7 +53658,7 @@ function createDispatchStore(deps) {
53516
53658
  flushTimer = null;
53517
53659
  }
53518
53660
  const content = { version: 1, records };
53519
- await import_promises.default.mkdir(import_node_path19.default.dirname(deps.filePath), { recursive: true });
53661
+ await import_promises.default.mkdir(import_node_path20.default.dirname(deps.filePath), { recursive: true });
53520
53662
  const tmp = `${deps.filePath}.tmp-${deps.now()}-${Math.floor(Math.random() * 1e6)}`;
53521
53663
  await import_promises.default.writeFile(tmp, JSON.stringify(content, null, 2), "utf8");
53522
53664
  await import_promises.default.rename(tmp, deps.filePath);
@@ -53582,7 +53724,7 @@ function createDispatchStore(deps) {
53582
53724
 
53583
53725
  // src/channel/json-store.ts
53584
53726
  var import_promises2 = __toESM(require("fs/promises"), 1);
53585
- var import_node_path20 = __toESM(require("path"), 1);
53727
+ var import_node_path21 = __toESM(require("path"), 1);
53586
53728
  function createJsonStore(deps) {
53587
53729
  let items = [];
53588
53730
  let flushTimer = null;
@@ -53593,7 +53735,7 @@ function createJsonStore(deps) {
53593
53735
  flushTimer = null;
53594
53736
  }
53595
53737
  const content = { version: version2, [deps.key]: items };
53596
- await import_promises2.default.mkdir(import_node_path20.default.dirname(deps.filePath), { recursive: true });
53738
+ await import_promises2.default.mkdir(import_node_path21.default.dirname(deps.filePath), { recursive: true });
53597
53739
  const tmp = `${deps.filePath}.tmp-${deps.now()}-${Math.floor(Math.random() * 1e6)}`;
53598
53740
  await import_promises2.default.writeFile(tmp, JSON.stringify(content, null, 2), "utf8");
53599
53741
  await import_promises2.default.rename(tmp, deps.filePath);
@@ -53885,10 +54027,10 @@ function createTopicStore(deps) {
53885
54027
  }
53886
54028
 
53887
54029
  // src/dispatch/mcp-config.ts
53888
- var import_node_fs21 = __toESM(require("fs"), 1);
53889
- var import_node_path21 = __toESM(require("path"), 1);
54030
+ var import_node_fs22 = __toESM(require("fs"), 1);
54031
+ var import_node_path22 = __toESM(require("path"), 1);
53890
54032
  function dispatchMcpConfigPath(dataDir) {
53891
- return import_node_path21.default.join(dataDir, "dispatch.mcp.json");
54033
+ return import_node_path22.default.join(dataDir, "dispatch.mcp.json");
53892
54034
  }
53893
54035
  function writeDispatchMcpConfig(args) {
53894
54036
  const cfgPath = dispatchMcpConfigPath(args.dataDir);
@@ -53907,16 +54049,16 @@ function writeDispatchMcpConfig(args) {
53907
54049
  }
53908
54050
  }
53909
54051
  };
53910
- import_node_fs21.default.mkdirSync(args.dataDir, { recursive: true });
53911
- import_node_fs21.default.writeFileSync(cfgPath, JSON.stringify(content, null, 2), "utf8");
54052
+ import_node_fs22.default.mkdirSync(args.dataDir, { recursive: true });
54053
+ import_node_fs22.default.writeFileSync(cfgPath, JSON.stringify(content, null, 2), "utf8");
53912
54054
  return cfgPath;
53913
54055
  }
53914
54056
 
53915
54057
  // src/ticket/mcp-config.ts
53916
- var import_node_fs22 = __toESM(require("fs"), 1);
53917
- var import_node_path22 = __toESM(require("path"), 1);
54058
+ var import_node_fs23 = __toESM(require("fs"), 1);
54059
+ var import_node_path23 = __toESM(require("path"), 1);
53918
54060
  function ticketMcpConfigPath(dataDir) {
53919
- return import_node_path22.default.join(dataDir, "ticket.mcp.json");
54061
+ return import_node_path23.default.join(dataDir, "ticket.mcp.json");
53920
54062
  }
53921
54063
  function writeTicketMcpConfig(args) {
53922
54064
  const cfgPath = ticketMcpConfigPath(args.dataDir);
@@ -53938,16 +54080,16 @@ function writeTicketMcpConfig(args) {
53938
54080
  }
53939
54081
  }
53940
54082
  };
53941
- import_node_fs22.default.mkdirSync(args.dataDir, { recursive: true });
53942
- import_node_fs22.default.writeFileSync(cfgPath, JSON.stringify(content, null, 2), "utf8");
54083
+ import_node_fs23.default.mkdirSync(args.dataDir, { recursive: true });
54084
+ import_node_fs23.default.writeFileSync(cfgPath, JSON.stringify(content, null, 2), "utf8");
53943
54085
  return cfgPath;
53944
54086
  }
53945
54087
 
53946
54088
  // src/shift/mcp-config.ts
53947
- var import_node_fs23 = __toESM(require("fs"), 1);
53948
- var import_node_path23 = __toESM(require("path"), 1);
54089
+ var import_node_fs24 = __toESM(require("fs"), 1);
54090
+ var import_node_path24 = __toESM(require("path"), 1);
53949
54091
  function shiftMcpConfigPath(dataDir) {
53950
- return import_node_path23.default.join(dataDir, "shift.mcp.json");
54092
+ return import_node_path24.default.join(dataDir, "shift.mcp.json");
53951
54093
  }
53952
54094
  async function writeShiftMcpConfig(args) {
53953
54095
  const cfgPath = shiftMcpConfigPath(args.dataDir);
@@ -53966,16 +54108,16 @@ async function writeShiftMcpConfig(args) {
53966
54108
  }
53967
54109
  }
53968
54110
  };
53969
- await import_node_fs23.default.promises.mkdir(args.dataDir, { recursive: true });
53970
- await import_node_fs23.default.promises.writeFile(cfgPath, JSON.stringify(content, null, 2), "utf8");
54111
+ await import_node_fs24.default.promises.mkdir(args.dataDir, { recursive: true });
54112
+ await import_node_fs24.default.promises.writeFile(cfgPath, JSON.stringify(content, null, 2), "utf8");
53971
54113
  return cfgPath;
53972
54114
  }
53973
54115
 
53974
54116
  // src/inbox/mcp-config.ts
53975
- var import_node_fs24 = __toESM(require("fs"), 1);
53976
- var import_node_path24 = __toESM(require("path"), 1);
54117
+ var import_node_fs25 = __toESM(require("fs"), 1);
54118
+ var import_node_path25 = __toESM(require("path"), 1);
53977
54119
  function inboxMcpConfigPath(dataDir) {
53978
- return import_node_path24.default.join(dataDir, "inbox.mcp.json");
54120
+ return import_node_path25.default.join(dataDir, "inbox.mcp.json");
53979
54121
  }
53980
54122
  async function writeInboxMcpConfig(args) {
53981
54123
  const cfgPath = inboxMcpConfigPath(args.dataDir);
@@ -53994,16 +54136,16 @@ async function writeInboxMcpConfig(args) {
53994
54136
  }
53995
54137
  }
53996
54138
  };
53997
- await import_node_fs24.default.promises.mkdir(args.dataDir, { recursive: true });
53998
- await import_node_fs24.default.promises.writeFile(cfgPath, JSON.stringify(content, null, 2), "utf8");
54139
+ await import_node_fs25.default.promises.mkdir(args.dataDir, { recursive: true });
54140
+ await import_node_fs25.default.promises.writeFile(cfgPath, JSON.stringify(content, null, 2), "utf8");
53999
54141
  return cfgPath;
54000
54142
  }
54001
54143
 
54002
54144
  // src/peer-ops/mcp-config.ts
54003
- var import_node_fs25 = __toESM(require("fs"), 1);
54004
- var import_node_path25 = __toESM(require("path"), 1);
54145
+ var import_node_fs26 = __toESM(require("fs"), 1);
54146
+ var import_node_path26 = __toESM(require("path"), 1);
54005
54147
  function peerOpsMcpConfigPath(dataDir) {
54006
- return import_node_path25.default.join(dataDir, "peer-ops.mcp.json");
54148
+ return import_node_path26.default.join(dataDir, "peer-ops.mcp.json");
54007
54149
  }
54008
54150
  function writePeerOpsMcpConfig(args) {
54009
54151
  const cfgPath = peerOpsMcpConfigPath(args.dataDir);
@@ -54020,16 +54162,16 @@ function writePeerOpsMcpConfig(args) {
54020
54162
  }
54021
54163
  }
54022
54164
  };
54023
- import_node_fs25.default.mkdirSync(args.dataDir, { recursive: true });
54024
- import_node_fs25.default.writeFileSync(cfgPath, JSON.stringify(cfg, null, 2));
54165
+ import_node_fs26.default.mkdirSync(args.dataDir, { recursive: true });
54166
+ import_node_fs26.default.writeFileSync(cfgPath, JSON.stringify(cfg, null, 2));
54025
54167
  return cfgPath;
54026
54168
  }
54027
54169
 
54028
54170
  // src/rpc-tool/mcp-config.ts
54029
- var import_node_fs26 = __toESM(require("fs"), 1);
54030
- var import_node_path26 = __toESM(require("path"), 1);
54171
+ var import_node_fs27 = __toESM(require("fs"), 1);
54172
+ var import_node_path27 = __toESM(require("path"), 1);
54031
54173
  function rpcToolMcpConfigPath(dataDir) {
54032
- return import_node_path26.default.join(dataDir, "rpc-tool.mcp.json");
54174
+ return import_node_path27.default.join(dataDir, "rpc-tool.mcp.json");
54033
54175
  }
54034
54176
  function writeRpcToolMcpConfig(args) {
54035
54177
  const cfgPath = rpcToolMcpConfigPath(args.dataDir);
@@ -54048,29 +54190,29 @@ function writeRpcToolMcpConfig(args) {
54048
54190
  }
54049
54191
  }
54050
54192
  };
54051
- import_node_fs26.default.mkdirSync(args.dataDir, { recursive: true });
54052
- import_node_fs26.default.writeFileSync(cfgPath, JSON.stringify(content, null, 2), "utf8");
54193
+ import_node_fs27.default.mkdirSync(args.dataDir, { recursive: true });
54194
+ import_node_fs27.default.writeFileSync(cfgPath, JSON.stringify(content, null, 2), "utf8");
54053
54195
  return cfgPath;
54054
54196
  }
54055
54197
 
54056
54198
  // src/deploy/secret-table.ts
54057
- var import_node_fs27 = __toESM(require("fs"), 1);
54058
- var import_node_path27 = __toESM(require("path"), 1);
54199
+ var import_node_fs28 = __toESM(require("fs"), 1);
54200
+ var import_node_path28 = __toESM(require("path"), 1);
54059
54201
  var import_node_url4 = require("url");
54060
54202
  var import_meta4 = {};
54061
54203
  var LOCAL_SECRETS_DIRNAME = "secrets";
54062
54204
  function findSecretsBundleRoot(logger) {
54063
54205
  const candidates = [];
54064
54206
  try {
54065
- const here = import_node_path27.default.dirname((0, import_node_url4.fileURLToPath)(import_meta4.url));
54066
- candidates.push(import_node_path27.default.resolve(here, "..", "secrets"));
54207
+ const here = import_node_path28.default.dirname((0, import_node_url4.fileURLToPath)(import_meta4.url));
54208
+ candidates.push(import_node_path28.default.resolve(here, "..", "secrets"));
54067
54209
  } catch {
54068
54210
  }
54069
54211
  const fromArgv = bundleSiblingFromArgv(process.argv[1], "secrets");
54070
54212
  if (fromArgv) candidates.push(fromArgv);
54071
54213
  for (const c of candidates) {
54072
54214
  try {
54073
- if (import_node_fs27.default.statSync(c).isDirectory()) return c;
54215
+ if (import_node_fs28.default.statSync(c).isDirectory()) return c;
54074
54216
  } catch {
54075
54217
  }
54076
54218
  }
@@ -54096,7 +54238,7 @@ function readDir(dir, logger) {
54096
54238
  const out = {};
54097
54239
  let files;
54098
54240
  try {
54099
- files = import_node_fs27.default.readdirSync(dir).filter((f) => f.endsWith(".env")).sort();
54241
+ files = import_node_fs28.default.readdirSync(dir).filter((f) => f.endsWith(".env")).sort();
54100
54242
  } catch (e) {
54101
54243
  const code = e.code;
54102
54244
  if (code !== "ENOENT") logger?.warn("secrets.dir-unreadable", { dir, code: code ?? "unknown" });
@@ -54104,9 +54246,9 @@ function readDir(dir, logger) {
54104
54246
  }
54105
54247
  for (const f of files) {
54106
54248
  try {
54107
- Object.assign(out, parseEnvFile(import_node_fs27.default.readFileSync(import_node_path27.default.join(dir, f), "utf8")));
54249
+ Object.assign(out, parseEnvFile(import_node_fs28.default.readFileSync(import_node_path28.default.join(dir, f), "utf8")));
54108
54250
  } catch (e) {
54109
- logger?.warn("secrets.file-unreadable", { file: import_node_path27.default.join(dir, f), error: e.message });
54251
+ logger?.warn("secrets.file-unreadable", { file: import_node_path28.default.join(dir, f), error: e.message });
54110
54252
  }
54111
54253
  }
54112
54254
  return out;
@@ -54116,7 +54258,7 @@ function collectKitPlaceholders(kitDir) {
54116
54258
  const scan = (file, re) => {
54117
54259
  let text;
54118
54260
  try {
54119
- text = import_node_fs27.default.readFileSync(file, "utf8");
54261
+ text = import_node_fs28.default.readFileSync(file, "utf8");
54120
54262
  } catch {
54121
54263
  return;
54122
54264
  }
@@ -54126,20 +54268,20 @@ function collectKitPlaceholders(kitDir) {
54126
54268
  if (depth > 6) return [];
54127
54269
  let entries;
54128
54270
  try {
54129
- entries = import_node_fs27.default.readdirSync(dir, { withFileTypes: true });
54271
+ entries = import_node_fs28.default.readdirSync(dir, { withFileTypes: true });
54130
54272
  } catch {
54131
54273
  return [];
54132
54274
  }
54133
54275
  return entries.flatMap((e) => {
54134
54276
  if (e.name === "node_modules") return [];
54135
- const p2 = import_node_path27.default.join(dir, e.name);
54277
+ const p2 = import_node_path28.default.join(dir, e.name);
54136
54278
  return e.isDirectory() ? walk2(p2, depth + 1) : [p2];
54137
54279
  });
54138
54280
  };
54139
- for (const f of walk2(import_node_path27.default.join(kitDir, "contract"), 0)) {
54281
+ for (const f of walk2(import_node_path28.default.join(kitDir, "contract"), 0)) {
54140
54282
  if (f.endsWith(".tmpl")) scan(f, /__([A-Z0-9_]+)__/g);
54141
54283
  }
54142
- for (const f of walk2(import_node_path27.default.join(kitDir, "examples"), 0)) {
54284
+ for (const f of walk2(import_node_path28.default.join(kitDir, "examples"), 0)) {
54143
54285
  if (f.endsWith(".env.example")) scan(f, /\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g);
54144
54286
  }
54145
54287
  return out;
@@ -54157,12 +54299,12 @@ function readSecretTable(args) {
54157
54299
  }
54158
54300
 
54159
54301
  // src/dispatch/source-transcript.ts
54160
- var import_node_path28 = __toESM(require("path"), 1);
54302
+ var import_node_path29 = __toESM(require("path"), 1);
54161
54303
  init_claude_history();
54162
54304
  var NO_SOURCE_TRANSCRIPT = "(no transcript yet \u2014 operate from the task description alone)";
54163
54305
  function resolveSourceJsonlPath(sourceFile, home) {
54164
54306
  if (!sourceFile?.toolSessionId) return NO_SOURCE_TRANSCRIPT;
54165
- return import_node_path28.default.join(
54307
+ return import_node_path29.default.join(
54166
54308
  home,
54167
54309
  ".claude",
54168
54310
  "projects",
@@ -54173,7 +54315,7 @@ function resolveSourceJsonlPath(sourceFile, home) {
54173
54315
 
54174
54316
  // src/shift/store.ts
54175
54317
  var import_promises3 = __toESM(require("fs/promises"), 1);
54176
- var import_node_path29 = __toESM(require("path"), 1);
54318
+ var import_node_path30 = __toESM(require("path"), 1);
54177
54319
  var import_node_crypto6 = require("crypto");
54178
54320
 
54179
54321
  // src/shift/schedule.ts
@@ -54248,7 +54390,7 @@ function createShiftStore(deps) {
54248
54390
  flushTimer = null;
54249
54391
  }
54250
54392
  const content = { version: 1, shifts };
54251
- await import_promises3.default.mkdir(import_node_path29.default.dirname(deps.filePath), { recursive: true });
54393
+ await import_promises3.default.mkdir(import_node_path30.default.dirname(deps.filePath), { recursive: true });
54252
54394
  const tmp = `${deps.filePath}.tmp-${deps.now()}-${Math.floor(Math.random() * 1e6)}`;
54253
54395
  await import_promises3.default.writeFile(tmp, JSON.stringify(content, null, 2), "utf8");
54254
54396
  await import_promises3.default.rename(tmp, deps.filePath);
@@ -54696,10 +54838,10 @@ function redactEvidence(evidence) {
54696
54838
 
54697
54839
  // src/deploy/deploy-file.ts
54698
54840
  var import_promises4 = __toESM(require("fs/promises"), 1);
54699
- var import_node_path30 = __toESM(require("path"), 1);
54841
+ var import_node_path31 = __toESM(require("path"), 1);
54700
54842
  init_protocol();
54701
- var DEPLOY_FILE = import_node_path30.default.join(".clawd", "deploy.json");
54702
- var SCAN_FILE = import_node_path30.default.join(".clawd", "deploy-scan.json");
54843
+ var DEPLOY_FILE = import_node_path31.default.join(".clawd", "deploy.json");
54844
+ var SCAN_FILE = import_node_path31.default.join(".clawd", "deploy-scan.json");
54703
54845
  async function readJson(file) {
54704
54846
  let raw;
54705
54847
  try {
@@ -54715,14 +54857,14 @@ async function readJson(file) {
54715
54857
  }
54716
54858
  }
54717
54859
  async function writeJson(file, value) {
54718
- await import_promises4.default.mkdir(import_node_path30.default.dirname(file), { recursive: true });
54860
+ await import_promises4.default.mkdir(import_node_path31.default.dirname(file), { recursive: true });
54719
54861
  const tmp = `${file}.tmp-${process.pid}`;
54720
54862
  await import_promises4.default.writeFile(tmp, `${JSON.stringify(value, null, 2)}
54721
54863
  `);
54722
54864
  await import_promises4.default.rename(tmp, file);
54723
54865
  }
54724
54866
  async function readDeployFile(dir) {
54725
- const raw = await readJson(import_node_path30.default.join(dir, DEPLOY_FILE));
54867
+ const raw = await readJson(import_node_path31.default.join(dir, DEPLOY_FILE));
54726
54868
  if (raw === void 0) return void 0;
54727
54869
  const parsed = DeployFileSchema.safeParse(raw);
54728
54870
  if (!parsed.success) {
@@ -54732,10 +54874,10 @@ async function readDeployFile(dir) {
54732
54874
  return parsed.data;
54733
54875
  }
54734
54876
  async function writeDeployFile(dir, file) {
54735
- await writeJson(import_node_path30.default.join(dir, DEPLOY_FILE), DeployFileSchema.parse(file));
54877
+ await writeJson(import_node_path31.default.join(dir, DEPLOY_FILE), DeployFileSchema.parse(file));
54736
54878
  }
54737
54879
  async function readScan(dir) {
54738
- const raw = await readJson(import_node_path30.default.join(dir, SCAN_FILE));
54880
+ const raw = await readJson(import_node_path31.default.join(dir, SCAN_FILE));
54739
54881
  if (raw === void 0) return void 0;
54740
54882
  const parsed = DeployScanSchema.safeParse(raw);
54741
54883
  if (!parsed.success) {
@@ -54745,7 +54887,7 @@ async function readScan(dir) {
54745
54887
  return parsed.data;
54746
54888
  }
54747
54889
  async function writeScan(dir, scan) {
54748
- await writeJson(import_node_path30.default.join(dir, SCAN_FILE), DeployScanSchema.parse(scan));
54890
+ await writeJson(import_node_path31.default.join(dir, SCAN_FILE), DeployScanSchema.parse(scan));
54749
54891
  }
54750
54892
  function emptyDeployFile() {
54751
54893
  return { version: 1, manifest: { version: 1, clis: [], secrets: [], assets: [] } };
@@ -54775,7 +54917,7 @@ function requiredEnvNames(file) {
54775
54917
  // src/deploy/repo.ts
54776
54918
  var import_node_child_process8 = require("child_process");
54777
54919
  var import_promises5 = __toESM(require("fs/promises"), 1);
54778
- var import_node_path31 = __toESM(require("path"), 1);
54920
+ var import_node_path32 = __toESM(require("path"), 1);
54779
54921
  init_protocol();
54780
54922
 
54781
54923
  // src/deploy/templates.ts
@@ -55069,7 +55211,7 @@ async function samePath(a, b2) {
55069
55211
  try {
55070
55212
  return await import_promises5.default.realpath(x);
55071
55213
  } catch {
55072
- return import_node_path31.default.resolve(x);
55214
+ return import_node_path32.default.resolve(x);
55073
55215
  }
55074
55216
  };
55075
55217
  return await real(a) === await real(b2);
@@ -55095,7 +55237,7 @@ async function identityArgs(exec, dir) {
55095
55237
  return ["-c", "user.name=clawd", "-c", "user.email=clawd@clawos.local"];
55096
55238
  }
55097
55239
  async function writeTemplates(dir) {
55098
- const gi = import_node_path31.default.join(dir, ".gitignore");
55240
+ const gi = import_node_path32.default.join(dir, ".gitignore");
55099
55241
  let existing;
55100
55242
  try {
55101
55243
  existing = await import_promises5.default.readFile(gi, "utf8");
@@ -55103,8 +55245,8 @@ async function writeTemplates(dir) {
55103
55245
  existing = void 0;
55104
55246
  }
55105
55247
  await import_promises5.default.writeFile(gi, mergeGitignore(existing));
55106
- const wf = import_node_path31.default.join(dir, WORKFLOW_PATH);
55107
- await import_promises5.default.mkdir(import_node_path31.default.dirname(wf), { recursive: true });
55248
+ const wf = import_node_path32.default.join(dir, WORKFLOW_PATH);
55249
+ await import_promises5.default.mkdir(import_node_path32.default.dirname(wf), { recursive: true });
55108
55250
  await import_promises5.default.writeFile(wf, WORKFLOW_TEMPLATE);
55109
55251
  }
55110
55252
  async function ensureRepo(exec, args) {
@@ -55208,8 +55350,8 @@ function runStatusOf(status) {
55208
55350
  if (status === "queued" || status === "waiting" || status === "requested" || status === "pending") return "queued";
55209
55351
  return "running";
55210
55352
  }
55211
- async function ghJson(exec, path97) {
55212
- const r = await exec("gh", ["api", path97], { timeoutMs: TIMEOUT_MS });
55353
+ async function ghJson(exec, path98) {
55354
+ const r = await exec("gh", ["api", path98], { timeoutMs: TIMEOUT_MS });
55213
55355
  if (r.spawnError || r.code !== 0) return void 0;
55214
55356
  try {
55215
55357
  return JSON.parse(r.stdout);
@@ -55269,12 +55411,12 @@ async function rerunJob(exec, slug, runId, jobId) {
55269
55411
  }
55270
55412
 
55271
55413
  // src/deploy/scan-task.ts
55272
- var import_node_path32 = __toESM(require("path"), 1);
55414
+ var import_node_path33 = __toESM(require("path"), 1);
55273
55415
  var BUTLER_PERSONA_ID = "persona-clawd-butler";
55274
55416
  var SCANNABLE_ASSETS = [
55275
55417
  {
55276
55418
  name: "deploy-kit",
55277
- path: (dataDir) => import_node_path32.default.join(dataDir, "deploy-kit"),
55419
+ path: (dataDir) => import_node_path33.default.join(dataDir, "deploy-kit"),
55278
55420
  what: "FC \u90E8\u7F72\u80FD\u529B\uFF08publish.sh / new-extension.sh / \u5DE5\u5177\u94FE / \u51ED\u8BC1\u76EE\u5F55\uFF09\u3002persona \u7528\u7EDD\u5BF9\u8DEF\u5F84\u53BB\u8C03\u8FD9\u91CC\u7684\u811A\u672C\u65F6\uFF0C\u5C31\u8BE5\u62A5\u4E00\u6761 asset\u3002"
55279
55421
  },
55280
55422
  {
@@ -55325,6 +55467,9 @@ function ensureOwner(ctx) {
55325
55467
  }
55326
55468
  }
55327
55469
  var invalid = (msg) => new ClawdError(ERROR_CODES.VALIDATION_ERROR, `VALIDATION_ERROR: ${msg}`);
55470
+ function wrongEngine(tool) {
55471
+ return cloudEngineOk(tool) ? void 0 : `\u5F15\u64CE\u662F ${tool || "claude"}\uFF0C\u4E91\u4E0A\u53EA\u8DD1 Codex\u2014\u2014\u53BB persona \u8BBE\u7F6E\u91CC\u628A\u5F15\u64CE\u5207\u6210 Codex\uFF0C\u518D\u9009\u4E2A\u6A21\u578B`;
55472
+ }
55328
55473
  function toClawdError(err) {
55329
55474
  if (err instanceof ClawdError) return err;
55330
55475
  if (err instanceof RepoError) return new ClawdError(ERROR_CODES.INTERNAL, err.message);
@@ -55402,6 +55547,8 @@ function buildDeployHandlers(deps) {
55402
55547
  ensureOwner(ctx);
55403
55548
  const { personaId: personaId2 } = parseArgs2(DeployPersonaArgsSchema, frame, "deploy:start");
55404
55549
  const dir = mustPersona(personaId2);
55550
+ const wrong = wrongEngine(deps.personaEngine(personaId2)?.tool);
55551
+ if (wrong) throw invalid(wrong);
55405
55552
  const current = await readScan(dir);
55406
55553
  if (current?.status === "scanning") return view(personaId2);
55407
55554
  if (!await repoInfo(deps.exec, dir)) {
@@ -55542,9 +55689,9 @@ function buildDeployHandlers(deps) {
55542
55689
  const missing = requiredEnvNames(file).filter((e) => !present.has(e));
55543
55690
  if (missing.length > 0) blockers.push(`${missing.join(" / ")} \u8FD8\u6CA1\u586B`);
55544
55691
  const engine = deps.personaEngine(personaId2);
55545
- const tool = engine?.tool || "claude";
55546
- if (tool !== "codex") {
55547
- blockers.push(`\u5F15\u64CE\u662F ${tool}\uFF0C\u4E91\u4E0A\u53EA\u8DD1 Codex\u2014\u2014\u53BB persona \u8BBE\u7F6E\u91CC\u628A\u5F15\u64CE\u5207\u6210 Codex\uFF0C\u518D\u9009\u4E2A\u6A21\u578B`);
55692
+ const wrongTool = wrongEngine(engine?.tool);
55693
+ if (wrongTool) {
55694
+ blockers.push(wrongTool);
55548
55695
  } else if (!engine?.model) {
55549
55696
  blockers.push("\u8FD8\u6CA1\u9009\u6A21\u578B\uFF08\u5207\u5F15\u64CE\u65F6\u4F1A\u6E05\u7A7A\uFF09\u2014\u2014\u53BB persona \u8BBE\u7F6E\u91CC\u9009\u4E00\u4E2A");
55550
55697
  }
@@ -55978,15 +56125,15 @@ async function refreshTunnelUrlOnStartup(deps) {
55978
56125
  }
55979
56126
 
55980
56127
  // src/lark-bot-connector/binding-store.ts
55981
- var import_node_fs28 = __toESM(require("fs"), 1);
55982
- var import_node_path33 = __toESM(require("path"), 1);
56128
+ var import_node_fs29 = __toESM(require("fs"), 1);
56129
+ var import_node_path34 = __toESM(require("path"), 1);
55983
56130
  function createLarkBotBindingStore(personaRoot) {
55984
- const filePath = (personaId2) => import_node_path33.default.join(personaRoot, safeFileName(personaId2), ".clawd", "lark-bot.json");
56131
+ const filePath = (personaId2) => import_node_path34.default.join(personaRoot, safeFileName(personaId2), ".clawd", "lark-bot.json");
55985
56132
  const read = (personaId2) => {
55986
56133
  const file = filePath(personaId2);
55987
- if (!import_node_fs28.default.existsSync(file)) return null;
56134
+ if (!import_node_fs29.default.existsSync(file)) return null;
55988
56135
  try {
55989
- const raw = JSON.parse(import_node_fs28.default.readFileSync(file, "utf8"));
56136
+ const raw = JSON.parse(import_node_fs29.default.readFileSync(file, "utf8"));
55990
56137
  if (typeof raw?.appId !== "string" || raw.appId.length === 0) return null;
55991
56138
  return raw;
55992
56139
  } catch {
@@ -55995,16 +56142,16 @@ function createLarkBotBindingStore(personaRoot) {
55995
56142
  };
55996
56143
  const write = (personaId2, meta) => {
55997
56144
  const file = filePath(personaId2);
55998
- import_node_fs28.default.mkdirSync(import_node_path33.default.dirname(file), { recursive: true });
56145
+ import_node_fs29.default.mkdirSync(import_node_path34.default.dirname(file), { recursive: true });
55999
56146
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
56000
- import_node_fs28.default.writeFileSync(tmp, JSON.stringify(meta, null, 2), { mode: 384 });
56001
- import_node_fs28.default.renameSync(tmp, file);
56147
+ import_node_fs29.default.writeFileSync(tmp, JSON.stringify(meta, null, 2), { mode: 384 });
56148
+ import_node_fs29.default.renameSync(tmp, file);
56002
56149
  };
56003
56150
  return {
56004
56151
  read,
56005
56152
  write,
56006
56153
  remove(personaId2) {
56007
- import_node_fs28.default.rmSync(filePath(personaId2), { force: true });
56154
+ import_node_fs29.default.rmSync(filePath(personaId2), { force: true });
56008
56155
  },
56009
56156
  addRemovedChat(personaId2, chatId) {
56010
56157
  const meta = read(personaId2);
@@ -56162,8 +56309,8 @@ function createLarkBotCloudClient(opts) {
56162
56309
  }
56163
56310
 
56164
56311
  // src/lark-bot-connector/chat-router.ts
56165
- var import_node_fs29 = __toESM(require("fs"), 1);
56166
- var import_node_path34 = __toESM(require("path"), 1);
56312
+ var import_node_fs30 = __toESM(require("fs"), 1);
56313
+ var import_node_path35 = __toESM(require("path"), 1);
56167
56314
  init_protocol();
56168
56315
  var ERROR_REPLY_TEXT = "\u5904\u7406\u51FA\u9519\u4E86\uFF0C\u8BF7\u91CD\u8BD5";
56169
56316
  var LOCAL_TURN_RETRIES = 2;
@@ -56229,9 +56376,9 @@ function createLarkChatRouter(deps) {
56229
56376
  continue;
56230
56377
  }
56231
56378
  const dir = deps.mediaRootFor(env.chatId);
56232
- import_node_fs29.default.mkdirSync(dir, { recursive: true });
56233
- const p2 = import_node_path34.default.join(dir, `${safeMediaName(ownerMessageId)}-${i}.${ext}`);
56234
- import_node_fs29.default.writeFileSync(p2, r.data);
56379
+ import_node_fs30.default.mkdirSync(dir, { recursive: true });
56380
+ const p2 = import_node_path35.default.join(dir, `${safeMediaName(ownerMessageId)}-${i}.${ext}`);
56381
+ import_node_fs30.default.writeFileSync(p2, r.data);
56235
56382
  lines.push(`[\u56FE\u7247: ${p2}]\uFF08\u7528 Read \u5DE5\u5177\u67E5\u770B\uFF09`);
56236
56383
  } catch (err) {
56237
56384
  deps.logger?.warn(`larkBot image fetch failed ${key}: ${err.message}`);
@@ -56252,9 +56399,9 @@ function createLarkChatRouter(deps) {
56252
56399
  continue;
56253
56400
  }
56254
56401
  const dir = deps.mediaRootFor(env.chatId);
56255
- import_node_fs29.default.mkdirSync(dir, { recursive: true });
56256
- const p2 = import_node_path34.default.join(dir, `${safeMediaName(ownerMessageId)}-${i}-${safeAttachmentName(f.name)}`);
56257
- import_node_fs29.default.writeFileSync(p2, r.data);
56402
+ import_node_fs30.default.mkdirSync(dir, { recursive: true });
56403
+ const p2 = import_node_path35.default.join(dir, `${safeMediaName(ownerMessageId)}-${i}-${safeAttachmentName(f.name)}`);
56404
+ import_node_fs30.default.writeFileSync(p2, r.data);
56258
56405
  lines.push(`[\u6587\u4EF6: ${p2}]\uFF08\u7528 Read \u5DE5\u5177\u67E5\u770B\uFF09`);
56259
56406
  } catch (err) {
56260
56407
  deps.logger?.warn(`larkBot file fetch failed ${f.key}: ${err.message}`);
@@ -57343,7 +57490,7 @@ var CodexHistoryReader = class {
57343
57490
  };
57344
57491
 
57345
57492
  // src/tools/codex-skills.ts
57346
- var import_node_path35 = __toESM(require("path"), 1);
57493
+ var import_node_path36 = __toESM(require("path"), 1);
57347
57494
  function str3(v2) {
57348
57495
  return typeof v2 === "string" ? v2 : void 0;
57349
57496
  }
@@ -57358,13 +57505,13 @@ function mapSkillsListResponse(res) {
57358
57505
  const r = s ?? {};
57359
57506
  const name = str3(r.name);
57360
57507
  if (!name) continue;
57361
- const path97 = str3(r.path);
57508
+ const path98 = str3(r.path);
57362
57509
  const description = str3(r.description);
57363
57510
  const isPlugin = name.includes(":");
57364
57511
  out.push({
57365
57512
  name,
57366
57513
  source: isPlugin ? "plugin" : "project",
57367
- ...path97 ? { path: path97 } : {},
57514
+ ...path98 ? { path: path98 } : {},
57368
57515
  ...description ? { description } : {},
57369
57516
  ...isPlugin ? { plugin: name.split(":")[0] } : {}
57370
57517
  });
@@ -57380,7 +57527,7 @@ async function listCodexSkills(cwd, deps = {}) {
57380
57527
  // 先写 extraRoots 再写 list(stdio 按写入顺序处理,fire-and-forget 不 await 回包;
57381
57528
  // codex-session.ts ready 序列同款,两处保持一致)。失败不阻塞 list。
57382
57529
  beforeRequest: (client) => {
57383
- void client.request("skills/extraRoots/set", { extraRoots: [import_node_path35.default.join(cwd, ".claude", "skills")] }).catch(() => void 0);
57530
+ void client.request("skills/extraRoots/set", { extraRoots: [import_node_path36.default.join(cwd, ".claude", "skills")] }).catch(() => void 0);
57384
57531
  }
57385
57532
  });
57386
57533
  return mapSkillsListResponse(res);
@@ -57465,23 +57612,23 @@ function str4(v2) {
57465
57612
  }
57466
57613
 
57467
57614
  // src/workspace/browser.ts
57468
- var import_node_fs30 = __toESM(require("fs"), 1);
57469
- var import_node_os8 = __toESM(require("os"), 1);
57470
- var import_node_path36 = __toESM(require("path"), 1);
57615
+ var import_node_fs31 = __toESM(require("fs"), 1);
57616
+ var import_node_os9 = __toESM(require("os"), 1);
57617
+ var import_node_path37 = __toESM(require("path"), 1);
57471
57618
  init_protocol();
57472
57619
  var MAX_FILE_BYTES2 = 2 * 1024 * 1024;
57473
57620
  function resolveInsideCwd(cwd, subpath) {
57474
- const absCwd = import_node_path36.default.resolve(cwd);
57475
- const joined = import_node_path36.default.resolve(absCwd, subpath ?? ".");
57476
- const rel = import_node_path36.default.relative(absCwd, joined);
57477
- if (rel.startsWith("..") || import_node_path36.default.isAbsolute(rel)) {
57621
+ const absCwd = import_node_path37.default.resolve(cwd);
57622
+ const joined = import_node_path37.default.resolve(absCwd, subpath ?? ".");
57623
+ const rel = import_node_path37.default.relative(absCwd, joined);
57624
+ if (rel.startsWith("..") || import_node_path37.default.isAbsolute(rel)) {
57478
57625
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
57479
57626
  }
57480
57627
  return joined;
57481
57628
  }
57482
57629
  function ensureCwd(cwd) {
57483
57630
  try {
57484
- const stat = import_node_fs30.default.statSync(cwd);
57631
+ const stat = import_node_fs31.default.statSync(cwd);
57485
57632
  if (!stat.isDirectory()) {
57486
57633
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${cwd}`);
57487
57634
  }
@@ -57492,10 +57639,10 @@ function ensureCwd(cwd) {
57492
57639
  }
57493
57640
  var WorkspaceBrowser = class {
57494
57641
  list(args) {
57495
- const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os8.default.homedir();
57642
+ const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os9.default.homedir();
57496
57643
  ensureCwd(cwd);
57497
57644
  const full = resolveInsideCwd(cwd, args.path);
57498
- const dirents = import_node_fs30.default.readdirSync(full, { withFileTypes: true });
57645
+ const dirents = import_node_fs31.default.readdirSync(full, { withFileTypes: true });
57499
57646
  const entries = [];
57500
57647
  for (const d of dirents) {
57501
57648
  if (!args.showHidden && d.name.startsWith(".")) continue;
@@ -57505,7 +57652,7 @@ var WorkspaceBrowser = class {
57505
57652
  mtime: ""
57506
57653
  };
57507
57654
  try {
57508
- const st = import_node_fs30.default.statSync(import_node_path36.default.join(full, d.name));
57655
+ const st = import_node_fs31.default.statSync(import_node_path37.default.join(full, d.name));
57509
57656
  entry.mtime = new Date(st.mtimeMs).toISOString();
57510
57657
  if (d.isFile()) entry.size = st.size;
57511
57658
  } catch {
@@ -57521,14 +57668,14 @@ var WorkspaceBrowser = class {
57521
57668
  read(args) {
57522
57669
  ensureCwd(args.cwd);
57523
57670
  const full = resolveInsideCwd(args.cwd, args.path);
57524
- const st = import_node_fs30.default.statSync(full);
57671
+ const st = import_node_fs31.default.statSync(full);
57525
57672
  if (!st.isFile()) {
57526
57673
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `not a file: ${args.path}`);
57527
57674
  }
57528
57675
  if (st.size > MAX_FILE_BYTES2) {
57529
57676
  throw new ClawdError(ERROR_CODES.FILE_TOO_LARGE, `file > ${MAX_FILE_BYTES2} bytes`);
57530
57677
  }
57531
- const buf = import_node_fs30.default.readFileSync(full);
57678
+ const buf = import_node_fs31.default.readFileSync(full);
57532
57679
  const isBinary = buf.includes(0);
57533
57680
  if (isBinary) {
57534
57681
  return {
@@ -57550,20 +57697,20 @@ var WorkspaceBrowser = class {
57550
57697
  };
57551
57698
 
57552
57699
  // src/skills/agents-scanner.ts
57553
- var import_node_fs31 = __toESM(require("fs"), 1);
57554
- var import_node_os9 = __toESM(require("os"), 1);
57555
- var import_node_path37 = __toESM(require("path"), 1);
57700
+ var import_node_fs32 = __toESM(require("fs"), 1);
57701
+ var import_node_os10 = __toESM(require("os"), 1);
57702
+ var import_node_path38 = __toESM(require("path"), 1);
57556
57703
  var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
57557
57704
  function isDirLikeSync2(p2) {
57558
57705
  try {
57559
- return import_node_fs31.default.statSync(p2).isDirectory();
57706
+ return import_node_fs32.default.statSync(p2).isDirectory();
57560
57707
  } catch {
57561
57708
  return false;
57562
57709
  }
57563
57710
  }
57564
57711
  function fileExistsSync(p2) {
57565
57712
  try {
57566
- return import_node_fs31.default.statSync(p2).isFile();
57713
+ return import_node_fs32.default.statSync(p2).isFile();
57567
57714
  } catch {
57568
57715
  return false;
57569
57716
  }
@@ -57571,7 +57718,7 @@ function fileExistsSync(p2) {
57571
57718
  function parseAgentFile(filePath) {
57572
57719
  let content;
57573
57720
  try {
57574
- content = import_node_fs31.default.readFileSync(filePath, "utf8");
57721
+ content = import_node_fs32.default.readFileSync(filePath, "utf8");
57575
57722
  } catch {
57576
57723
  return {};
57577
57724
  }
@@ -57584,16 +57731,16 @@ function parseAgentFile(filePath) {
57584
57731
  function scanAgentsDir(dir, source, seen, out) {
57585
57732
  let entries;
57586
57733
  try {
57587
- entries = import_node_fs31.default.readdirSync(dir, { withFileTypes: true });
57734
+ entries = import_node_fs32.default.readdirSync(dir, { withFileTypes: true });
57588
57735
  } catch {
57589
57736
  return;
57590
57737
  }
57591
57738
  for (const ent of entries) {
57592
57739
  if (!ent.name.endsWith(".md")) continue;
57593
- if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path37.default.join(dir, ent.name)))) {
57740
+ if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path38.default.join(dir, ent.name)))) {
57594
57741
  continue;
57595
57742
  }
57596
- const filePath = import_node_path37.default.join(dir, ent.name);
57743
+ const filePath = import_node_path38.default.join(dir, ent.name);
57597
57744
  const baseName = ent.name.replace(/\.md$/, "");
57598
57745
  if (seen.has(baseName)) continue;
57599
57746
  seen.add(baseName);
@@ -57611,12 +57758,12 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
57611
57758
  function walk2(dir, namespaces) {
57612
57759
  let entries;
57613
57760
  try {
57614
- entries = import_node_fs31.default.readdirSync(dir, { withFileTypes: true });
57761
+ entries = import_node_fs32.default.readdirSync(dir, { withFileTypes: true });
57615
57762
  } catch {
57616
57763
  return;
57617
57764
  }
57618
57765
  for (const ent of entries) {
57619
- const childPath = import_node_path37.default.join(dir, ent.name);
57766
+ const childPath = import_node_path38.default.join(dir, ent.name);
57620
57767
  if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
57621
57768
  walk2(childPath, [...namespaces, ent.name]);
57622
57769
  continue;
@@ -57641,13 +57788,13 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
57641
57788
  walk2(root, []);
57642
57789
  }
57643
57790
  function readInstalledPlugins2(home) {
57644
- const pluginsDir = import_node_path37.default.join(home, ".claude", "plugins");
57645
- const v2 = import_node_path37.default.join(pluginsDir, "installed_plugins_v2.json");
57646
- const v1 = import_node_path37.default.join(pluginsDir, "installed_plugins.json");
57791
+ const pluginsDir = import_node_path38.default.join(home, ".claude", "plugins");
57792
+ const v2 = import_node_path38.default.join(pluginsDir, "installed_plugins_v2.json");
57793
+ const v1 = import_node_path38.default.join(pluginsDir, "installed_plugins.json");
57647
57794
  let raw = null;
57648
57795
  for (const candidate of [v2, v1]) {
57649
57796
  try {
57650
- raw = import_node_fs31.default.readFileSync(candidate, "utf8");
57797
+ raw = import_node_fs32.default.readFileSync(candidate, "utf8");
57651
57798
  break;
57652
57799
  } catch {
57653
57800
  }
@@ -57672,19 +57819,19 @@ function readInstalledPlugins2(home) {
57672
57819
  return out;
57673
57820
  }
57674
57821
  function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
57675
- let cur = import_node_path37.default.resolve(startCwd);
57676
- const fsRoot = import_node_path37.default.parse(cur).root;
57822
+ let cur = import_node_path38.default.resolve(startCwd);
57823
+ const fsRoot = import_node_path38.default.parse(cur).root;
57677
57824
  while (true) {
57678
- scanAgentsDir(import_node_path37.default.join(cur, ".claude", "agents"), "project", seen, out);
57825
+ scanAgentsDir(import_node_path38.default.join(cur, ".claude", "agents"), "project", seen, out);
57679
57826
  let hasGit = false;
57680
57827
  try {
57681
- hasGit = import_node_fs31.default.existsSync(import_node_path37.default.join(cur, ".git"));
57828
+ hasGit = import_node_fs32.default.existsSync(import_node_path38.default.join(cur, ".git"));
57682
57829
  } catch {
57683
57830
  }
57684
57831
  if (hasGit) return;
57685
57832
  if (cur === home) return;
57686
57833
  if (cur === fsRoot) return;
57687
- const parent = import_node_path37.default.dirname(cur);
57834
+ const parent = import_node_path38.default.dirname(cur);
57688
57835
  if (parent === cur) return;
57689
57836
  cur = parent;
57690
57837
  }
@@ -57694,7 +57841,7 @@ var AgentsScanner = class {
57694
57841
  extraPluginRoots;
57695
57842
  policyDir;
57696
57843
  constructor(opts = {}) {
57697
- this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os9.default.homedir();
57844
+ this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os10.default.homedir();
57698
57845
  this.extraPluginRoots = opts.extraPluginRoots ?? [];
57699
57846
  if (opts.policyDir !== void 0) {
57700
57847
  this.policyDir = opts.policyDir;
@@ -57719,7 +57866,7 @@ var AgentsScanner = class {
57719
57866
  }
57720
57867
  const fsBlock = [];
57721
57868
  scanAgentsDir(
57722
- import_node_path37.default.join(this.home, ".claude", "agents"),
57869
+ import_node_path38.default.join(this.home, ".claude", "agents"),
57723
57870
  "global",
57724
57871
  seen,
57725
57872
  fsBlock
@@ -57733,7 +57880,7 @@ var AgentsScanner = class {
57733
57880
  ...this.extraPluginRoots
57734
57881
  ];
57735
57882
  for (const { name, root } of plugins) {
57736
- const agentsRoot = import_node_path37.default.join(root, "agents");
57883
+ const agentsRoot = import_node_path38.default.join(root, "agents");
57737
57884
  scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
57738
57885
  }
57739
57886
  return [...builtinBlock, ...fsBlock];
@@ -57741,28 +57888,28 @@ var AgentsScanner = class {
57741
57888
  };
57742
57889
 
57743
57890
  // src/observer/session-observer.ts
57744
- var import_node_fs33 = __toESM(require("fs"), 1);
57745
- var import_node_os11 = __toESM(require("os"), 1);
57746
- var import_node_path39 = __toESM(require("path"), 1);
57891
+ var import_node_fs34 = __toESM(require("fs"), 1);
57892
+ var import_node_os12 = __toESM(require("os"), 1);
57893
+ var import_node_path40 = __toESM(require("path"), 1);
57747
57894
  init_claude_history();
57748
57895
 
57749
57896
  // src/observer/subagent-meta-observer.ts
57750
- var import_node_fs32 = __toESM(require("fs"), 1);
57751
- var import_node_os10 = __toESM(require("os"), 1);
57752
- var import_node_path38 = __toESM(require("path"), 1);
57897
+ var import_node_fs33 = __toESM(require("fs"), 1);
57898
+ var import_node_os11 = __toESM(require("os"), 1);
57899
+ var import_node_path39 = __toESM(require("path"), 1);
57753
57900
  init_claude_history();
57754
57901
  var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
57755
57902
  var SubagentMetaObserver = class {
57756
57903
  constructor(opts) {
57757
57904
  this.opts = opts;
57758
- this.home = opts.home ?? import_node_os10.default.homedir();
57905
+ this.home = opts.home ?? import_node_os11.default.homedir();
57759
57906
  }
57760
57907
  opts;
57761
57908
  home;
57762
57909
  watches = /* @__PURE__ */ new Map();
57763
57910
  // public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
57764
57911
  resolveSubagentDir(cwd, toolSessionId) {
57765
- return import_node_path38.default.join(
57912
+ return import_node_path39.default.join(
57766
57913
  this.home,
57767
57914
  ".claude",
57768
57915
  "projects",
@@ -57792,7 +57939,7 @@ var SubagentMetaObserver = class {
57792
57939
  attachWatcher(w2) {
57793
57940
  if (w2.watcher) return;
57794
57941
  try {
57795
- w2.watcher = import_node_fs32.default.watch(w2.dirPath, { persistent: false }, (_evt, name) => {
57942
+ w2.watcher = import_node_fs33.default.watch(w2.dirPath, { persistent: false }, (_evt, name) => {
57796
57943
  if (!name) return;
57797
57944
  const m2 = META_RE.exec(String(name));
57798
57945
  if (!m2) return;
@@ -57804,7 +57951,7 @@ var SubagentMetaObserver = class {
57804
57951
  scan(w2) {
57805
57952
  let entries;
57806
57953
  try {
57807
- entries = import_node_fs32.default.readdirSync(w2.dirPath);
57954
+ entries = import_node_fs33.default.readdirSync(w2.dirPath);
57808
57955
  } catch {
57809
57956
  return;
57810
57957
  }
@@ -57818,10 +57965,10 @@ var SubagentMetaObserver = class {
57818
57965
  if (!m2) return;
57819
57966
  const agentId = m2[1];
57820
57967
  if (w2.emitted.has(agentId)) return;
57821
- const file = import_node_path38.default.join(w2.dirPath, name);
57968
+ const file = import_node_path39.default.join(w2.dirPath, name);
57822
57969
  let raw;
57823
57970
  try {
57824
- raw = import_node_fs32.default.readFileSync(file, "utf8");
57971
+ raw = import_node_fs33.default.readFileSync(file, "utf8");
57825
57972
  } catch {
57826
57973
  return;
57827
57974
  }
@@ -57866,7 +58013,7 @@ var SubagentMetaObserver = class {
57866
58013
  var SessionObserver = class {
57867
58014
  constructor(opts) {
57868
58015
  this.opts = opts;
57869
- this.home = opts.home ?? import_node_os11.default.homedir();
58016
+ this.home = opts.home ?? import_node_os12.default.homedir();
57870
58017
  this.metaObserver = opts.enableSubagentMetaObserver ? new SubagentMetaObserver({ home: this.home, onEvent: opts.onEvent }) : null;
57871
58018
  }
57872
58019
  opts;
@@ -57878,14 +58025,14 @@ var SessionObserver = class {
57878
58025
  metaObserver;
57879
58026
  resolveJsonlPath(cwd, toolSessionId, override) {
57880
58027
  if (override) return override;
57881
- return import_node_path39.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
58028
+ return import_node_path40.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
57882
58029
  }
57883
58030
  start(args) {
57884
58031
  this.stop(args.sessionId);
57885
58032
  const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
57886
58033
  let size = 0;
57887
58034
  try {
57888
- size = import_node_fs33.default.statSync(filePath).size;
58035
+ size = import_node_fs34.default.statSync(filePath).size;
57889
58036
  } catch {
57890
58037
  }
57891
58038
  const w2 = {
@@ -57898,16 +58045,16 @@ var SessionObserver = class {
57898
58045
  adapter: args.adapter,
57899
58046
  prevIsRejectSentinel: false,
57900
58047
  toolSessionId: args.toolSessionId,
57901
- sawFile: import_node_fs33.default.existsSync(filePath),
58048
+ sawFile: import_node_fs34.default.existsSync(filePath),
57902
58049
  lastRelocateScanMs: 0,
57903
58050
  pendingCwdDerive: false,
57904
58051
  lastDeriveMs: 0
57905
58052
  };
57906
58053
  try {
57907
- import_node_fs33.default.mkdirSync(import_node_path39.default.dirname(filePath), { recursive: true });
58054
+ import_node_fs34.default.mkdirSync(import_node_path40.default.dirname(filePath), { recursive: true });
57908
58055
  } catch {
57909
58056
  }
57910
- w2.watcher = import_node_fs33.default.watch(import_node_path39.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
58057
+ w2.watcher = import_node_fs34.default.watch(import_node_path40.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
57911
58058
  if (!changedName || !w2.filePath.endsWith(changedName)) return;
57912
58059
  this.poll(w2);
57913
58060
  });
@@ -57930,7 +58077,7 @@ var SessionObserver = class {
57930
58077
  // 异常静默吞,不阻塞 watcher 启动
57931
58078
  hydrateMetaTail(w2, maxLines = 200) {
57932
58079
  try {
57933
- const raw = import_node_fs33.default.readFileSync(w2.filePath, "utf8");
58080
+ const raw = import_node_fs34.default.readFileSync(w2.filePath, "utf8");
57934
58081
  if (!raw) return;
57935
58082
  const allLines = raw.split("\n").filter((l) => l.trim().length > 0);
57936
58083
  if (allLines.length === 0) return;
@@ -57954,7 +58101,7 @@ var SessionObserver = class {
57954
58101
  poll(w2) {
57955
58102
  let size = 0;
57956
58103
  try {
57957
- size = import_node_fs33.default.statSync(w2.filePath).size;
58104
+ size = import_node_fs34.default.statSync(w2.filePath).size;
57958
58105
  } catch {
57959
58106
  if (w2.sawFile) this.maybeRelocate(w2);
57960
58107
  return;
@@ -57965,11 +58112,11 @@ var SessionObserver = class {
57965
58112
  w2.buf = "";
57966
58113
  }
57967
58114
  if (size === w2.lastSize) return;
57968
- const fd = import_node_fs33.default.openSync(w2.filePath, "r");
58115
+ const fd = import_node_fs34.default.openSync(w2.filePath, "r");
57969
58116
  try {
57970
58117
  const len = size - w2.lastSize;
57971
58118
  const buf = Buffer.alloc(len);
57972
- import_node_fs33.default.readSync(fd, buf, 0, len, w2.lastSize);
58119
+ import_node_fs34.default.readSync(fd, buf, 0, len, w2.lastSize);
57973
58120
  w2.lastSize = size;
57974
58121
  w2.buf += buf.toString("utf8");
57975
58122
  let newlineIndex;
@@ -57992,7 +58139,7 @@ var SessionObserver = class {
57992
58139
  }
57993
58140
  }
57994
58141
  } finally {
57995
- import_node_fs33.default.closeSync(fd);
58142
+ import_node_fs34.default.closeSync(fd);
57996
58143
  }
57997
58144
  if (w2.pendingCwdDerive) this.maybeDeriveCwd(w2);
57998
58145
  }
@@ -58004,7 +58151,7 @@ var SessionObserver = class {
58004
58151
  const now = Date.now();
58005
58152
  if (now - w2.lastRelocateScanMs < 1e3) return;
58006
58153
  w2.lastRelocateScanMs = now;
58007
- const projectsRoot = import_node_path39.default.join(this.home, ".claude", "projects");
58154
+ const projectsRoot = import_node_path40.default.join(this.home, ".claude", "projects");
58008
58155
  const found = findTranscriptByToolSessionId(projectsRoot, w2.toolSessionId);
58009
58156
  if (!found || found === w2.filePath) return;
58010
58157
  try {
@@ -58013,7 +58160,7 @@ var SessionObserver = class {
58013
58160
  }
58014
58161
  w2.filePath = found;
58015
58162
  try {
58016
- w2.watcher = import_node_fs33.default.watch(import_node_path39.default.dirname(found), { persistent: false }, (_event, changedName) => {
58163
+ w2.watcher = import_node_fs34.default.watch(import_node_path40.default.dirname(found), { persistent: false }, (_event, changedName) => {
58017
58164
  if (!changedName || !w2.filePath.endsWith(changedName)) return;
58018
58165
  this.poll(w2);
58019
58166
  });
@@ -58134,9 +58281,9 @@ function listRegistered() {
58134
58281
 
58135
58282
  // src/tools/title-generator.ts
58136
58283
  var import_node_child_process9 = require("child_process");
58137
- var import_node_fs34 = __toESM(require("fs"), 1);
58138
- var import_node_os12 = __toESM(require("os"), 1);
58139
- var import_node_path40 = __toESM(require("path"), 1);
58284
+ var import_node_fs35 = __toESM(require("fs"), 1);
58285
+ var import_node_os13 = __toESM(require("os"), 1);
58286
+ var import_node_path41 = __toESM(require("path"), 1);
58140
58287
  var TITLE_GEN_DIR_PREFIX = "clawd-title-";
58141
58288
  var TITLE_MODEL_BY_TOOL = {
58142
58289
  claude: "haiku",
@@ -58207,21 +58354,21 @@ async function generateSessionTitle(tool, firstMessage, deps = {}) {
58207
58354
  if (!text) return null;
58208
58355
  let workDir;
58209
58356
  try {
58210
- workDir = import_node_fs34.default.mkdtempSync(import_node_path40.default.join(import_node_os12.default.tmpdir(), TITLE_GEN_DIR_PREFIX));
58357
+ workDir = import_node_fs35.default.mkdtempSync(import_node_path41.default.join(import_node_os13.default.tmpdir(), TITLE_GEN_DIR_PREFIX));
58211
58358
  } catch {
58212
58359
  return null;
58213
58360
  }
58214
58361
  const cleanupWorkDir = () => {
58215
58362
  try {
58216
- import_node_fs34.default.rmSync(workDir, { recursive: true, force: true });
58363
+ import_node_fs35.default.rmSync(workDir, { recursive: true, force: true });
58217
58364
  } catch {
58218
58365
  }
58219
58366
  };
58220
- const outFile = import_node_path40.default.join(workDir, `codex-title-${process.pid}-${++outFileSeq}-${Date.now()}.txt`);
58221
- const schemaFile = import_node_path40.default.join(workDir, "title-schema.json");
58367
+ const outFile = import_node_path41.default.join(workDir, `codex-title-${process.pid}-${++outFileSeq}-${Date.now()}.txt`);
58368
+ const schemaFile = import_node_path41.default.join(workDir, "title-schema.json");
58222
58369
  if (tool === "codex") {
58223
58370
  try {
58224
- import_node_fs34.default.writeFileSync(schemaFile, CODEX_TITLE_SCHEMA);
58371
+ import_node_fs35.default.writeFileSync(schemaFile, CODEX_TITLE_SCHEMA);
58225
58372
  } catch {
58226
58373
  cleanupWorkDir();
58227
58374
  return null;
@@ -58271,7 +58418,7 @@ async function generateSessionTitle(tool, firstMessage, deps = {}) {
58271
58418
  if (tool === "claude") return finish(parseTitleJson(stdout));
58272
58419
  let fileText = "";
58273
58420
  try {
58274
- fileText = import_node_fs34.default.readFileSync(outFile, "utf8");
58421
+ fileText = import_node_fs35.default.readFileSync(outFile, "utf8");
58275
58422
  } catch {
58276
58423
  return finish(null);
58277
58424
  }
@@ -58981,8 +59128,8 @@ async function authenticate(token, deps) {
58981
59128
  }
58982
59129
 
58983
59130
  // src/legacy-cleanup.ts
58984
- var fs45 = __toESM(require("fs/promises"), 1);
58985
- var path48 = __toESM(require("path"), 1);
59131
+ var fs46 = __toESM(require("fs/promises"), 1);
59132
+ var path49 = __toESM(require("path"), 1);
58986
59133
  var LEGACY_FILES = [
58987
59134
  "personal-capability.json",
58988
59135
  "received-capabilities.json",
@@ -58991,9 +59138,9 @@ var LEGACY_FILES = [
58991
59138
  async function cleanupLegacyCapabilityFiles(dataDir, logger) {
58992
59139
  const removed = [];
58993
59140
  for (const name of LEGACY_FILES) {
58994
- const p2 = path48.join(dataDir, name);
59141
+ const p2 = path49.join(dataDir, name);
58995
59142
  try {
58996
- await fs45.unlink(p2);
59143
+ await fs46.unlink(p2);
58997
59144
  removed.push(name);
58998
59145
  logger.debug("legacy capability file removed", { file: name });
58999
59146
  } catch (err) {
@@ -59005,13 +59152,13 @@ async function cleanupLegacyCapabilityFiles(dataDir, logger) {
59005
59152
  }
59006
59153
 
59007
59154
  // src/inbox/inbox-store.ts
59008
- var fs46 = __toESM(require("fs"), 1);
59009
- var path49 = __toESM(require("path"), 1);
59155
+ var fs47 = __toESM(require("fs"), 1);
59156
+ var path50 = __toESM(require("path"), 1);
59010
59157
  var INBOX_SUBDIR = "inbox";
59011
59158
  var InboxStore = class {
59012
59159
  constructor(dataDir) {
59013
59160
  this.dataDir = dataDir;
59014
- fs46.mkdirSync(this.dirPath(), { recursive: true });
59161
+ fs47.mkdirSync(this.dirPath(), { recursive: true });
59015
59162
  }
59016
59163
  dataDir;
59017
59164
  /**
@@ -59023,7 +59170,7 @@ var InboxStore = class {
59023
59170
  const file = this.filePath(peerDeviceId);
59024
59171
  let raw;
59025
59172
  try {
59026
- raw = fs46.readFileSync(file, "utf8");
59173
+ raw = fs47.readFileSync(file, "utf8");
59027
59174
  } catch (err) {
59028
59175
  if (err?.code === "ENOENT") return [];
59029
59176
  return [];
@@ -59039,7 +59186,7 @@ var InboxStore = class {
59039
59186
  const dir = this.dirPath();
59040
59187
  let entries;
59041
59188
  try {
59042
- entries = fs46.readdirSync(dir);
59189
+ entries = fs47.readdirSync(dir);
59043
59190
  } catch (err) {
59044
59191
  if (err?.code === "ENOENT") return [];
59045
59192
  return [];
@@ -59055,9 +59202,9 @@ var InboxStore = class {
59055
59202
  if (existing.some((m2) => m2.id === message.id)) return;
59056
59203
  const file = this.filePath(message.peerDeviceId);
59057
59204
  const line = JSON.stringify(message) + "\n";
59058
- fs46.appendFileSync(file, line, { mode: 384 });
59205
+ fs47.appendFileSync(file, line, { mode: 384 });
59059
59206
  try {
59060
- fs46.chmodSync(file, 384);
59207
+ fs47.chmodSync(file, 384);
59061
59208
  } catch {
59062
59209
  }
59063
59210
  }
@@ -59087,7 +59234,7 @@ var InboxStore = class {
59087
59234
  removeByPeerDeviceId(peerDeviceId) {
59088
59235
  const file = this.filePath(peerDeviceId);
59089
59236
  try {
59090
- fs46.unlinkSync(file);
59237
+ fs47.unlinkSync(file);
59091
59238
  } catch (err) {
59092
59239
  if (err?.code === "ENOENT") return;
59093
59240
  }
@@ -59096,18 +59243,18 @@ var InboxStore = class {
59096
59243
  const file = this.filePath(peerDeviceId);
59097
59244
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
59098
59245
  const content = messages.map((m2) => JSON.stringify(m2)).join("\n") + (messages.length > 0 ? "\n" : "");
59099
- fs46.writeFileSync(tmp, content, { mode: 384 });
59100
- fs46.renameSync(tmp, file);
59246
+ fs47.writeFileSync(tmp, content, { mode: 384 });
59247
+ fs47.renameSync(tmp, file);
59101
59248
  try {
59102
- fs46.chmodSync(file, 384);
59249
+ fs47.chmodSync(file, 384);
59103
59250
  } catch {
59104
59251
  }
59105
59252
  }
59106
59253
  dirPath() {
59107
- return path49.join(this.dataDir, INBOX_SUBDIR);
59254
+ return path50.join(this.dataDir, INBOX_SUBDIR);
59108
59255
  }
59109
59256
  filePath(peerDeviceId) {
59110
- return path49.join(this.dirPath(), `${peerDeviceId}.jsonl`);
59257
+ return path50.join(this.dirPath(), `${peerDeviceId}.jsonl`);
59111
59258
  }
59112
59259
  };
59113
59260
  function parseAllLines(raw) {
@@ -59195,8 +59342,8 @@ var InboxManager = class {
59195
59342
  };
59196
59343
 
59197
59344
  // src/state/contact-store.ts
59198
- var fs47 = __toESM(require("fs"), 1);
59199
- var path50 = __toESM(require("path"), 1);
59345
+ var fs48 = __toESM(require("fs"), 1);
59346
+ var path51 = __toESM(require("path"), 1);
59200
59347
  var FILE_NAME = "contacts.json";
59201
59348
  var ContactStore = class {
59202
59349
  constructor(dataDir) {
@@ -59206,10 +59353,10 @@ var ContactStore = class {
59206
59353
  contacts = /* @__PURE__ */ new Map();
59207
59354
  load() {
59208
59355
  this.contacts.clear();
59209
- const file = path50.join(this.dataDir, FILE_NAME);
59356
+ const file = path51.join(this.dataDir, FILE_NAME);
59210
59357
  let raw;
59211
59358
  try {
59212
- raw = fs47.readFileSync(file, "utf8");
59359
+ raw = fs48.readFileSync(file, "utf8");
59213
59360
  } catch (err) {
59214
59361
  if (err?.code !== "ENOENT") this.renameBak(file);
59215
59362
  return;
@@ -59290,20 +59437,20 @@ var ContactStore = class {
59290
59437
  return true;
59291
59438
  }
59292
59439
  flush() {
59293
- const file = path50.join(this.dataDir, FILE_NAME);
59440
+ const file = path51.join(this.dataDir, FILE_NAME);
59294
59441
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
59295
59442
  const content = JSON.stringify(
59296
59443
  { contacts: Array.from(this.contacts.values()) },
59297
59444
  null,
59298
59445
  2
59299
59446
  );
59300
- fs47.mkdirSync(this.dataDir, { recursive: true });
59301
- fs47.writeFileSync(tmp, content, { mode: 384 });
59302
- fs47.renameSync(tmp, file);
59447
+ fs48.mkdirSync(this.dataDir, { recursive: true });
59448
+ fs48.writeFileSync(tmp, content, { mode: 384 });
59449
+ fs48.renameSync(tmp, file);
59303
59450
  }
59304
59451
  renameBak(file) {
59305
59452
  try {
59306
- fs47.renameSync(file, `${file}.bak`);
59453
+ fs48.renameSync(file, `${file}.bak`);
59307
59454
  } catch {
59308
59455
  }
59309
59456
  }
@@ -59411,61 +59558,61 @@ async function connectRemote(args) {
59411
59558
  }
59412
59559
 
59413
59560
  // src/migrations/2026-05-20-flatten-sessions.ts
59414
- var fs48 = __toESM(require("fs"), 1);
59415
- var path51 = __toESM(require("path"), 1);
59561
+ var fs49 = __toESM(require("fs"), 1);
59562
+ var path52 = __toESM(require("path"), 1);
59416
59563
  var MIGRATION_FLAG_NAME = ".migration.v1.done";
59417
59564
  function migrateFlattenSessions(opts) {
59418
59565
  const dataDir = opts.dataDir;
59419
59566
  const now = opts.now ?? Date.now;
59420
- const sessionsDir = path51.join(dataDir, "sessions");
59421
- const flagPath = path51.join(sessionsDir, MIGRATION_FLAG_NAME);
59567
+ const sessionsDir = path52.join(dataDir, "sessions");
59568
+ const flagPath = path52.join(sessionsDir, MIGRATION_FLAG_NAME);
59422
59569
  if (existsSync3(flagPath)) {
59423
59570
  return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
59424
59571
  }
59425
59572
  let movedBare = 0;
59426
59573
  let movedVmOwner = 0;
59427
59574
  let archivedListener = 0;
59428
- const defaultDir = path51.join(sessionsDir, "default");
59575
+ const defaultDir = path52.join(sessionsDir, "default");
59429
59576
  if (existsSync3(defaultDir)) {
59430
59577
  for (const entry of readdirSafe(defaultDir)) {
59431
59578
  if (!entry.endsWith(".json")) continue;
59432
- const src = path51.join(defaultDir, entry);
59433
- const dst = path51.join(sessionsDir, entry);
59434
- fs48.renameSync(src, dst);
59579
+ const src = path52.join(defaultDir, entry);
59580
+ const dst = path52.join(sessionsDir, entry);
59581
+ fs49.renameSync(src, dst);
59435
59582
  movedBare += 1;
59436
59583
  }
59437
59584
  rmdirIfEmpty(defaultDir);
59438
59585
  }
59439
59586
  for (const pid of readdirSafe(sessionsDir)) {
59440
- const personaDir = path51.join(sessionsDir, pid);
59587
+ const personaDir = path52.join(sessionsDir, pid);
59441
59588
  if (!isDir(personaDir)) continue;
59442
59589
  if (pid === "default") continue;
59443
- const ownerSrc = path51.join(personaDir, "owner");
59590
+ const ownerSrc = path52.join(personaDir, "owner");
59444
59591
  if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
59445
- const ownerDst = path51.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
59446
- fs48.mkdirSync(ownerDst, { recursive: true });
59592
+ const ownerDst = path52.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
59593
+ fs49.mkdirSync(ownerDst, { recursive: true });
59447
59594
  for (const file of readdirSafe(ownerSrc)) {
59448
59595
  if (!file.endsWith(".json")) continue;
59449
- fs48.renameSync(path51.join(ownerSrc, file), path51.join(ownerDst, file));
59596
+ fs49.renameSync(path52.join(ownerSrc, file), path52.join(ownerDst, file));
59450
59597
  movedVmOwner += 1;
59451
59598
  }
59452
59599
  rmdirIfEmpty(ownerSrc);
59453
59600
  }
59454
- const listenerSrc = path51.join(personaDir, "listener");
59601
+ const listenerSrc = path52.join(personaDir, "listener");
59455
59602
  if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
59456
- const archiveDst = path51.join(dataDir, ".legacy", `listener-${pid}`);
59457
- fs48.mkdirSync(archiveDst, { recursive: true });
59603
+ const archiveDst = path52.join(dataDir, ".legacy", `listener-${pid}`);
59604
+ fs49.mkdirSync(archiveDst, { recursive: true });
59458
59605
  for (const file of readdirSafe(listenerSrc)) {
59459
59606
  if (!file.endsWith(".json")) continue;
59460
- fs48.renameSync(path51.join(listenerSrc, file), path51.join(archiveDst, file));
59607
+ fs49.renameSync(path52.join(listenerSrc, file), path52.join(archiveDst, file));
59461
59608
  archivedListener += 1;
59462
59609
  }
59463
59610
  rmdirIfEmpty(listenerSrc);
59464
59611
  }
59465
59612
  rmdirIfEmpty(personaDir);
59466
59613
  }
59467
- fs48.mkdirSync(sessionsDir, { recursive: true });
59468
- fs48.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
59614
+ fs49.mkdirSync(sessionsDir, { recursive: true });
59615
+ fs49.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
59469
59616
  return {
59470
59617
  skipped: false,
59471
59618
  flagWritten: true,
@@ -59476,7 +59623,7 @@ function migrateFlattenSessions(opts) {
59476
59623
  }
59477
59624
  function existsSync3(p2) {
59478
59625
  try {
59479
- fs48.statSync(p2);
59626
+ fs49.statSync(p2);
59480
59627
  return true;
59481
59628
  } catch {
59482
59629
  return false;
@@ -59484,61 +59631,61 @@ function existsSync3(p2) {
59484
59631
  }
59485
59632
  function isDir(p2) {
59486
59633
  try {
59487
- return fs48.statSync(p2).isDirectory();
59634
+ return fs49.statSync(p2).isDirectory();
59488
59635
  } catch {
59489
59636
  return false;
59490
59637
  }
59491
59638
  }
59492
59639
  function readdirSafe(p2) {
59493
59640
  try {
59494
- return fs48.readdirSync(p2);
59641
+ return fs49.readdirSync(p2);
59495
59642
  } catch {
59496
59643
  return [];
59497
59644
  }
59498
59645
  }
59499
59646
  function rmdirIfEmpty(p2) {
59500
59647
  try {
59501
- fs48.rmdirSync(p2);
59648
+ fs49.rmdirSync(p2);
59502
59649
  } catch {
59503
59650
  }
59504
59651
  }
59505
59652
 
59506
59653
  // src/migrations/2026-08-18-drop-seeded-projects.ts
59507
- var fs49 = __toESM(require("fs"), 1);
59508
- var path52 = __toESM(require("path"), 1);
59654
+ var fs50 = __toESM(require("fs"), 1);
59655
+ var path53 = __toESM(require("path"), 1);
59509
59656
  var DROP_SEEDED_PROJECTS_FLAG = ".projects-seed-dropped.v1.done";
59510
59657
  function dropSeededProjects(opts) {
59511
- fs49.mkdirSync(opts.dataDir, { recursive: true });
59512
- const flag = path52.join(opts.dataDir, DROP_SEEDED_PROJECTS_FLAG);
59513
- if (fs49.existsSync(flag)) return { skipped: true, dropped: 0, backup: null };
59514
- const file = path52.join(opts.dataDir, "projects.json");
59658
+ fs50.mkdirSync(opts.dataDir, { recursive: true });
59659
+ const flag = path53.join(opts.dataDir, DROP_SEEDED_PROJECTS_FLAG);
59660
+ if (fs50.existsSync(flag)) return { skipped: true, dropped: 0, backup: null };
59661
+ const file = path53.join(opts.dataDir, "projects.json");
59515
59662
  let raw = null;
59516
59663
  let dropped = 0;
59517
59664
  try {
59518
- raw = fs49.readFileSync(file, "utf8");
59665
+ raw = fs50.readFileSync(file, "utf8");
59519
59666
  dropped = JSON.parse(raw).projects?.length ?? 0;
59520
59667
  } catch {
59521
59668
  }
59522
59669
  let backup = null;
59523
59670
  if (raw != null && dropped > 0) {
59524
- const dir = path52.join(opts.dataDir, "backups");
59525
- fs49.mkdirSync(dir, { recursive: true });
59526
- backup = path52.join(dir, `projects.seed-dropped.${(opts.now ?? Date.now)()}.json`);
59527
- fs49.writeFileSync(backup, raw);
59671
+ const dir = path53.join(opts.dataDir, "backups");
59672
+ fs50.mkdirSync(dir, { recursive: true });
59673
+ backup = path53.join(dir, `projects.seed-dropped.${(opts.now ?? Date.now)()}.json`);
59674
+ fs50.writeFileSync(backup, raw);
59528
59675
  }
59529
59676
  if (raw != null || dropped > 0) {
59530
- fs49.writeFileSync(file, JSON.stringify({ projects: [] }, null, 2));
59677
+ fs50.writeFileSync(file, JSON.stringify({ projects: [] }, null, 2));
59531
59678
  }
59532
- fs49.writeFileSync(flag, (/* @__PURE__ */ new Date()).toISOString());
59679
+ fs50.writeFileSync(flag, (/* @__PURE__ */ new Date()).toISOString());
59533
59680
  return { skipped: false, dropped, backup };
59534
59681
  }
59535
59682
 
59536
59683
  // src/transport/http-router.ts
59537
- var import_node_fs36 = __toESM(require("fs"), 1);
59538
- var import_node_path44 = __toESM(require("path"), 1);
59684
+ var import_node_fs37 = __toESM(require("fs"), 1);
59685
+ var import_node_path45 = __toESM(require("path"), 1);
59539
59686
 
59540
59687
  // src/attachment/mime.ts
59541
- var import_node_path41 = __toESM(require("path"), 1);
59688
+ var import_node_path42 = __toESM(require("path"), 1);
59542
59689
  var TEXT_PLAIN = "text/plain; charset=utf-8";
59543
59690
  var EXT_TO_NATIVE_MIME = {
59544
59691
  // 图片
@@ -59645,7 +59792,7 @@ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
59645
59792
  ".mk"
59646
59793
  ]);
59647
59794
  function lookupMime(filePathOrName) {
59648
- const ext = import_node_path41.default.extname(filePathOrName).toLowerCase();
59795
+ const ext = import_node_path42.default.extname(filePathOrName).toLowerCase();
59649
59796
  if (EXT_TO_NATIVE_MIME[ext]) return EXT_TO_NATIVE_MIME[ext];
59650
59797
  if (TEXT_EXTENSIONS.has(ext)) return TEXT_PLAIN;
59651
59798
  return "application/octet-stream";
@@ -59715,8 +59862,8 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
59715
59862
  }
59716
59863
 
59717
59864
  // src/attachment/upload.ts
59718
- var import_node_fs35 = __toESM(require("fs"), 1);
59719
- var import_node_path42 = __toESM(require("path"), 1);
59865
+ var import_node_fs36 = __toESM(require("fs"), 1);
59866
+ var import_node_path43 = __toESM(require("path"), 1);
59720
59867
  var import_node_crypto10 = __toESM(require("crypto"), 1);
59721
59868
  var import_promises7 = require("stream/promises");
59722
59869
  var UploadError = class extends Error {
@@ -59728,22 +59875,22 @@ var UploadError = class extends Error {
59728
59875
  code;
59729
59876
  };
59730
59877
  function assertValidFileName(fileName) {
59731
- if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path42.default.basename(fileName)) {
59878
+ if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path43.default.basename(fileName)) {
59732
59879
  throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
59733
59880
  }
59734
59881
  }
59735
59882
  var HASH_PREFIX_LEN = 16;
59736
59883
  async function writeUploadedAttachment(args) {
59737
59884
  assertValidFileName(args.fileName);
59738
- const attachmentsRoot = import_node_path42.default.join(args.baseDir, ".attachments");
59885
+ const attachmentsRoot = import_node_path43.default.join(args.baseDir, ".attachments");
59739
59886
  try {
59740
- import_node_fs35.default.mkdirSync(attachmentsRoot, { recursive: true });
59887
+ import_node_fs36.default.mkdirSync(attachmentsRoot, { recursive: true });
59741
59888
  } catch (err) {
59742
59889
  throw new UploadError("STORAGE_ERROR", `mkdir failed: ${err.message}`);
59743
59890
  }
59744
59891
  const hasher = import_node_crypto10.default.createHash("sha256");
59745
59892
  let actualSize = 0;
59746
- const tmpPath = import_node_path42.default.join(
59893
+ const tmpPath = import_node_path43.default.join(
59747
59894
  attachmentsRoot,
59748
59895
  `.upload-${process.pid}-${Date.now()}-${import_node_crypto10.default.randomBytes(4).toString("hex")}`
59749
59896
  );
@@ -59758,18 +59905,18 @@ async function writeUploadedAttachment(args) {
59758
59905
  yield buf;
59759
59906
  }
59760
59907
  },
59761
- import_node_fs35.default.createWriteStream(tmpPath, { mode: 384 })
59908
+ import_node_fs36.default.createWriteStream(tmpPath, { mode: 384 })
59762
59909
  );
59763
59910
  } catch (err) {
59764
59911
  try {
59765
- import_node_fs35.default.unlinkSync(tmpPath);
59912
+ import_node_fs36.default.unlinkSync(tmpPath);
59766
59913
  } catch {
59767
59914
  }
59768
59915
  throw new UploadError("STORAGE_ERROR", `write failed: ${err.message}`);
59769
59916
  }
59770
59917
  if (actualSize !== args.contentLength) {
59771
59918
  try {
59772
- import_node_fs35.default.unlinkSync(tmpPath);
59919
+ import_node_fs36.default.unlinkSync(tmpPath);
59773
59920
  } catch {
59774
59921
  }
59775
59922
  throw new UploadError(
@@ -59778,34 +59925,34 @@ async function writeUploadedAttachment(args) {
59778
59925
  );
59779
59926
  }
59780
59927
  const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
59781
- const hashDir = import_node_path42.default.join(attachmentsRoot, attachmentId);
59928
+ const hashDir = import_node_path43.default.join(attachmentsRoot, attachmentId);
59782
59929
  let finalFileName;
59783
59930
  let hashDirExists = false;
59784
59931
  try {
59785
- hashDirExists = import_node_fs35.default.statSync(hashDir).isDirectory();
59932
+ hashDirExists = import_node_fs36.default.statSync(hashDir).isDirectory();
59786
59933
  } catch {
59787
59934
  }
59788
59935
  if (hashDirExists) {
59789
- const existing = import_node_fs35.default.readdirSync(hashDir).filter((n) => !n.startsWith("."));
59936
+ const existing = import_node_fs36.default.readdirSync(hashDir).filter((n) => !n.startsWith("."));
59790
59937
  finalFileName = existing[0] ?? args.fileName;
59791
59938
  try {
59792
- import_node_fs35.default.unlinkSync(tmpPath);
59939
+ import_node_fs36.default.unlinkSync(tmpPath);
59793
59940
  } catch {
59794
59941
  }
59795
59942
  } else {
59796
59943
  try {
59797
- import_node_fs35.default.mkdirSync(hashDir, { recursive: true });
59944
+ import_node_fs36.default.mkdirSync(hashDir, { recursive: true });
59798
59945
  finalFileName = args.fileName;
59799
- import_node_fs35.default.renameSync(tmpPath, import_node_path42.default.join(hashDir, finalFileName));
59946
+ import_node_fs36.default.renameSync(tmpPath, import_node_path43.default.join(hashDir, finalFileName));
59800
59947
  } catch (err) {
59801
59948
  try {
59802
- import_node_fs35.default.unlinkSync(tmpPath);
59949
+ import_node_fs36.default.unlinkSync(tmpPath);
59803
59950
  } catch {
59804
59951
  }
59805
59952
  throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
59806
59953
  }
59807
59954
  }
59808
- const absPath = import_node_path42.default.join(hashDir, finalFileName);
59955
+ const absPath = import_node_path43.default.join(hashDir, finalFileName);
59809
59956
  const relPath = absPath;
59810
59957
  args.groupFileStore.upsert(args.scope, args.sessionId, {
59811
59958
  relPath: absPath,
@@ -59820,8 +59967,8 @@ async function writeUploadedAttachment(args) {
59820
59967
 
59821
59968
  // src/extension/import.ts
59822
59969
  var import_promises8 = __toESM(require("fs/promises"), 1);
59823
- var import_node_path43 = __toESM(require("path"), 1);
59824
- var import_node_os13 = __toESM(require("os"), 1);
59970
+ var import_node_path44 = __toESM(require("path"), 1);
59971
+ var import_node_os14 = __toESM(require("os"), 1);
59825
59972
  var import_jszip = __toESM(require_lib3(), 1);
59826
59973
  var ImportError = class extends Error {
59827
59974
  constructor(code, message) {
@@ -59838,7 +59985,7 @@ async function importZip(buf, root) {
59838
59985
  throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
59839
59986
  }
59840
59987
  for (const name of Object.keys(zip.files)) {
59841
- if (name.includes("..") || name.startsWith("/") || import_node_path43.default.isAbsolute(name)) {
59988
+ if (name.includes("..") || name.startsWith("/") || import_node_path44.default.isAbsolute(name)) {
59842
59989
  throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
59843
59990
  }
59844
59991
  }
@@ -59871,7 +60018,7 @@ async function importZip(buf, root) {
59871
60018
  );
59872
60019
  }
59873
60020
  }
59874
- const destDir = import_node_path43.default.join(root, manifest.id);
60021
+ const destDir = import_node_path44.default.join(root, manifest.id);
59875
60022
  let destExists = false;
59876
60023
  try {
59877
60024
  await import_promises8.default.access(destDir);
@@ -59881,15 +60028,15 @@ async function importZip(buf, root) {
59881
60028
  if (destExists) {
59882
60029
  throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
59883
60030
  }
59884
- const stage = await import_promises8.default.mkdtemp(import_node_path43.default.join(import_node_os13.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
60031
+ const stage = await import_promises8.default.mkdtemp(import_node_path44.default.join(import_node_os14.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
59885
60032
  try {
59886
60033
  for (const [name, entry] of Object.entries(zip.files)) {
59887
- const dest = import_node_path43.default.join(stage, name);
60034
+ const dest = import_node_path44.default.join(stage, name);
59888
60035
  if (entry.dir) {
59889
60036
  await import_promises8.default.mkdir(dest, { recursive: true });
59890
60037
  continue;
59891
60038
  }
59892
- await import_promises8.default.mkdir(import_node_path43.default.dirname(dest), { recursive: true });
60039
+ await import_promises8.default.mkdir(import_node_path44.default.dirname(dest), { recursive: true });
59893
60040
  const content = await entry.async("nodebuffer");
59894
60041
  await import_promises8.default.writeFile(dest, content);
59895
60042
  }
@@ -59919,7 +60066,7 @@ var SHARE_UI_ASSET_MIME = {
59919
60066
  ".wasm": "application/wasm"
59920
60067
  };
59921
60068
  function shareUiAssetMime(filePath) {
59922
- const ext = import_node_path44.default.extname(filePath).toLowerCase();
60069
+ const ext = import_node_path45.default.extname(filePath).toLowerCase();
59923
60070
  return SHARE_UI_ASSET_MIME[ext] ?? lookupMime(filePath);
59924
60071
  }
59925
60072
  var AUTHED_RPC_ROUTE_PREFIX = "/rpc/";
@@ -60018,7 +60165,7 @@ function isValidUploadFileName(fileName) {
60018
60165
  if (fileName === "." || fileName === "..") return false;
60019
60166
  if (fileName.startsWith(".")) return false;
60020
60167
  if (fileName.includes("/") || fileName.includes("\\")) return false;
60021
- return fileName === import_node_path44.default.basename(fileName);
60168
+ return fileName === import_node_path45.default.basename(fileName);
60022
60169
  }
60023
60170
  function createHttpRouter(deps) {
60024
60171
  return async (req, res) => {
@@ -60106,7 +60253,7 @@ function createHttpRouter(deps) {
60106
60253
  }
60107
60254
  let buf;
60108
60255
  try {
60109
- buf = await import_node_fs36.default.promises.readFile(abs);
60256
+ buf = await import_node_fs37.default.promises.readFile(abs);
60110
60257
  } catch {
60111
60258
  sendJson(res, 404, { code: "NOT_FOUND", message: "asset not found" });
60112
60259
  return true;
@@ -60254,7 +60401,7 @@ function createHttpRouter(deps) {
60254
60401
  sendHtml(res, statusByCode[r.code], loader.renderErrorHtml(r.code, msgByCode[r.code]));
60255
60402
  return true;
60256
60403
  }
60257
- sendHtml(res, 200, loader.renderViewerHtml(import_node_path44.default.basename(r.absPath)));
60404
+ sendHtml(res, 200, loader.renderViewerHtml(import_node_path45.default.basename(r.absPath)));
60258
60405
  return true;
60259
60406
  }
60260
60407
  const ctx = deps.authResolver.resolveFromHeader(
@@ -60375,7 +60522,7 @@ function createHttpRouter(deps) {
60375
60522
  return true;
60376
60523
  }
60377
60524
  let absPath;
60378
- if (import_node_path44.default.isAbsolute(pathParam)) {
60525
+ if (import_node_path45.default.isAbsolute(pathParam)) {
60379
60526
  absPath = pathParam;
60380
60527
  } else if (deps.sessionStore) {
60381
60528
  const file = deps.sessionStore.read(sid);
@@ -60383,7 +60530,7 @@ function createHttpRouter(deps) {
60383
60530
  sendJson(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
60384
60531
  return true;
60385
60532
  }
60386
- absPath = import_node_path44.default.join(file.cwd, pathParam);
60533
+ absPath = import_node_path45.default.join(file.cwd, pathParam);
60387
60534
  } else {
60388
60535
  sendJson(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
60389
60536
  return true;
@@ -60470,7 +60617,7 @@ function withCtx(ctx, body) {
60470
60617
  function streamFile(res, absPath, logger) {
60471
60618
  let stat;
60472
60619
  try {
60473
- stat = import_node_fs36.default.statSync(absPath);
60620
+ stat = import_node_fs37.default.statSync(absPath);
60474
60621
  } catch (err) {
60475
60622
  const code = err?.code;
60476
60623
  if (code === "ENOENT") {
@@ -60485,7 +60632,7 @@ function streamFile(res, absPath, logger) {
60485
60632
  return;
60486
60633
  }
60487
60634
  const mime = lookupMime(absPath);
60488
- const basename2 = import_node_path44.default.basename(absPath);
60635
+ const basename2 = import_node_path45.default.basename(absPath);
60489
60636
  res.writeHead(200, {
60490
60637
  "Content-Type": mime,
60491
60638
  "Content-Length": String(stat.size),
@@ -60493,7 +60640,7 @@ function streamFile(res, absPath, logger) {
60493
60640
  // 防止浏览器把任意 mime 当 html 渲染
60494
60641
  "X-Content-Type-Options": "nosniff"
60495
60642
  });
60496
- const stream = import_node_fs36.default.createReadStream(absPath);
60643
+ const stream = import_node_fs37.default.createReadStream(absPath);
60497
60644
  stream.on("error", (err) => {
60498
60645
  logger?.warn("streamFile read error", { absPath, err: err.message });
60499
60646
  res.destroy();
@@ -60502,8 +60649,8 @@ function streamFile(res, absPath, logger) {
60502
60649
  }
60503
60650
 
60504
60651
  // src/attachment/gc.ts
60505
- var import_node_fs37 = __toESM(require("fs"), 1);
60506
- var import_node_path45 = __toESM(require("path"), 1);
60652
+ var import_node_fs38 = __toESM(require("fs"), 1);
60653
+ var import_node_path46 = __toESM(require("path"), 1);
60507
60654
  var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
60508
60655
  function runAttachmentGc(args) {
60509
60656
  const now = (args.now ?? Date.now)();
@@ -60512,12 +60659,12 @@ function runAttachmentGc(args) {
60512
60659
  for (const { scope, sessionId } of args.sessionScopes) {
60513
60660
  for (const entry of args.groupFileStore.list(scope, sessionId)) {
60514
60661
  if (entry.stale) continue;
60515
- if (import_node_path45.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
60662
+ if (import_node_path46.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
60516
60663
  }
60517
60664
  }
60518
60665
  const visited = /* @__PURE__ */ new Set();
60519
60666
  for (const { scope, sessionId } of args.sessionScopes) {
60520
- const legacyDir = args.getSessionCwd?.(sessionId) ?? import_node_path45.default.join(
60667
+ const legacyDir = args.getSessionCwd?.(sessionId) ?? import_node_path46.default.join(
60521
60668
  args.dataDir,
60522
60669
  "sessions",
60523
60670
  ...scopeSubPath(scope).map(safeFileName),
@@ -60530,28 +60677,28 @@ function runAttachmentGc(args) {
60530
60677
  return true;
60531
60678
  });
60532
60679
  for (const rootDir of roots) {
60533
- const attRoot = import_node_path45.default.join(rootDir, ".attachments");
60680
+ const attRoot = import_node_path46.default.join(rootDir, ".attachments");
60534
60681
  let hashDirs;
60535
60682
  try {
60536
- hashDirs = import_node_fs37.default.readdirSync(attRoot);
60683
+ hashDirs = import_node_fs38.default.readdirSync(attRoot);
60537
60684
  } catch (err) {
60538
60685
  if (err.code === "ENOENT") continue;
60539
60686
  args.logger?.warn("attachment gc: readdir failed", { attRoot, err: err.message });
60540
60687
  continue;
60541
60688
  }
60542
60689
  for (const hashDir of hashDirs) {
60543
- const hashDirAbs = import_node_path45.default.join(attRoot, hashDir);
60690
+ const hashDirAbs = import_node_path46.default.join(attRoot, hashDir);
60544
60691
  let files;
60545
60692
  try {
60546
- files = import_node_fs37.default.readdirSync(hashDirAbs);
60693
+ files = import_node_fs38.default.readdirSync(hashDirAbs);
60547
60694
  } catch {
60548
60695
  continue;
60549
60696
  }
60550
60697
  for (const name of files) {
60551
- const file = import_node_path45.default.join(hashDirAbs, name);
60698
+ const file = import_node_path46.default.join(hashDirAbs, name);
60552
60699
  let stat;
60553
60700
  try {
60554
- stat = import_node_fs37.default.statSync(file);
60701
+ stat = import_node_fs38.default.statSync(file);
60555
60702
  } catch {
60556
60703
  continue;
60557
60704
  }
@@ -60560,18 +60707,18 @@ function runAttachmentGc(args) {
60560
60707
  if (age < ttlMs) continue;
60561
60708
  if (liveAbs.has(file)) continue;
60562
60709
  try {
60563
- import_node_fs37.default.unlinkSync(file);
60710
+ import_node_fs38.default.unlinkSync(file);
60564
60711
  } catch (err) {
60565
60712
  args.logger?.warn("attachment gc: unlink failed", { file, err: err.message });
60566
60713
  }
60567
60714
  }
60568
60715
  try {
60569
- if (import_node_fs37.default.readdirSync(hashDirAbs).length === 0) import_node_fs37.default.rmdirSync(hashDirAbs);
60716
+ if (import_node_fs38.default.readdirSync(hashDirAbs).length === 0) import_node_fs38.default.rmdirSync(hashDirAbs);
60570
60717
  } catch {
60571
60718
  }
60572
60719
  }
60573
60720
  try {
60574
- if (import_node_fs37.default.readdirSync(attRoot).length === 0) import_node_fs37.default.rmdirSync(attRoot);
60721
+ if (import_node_fs38.default.readdirSync(attRoot).length === 0) import_node_fs38.default.rmdirSync(attRoot);
60575
60722
  } catch {
60576
60723
  }
60577
60724
  }
@@ -60579,8 +60726,8 @@ function runAttachmentGc(args) {
60579
60726
  }
60580
60727
 
60581
60728
  // src/attachment/group.ts
60582
- var import_node_fs38 = __toESM(require("fs"), 1);
60583
- var import_node_path46 = __toESM(require("path"), 1);
60729
+ var import_node_fs39 = __toESM(require("fs"), 1);
60730
+ var import_node_path47 = __toESM(require("path"), 1);
60584
60731
  var import_node_crypto11 = __toESM(require("crypto"), 1);
60585
60732
  init_protocol();
60586
60733
  var GroupFileStore = class {
@@ -60592,11 +60739,11 @@ var GroupFileStore = class {
60592
60739
  this.logger = opts.logger;
60593
60740
  }
60594
60741
  rootForScope(scope) {
60595
- return import_node_path46.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
60742
+ return import_node_path47.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
60596
60743
  }
60597
60744
  /** 与 SessionStore.filePath 平级,扩展名 .group-files.json */
60598
60745
  filePath(scope, sessionId) {
60599
- return import_node_path46.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
60746
+ return import_node_path47.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
60600
60747
  }
60601
60748
  cacheKey(scope, sessionId) {
60602
60749
  return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
@@ -60605,7 +60752,7 @@ var GroupFileStore = class {
60605
60752
  readFile(scope, sessionId) {
60606
60753
  const file = this.filePath(scope, sessionId);
60607
60754
  try {
60608
- const raw = import_node_fs38.default.readFileSync(file, "utf8");
60755
+ const raw = import_node_fs39.default.readFileSync(file, "utf8");
60609
60756
  const parsed = JSON.parse(raw);
60610
60757
  if (!Array.isArray(parsed)) {
60611
60758
  this.logger?.warn("GroupFileStore.readFile: not an array; resetting session entries", {
@@ -60631,10 +60778,10 @@ var GroupFileStore = class {
60631
60778
  }
60632
60779
  writeFile(scope, sessionId, entries) {
60633
60780
  const file = this.filePath(scope, sessionId);
60634
- import_node_fs38.default.mkdirSync(import_node_path46.default.dirname(file), { recursive: true });
60781
+ import_node_fs39.default.mkdirSync(import_node_path47.default.dirname(file), { recursive: true });
60635
60782
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
60636
- import_node_fs38.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
60637
- import_node_fs38.default.renameSync(tmp, file);
60783
+ import_node_fs39.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
60784
+ import_node_fs39.default.renameSync(tmp, file);
60638
60785
  }
60639
60786
  /** 拉一份当前 session 的清单。读盘 → cache;之后调用复用 cache */
60640
60787
  list(scope, sessionId) {
@@ -60720,10 +60867,10 @@ var GroupFileStore = class {
60720
60867
  };
60721
60868
 
60722
60869
  // src/discovery/state-file.ts
60723
- var import_node_fs39 = __toESM(require("fs"), 1);
60724
- var import_node_path47 = __toESM(require("path"), 1);
60870
+ var import_node_fs40 = __toESM(require("fs"), 1);
60871
+ var import_node_path48 = __toESM(require("path"), 1);
60725
60872
  function defaultStateFilePath(dataDir) {
60726
- return import_node_path47.default.join(dataDir, "state.json");
60873
+ return import_node_path48.default.join(dataDir, "state.json");
60727
60874
  }
60728
60875
  function isPidAlive(pid) {
60729
60876
  if (!Number.isFinite(pid) || pid <= 0) return false;
@@ -60745,7 +60892,7 @@ var StateFileManager = class {
60745
60892
  }
60746
60893
  read() {
60747
60894
  try {
60748
- const raw = import_node_fs39.default.readFileSync(this.file, "utf8");
60895
+ const raw = import_node_fs40.default.readFileSync(this.file, "utf8");
60749
60896
  const parsed = JSON.parse(raw);
60750
60897
  return parsed;
60751
60898
  } catch {
@@ -60759,20 +60906,20 @@ var StateFileManager = class {
60759
60906
  return { status: "stale", existing };
60760
60907
  }
60761
60908
  write(state) {
60762
- import_node_fs39.default.mkdirSync(import_node_path47.default.dirname(this.file), { recursive: true });
60909
+ import_node_fs40.default.mkdirSync(import_node_path48.default.dirname(this.file), { recursive: true });
60763
60910
  const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
60764
- import_node_fs39.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
60765
- import_node_fs39.default.renameSync(tmp, this.file);
60911
+ import_node_fs40.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
60912
+ import_node_fs40.default.renameSync(tmp, this.file);
60766
60913
  if (process.platform !== "win32") {
60767
60914
  try {
60768
- import_node_fs39.default.chmodSync(this.file, 384);
60915
+ import_node_fs40.default.chmodSync(this.file, 384);
60769
60916
  } catch {
60770
60917
  }
60771
60918
  }
60772
60919
  }
60773
60920
  delete() {
60774
60921
  try {
60775
- import_node_fs39.default.unlinkSync(this.file);
60922
+ import_node_fs40.default.unlinkSync(this.file);
60776
60923
  } catch {
60777
60924
  }
60778
60925
  }
@@ -60786,14 +60933,14 @@ function readSpawnedByDesktopFromEnv(env = process.env) {
60786
60933
  }
60787
60934
 
60788
60935
  // src/tunnel/tunnel-manager.ts
60789
- var import_node_fs43 = __toESM(require("fs"), 1);
60790
- var import_node_path51 = __toESM(require("path"), 1);
60936
+ var import_node_fs44 = __toESM(require("fs"), 1);
60937
+ var import_node_path52 = __toESM(require("path"), 1);
60791
60938
  var import_node_crypto12 = __toESM(require("crypto"), 1);
60792
60939
  var import_node_child_process12 = require("child_process");
60793
60940
 
60794
60941
  // src/tunnel/tunnel-store.ts
60795
- var import_node_fs40 = __toESM(require("fs"), 1);
60796
- var import_node_path48 = __toESM(require("path"), 1);
60942
+ var import_node_fs41 = __toESM(require("fs"), 1);
60943
+ var import_node_path49 = __toESM(require("path"), 1);
60797
60944
  var TunnelStore = class {
60798
60945
  constructor(filePath) {
60799
60946
  this.filePath = filePath;
@@ -60801,7 +60948,7 @@ var TunnelStore = class {
60801
60948
  filePath;
60802
60949
  async get() {
60803
60950
  try {
60804
- const raw = await import_node_fs40.default.promises.readFile(this.filePath, "utf8");
60951
+ const raw = await import_node_fs41.default.promises.readFile(this.filePath, "utf8");
60805
60952
  const obj = JSON.parse(raw);
60806
60953
  if (!isPersistedTunnel(obj)) return null;
60807
60954
  return obj;
@@ -60812,22 +60959,22 @@ var TunnelStore = class {
60812
60959
  }
60813
60960
  }
60814
60961
  async set(v2) {
60815
- const dir = import_node_path48.default.dirname(this.filePath);
60816
- await import_node_fs40.default.promises.mkdir(dir, { recursive: true });
60962
+ const dir = import_node_path49.default.dirname(this.filePath);
60963
+ await import_node_fs41.default.promises.mkdir(dir, { recursive: true });
60817
60964
  const data = JSON.stringify(v2, null, 2);
60818
60965
  const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
60819
- await import_node_fs40.default.promises.writeFile(tmp, data, { mode: 384 });
60966
+ await import_node_fs41.default.promises.writeFile(tmp, data, { mode: 384 });
60820
60967
  if (process.platform !== "win32") {
60821
60968
  try {
60822
- await import_node_fs40.default.promises.chmod(tmp, 384);
60969
+ await import_node_fs41.default.promises.chmod(tmp, 384);
60823
60970
  } catch {
60824
60971
  }
60825
60972
  }
60826
- await import_node_fs40.default.promises.rename(tmp, this.filePath);
60973
+ await import_node_fs41.default.promises.rename(tmp, this.filePath);
60827
60974
  }
60828
60975
  async clear() {
60829
60976
  try {
60830
- await import_node_fs40.default.promises.unlink(this.filePath);
60977
+ await import_node_fs41.default.promises.unlink(this.filePath);
60831
60978
  } catch (err) {
60832
60979
  const code = err?.code;
60833
60980
  if (code !== "ENOENT") throw err;
@@ -60922,9 +61069,9 @@ function escape(v2) {
60922
61069
  }
60923
61070
 
60924
61071
  // src/tunnel/frpc-binary.ts
60925
- var import_node_fs41 = __toESM(require("fs"), 1);
60926
- var import_node_os14 = __toESM(require("os"), 1);
60927
- var import_node_path49 = __toESM(require("path"), 1);
61072
+ var import_node_fs42 = __toESM(require("fs"), 1);
61073
+ var import_node_os15 = __toESM(require("os"), 1);
61074
+ var import_node_path50 = __toESM(require("path"), 1);
60928
61075
  var import_node_child_process10 = require("child_process");
60929
61076
  var import_node_stream3 = require("stream");
60930
61077
  var import_promises9 = require("stream/promises");
@@ -60956,20 +61103,20 @@ function frpcDownloadUrl(version2, p2) {
60956
61103
  }
60957
61104
  async function ensureFrpcBinary(opts) {
60958
61105
  if (opts.override) {
60959
- if (!import_node_fs41.default.existsSync(opts.override)) {
61106
+ if (!import_node_fs42.default.existsSync(opts.override)) {
60960
61107
  throw new Error(`frpc binary not found at override path: ${opts.override}`);
60961
61108
  }
60962
61109
  return opts.override;
60963
61110
  }
60964
61111
  const version2 = opts.version ?? FRPC_VERSION;
60965
61112
  const platform = opts.platform ?? detectPlatform();
60966
- const binDir = import_node_path49.default.join(opts.dataDir, "bin");
60967
- import_node_fs41.default.mkdirSync(binDir, { recursive: true });
61113
+ const binDir = import_node_path50.default.join(opts.dataDir, "bin");
61114
+ import_node_fs42.default.mkdirSync(binDir, { recursive: true });
60968
61115
  cleanupStaleArtifacts(binDir);
60969
- const stableBin = import_node_path49.default.join(binDir, "frpc");
60970
- if (import_node_fs41.default.existsSync(stableBin)) return stableBin;
61116
+ const stableBin = import_node_path50.default.join(binDir, "frpc");
61117
+ if (import_node_fs42.default.existsSync(stableBin)) return stableBin;
60971
61118
  const partialBin = `${stableBin}.partial`;
60972
- const tarballPath = import_node_path49.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
61119
+ const tarballPath = import_node_path50.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
60973
61120
  try {
60974
61121
  const url = frpcDownloadUrl(version2, platform);
60975
61122
  await downloadToFile(url, tarballPath, opts.fetchImpl);
@@ -60978,8 +61125,8 @@ async function ensureFrpcBinary(opts) {
60978
61125
  } else {
60979
61126
  await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
60980
61127
  }
60981
- import_node_fs41.default.chmodSync(partialBin, 493);
60982
- import_node_fs41.default.renameSync(partialBin, stableBin);
61128
+ import_node_fs42.default.chmodSync(partialBin, 493);
61129
+ import_node_fs42.default.renameSync(partialBin, stableBin);
60983
61130
  } finally {
60984
61131
  safeUnlink(tarballPath);
60985
61132
  safeUnlink(partialBin);
@@ -60989,15 +61136,15 @@ async function ensureFrpcBinary(opts) {
60989
61136
  function cleanupStaleArtifacts(binDir) {
60990
61137
  let entries;
60991
61138
  try {
60992
- entries = import_node_fs41.default.readdirSync(binDir);
61139
+ entries = import_node_fs42.default.readdirSync(binDir);
60993
61140
  } catch {
60994
61141
  return;
60995
61142
  }
60996
61143
  for (const name of entries) {
60997
61144
  if (name.endsWith(".partial") || name.startsWith("extract-")) {
60998
- const full = import_node_path49.default.join(binDir, name);
61145
+ const full = import_node_path50.default.join(binDir, name);
60999
61146
  try {
61000
- import_node_fs41.default.rmSync(full, { recursive: true, force: true });
61147
+ import_node_fs42.default.rmSync(full, { recursive: true, force: true });
61001
61148
  } catch {
61002
61149
  }
61003
61150
  }
@@ -61005,7 +61152,7 @@ function cleanupStaleArtifacts(binDir) {
61005
61152
  }
61006
61153
  function safeUnlink(p2) {
61007
61154
  try {
61008
- import_node_fs41.default.unlinkSync(p2);
61155
+ import_node_fs42.default.unlinkSync(p2);
61009
61156
  } catch {
61010
61157
  }
61011
61158
  }
@@ -61016,13 +61163,13 @@ async function downloadToFile(url, dest, fetchImpl) {
61016
61163
  if (!res.ok || !res.body) {
61017
61164
  throw new Error(`download failed: ${res.status} ${res.statusText}`);
61018
61165
  }
61019
- const out = import_node_fs41.default.createWriteStream(dest);
61166
+ const out = import_node_fs42.default.createWriteStream(dest);
61020
61167
  const nodeStream = import_node_stream3.Readable.fromWeb(res.body);
61021
61168
  await (0, import_promises9.pipeline)(nodeStream, out);
61022
61169
  }
61023
61170
  async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
61024
- const work = import_node_path49.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
61025
- import_node_fs41.default.mkdirSync(work, { recursive: true });
61171
+ const work = import_node_path50.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
61172
+ import_node_fs42.default.mkdirSync(work, { recursive: true });
61026
61173
  try {
61027
61174
  await new Promise((resolve9, reject) => {
61028
61175
  const proc = (0, import_node_child_process10.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
@@ -61030,32 +61177,32 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
61030
61177
  proc.on("exit", (code) => code === 0 ? resolve9() : reject(new Error(`tar exited ${code}`)));
61031
61178
  });
61032
61179
  const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
61033
- const src = import_node_path49.default.join(work, dirName, "frpc");
61034
- if (!import_node_fs41.default.existsSync(src)) {
61180
+ const src = import_node_path50.default.join(work, dirName, "frpc");
61181
+ if (!import_node_fs42.default.existsSync(src)) {
61035
61182
  throw new Error(`frpc not found inside tarball at ${src}`);
61036
61183
  }
61037
- import_node_fs41.default.copyFileSync(src, destBin);
61184
+ import_node_fs42.default.copyFileSync(src, destBin);
61038
61185
  } finally {
61039
- import_node_fs41.default.rmSync(work, { recursive: true, force: true });
61186
+ import_node_fs42.default.rmSync(work, { recursive: true, force: true });
61040
61187
  }
61041
61188
  }
61042
61189
 
61043
61190
  // src/tunnel/frpc-process.ts
61044
- var import_node_fs42 = __toESM(require("fs"), 1);
61045
- var import_node_path50 = __toESM(require("path"), 1);
61191
+ var import_node_fs43 = __toESM(require("fs"), 1);
61192
+ var import_node_path51 = __toESM(require("path"), 1);
61046
61193
  var import_node_child_process11 = require("child_process");
61047
61194
  function frpcPidFilePath(dataDir) {
61048
- return import_node_path50.default.join(dataDir, "frpc.pid");
61195
+ return import_node_path51.default.join(dataDir, "frpc.pid");
61049
61196
  }
61050
61197
  function writeFrpcPid(dataDir, pid) {
61051
61198
  try {
61052
- import_node_fs42.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
61199
+ import_node_fs43.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
61053
61200
  } catch {
61054
61201
  }
61055
61202
  }
61056
61203
  function clearFrpcPid(dataDir) {
61057
61204
  try {
61058
- import_node_fs42.default.unlinkSync(frpcPidFilePath(dataDir));
61205
+ import_node_fs43.default.unlinkSync(frpcPidFilePath(dataDir));
61059
61206
  } catch {
61060
61207
  }
61061
61208
  }
@@ -61071,7 +61218,7 @@ function defaultIsPidAlive(pid) {
61071
61218
  }
61072
61219
  function defaultReadPidFile(file) {
61073
61220
  try {
61074
- return import_node_fs42.default.readFileSync(file, "utf8");
61221
+ return import_node_fs43.default.readFileSync(file, "utf8");
61075
61222
  } catch {
61076
61223
  return null;
61077
61224
  }
@@ -61087,7 +61234,7 @@ function defaultSleep2(ms) {
61087
61234
  }
61088
61235
  async function killStaleFrpc(deps) {
61089
61236
  const pidFile = frpcPidFilePath(deps.dataDir);
61090
- const tomlPath = import_node_path50.default.join(deps.dataDir, "frpc.toml");
61237
+ const tomlPath = import_node_path51.default.join(deps.dataDir, "frpc.toml");
61091
61238
  const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
61092
61239
  const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
61093
61240
  const killPid = deps.killPidImpl ?? defaultKillPid;
@@ -61111,7 +61258,7 @@ async function killStaleFrpc(deps) {
61111
61258
  }
61112
61259
  if (victims.size === 0) {
61113
61260
  try {
61114
- import_node_fs42.default.unlinkSync(pidFile);
61261
+ import_node_fs43.default.unlinkSync(pidFile);
61115
61262
  } catch {
61116
61263
  }
61117
61264
  return;
@@ -61122,7 +61269,7 @@ async function killStaleFrpc(deps) {
61122
61269
  }
61123
61270
  await sleep2(deps.reapWaitMs ?? 300);
61124
61271
  try {
61125
- import_node_fs42.default.unlinkSync(pidFile);
61272
+ import_node_fs43.default.unlinkSync(pidFile);
61126
61273
  } catch {
61127
61274
  }
61128
61275
  }
@@ -61159,7 +61306,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
61159
61306
  var TunnelManager = class {
61160
61307
  constructor(deps) {
61161
61308
  this.deps = deps;
61162
- this.store = deps.store ?? new TunnelStore(import_node_path51.default.join(deps.dataDir, "tunnel.json"));
61309
+ this.store = deps.store ?? new TunnelStore(import_node_path52.default.join(deps.dataDir, "tunnel.json"));
61163
61310
  this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
61164
61311
  this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
61165
61312
  }
@@ -61286,7 +61433,7 @@ var TunnelManager = class {
61286
61433
  dataDir: this.deps.dataDir,
61287
61434
  override: this.deps.frpcBinaryOverride ?? void 0
61288
61435
  });
61289
- const tomlPath = import_node_path51.default.join(this.deps.dataDir, "frpc.toml");
61436
+ const tomlPath = import_node_path52.default.join(this.deps.dataDir, "frpc.toml");
61290
61437
  const proxyName = `clawd-${t.subdomain}-${localPort}-${import_node_crypto12.default.randomBytes(3).toString("hex")}`;
61291
61438
  const toml = buildFrpcToml({
61292
61439
  serverAddr: t.frpsHost,
@@ -61297,14 +61444,14 @@ var TunnelManager = class {
61297
61444
  localPort,
61298
61445
  logLevel: "info"
61299
61446
  });
61300
- await import_node_fs43.default.promises.writeFile(tomlPath, toml, { mode: 384 });
61447
+ await import_node_fs44.default.promises.writeFile(tomlPath, toml, { mode: 384 });
61301
61448
  const proc = (this.deps.spawnImpl ?? import_node_child_process12.spawn)(frpcBin, ["-c", tomlPath], {
61302
61449
  stdio: ["ignore", "pipe", "pipe"]
61303
61450
  });
61304
- const logDir = import_node_path51.default.join(this.deps.dataDir, "log");
61305
- import_node_fs43.default.mkdirSync(logDir, { recursive: true });
61306
- const logFilePath = import_node_path51.default.join(logDir, "frpc.log");
61307
- const logStream = import_node_fs43.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
61451
+ const logDir = import_node_path52.default.join(this.deps.dataDir, "log");
61452
+ import_node_fs44.default.mkdirSync(logDir, { recursive: true });
61453
+ const logFilePath = import_node_path52.default.join(logDir, "frpc.log");
61454
+ const logStream = import_node_fs44.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
61308
61455
  logStream.on("error", () => {
61309
61456
  });
61310
61457
  const tee = (chunk) => {
@@ -61386,28 +61533,28 @@ async function waitForFrpcReady(proc, timeoutMs) {
61386
61533
  }
61387
61534
 
61388
61535
  // src/tunnel/device-key.ts
61389
- var import_node_os15 = __toESM(require("os"), 1);
61390
- var import_node_path52 = __toESM(require("path"), 1);
61536
+ var import_node_os16 = __toESM(require("os"), 1);
61537
+ var import_node_path53 = __toESM(require("path"), 1);
61391
61538
  var import_node_crypto13 = __toESM(require("crypto"), 1);
61392
61539
  var DERIVE_SALT = "clawd-tunnel-device-v1";
61393
61540
  function deriveStableDeviceKey(opts = {}) {
61394
- const hostname = opts.hostname ?? import_node_os15.default.hostname();
61395
- const uid = opts.uid ?? (typeof import_node_os15.default.userInfo === "function" ? import_node_os15.default.userInfo().uid : 0);
61396
- const home = opts.home ?? import_node_os15.default.homedir();
61397
- const defaultDataDir = import_node_path52.default.resolve(import_node_path52.default.join(home, ".clawd"));
61398
- const normalizedDataDir = opts.dataDir ? import_node_path52.default.resolve(opts.dataDir) : null;
61541
+ const hostname = opts.hostname ?? import_node_os16.default.hostname();
61542
+ const uid = opts.uid ?? (typeof import_node_os16.default.userInfo === "function" ? import_node_os16.default.userInfo().uid : 0);
61543
+ const home = opts.home ?? import_node_os16.default.homedir();
61544
+ const defaultDataDir = import_node_path53.default.resolve(import_node_path53.default.join(home, ".clawd"));
61545
+ const normalizedDataDir = opts.dataDir ? import_node_path53.default.resolve(opts.dataDir) : null;
61399
61546
  const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
61400
61547
  const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
61401
61548
  return import_node_crypto13.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
61402
61549
  }
61403
61550
 
61404
61551
  // src/auth-store.ts
61405
- var import_node_fs44 = __toESM(require("fs"), 1);
61406
- var import_node_path53 = __toESM(require("path"), 1);
61552
+ var import_node_fs45 = __toESM(require("fs"), 1);
61553
+ var import_node_path54 = __toESM(require("path"), 1);
61407
61554
  var import_node_crypto14 = __toESM(require("crypto"), 1);
61408
61555
  var AUTH_FILE_NAME = "auth.json";
61409
61556
  function authFilePath(dataDir) {
61410
- return import_node_path53.default.join(dataDir, AUTH_FILE_NAME);
61557
+ return import_node_path54.default.join(dataDir, AUTH_FILE_NAME);
61411
61558
  }
61412
61559
  function loadOrCreateAuthFile(opts) {
61413
61560
  const file = authFilePath(opts.dataDir);
@@ -61439,7 +61586,7 @@ function defaultGenerateOwnerPrincipalId() {
61439
61586
  }
61440
61587
  function readAuthFile(file) {
61441
61588
  try {
61442
- const raw = import_node_fs44.default.readFileSync(file, "utf8");
61589
+ const raw = import_node_fs45.default.readFileSync(file, "utf8");
61443
61590
  const parsed = JSON.parse(raw);
61444
61591
  if (typeof parsed?.token !== "string" || parsed.token.length === 0) {
61445
61592
  return null;
@@ -61459,26 +61606,26 @@ function readAuthFile(file) {
61459
61606
  }
61460
61607
  }
61461
61608
  function writeAuthFile(file, content) {
61462
- import_node_fs44.default.mkdirSync(import_node_path53.default.dirname(file), { recursive: true });
61463
- import_node_fs44.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
61609
+ import_node_fs45.default.mkdirSync(import_node_path54.default.dirname(file), { recursive: true });
61610
+ import_node_fs45.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
61464
61611
  try {
61465
- import_node_fs44.default.chmodSync(file, 384);
61612
+ import_node_fs45.default.chmodSync(file, 384);
61466
61613
  } catch {
61467
61614
  }
61468
61615
  }
61469
61616
 
61470
61617
  // src/owner-profile.ts
61471
- var import_node_fs45 = __toESM(require("fs"), 1);
61472
- var import_node_os16 = __toESM(require("os"), 1);
61473
- var import_node_path54 = __toESM(require("path"), 1);
61618
+ var import_node_fs46 = __toESM(require("fs"), 1);
61619
+ var import_node_os17 = __toESM(require("os"), 1);
61620
+ var import_node_path55 = __toESM(require("path"), 1);
61474
61621
  var PROFILE_FILENAME = "profile.json";
61475
61622
  function profilePath(dataDir) {
61476
- return import_node_path54.default.join(dataDir, PROFILE_FILENAME);
61623
+ return import_node_path55.default.join(dataDir, PROFILE_FILENAME);
61477
61624
  }
61478
61625
  function loadOwnerProfile(dataDir) {
61479
61626
  let raw;
61480
61627
  try {
61481
- raw = import_node_fs45.default.readFileSync(profilePath(dataDir), "utf8");
61628
+ raw = import_node_fs46.default.readFileSync(profilePath(dataDir), "utf8");
61482
61629
  } catch {
61483
61630
  return {};
61484
61631
  }
@@ -61494,11 +61641,11 @@ function loadOwnerProfile(dataDir) {
61494
61641
  }
61495
61642
  function patchOwnerProfile(dataDir, patch) {
61496
61643
  const merged = { ...loadOwnerProfile(dataDir), ...patch };
61497
- import_node_fs45.default.writeFileSync(profilePath(dataDir), JSON.stringify(merged, null, 2), { encoding: "utf8", mode: 384 });
61644
+ import_node_fs46.default.writeFileSync(profilePath(dataDir), JSON.stringify(merged, null, 2), { encoding: "utf8", mode: 384 });
61498
61645
  return merged;
61499
61646
  }
61500
61647
  function loadOwnerDisplayName(dataDir) {
61501
- const fallback = import_node_os16.default.userInfo().username;
61648
+ const fallback = import_node_os17.default.userInfo().username;
61502
61649
  const displayName = loadOwnerProfile(dataDir).displayName;
61503
61650
  if (typeof displayName !== "string" || displayName.length === 0) {
61504
61651
  if (displayName !== void 0) {
@@ -61510,18 +61657,18 @@ function loadOwnerDisplayName(dataDir) {
61510
61657
  }
61511
61658
 
61512
61659
  // src/feishu-auth/owner-identity-store.ts
61513
- var import_node_fs46 = __toESM(require("fs"), 1);
61514
- var import_node_path55 = __toESM(require("path"), 1);
61660
+ var import_node_fs47 = __toESM(require("fs"), 1);
61661
+ var import_node_path56 = __toESM(require("path"), 1);
61515
61662
  var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
61516
61663
  var OwnerIdentityStore = class {
61517
61664
  file;
61518
61665
  constructor(dataDir) {
61519
- this.file = import_node_path55.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
61666
+ this.file = import_node_path56.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
61520
61667
  }
61521
61668
  read() {
61522
61669
  let raw;
61523
61670
  try {
61524
- raw = import_node_fs46.default.readFileSync(this.file, "utf8");
61671
+ raw = import_node_fs47.default.readFileSync(this.file, "utf8");
61525
61672
  } catch {
61526
61673
  return null;
61527
61674
  }
@@ -61549,16 +61696,16 @@ var OwnerIdentityStore = class {
61549
61696
  };
61550
61697
  }
61551
61698
  write(record3) {
61552
- import_node_fs46.default.mkdirSync(import_node_path55.default.dirname(this.file), { recursive: true });
61553
- import_node_fs46.default.writeFileSync(this.file, JSON.stringify(record3, null, 2), { mode: 384 });
61699
+ import_node_fs47.default.mkdirSync(import_node_path56.default.dirname(this.file), { recursive: true });
61700
+ import_node_fs47.default.writeFileSync(this.file, JSON.stringify(record3, null, 2), { mode: 384 });
61554
61701
  try {
61555
- import_node_fs46.default.chmodSync(this.file, 384);
61702
+ import_node_fs47.default.chmodSync(this.file, 384);
61556
61703
  } catch {
61557
61704
  }
61558
61705
  }
61559
61706
  clear() {
61560
61707
  try {
61561
- import_node_fs46.default.unlinkSync(this.file);
61708
+ import_node_fs47.default.unlinkSync(this.file);
61562
61709
  } catch (err) {
61563
61710
  const code = err?.code;
61564
61711
  if (code !== "ENOENT") throw err;
@@ -61695,9 +61842,9 @@ var CentralClientError = class extends Error {
61695
61842
  code;
61696
61843
  cause;
61697
61844
  };
61698
- async function centralRequest(opts, path97, init) {
61845
+ async function centralRequest(opts, path98, init) {
61699
61846
  const f = opts.fetchImpl ?? globalThis.fetch;
61700
- const url = `${opts.api.replace(/\/+$/, "")}${path97}`;
61847
+ const url = `${opts.api.replace(/\/+$/, "")}${path98}`;
61701
61848
  const ctrl = new AbortController();
61702
61849
  const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
61703
61850
  let res;
@@ -62168,8 +62315,8 @@ function verifyConnectToken(args) {
62168
62315
  }
62169
62316
 
62170
62317
  // src/feishu-auth/server-key.ts
62171
- var fs63 = __toESM(require("fs"), 1);
62172
- var path68 = __toESM(require("path"), 1);
62318
+ var fs64 = __toESM(require("fs"), 1);
62319
+ var path69 = __toESM(require("path"), 1);
62173
62320
  var FILE_NAME2 = "server-signing-key.json";
62174
62321
  var ServerKeyStore = class {
62175
62322
  constructor(dataDir) {
@@ -62177,12 +62324,12 @@ var ServerKeyStore = class {
62177
62324
  }
62178
62325
  dataDir;
62179
62326
  filePath() {
62180
- return path68.join(this.dataDir, FILE_NAME2);
62327
+ return path69.join(this.dataDir, FILE_NAME2);
62181
62328
  }
62182
62329
  /** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
62183
62330
  read() {
62184
62331
  try {
62185
- const raw = fs63.readFileSync(this.filePath(), "utf8");
62332
+ const raw = fs64.readFileSync(this.filePath(), "utf8");
62186
62333
  const parsed = JSON.parse(raw);
62187
62334
  if (typeof parsed.publicKeyPem === "string" && parsed.publicKeyPem.includes("PUBLIC KEY")) {
62188
62335
  return parsed.publicKeyPem;
@@ -62197,12 +62344,12 @@ var ServerKeyStore = class {
62197
62344
  publicKeyPem,
62198
62345
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
62199
62346
  };
62200
- fs63.mkdirSync(this.dataDir, { recursive: true });
62201
- fs63.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
62347
+ fs64.mkdirSync(this.dataDir, { recursive: true });
62348
+ fs64.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
62202
62349
  }
62203
62350
  clear() {
62204
62351
  try {
62205
- fs63.unlinkSync(this.filePath());
62352
+ fs64.unlinkSync(this.filePath());
62206
62353
  } catch {
62207
62354
  }
62208
62355
  }
@@ -62212,19 +62359,19 @@ var ServerKeyStore = class {
62212
62359
  init_protocol();
62213
62360
 
62214
62361
  // src/handlers/index.ts
62215
- var import_node_path71 = __toESM(require("path"), 1);
62362
+ var import_node_path72 = __toESM(require("path"), 1);
62216
62363
 
62217
62364
  // src/handlers/session.ts
62218
62365
  init_protocol();
62219
62366
 
62220
62367
  // src/session/fork.ts
62221
- var import_node_fs47 = __toESM(require("fs"), 1);
62222
- var import_node_os17 = __toESM(require("os"), 1);
62223
- var import_node_path56 = __toESM(require("path"), 1);
62368
+ var import_node_fs48 = __toESM(require("fs"), 1);
62369
+ var import_node_os18 = __toESM(require("os"), 1);
62370
+ var import_node_path57 = __toESM(require("path"), 1);
62224
62371
  var import_node_crypto16 = require("crypto");
62225
62372
  init_claude_history();
62226
62373
  function readJsonlEntries(file) {
62227
- const raw = import_node_fs47.default.readFileSync(file, "utf8");
62374
+ const raw = import_node_fs48.default.readFileSync(file, "utf8");
62228
62375
  const out = [];
62229
62376
  for (const line of raw.split("\n")) {
62230
62377
  const t = line.trim();
@@ -62237,19 +62384,19 @@ function readJsonlEntries(file) {
62237
62384
  return out;
62238
62385
  }
62239
62386
  function forkSession(input) {
62240
- const baseDir = input.baseDir ?? import_node_path56.default.join(import_node_os17.default.homedir(), ".claude");
62241
- let projectDir = import_node_path56.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
62242
- let sourceFile = import_node_path56.default.join(projectDir, `${input.toolSessionId}.jsonl`);
62243
- if (!import_node_fs47.default.existsSync(sourceFile)) {
62387
+ const baseDir = input.baseDir ?? import_node_path57.default.join(import_node_os18.default.homedir(), ".claude");
62388
+ let projectDir = import_node_path57.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
62389
+ let sourceFile = import_node_path57.default.join(projectDir, `${input.toolSessionId}.jsonl`);
62390
+ if (!import_node_fs48.default.existsSync(sourceFile)) {
62244
62391
  const found = findTranscriptByToolSessionId(
62245
- import_node_path56.default.join(baseDir, "projects"),
62392
+ import_node_path57.default.join(baseDir, "projects"),
62246
62393
  input.toolSessionId
62247
62394
  );
62248
62395
  if (!found) {
62249
62396
  throw new Error(`fork: source transcript not found: ${sourceFile}`);
62250
62397
  }
62251
62398
  sourceFile = found;
62252
- projectDir = import_node_path56.default.dirname(found);
62399
+ projectDir = import_node_path57.default.dirname(found);
62253
62400
  }
62254
62401
  const entries = readJsonlEntries(sourceFile);
62255
62402
  const mainEntries = entries.filter((e) => e.isSidechain !== true);
@@ -62278,27 +62425,27 @@ function forkSession(input) {
62278
62425
  }
62279
62426
  forkedLines.push(JSON.stringify(forked));
62280
62427
  }
62281
- const outDir = input.targetCwd ? import_node_path56.default.join(baseDir, "projects", cwdToHashDir(input.targetCwd)) : projectDir;
62282
- const forkedFilePath = import_node_path56.default.join(outDir, `${forkedToolSessionId}.jsonl`);
62283
- import_node_fs47.default.mkdirSync(outDir, { recursive: true });
62284
- import_node_fs47.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
62428
+ const outDir = input.targetCwd ? import_node_path57.default.join(baseDir, "projects", cwdToHashDir(input.targetCwd)) : projectDir;
62429
+ const forkedFilePath = import_node_path57.default.join(outDir, `${forkedToolSessionId}.jsonl`);
62430
+ import_node_fs48.default.mkdirSync(outDir, { recursive: true });
62431
+ import_node_fs48.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
62285
62432
  return { forkedToolSessionId, forkedFilePath };
62286
62433
  }
62287
62434
 
62288
62435
  // src/session/external-scan.ts
62289
- var import_node_fs48 = __toESM(require("fs"), 1);
62436
+ var import_node_fs49 = __toESM(require("fs"), 1);
62290
62437
  var import_promises10 = __toESM(require("fs/promises"), 1);
62291
- var import_node_os18 = __toESM(require("os"), 1);
62292
- var import_node_path57 = __toESM(require("path"), 1);
62438
+ var import_node_os19 = __toESM(require("os"), 1);
62439
+ var import_node_path58 = __toESM(require("path"), 1);
62293
62440
  var import_node_module = require("module");
62294
62441
  var import_node_child_process13 = require("child_process");
62295
62442
  var import_meta5 = {};
62296
62443
  function defaultRoots() {
62297
- const home = import_node_os18.default.homedir();
62444
+ const home = import_node_os19.default.homedir();
62298
62445
  return {
62299
- claudeProjectsDir: import_node_path57.default.join(home, ".claude", "projects"),
62300
- codexDir: import_node_path57.default.join(home, ".codex"),
62301
- clawdDir: import_node_path57.default.join(home, ".clawd")
62446
+ claudeProjectsDir: import_node_path58.default.join(home, ".claude", "projects"),
62447
+ codexDir: import_node_path58.default.join(home, ".codex"),
62448
+ clawdDir: import_node_path58.default.join(home, ".clawd")
62302
62449
  };
62303
62450
  }
62304
62451
  function width(s) {
@@ -62349,7 +62496,7 @@ function userText(msg) {
62349
62496
  }
62350
62497
  function isDir2(p2) {
62351
62498
  try {
62352
- return import_node_fs48.default.statSync(p2).isDirectory();
62499
+ return import_node_fs49.default.statSync(p2).isDirectory();
62353
62500
  } catch {
62354
62501
  return false;
62355
62502
  }
@@ -62358,7 +62505,7 @@ async function scanClaude(roots) {
62358
62505
  const out = [];
62359
62506
  let dirs;
62360
62507
  try {
62361
- dirs = import_node_fs48.default.readdirSync(roots.claudeProjectsDir, { withFileTypes: true });
62508
+ dirs = import_node_fs49.default.readdirSync(roots.claudeProjectsDir, { withFileTypes: true });
62362
62509
  } catch {
62363
62510
  return out;
62364
62511
  }
@@ -62366,16 +62513,16 @@ async function scanClaude(roots) {
62366
62513
  if (!d.isDirectory()) continue;
62367
62514
  let files;
62368
62515
  try {
62369
- files = import_node_fs48.default.readdirSync(import_node_path57.default.join(roots.claudeProjectsDir, d.name));
62516
+ files = import_node_fs49.default.readdirSync(import_node_path58.default.join(roots.claudeProjectsDir, d.name));
62370
62517
  } catch {
62371
62518
  continue;
62372
62519
  }
62373
62520
  for (const name of files) {
62374
62521
  if (!name.endsWith(".jsonl")) continue;
62375
- const file = import_node_path57.default.join(roots.claudeProjectsDir, d.name, name);
62522
+ const file = import_node_path58.default.join(roots.claudeProjectsDir, d.name, name);
62376
62523
  let st;
62377
62524
  try {
62378
- st = import_node_fs48.default.statSync(file);
62525
+ st = import_node_fs49.default.statSync(file);
62379
62526
  } catch {
62380
62527
  continue;
62381
62528
  }
@@ -62428,7 +62575,7 @@ async function scanClaude(roots) {
62428
62575
  return out;
62429
62576
  }
62430
62577
  async function countCodexTurns(rolloutPath) {
62431
- if (!rolloutPath || !import_node_fs48.default.existsSync(rolloutPath)) return { turns: 0, first: "" };
62578
+ if (!rolloutPath || !import_node_fs49.default.existsSync(rolloutPath)) return { turns: 0, first: "" };
62432
62579
  let turns = 0;
62433
62580
  let first = "";
62434
62581
  for await (const rec4 of jsonLines(rolloutPath)) {
@@ -62502,7 +62649,7 @@ async function codexFromRows(rows) {
62502
62649
  async function scanCodex(roots) {
62503
62650
  let dbs = [];
62504
62651
  try {
62505
- dbs = import_node_fs48.default.readdirSync(roots.codexDir).filter((n) => /^state_.*\.sqlite$/.test(n)).sort().map((n) => import_node_path57.default.join(roots.codexDir, n));
62652
+ dbs = import_node_fs49.default.readdirSync(roots.codexDir).filter((n) => /^state_.*\.sqlite$/.test(n)).sort().map((n) => import_node_path58.default.join(roots.codexDir, n));
62506
62653
  } catch {
62507
62654
  }
62508
62655
  if (!dbs.length) return [];
@@ -62511,14 +62658,14 @@ async function scanCodex(roots) {
62511
62658
  }
62512
62659
  async function scanExternalSessions(rootsIn) {
62513
62660
  const roots = { ...defaultRoots(), ...rootsIn };
62514
- const personaRoot = import_node_path57.default.join(roots.clawdDir, "personas");
62661
+ const personaRoot = import_node_path58.default.join(roots.clawdDir, "personas");
62515
62662
  const all = [...await scanClaude(roots), ...await scanCodex(roots)];
62516
62663
  const out = [];
62517
62664
  for (const c of all) {
62518
62665
  if (c.skip) continue;
62519
62666
  if (c.turns < 1) continue;
62520
62667
  if (!c.cwd || !isDir2(c.cwd)) continue;
62521
- if (c.cwd === roots.clawdDir || c.cwd === personaRoot || c.cwd.startsWith(personaRoot + import_node_path57.default.sep) || c.cwd.startsWith(roots.clawdDir + import_node_path57.default.sep)) {
62668
+ if (c.cwd === roots.clawdDir || c.cwd === personaRoot || c.cwd.startsWith(personaRoot + import_node_path58.default.sep) || c.cwd.startsWith(roots.clawdDir + import_node_path58.default.sep)) {
62522
62669
  continue;
62523
62670
  }
62524
62671
  out.push({
@@ -62535,13 +62682,13 @@ async function scanExternalSessions(rootsIn) {
62535
62682
  }
62536
62683
 
62537
62684
  // src/session/import-ledger.ts
62538
- var import_node_fs49 = __toESM(require("fs"), 1);
62539
- var import_node_path58 = __toESM(require("path"), 1);
62685
+ var import_node_fs50 = __toESM(require("fs"), 1);
62686
+ var import_node_path59 = __toESM(require("path"), 1);
62540
62687
  var LEDGER_FILENAME = "session-import-ledger.json";
62541
62688
  function readImportLedger(dataDir) {
62542
62689
  try {
62543
62690
  const parsed = JSON.parse(
62544
- import_node_fs49.default.readFileSync(import_node_path58.default.join(dataDir, LEDGER_FILENAME), "utf8")
62691
+ import_node_fs50.default.readFileSync(import_node_path59.default.join(dataDir, LEDGER_FILENAME), "utf8")
62545
62692
  );
62546
62693
  return Array.isArray(parsed) ? parsed : [];
62547
62694
  } catch {
@@ -62549,26 +62696,26 @@ function readImportLedger(dataDir) {
62549
62696
  }
62550
62697
  }
62551
62698
  function appendImportLedger(dataDir, entry) {
62552
- const file = import_node_path58.default.join(dataDir, LEDGER_FILENAME);
62699
+ const file = import_node_path59.default.join(dataDir, LEDGER_FILENAME);
62553
62700
  const entries = readImportLedger(dataDir);
62554
62701
  entries.push(entry);
62555
- import_node_fs49.default.writeFileSync(file, JSON.stringify(entries, null, 2), { encoding: "utf8", mode: 384 });
62702
+ import_node_fs50.default.writeFileSync(file, JSON.stringify(entries, null, 2), { encoding: "utf8", mode: 384 });
62556
62703
  }
62557
62704
 
62558
62705
  // src/tools/transcript-search.ts
62559
- var import_node_fs50 = __toESM(require("fs"), 1);
62560
- var import_node_path59 = __toESM(require("path"), 1);
62706
+ var import_node_fs51 = __toESM(require("fs"), 1);
62707
+ var import_node_path60 = __toESM(require("path"), 1);
62561
62708
  var SNIPPET_PAD = 60;
62562
62709
  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/;
62563
62710
  var CODEX_WRAPPER_RE = /<(related-dir|environment_context|user_instructions)>[\s\S]*?<\/\1>/g;
62564
- function asRecord(v2) {
62711
+ function asRecord2(v2) {
62565
62712
  return typeof v2 === "object" && v2 !== null ? v2 : null;
62566
62713
  }
62567
62714
  function textOfBlocks(content, types) {
62568
62715
  if (!Array.isArray(content)) return null;
62569
62716
  const parts = [];
62570
62717
  for (const block of content) {
62571
- const b2 = asRecord(block);
62718
+ const b2 = asRecord2(block);
62572
62719
  if (!b2 || typeof b2.type !== "string" || !types.includes(b2.type)) continue;
62573
62720
  const text = b2.text;
62574
62721
  if (typeof text === "string" && text !== "") parts.push(text);
@@ -62576,10 +62723,10 @@ function textOfBlocks(content, types) {
62576
62723
  return parts.length > 0 ? parts.join("\n") : null;
62577
62724
  }
62578
62725
  function lineToSearchableText(raw) {
62579
- const line = asRecord(raw);
62726
+ const line = asRecord2(raw);
62580
62727
  if (!line) return null;
62581
62728
  if (line.type === "response_item") {
62582
- const payload = asRecord(line.payload);
62729
+ const payload = asRecord2(line.payload);
62583
62730
  if (!payload || payload.type !== "message") return null;
62584
62731
  const role = payload.role;
62585
62732
  if (role !== "user" && role !== "assistant") return null;
@@ -62591,7 +62738,7 @@ function lineToSearchableText(raw) {
62591
62738
  return INJECTED_ENVELOPE_RE.test(stripped) ? null : stripped;
62592
62739
  }
62593
62740
  if (line.type !== "user" && line.type !== "assistant") return null;
62594
- const message = asRecord(line.message);
62741
+ const message = asRecord2(line.message);
62595
62742
  if (!message) return null;
62596
62743
  const content = message.content;
62597
62744
  const text = typeof content === "string" && content !== "" ? content : textOfBlocks(content, ["text"]);
@@ -62612,7 +62759,7 @@ function makeSnippet(text, at2, needleLength) {
62612
62759
  function searchTranscriptFile(file, query) {
62613
62760
  let buf;
62614
62761
  try {
62615
- buf = import_node_fs50.default.readFileSync(file);
62762
+ buf = import_node_fs51.default.readFileSync(file);
62616
62763
  } catch {
62617
62764
  return null;
62618
62765
  }
@@ -62645,12 +62792,12 @@ function createCodexRolloutLocator(roots) {
62645
62792
  const walk2 = (dir, into) => {
62646
62793
  let entries;
62647
62794
  try {
62648
- entries = import_node_fs50.default.readdirSync(dir, { withFileTypes: true });
62795
+ entries = import_node_fs51.default.readdirSync(dir, { withFileTypes: true });
62649
62796
  } catch {
62650
62797
  return;
62651
62798
  }
62652
62799
  for (const entry of entries) {
62653
- const full = import_node_path59.default.join(dir, entry.name);
62800
+ const full = import_node_path60.default.join(dir, entry.name);
62654
62801
  if (entry.isDirectory()) {
62655
62802
  walk2(full, into);
62656
62803
  continue;
@@ -62670,16 +62817,16 @@ function createCodexRolloutLocator(roots) {
62670
62817
 
62671
62818
  // src/handlers/session.ts
62672
62819
  init_protocol();
62673
- var import_node_os19 = __toESM(require("os"), 1);
62674
- var import_node_path60 = __toESM(require("path"), 1);
62820
+ var import_node_os20 = __toESM(require("os"), 1);
62821
+ var import_node_path61 = __toESM(require("path"), 1);
62675
62822
  function canReadSearchHit(ctx, file) {
62676
62823
  if (!ctx || ctx.principal.kind === "owner") return true;
62677
62824
  return canAccessPersona(ctx.grants, file.ownerPersonaId, "read") && file.creatorPrincipalId === ctx.principal.id;
62678
62825
  }
62679
62826
  var DEFAULT_SEARCH_LIMIT = 9;
62680
62827
  function codexRolloutRoots(dataDir) {
62681
- const roots = [import_node_path60.default.join(import_node_os19.default.homedir(), ".codex", "sessions")];
62682
- if (dataDir) roots.push(import_node_path60.default.join(dataDir, "codex-home", "sessions"));
62828
+ const roots = [import_node_path61.default.join(import_node_os20.default.homedir(), ".codex", "sessions")];
62829
+ if (dataDir) roots.push(import_node_path61.default.join(dataDir, "codex-home", "sessions"));
62683
62830
  return roots;
62684
62831
  }
62685
62832
  function buildSessionHandlers(deps) {
@@ -63228,7 +63375,7 @@ function buildPermissionHandlers(deps) {
63228
63375
  }
63229
63376
 
63230
63377
  // src/handlers/history.ts
63231
- var path75 = __toESM(require("path"), 1);
63378
+ var path76 = __toESM(require("path"), 1);
63232
63379
  init_protocol();
63233
63380
 
63234
63381
  // src/session/recent-dirs.ts
@@ -63246,7 +63393,7 @@ function listRecentDirs(store, limit = 50) {
63246
63393
  }
63247
63394
 
63248
63395
  // src/permission/persona-paths.ts
63249
- var path74 = __toESM(require("path"), 1);
63396
+ var path75 = __toESM(require("path"), 1);
63250
63397
  function getAllowedPersonaIds(grants, action) {
63251
63398
  const ids = /* @__PURE__ */ new Set();
63252
63399
  for (const g2 of grants) {
@@ -63259,42 +63406,42 @@ function getAllowedPersonaIds(grants, action) {
63259
63406
  return ids;
63260
63407
  }
63261
63408
  function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
63262
- const target = path74.resolve(absPath);
63409
+ const target = path75.resolve(absPath);
63263
63410
  if (userWorkDir) {
63264
- const u = path74.resolve(userWorkDir);
63265
- const usep = u.endsWith(path74.sep) ? "" : path74.sep;
63411
+ const u = path75.resolve(userWorkDir);
63412
+ const usep = u.endsWith(path75.sep) ? "" : path75.sep;
63266
63413
  if (target === u || target.startsWith(u + usep)) return true;
63267
63414
  }
63268
- const root = path74.resolve(personaRoot);
63269
- const sep4 = root.endsWith(path74.sep) ? "" : path74.sep;
63415
+ const root = path75.resolve(personaRoot);
63416
+ const sep4 = root.endsWith(path75.sep) ? "" : path75.sep;
63270
63417
  if (!target.startsWith(root + sep4)) return false;
63271
- const rel = path74.relative(root, target);
63418
+ const rel = path75.relative(root, target);
63272
63419
  if (!rel || rel.startsWith("..")) return false;
63273
- const personaId2 = rel.split(path74.sep)[0];
63420
+ const personaId2 = rel.split(path75.sep)[0];
63274
63421
  if (!personaId2) return false;
63275
63422
  const allowed = getAllowedPersonaIds(grants, action);
63276
63423
  if (allowed === "*") return true;
63277
63424
  return allowed.has(personaId2);
63278
63425
  }
63279
63426
  function personaIdFromPath(absPath, personaRoot) {
63280
- const root = path74.resolve(personaRoot);
63281
- const target = path74.resolve(absPath);
63282
- const sep4 = root.endsWith(path74.sep) ? "" : path74.sep;
63427
+ const root = path75.resolve(personaRoot);
63428
+ const target = path75.resolve(absPath);
63429
+ const sep4 = root.endsWith(path75.sep) ? "" : path75.sep;
63283
63430
  if (!target.startsWith(root + sep4)) return null;
63284
- const rel = path74.relative(root, target);
63431
+ const rel = path75.relative(root, target);
63285
63432
  if (!rel || rel.startsWith("..")) return null;
63286
- const id = rel.split(path74.sep)[0];
63433
+ const id = rel.split(path75.sep)[0];
63287
63434
  return id || null;
63288
63435
  }
63289
63436
  function isPathWithin(dir, absPath) {
63290
- const d = path74.resolve(dir);
63291
- const t = path74.resolve(absPath);
63292
- const sep4 = d.endsWith(path74.sep) ? "" : path74.sep;
63437
+ const d = path75.resolve(dir);
63438
+ const t = path75.resolve(absPath);
63439
+ const sep4 = d.endsWith(path75.sep) ? "" : path75.sep;
63293
63440
  return t === d || t.startsWith(d + sep4);
63294
63441
  }
63295
63442
  function isPathInGuestBoundary(personaRoot, personaId2, userWorkDir, absPath) {
63296
63443
  if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
63297
- return personaIdFromPath(path74.resolve(absPath), personaRoot) === personaId2;
63444
+ return personaIdFromPath(path75.resolve(absPath), personaRoot) === personaId2;
63298
63445
  }
63299
63446
 
63300
63447
  // src/handlers/history.ts
@@ -63347,7 +63494,7 @@ function buildHistoryHandlers(deps) {
63347
63494
  if (!pid) return false;
63348
63495
  return isGuestPathAllowed(
63349
63496
  ctx.grants,
63350
- path75.join(personaRoot, pid),
63497
+ path76.join(personaRoot, pid),
63351
63498
  personaRoot,
63352
63499
  "read",
63353
63500
  userWorkDir
@@ -63359,7 +63506,7 @@ function buildHistoryHandlers(deps) {
63359
63506
  };
63360
63507
  const list = async (frame, _client, ctx) => {
63361
63508
  const args = HistoryListArgs.parse(frame);
63362
- assertGuestPath(ctx, path75.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
63509
+ assertGuestPath(ctx, path76.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
63363
63510
  const sessions = await history.listSessions(args);
63364
63511
  return { response: { type: "history:list", sessions } };
63365
63512
  };
@@ -63407,14 +63554,14 @@ function buildHistoryHandlers(deps) {
63407
63554
  };
63408
63555
  const subagents = async (frame, _client, ctx) => {
63409
63556
  const args = HistorySubagentsArgs.parse(frame);
63410
- assertGuestPath(ctx, path75.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
63557
+ assertGuestPath(ctx, path76.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
63411
63558
  assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagents");
63412
63559
  const subs = await historyReaderForToolSession(args.toolSessionId).listSubagents(args);
63413
63560
  return { response: { type: "history:subagents", subagents: subs } };
63414
63561
  };
63415
63562
  const subagentRead = async (frame, _client, ctx) => {
63416
63563
  const args = HistorySubagentReadArgs.parse(frame);
63417
- assertGuestPath(ctx, path75.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
63564
+ assertGuestPath(ctx, path76.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
63418
63565
  assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagent-read");
63419
63566
  const res = await historyReaderForToolSession(args.toolSessionId).readSubagent(args);
63420
63567
  return { response: { type: "history:subagent-read", ...res } };
@@ -63424,7 +63571,7 @@ function buildHistoryHandlers(deps) {
63424
63571
  if (ctx?.principal.kind === "guest" && personaRoot) {
63425
63572
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
63426
63573
  const filtered = dirs.filter(
63427
- (d) => isGuestPathAllowed(ctx.grants, path75.resolve(d.cwd), personaRoot, "read", userWorkDir)
63574
+ (d) => isGuestPathAllowed(ctx.grants, path76.resolve(d.cwd), personaRoot, "read", userWorkDir)
63428
63575
  );
63429
63576
  return { response: { type: "history:recentDirs", dirs: filtered } };
63430
63577
  }
@@ -63441,17 +63588,17 @@ function buildHistoryHandlers(deps) {
63441
63588
  }
63442
63589
 
63443
63590
  // src/handlers/projects.ts
63444
- var fs68 = __toESM(require("fs"), 1);
63445
- var os21 = __toESM(require("os"), 1);
63446
- var path76 = __toESM(require("path"), 1);
63591
+ var fs69 = __toESM(require("fs"), 1);
63592
+ var os22 = __toESM(require("os"), 1);
63593
+ var path77 = __toESM(require("path"), 1);
63447
63594
  var import_node_child_process14 = require("child_process");
63448
63595
  init_protocol();
63449
- var DEFAULT_PROJECTS_ROOT = path76.join(os21.homedir(), "Documents", "ChatGPT");
63596
+ var DEFAULT_PROJECTS_ROOT = path77.join(os22.homedir(), "Documents", "ChatGPT");
63450
63597
  function allocateDir(root, name) {
63451
- let candidate = path76.join(root, name);
63598
+ let candidate = path77.join(root, name);
63452
63599
  let n = 2;
63453
- while (fs68.existsSync(candidate)) {
63454
- candidate = path76.join(root, `${name} ${n}`);
63600
+ while (fs69.existsSync(candidate)) {
63601
+ candidate = path77.join(root, `${name} ${n}`);
63455
63602
  n += 1;
63456
63603
  }
63457
63604
  return candidate;
@@ -63479,7 +63626,7 @@ function buildProjectHandlers(deps) {
63479
63626
  throw new ClawdError(ERROR_CODES.INVALID_CWD, "project:reveal \u4EC5\u652F\u6301 macOS");
63480
63627
  }
63481
63628
  try {
63482
- if (!fs68.statSync(args.path).isDirectory()) throw new Error("not dir");
63629
+ if (!fs69.statSync(args.path).isDirectory()) throw new Error("not dir");
63483
63630
  } catch {
63484
63631
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
63485
63632
  }
@@ -63495,7 +63642,7 @@ function buildProjectHandlers(deps) {
63495
63642
  let target;
63496
63643
  if (args.path) {
63497
63644
  try {
63498
- if (!fs68.statSync(args.path).isDirectory()) throw new Error("not dir");
63645
+ if (!fs69.statSync(args.path).isDirectory()) throw new Error("not dir");
63499
63646
  } catch {
63500
63647
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
63501
63648
  }
@@ -63503,15 +63650,15 @@ function buildProjectHandlers(deps) {
63503
63650
  } else {
63504
63651
  const name = args.name;
63505
63652
  try {
63506
- fs68.mkdirSync(root, { recursive: true });
63653
+ fs69.mkdirSync(root, { recursive: true });
63507
63654
  target = allocateDir(root, name);
63508
- fs68.mkdirSync(target);
63655
+ fs69.mkdirSync(target);
63509
63656
  } catch (err) {
63510
63657
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `\u521B\u5EFA\u9879\u76EE\u76EE\u5F55\u5931\u8D25: ${String(err)}`);
63511
63658
  }
63512
63659
  const git2 = (0, import_node_child_process14.spawnSync)("git", ["init"], { cwd: target, stdio: "ignore" });
63513
63660
  if (git2.status !== 0) {
63514
- fs68.rmSync(target, { recursive: true, force: true });
63661
+ fs69.rmSync(target, { recursive: true, force: true });
63515
63662
  throw new ClawdError(
63516
63663
  ERROR_CODES.INVALID_CWD,
63517
63664
  `git init \u5931\u8D25\uFF08${git2.error ? String(git2.error) : `exit ${git2.status}`}\uFF09: ${target}`
@@ -63536,8 +63683,8 @@ function buildProjectHandlers(deps) {
63536
63683
  }
63537
63684
 
63538
63685
  // src/handlers/workspace.ts
63539
- var path77 = __toESM(require("path"), 1);
63540
- var os22 = __toESM(require("os"), 1);
63686
+ var path78 = __toESM(require("path"), 1);
63687
+ var os23 = __toESM(require("os"), 1);
63541
63688
  init_protocol();
63542
63689
  init_protocol();
63543
63690
  function buildEnabledPluginNames(personaManager, personaId2) {
@@ -63577,23 +63724,23 @@ function buildWorkspaceHandlers(deps) {
63577
63724
  const list = async (frame, _client, ctx) => {
63578
63725
  const args = WorkspaceListArgs.parse(frame);
63579
63726
  const isGuest = ctx?.principal.kind === "guest";
63580
- const fallbackCwd = isGuest && personaRoot ? personaRoot : os22.homedir();
63581
- const resolvedCwd = path77.resolve(args.cwd ?? fallbackCwd);
63582
- const target = args.path ? path77.resolve(resolvedCwd, args.path) : resolvedCwd;
63727
+ const fallbackCwd = isGuest && personaRoot ? personaRoot : os23.homedir();
63728
+ const resolvedCwd = path78.resolve(args.cwd ?? fallbackCwd);
63729
+ const target = args.path ? path78.resolve(resolvedCwd, args.path) : resolvedCwd;
63583
63730
  assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
63584
63731
  const res = workspace.list({ ...args, cwd: resolvedCwd });
63585
63732
  return { response: { type: "workspace:list", ...res } };
63586
63733
  };
63587
63734
  const read = async (frame, _client, ctx) => {
63588
63735
  const args = WorkspaceReadArgs.parse(frame);
63589
- const target = path77.isAbsolute(args.path) ? path77.resolve(args.path) : path77.resolve(args.cwd, args.path);
63736
+ const target = path78.isAbsolute(args.path) ? path78.resolve(args.path) : path78.resolve(args.cwd, args.path);
63590
63737
  assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
63591
63738
  const res = workspace.read(args);
63592
63739
  return { response: { type: "workspace:read", ...res } };
63593
63740
  };
63594
63741
  const skillsList = async (frame, _client, ctx) => {
63595
63742
  const args = SkillsListArgs.parse(frame);
63596
- const cwdAbs = path77.resolve(args.cwd);
63743
+ const cwdAbs = path78.resolve(args.cwd);
63597
63744
  assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
63598
63745
  const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
63599
63746
  if (ctx?.principal.kind === "guest" && personaRoot) {
@@ -63605,7 +63752,7 @@ function buildWorkspaceHandlers(deps) {
63605
63752
  };
63606
63753
  const agentsList = async (frame, _client, ctx) => {
63607
63754
  const args = AgentsListArgs.parse(frame);
63608
- const cwdAbs = path77.resolve(args.cwd);
63755
+ const cwdAbs = path78.resolve(args.cwd);
63609
63756
  assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
63610
63757
  if (args.tool === "codex") {
63611
63758
  return { response: { type: "agents:list", agents: [] } };
@@ -63627,20 +63774,20 @@ function buildWorkspaceHandlers(deps) {
63627
63774
  }
63628
63775
 
63629
63776
  // src/handlers/git.ts
63630
- var path79 = __toESM(require("path"), 1);
63777
+ var path80 = __toESM(require("path"), 1);
63631
63778
  init_protocol();
63632
63779
  init_protocol();
63633
63780
 
63634
63781
  // src/workspace/git.ts
63635
63782
  var import_node_child_process15 = require("child_process");
63636
- var import_node_fs51 = __toESM(require("fs"), 1);
63637
- var import_node_path61 = __toESM(require("path"), 1);
63783
+ var import_node_fs52 = __toESM(require("fs"), 1);
63784
+ var import_node_path62 = __toESM(require("path"), 1);
63638
63785
  var import_node_util = require("util");
63639
63786
  var pexec = (0, import_node_util.promisify)(import_node_child_process15.execFile);
63640
63787
  function normalizePath(p2) {
63641
- const resolved = import_node_path61.default.resolve(p2);
63788
+ const resolved = import_node_path62.default.resolve(p2);
63642
63789
  try {
63643
- return import_node_fs51.default.realpathSync(resolved);
63790
+ return import_node_fs52.default.realpathSync(resolved);
63644
63791
  } catch {
63645
63792
  return resolved;
63646
63793
  }
@@ -63714,7 +63861,7 @@ async function listGitBranches(cwd) {
63714
63861
  function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
63715
63862
  if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
63716
63863
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
63717
- if (!isGuestPathAllowed(ctx.grants, path79.resolve(cwd), personaRoot, "read", userWorkDir)) {
63864
+ if (!isGuestPathAllowed(ctx.grants, path80.resolve(cwd), personaRoot, "read", userWorkDir)) {
63718
63865
  throw new ClawdError(
63719
63866
  ERROR_CODES.UNAUTHORIZED,
63720
63867
  `guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
@@ -64284,7 +64431,7 @@ function buildFeishuAuthHandlers(deps) {
64284
64431
  }
64285
64432
 
64286
64433
  // src/handlers/meta.ts
64287
- var import_node_os20 = __toESM(require("os"), 1);
64434
+ var import_node_os21 = __toESM(require("os"), 1);
64288
64435
  init_protocol();
64289
64436
 
64290
64437
  // src/handlers/method-grants.ts
@@ -64587,21 +64734,21 @@ function computeMethodAccess(args) {
64587
64734
  }
64588
64735
 
64589
64736
  // src/version.ts
64590
- var version = "0.2.485".length > 0 ? "0.2.485" : "dev";
64737
+ var version = "0.2.487".length > 0 ? "0.2.487" : "dev";
64591
64738
 
64592
64739
  // src/cli-probe/probe.ts
64593
- var fs70 = __toESM(require("fs"), 1);
64594
- var path80 = __toESM(require("path"), 1);
64740
+ var fs71 = __toESM(require("fs"), 1);
64741
+ var path81 = __toESM(require("path"), 1);
64595
64742
  var PKG_NAME = "@clawos-dev/clawd";
64596
64743
  var BIN_NAME = "clawd";
64597
64744
  var MAX_PARENT_HOPS = 5;
64598
64745
  function probeGlobalCli(pathEnv) {
64599
64746
  if (!pathEnv) return null;
64600
- for (const dir of pathEnv.split(path80.delimiter)) {
64747
+ for (const dir of pathEnv.split(path81.delimiter)) {
64601
64748
  if (!dir) continue;
64602
64749
  let real;
64603
64750
  try {
64604
- real = fs70.realpathSync(path80.join(dir, BIN_NAME));
64751
+ real = fs71.realpathSync(path81.join(dir, BIN_NAME));
64605
64752
  } catch {
64606
64753
  continue;
64607
64754
  }
@@ -64611,15 +64758,15 @@ function probeGlobalCli(pathEnv) {
64611
64758
  return null;
64612
64759
  }
64613
64760
  function readOwnPackageVersion(entryPath) {
64614
- let dir = path80.dirname(entryPath);
64761
+ let dir = path81.dirname(entryPath);
64615
64762
  for (let i = 0; i < MAX_PARENT_HOPS; i++) {
64616
64763
  try {
64617
- const raw = fs70.readFileSync(path80.join(dir, "package.json"), "utf8");
64764
+ const raw = fs71.readFileSync(path81.join(dir, "package.json"), "utf8");
64618
64765
  const pkg = JSON.parse(raw);
64619
64766
  if (pkg.name !== PKG_NAME) return null;
64620
64767
  return typeof pkg.version === "string" && pkg.version ? pkg.version : null;
64621
64768
  } catch {
64622
- const parent = path80.dirname(dir);
64769
+ const parent = path81.dirname(dir);
64623
64770
  if (parent === dir) return null;
64624
64771
  dir = parent;
64625
64772
  }
@@ -64655,7 +64802,7 @@ function buildReadyFrame(deps, client) {
64655
64802
  return {
64656
64803
  version,
64657
64804
  protocolVersion: PROTOCOL_VERSION,
64658
- hostname: import_node_os20.default.hostname(),
64805
+ hostname: import_node_os21.default.hostname(),
64659
64806
  os: process.platform,
64660
64807
  tools,
64661
64808
  runningSessions: info.runningSessions,
@@ -64791,7 +64938,7 @@ function buildPersonaHandlers(deps) {
64791
64938
  }
64792
64939
 
64793
64940
  // src/handlers/attachment.ts
64794
- var import_node_path62 = __toESM(require("path"), 1);
64941
+ var import_node_path63 = __toESM(require("path"), 1);
64795
64942
  init_protocol();
64796
64943
  init_protocol();
64797
64944
  var DEFAULT_TTL_SECONDS = 24 * 3600;
@@ -64871,12 +65018,12 @@ function buildAttachmentHandlers(deps) {
64871
65018
  `session ${args.sessionId} scope unresolved`
64872
65019
  );
64873
65020
  }
64874
- const cwdAbs = import_node_path62.default.resolve(sessionFile.cwd);
64875
- const candidateAbs = import_node_path62.default.isAbsolute(args.relPath) ? import_node_path62.default.resolve(args.relPath) : import_node_path62.default.resolve(cwdAbs, args.relPath);
65021
+ const cwdAbs = import_node_path63.default.resolve(sessionFile.cwd);
65022
+ const candidateAbs = import_node_path63.default.isAbsolute(args.relPath) ? import_node_path63.default.resolve(args.relPath) : import_node_path63.default.resolve(cwdAbs, args.relPath);
64876
65023
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
64877
65024
  const entries = deps.groupFileStore.list(scope, args.sessionId);
64878
65025
  const entry = entries.find((e) => {
64879
- const storedAbs = import_node_path62.default.isAbsolute(e.relPath) ? import_node_path62.default.resolve(e.relPath) : import_node_path62.default.resolve(cwdAbs, e.relPath);
65026
+ const storedAbs = import_node_path63.default.isAbsolute(e.relPath) ? import_node_path63.default.resolve(e.relPath) : import_node_path63.default.resolve(cwdAbs, e.relPath);
64880
65027
  return storedAbs === candidateAbs && !e.stale;
64881
65028
  });
64882
65029
  if (!entry) {
@@ -64901,7 +65048,7 @@ function buildAttachmentHandlers(deps) {
64901
65048
  if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
64902
65049
  const f = deps.sessionStore.read(sessionId);
64903
65050
  if (!f) return;
64904
- assertGuestAttachmentPath(ctx, import_node_path62.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
65051
+ assertGuestAttachmentPath(ctx, import_node_path63.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
64905
65052
  }
64906
65053
  const groupAdd = async (frame, _client, ctx) => {
64907
65054
  if (!deps.groupFileStore || !deps.getSessionScope) {
@@ -64916,8 +65063,8 @@ function buildAttachmentHandlers(deps) {
64916
65063
  if (!scope) {
64917
65064
  throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
64918
65065
  }
64919
- const cwdAbs = import_node_path62.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
64920
- const candidateAbs = import_node_path62.default.isAbsolute(args.relPath) ? import_node_path62.default.resolve(args.relPath) : import_node_path62.default.resolve(cwdAbs, args.relPath);
65066
+ const cwdAbs = import_node_path63.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
65067
+ const candidateAbs = import_node_path63.default.isAbsolute(args.relPath) ? import_node_path63.default.resolve(args.relPath) : import_node_path63.default.resolve(cwdAbs, args.relPath);
64921
65068
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
64922
65069
  const from = args.origin === "agent" ? "agent" : ctx?.principal.kind === "owner" ? "owner" : "agent";
64923
65070
  const size = 0;
@@ -64976,19 +65123,19 @@ function buildAttachmentHandlers(deps) {
64976
65123
 
64977
65124
  // src/handlers/extension.ts
64978
65125
  var import_promises14 = __toESM(require("fs/promises"), 1);
64979
- var import_node_path67 = __toESM(require("path"), 1);
65126
+ var import_node_path68 = __toESM(require("path"), 1);
64980
65127
  init_protocol();
64981
65128
 
64982
65129
  // src/extension/bundle-zip.ts
64983
65130
  var import_promises11 = __toESM(require("fs/promises"), 1);
64984
- var import_node_path63 = __toESM(require("path"), 1);
65131
+ var import_node_path64 = __toESM(require("path"), 1);
64985
65132
  var import_node_crypto17 = __toESM(require("crypto"), 1);
64986
65133
  var import_jszip2 = __toESM(require_lib3(), 1);
64987
65134
  async function bundleExtensionDir(dir) {
64988
65135
  const entries = await listFilesSorted(dir);
64989
65136
  const zip = new import_jszip2.default();
64990
65137
  for (const rel of entries) {
64991
- const abs = import_node_path63.default.join(dir, rel);
65138
+ const abs = import_node_path64.default.join(dir, rel);
64992
65139
  const content = await import_promises11.default.readFile(abs);
64993
65140
  zip.file(rel, content, { date: FIXED_DATE });
64994
65141
  }
@@ -65009,7 +65156,7 @@ async function listFilesSorted(rootDir) {
65009
65156
  return out;
65010
65157
  }
65011
65158
  async function walk(absRoot, relPrefix, out) {
65012
- const dirAbs = import_node_path63.default.join(absRoot, relPrefix);
65159
+ const dirAbs = import_node_path64.default.join(absRoot, relPrefix);
65013
65160
  const entries = await import_promises11.default.readdir(dirAbs, { withFileTypes: true });
65014
65161
  for (const e of entries) {
65015
65162
  if (IGNORE_BASENAMES.has(e.name)) continue;
@@ -65063,25 +65210,25 @@ function computePublishCheck(args) {
65063
65210
 
65064
65211
  // src/extension/install-flow.ts
65065
65212
  var import_promises12 = __toESM(require("fs/promises"), 1);
65066
- var import_node_path65 = __toESM(require("path"), 1);
65067
- var import_node_os22 = __toESM(require("os"), 1);
65213
+ var import_node_path66 = __toESM(require("path"), 1);
65214
+ var import_node_os23 = __toESM(require("os"), 1);
65068
65215
  var import_node_crypto18 = __toESM(require("crypto"), 1);
65069
65216
  var import_jszip3 = __toESM(require_lib3(), 1);
65070
65217
 
65071
65218
  // src/extension/paths.ts
65072
- var import_node_os21 = __toESM(require("os"), 1);
65073
- var import_node_path64 = __toESM(require("path"), 1);
65219
+ var import_node_os22 = __toESM(require("os"), 1);
65220
+ var import_node_path65 = __toESM(require("path"), 1);
65074
65221
  function clawdHomeRoot(override) {
65075
- return override ?? process.env.CLAWD_HOME ?? import_node_path64.default.join(import_node_os21.default.homedir(), ".clawd");
65222
+ return override ?? process.env.CLAWD_HOME ?? import_node_path65.default.join(import_node_os22.default.homedir(), ".clawd");
65076
65223
  }
65077
65224
  function extensionsRoot(override) {
65078
- return import_node_path64.default.join(clawdHomeRoot(override), "extensions");
65225
+ return import_node_path65.default.join(clawdHomeRoot(override), "extensions");
65079
65226
  }
65080
65227
  function publishedChannelsFile(override) {
65081
- return import_node_path64.default.join(clawdHomeRoot(override), "extensions-published.json");
65228
+ return import_node_path65.default.join(clawdHomeRoot(override), "extensions-published.json");
65082
65229
  }
65083
65230
  function bundleCacheRoot(override) {
65084
- return import_node_path64.default.join(clawdHomeRoot(override), "extension-bundles");
65231
+ return import_node_path65.default.join(clawdHomeRoot(override), "extension-bundles");
65085
65232
  }
65086
65233
 
65087
65234
  // src/extension/install-flow.ts
@@ -65108,7 +65255,7 @@ async function installFromChannel(args, deps) {
65108
65255
  throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
65109
65256
  }
65110
65257
  for (const name of Object.keys(zip.files)) {
65111
- if (name.includes("..") || name.startsWith("/") || import_node_path65.default.isAbsolute(name)) {
65258
+ if (name.includes("..") || name.startsWith("/") || import_node_path66.default.isAbsolute(name)) {
65112
65259
  throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
65113
65260
  }
65114
65261
  }
@@ -65140,7 +65287,7 @@ async function installFromChannel(args, deps) {
65140
65287
  );
65141
65288
  }
65142
65289
  const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
65143
- const destDir = import_node_path65.default.join(deps.extensionsRoot, localExtId);
65290
+ const destDir = import_node_path66.default.join(deps.extensionsRoot, localExtId);
65144
65291
  let destExists = false;
65145
65292
  try {
65146
65293
  await import_promises12.default.access(destDir);
@@ -65154,16 +65301,16 @@ async function installFromChannel(args, deps) {
65154
65301
  );
65155
65302
  }
65156
65303
  const stage = await import_promises12.default.mkdtemp(
65157
- import_node_path65.default.join(import_node_os22.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
65304
+ import_node_path66.default.join(import_node_os23.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
65158
65305
  );
65159
65306
  try {
65160
65307
  for (const [name, entry] of Object.entries(zip.files)) {
65161
- const dest = import_node_path65.default.join(stage, name);
65308
+ const dest = import_node_path66.default.join(stage, name);
65162
65309
  if (entry.dir) {
65163
65310
  await import_promises12.default.mkdir(dest, { recursive: true });
65164
65311
  continue;
65165
65312
  }
65166
- await import_promises12.default.mkdir(import_node_path65.default.dirname(dest), { recursive: true });
65313
+ await import_promises12.default.mkdir(import_node_path66.default.dirname(dest), { recursive: true });
65167
65314
  if (name === "manifest.json") {
65168
65315
  const rewritten = { ...parsed.data, id: localExtId };
65169
65316
  await import_promises12.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -65184,8 +65331,8 @@ async function installFromChannel(args, deps) {
65184
65331
 
65185
65332
  // src/extension/update-flow.ts
65186
65333
  var import_promises13 = __toESM(require("fs/promises"), 1);
65187
- var import_node_path66 = __toESM(require("path"), 1);
65188
- var import_node_os23 = __toESM(require("os"), 1);
65334
+ var import_node_path67 = __toESM(require("path"), 1);
65335
+ var import_node_os24 = __toESM(require("os"), 1);
65189
65336
  var import_node_crypto19 = __toESM(require("crypto"), 1);
65190
65337
  var import_jszip4 = __toESM(require_lib3(), 1);
65191
65338
  var UpdateError = class extends Error {
@@ -65201,11 +65348,11 @@ async function updateFromChannel(args, deps) {
65201
65348
  channelRef.extId,
65202
65349
  channelRef.ownerPrincipalId
65203
65350
  );
65204
- const liveDir = import_node_path66.default.join(deps.extensionsRoot, localExtId);
65351
+ const liveDir = import_node_path67.default.join(deps.extensionsRoot, localExtId);
65205
65352
  const prevDir = `${liveDir}.prev`;
65206
65353
  let existingVersion;
65207
65354
  try {
65208
- const raw = await import_promises13.default.readFile(import_node_path66.default.join(liveDir, "manifest.json"), "utf8");
65355
+ const raw = await import_promises13.default.readFile(import_node_path67.default.join(liveDir, "manifest.json"), "utf8");
65209
65356
  const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
65210
65357
  if (!parsed2.success) {
65211
65358
  throw new UpdateError(
@@ -65238,7 +65385,7 @@ async function updateFromChannel(args, deps) {
65238
65385
  throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
65239
65386
  }
65240
65387
  for (const name of Object.keys(zip.files)) {
65241
- if (name.includes("..") || name.startsWith("/") || import_node_path66.default.isAbsolute(name)) {
65388
+ if (name.includes("..") || name.startsWith("/") || import_node_path67.default.isAbsolute(name)) {
65242
65389
  throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
65243
65390
  }
65244
65391
  }
@@ -65273,16 +65420,16 @@ async function updateFromChannel(args, deps) {
65273
65420
  await import_promises13.default.rm(prevDir, { recursive: true, force: true });
65274
65421
  await import_promises13.default.rename(liveDir, prevDir);
65275
65422
  const stage = await import_promises13.default.mkdtemp(
65276
- import_node_path66.default.join(import_node_os23.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
65423
+ import_node_path67.default.join(import_node_os24.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
65277
65424
  );
65278
65425
  try {
65279
65426
  for (const [name, entry] of Object.entries(zip.files)) {
65280
- const dest = import_node_path66.default.join(stage, name);
65427
+ const dest = import_node_path67.default.join(stage, name);
65281
65428
  if (entry.dir) {
65282
65429
  await import_promises13.default.mkdir(dest, { recursive: true });
65283
65430
  continue;
65284
65431
  }
65285
- await import_promises13.default.mkdir(import_node_path66.default.dirname(dest), { recursive: true });
65432
+ await import_promises13.default.mkdir(import_node_path67.default.dirname(dest), { recursive: true });
65286
65433
  if (name === "manifest.json") {
65287
65434
  const rewritten = { ...parsed.data, id: localExtId };
65288
65435
  await import_promises13.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -65349,7 +65496,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
65349
65496
  );
65350
65497
  }
65351
65498
  }
65352
- const manifestPath = import_node_path67.default.join(root, extId, "manifest.json");
65499
+ const manifestPath = import_node_path68.default.join(root, extId, "manifest.json");
65353
65500
  const manifest = await readManifest(root, extId);
65354
65501
  const next = { ...manifest, version: newVersion };
65355
65502
  const tmp = `${manifestPath}.tmp`;
@@ -65357,7 +65504,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
65357
65504
  await import_promises14.default.rename(tmp, manifestPath);
65358
65505
  }
65359
65506
  async function readManifest(root, extId) {
65360
- const file = import_node_path67.default.join(root, extId, "manifest.json");
65507
+ const file = import_node_path68.default.join(root, extId, "manifest.json");
65361
65508
  let raw;
65362
65509
  try {
65363
65510
  raw = await import_promises14.default.readFile(file, "utf8");
@@ -65441,7 +65588,7 @@ function buildExtensionHandlers(deps) {
65441
65588
  };
65442
65589
  async function buildSnapshotMeta(extId) {
65443
65590
  const manifest = await readManifest(deps.root, extId);
65444
- const { sha256, buffer } = await bundleExtensionDir(import_node_path67.default.join(deps.root, extId));
65591
+ const { sha256, buffer } = await bundleExtensionDir(import_node_path68.default.join(deps.root, extId));
65445
65592
  return { manifest, contentHash: sha256, buffer };
65446
65593
  }
65447
65594
  const publish = async (frame, _client, ctx) => {
@@ -65684,8 +65831,8 @@ var APP_BUILDER_PERSONAS = ["persona-app-builder", "persona-dataclaw-builder"];
65684
65831
 
65685
65832
  // src/handlers/app-builder.ts
65686
65833
  init_protocol();
65687
- var import_node_path68 = require("path");
65688
- var import_node_fs52 = require("fs");
65834
+ var import_node_path69 = require("path");
65835
+ var import_node_fs53 = require("fs");
65689
65836
  var DEFAULT_TEMPLATE = "nestjs-react";
65690
65837
  var DEV_SERVER_READY_TIMEOUT_MS = 3e4;
65691
65838
  function buildAppBuilderHandlers(deps) {
@@ -65758,7 +65905,7 @@ function buildAppBuilderHandlers(deps) {
65758
65905
  async function listAllUsersProjects() {
65759
65906
  if (!deps.usersRoot || !deps.getStore) return [];
65760
65907
  const getStore = deps.getStore;
65761
- const userIds = await import_node_fs52.promises.readdir(deps.usersRoot).catch(() => []);
65908
+ const userIds = await import_node_fs53.promises.readdir(deps.usersRoot).catch(() => []);
65762
65909
  const perUser = await Promise.all(
65763
65910
  userIds.map((uid) => getStore(uid).list().catch(() => []))
65764
65911
  );
@@ -65831,13 +65978,13 @@ function buildAppBuilderHandlers(deps) {
65831
65978
  const created = await deps.createProjectOnDisk({
65832
65979
  store: userStore,
65833
65980
  name: f.name,
65834
- templateSrcDir: (0, import_node_path68.join)(personaRoot, "extension-kit", "examples", DEFAULT_TEMPLATE),
65835
- scaffoldScript: (0, import_node_path68.join)(deps.deployKitRoot, "scripts", "new-extension.sh"),
65981
+ templateSrcDir: (0, import_node_path69.join)(personaRoot, "extension-kit", "examples", DEFAULT_TEMPLATE),
65982
+ scaffoldScript: (0, import_node_path69.join)(deps.deployKitRoot, "scripts", "new-extension.sh"),
65836
65983
  reservedPorts,
65837
65984
  // 凭据只进 scaffold 子进程的 env,且**只给这个 persona 的 kit 模板声明要的那几个变量**
65838
65985
  // (M1b Step 5)。整表塞进去粒度只到「进程」——那会把 service-role key 交给一个用不到
65839
65986
  // 它的脚本。new-extension.sh 用它把模板的 `${VAR}` 渲成项目可跑的 server/.env。
65840
- extraEnv: secretsForKit(deps.readSecrets?.(), (0, import_node_path68.join)(personaRoot, "extension-kit")),
65987
+ extraEnv: secretsForKit(deps.readSecrets?.(), (0, import_node_path69.join)(personaRoot, "extension-kit")),
65841
65988
  ...deps.logger ? { logger: deps.logger } : {}
65842
65989
  });
65843
65990
  project = created.project;
@@ -66036,7 +66183,7 @@ function buildAppBuilderHandlers(deps) {
66036
66183
  await userStore.clearPublishJob(args.name);
66037
66184
  }
66038
66185
  const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(boundSession.ownerPersonaId ?? "") : deps.personaRoot;
66039
- const scriptPath = (0, import_node_path68.join)(deps.deployKitRoot, "scripts", "publish.sh");
66186
+ const scriptPath = (0, import_node_path69.join)(deps.deployKitRoot, "scripts", "publish.sh");
66040
66187
  deps.logger?.info("app-builder.publish.start", {
66041
66188
  name: args.name,
66042
66189
  sessionId: boundSession.sessionId,
@@ -66052,7 +66199,7 @@ function buildAppBuilderHandlers(deps) {
66052
66199
  // 凭据只进 publish.sh 这个子进程的 env,且只给它的 kit 模板声明要的那几个变量
66053
66200
  // (M1b Step 5)。那个进程里跑着 `eval "$BUILD_CMD"`——项目自带的构建命令会继承这份
66054
66201
  // env,多给一个变量就是多交一个凭据给它。personaRoot 上面已按绑定 session 的 persona 解析。
66055
- extraEnv: secretsForKit(deps.readSecrets?.(), (0, import_node_path68.join)(personaRoot, "extension-kit")),
66202
+ extraEnv: secretsForKit(deps.readSecrets?.(), (0, import_node_path69.join)(personaRoot, "extension-kit")),
66056
66203
  hooks: {
66057
66204
  // 元数据每次写盘(publishJob 起落 / prodUrl 回填)后重推一帧:UI 渲染 PublishProgress
66058
66205
  // 三段 checklist 依赖 project.publishJob.status==='in-flight',而 publishJob 字段只有
@@ -66585,20 +66732,20 @@ function mapPrState(state, isDraft) {
66585
66732
  if (state === "CLOSED") return "closed";
66586
66733
  return isDraft === true ? "draft" : "open";
66587
66734
  }
66588
- function asRecord2(v2) {
66735
+ function asRecord3(v2) {
66589
66736
  return typeof v2 === "object" && v2 !== null ? v2 : {};
66590
66737
  }
66591
66738
  function lastCommitRollup(node) {
66592
- const first = asRecord2(node.commits).nodes?.[0];
66593
- return asRecord2(asRecord2(first).commit).statusCheckRollup;
66739
+ const first = asRecord3(node.commits).nodes?.[0];
66740
+ return asRecord3(asRecord3(first).commit).statusCheckRollup;
66594
66741
  }
66595
66742
  function parsePrListResponse(json) {
66596
- const nodes = asRecord2(asRecord2(asRecord2(json).data).search).nodes ?? [];
66743
+ const nodes = asRecord3(asRecord3(asRecord3(json).data).search).nodes ?? [];
66597
66744
  const items = [];
66598
66745
  for (const raw of nodes) {
66599
- const n = asRecord2(raw);
66746
+ const n = asRecord3(raw);
66600
66747
  if (typeof n.number !== "number") continue;
66601
- const nameWithOwner = String(asRecord2(n.repository).nameWithOwner ?? "");
66748
+ const nameWithOwner = String(asRecord3(n.repository).nameWithOwner ?? "");
66602
66749
  const slash = nameWithOwner.indexOf("/");
66603
66750
  if (slash <= 0) continue;
66604
66751
  const rollup = lastCommitRollup(n);
@@ -66612,27 +66759,27 @@ function parsePrListResponse(json) {
66612
66759
  additions: typeof n.additions === "number" ? n.additions : 0,
66613
66760
  deletions: typeof n.deletions === "number" ? n.deletions : 0,
66614
66761
  updatedAt: String(n.updatedAt ?? ""),
66615
- author: String(asRecord2(n.author).login ?? ""),
66616
- checksRollup: rollup == null ? "none" : mapRollupState(asRecord2(rollup).state)
66762
+ author: String(asRecord3(n.author).login ?? ""),
66763
+ checksRollup: rollup == null ? "none" : mapRollupState(asRecord3(rollup).state)
66617
66764
  });
66618
66765
  }
66619
66766
  return items;
66620
66767
  }
66621
66768
  function parsePrDetailResponse(json, repoRef) {
66622
- const pr = asRecord2(asRecord2(asRecord2(json).data).repository).pullRequest;
66769
+ const pr = asRecord3(asRecord3(asRecord3(json).data).repository).pullRequest;
66623
66770
  if (pr == null || typeof pr !== "object") return null;
66624
- const n = asRecord2(pr);
66771
+ const n = asRecord3(pr);
66625
66772
  const rollup = lastCommitRollup(n);
66626
- const contextNodes = asRecord2(asRecord2(rollup).contexts).nodes ?? [];
66773
+ const contextNodes = asRecord3(asRecord3(rollup).contexts).nodes ?? [];
66627
66774
  const checks = [];
66628
66775
  for (const c of contextNodes) {
66629
- const mapped = mapCheckNode(asRecord2(c));
66776
+ const mapped = mapCheckNode(asRecord3(c));
66630
66777
  if (mapped) checks.push(mapped);
66631
66778
  }
66632
- const reviewerNodes = asRecord2(n.reviewRequests).nodes ?? [];
66633
- const reviewers = reviewerNodes.map((r) => String(asRecord2(asRecord2(r).requestedReviewer).login ?? "")).filter((s) => s !== "");
66779
+ const reviewerNodes = asRecord3(n.reviewRequests).nodes ?? [];
66780
+ const reviewers = reviewerNodes.map((r) => String(asRecord3(asRecord3(r).requestedReviewer).login ?? "")).filter((s) => s !== "");
66634
66781
  const mergeable = n.mergeable === "MERGEABLE" ? "mergeable" : n.mergeable === "CONFLICTING" ? "conflicting" : "unknown";
66635
- const commentCountRaw = asRecord2(n.comments).totalCount;
66782
+ const commentCountRaw = asRecord3(n.comments).totalCount;
66636
66783
  return {
66637
66784
  owner: repoRef.owner,
66638
66785
  repo: repoRef.repo,
@@ -66640,7 +66787,7 @@ function parsePrDetailResponse(json, repoRef) {
66640
66787
  title: String(n.title ?? ""),
66641
66788
  body: String(n.body ?? ""),
66642
66789
  state: mapPrState(n.state, n.isDraft),
66643
- author: String(asRecord2(n.author).login ?? ""),
66790
+ author: String(asRecord3(n.author).login ?? ""),
66644
66791
  updatedAt: String(n.updatedAt ?? ""),
66645
66792
  headRef: String(n.headRefName ?? ""),
66646
66793
  baseRef: String(n.baseRefName ?? ""),
@@ -66650,7 +66797,7 @@ function parsePrDetailResponse(json, repoRef) {
66650
66797
  mergeable,
66651
66798
  reviewers,
66652
66799
  commentCount: typeof commentCountRaw === "number" ? commentCountRaw : 0,
66653
- checksRollup: rollup == null ? "none" : mapRollupState(asRecord2(rollup).state),
66800
+ checksRollup: rollup == null ? "none" : mapRollupState(asRecord3(rollup).state),
66654
66801
  checks
66655
66802
  };
66656
66803
  }
@@ -66788,7 +66935,7 @@ function buildVisitorHandlers(deps) {
66788
66935
 
66789
66936
  // src/extension/registry.ts
66790
66937
  var import_promises16 = __toESM(require("fs/promises"), 1);
66791
- var import_node_path69 = __toESM(require("path"), 1);
66938
+ var import_node_path70 = __toESM(require("path"), 1);
66792
66939
  async function loadAll(root) {
66793
66940
  let entries;
66794
66941
  try {
@@ -66801,13 +66948,13 @@ async function loadAll(root) {
66801
66948
  for (const ent of entries) {
66802
66949
  if (!ent.isDirectory()) continue;
66803
66950
  if (ent.name.startsWith(".")) continue;
66804
- records.push(await loadOne(import_node_path69.default.join(root, ent.name), ent.name));
66951
+ records.push(await loadOne(import_node_path70.default.join(root, ent.name), ent.name));
66805
66952
  }
66806
66953
  records.sort((a, b2) => a.extId < b2.extId ? -1 : a.extId > b2.extId ? 1 : 0);
66807
66954
  return records;
66808
66955
  }
66809
66956
  async function loadOne(dir, dirName) {
66810
- const manifestPath = import_node_path69.default.join(dir, "manifest.json");
66957
+ const manifestPath = import_node_path70.default.join(dir, "manifest.json");
66811
66958
  let raw;
66812
66959
  try {
66813
66960
  raw = await import_promises16.default.readFile(manifestPath, "utf8");
@@ -66852,7 +66999,7 @@ async function loadOne(dir, dirName) {
66852
66999
 
66853
67000
  // src/extension/uninstall.ts
66854
67001
  var import_promises17 = __toESM(require("fs/promises"), 1);
66855
- var import_node_path70 = __toESM(require("path"), 1);
67002
+ var import_node_path71 = __toESM(require("path"), 1);
66856
67003
  var UninstallError = class extends Error {
66857
67004
  constructor(code, message) {
66858
67005
  super(message);
@@ -66861,7 +67008,7 @@ var UninstallError = class extends Error {
66861
67008
  code;
66862
67009
  };
66863
67010
  async function uninstall(deps) {
66864
- const dir = import_node_path70.default.join(deps.root, deps.extId);
67011
+ const dir = import_node_path71.default.join(deps.root, deps.extId);
66865
67012
  try {
66866
67013
  await import_promises17.default.access(dir);
66867
67014
  } catch {
@@ -66879,14 +67026,14 @@ init_protocol();
66879
67026
 
66880
67027
  // src/peer-ops/run-command.ts
66881
67028
  var import_node_child_process17 = require("child_process");
66882
- var import_node_os24 = __toESM(require("os"), 1);
67029
+ var import_node_os25 = __toESM(require("os"), 1);
66883
67030
  var DEFAULT_TIMEOUT_MS6 = 3e4;
66884
67031
  var MAX_TIMEOUT_MS = 3e5;
66885
67032
  var MAX_OUTPUT_BYTES = 1048576;
66886
67033
  function runCommand2(command, opts = {}) {
66887
67034
  const timeoutMs = Math.min(opts.timeoutMs ?? DEFAULT_TIMEOUT_MS6, MAX_TIMEOUT_MS);
66888
67035
  return new Promise((resolve9) => {
66889
- const child = (0, import_node_child_process17.spawn)("bash", ["-c", command], { cwd: import_node_os24.default.homedir() });
67036
+ const child = (0, import_node_child_process17.spawn)("bash", ["-c", command], { cwd: import_node_os25.default.homedir() });
66890
67037
  const out = [];
66891
67038
  const err = [];
66892
67039
  let outBytes = 0;
@@ -67097,7 +67244,7 @@ function buildMethodHandlers(deps) {
67097
67244
  broadcast: deps.broadcastToOwners
67098
67245
  }),
67099
67246
  ...buildMasterHandlers({
67100
- authorityTablePath: import_node_path71.default.join(deps.masterDataDir, "master-authority.json")
67247
+ authorityTablePath: import_node_path72.default.join(deps.masterDataDir, "master-authority.json")
67101
67248
  }),
67102
67249
  ...buildTopicHandlers({
67103
67250
  topicStore: deps.topicStore,
@@ -67133,18 +67280,18 @@ init_claude();
67133
67280
 
67134
67281
  // src/tools/shell-path.ts
67135
67282
  var import_node_child_process18 = require("child_process");
67136
- var import_node_os25 = __toESM(require("os"), 1);
67283
+ var import_node_os26 = __toESM(require("os"), 1);
67137
67284
  function refreshPathFromLoginShell() {
67138
67285
  if (process.platform === "win32") return;
67139
- const shell = process.env.SHELL ?? import_node_os25.default.userInfo().shell ?? "/bin/zsh";
67286
+ const shell = process.env.SHELL ?? import_node_os26.default.userInfo().shell ?? "/bin/zsh";
67140
67287
  try {
67141
67288
  const out = (0, import_node_child_process18.execFileSync)(shell, ["-ilc", 'command echo -n "$PATH"'], {
67142
67289
  encoding: "utf8",
67143
67290
  timeout: 3e3,
67144
67291
  stdio: ["ignore", "pipe", "ignore"]
67145
67292
  });
67146
- const path97 = out.trim();
67147
- if (path97) process.env.PATH = path97;
67293
+ const path98 = out.trim();
67294
+ if (path98) process.env.PATH = path98;
67148
67295
  } catch {
67149
67296
  }
67150
67297
  }
@@ -67268,9 +67415,9 @@ function buildOnboardingHandlers(deps) {
67268
67415
  }
67269
67416
 
67270
67417
  // src/app-builder-plugin/project-store.ts
67271
- var import_node_fs53 = require("fs");
67418
+ var import_node_fs54 = require("fs");
67272
67419
  var import_node_child_process20 = require("child_process");
67273
- var import_node_path72 = require("path");
67420
+ var import_node_path73 = require("path");
67274
67421
  init_protocol();
67275
67422
  var PROJECTS_DIR = "projects";
67276
67423
  var META_FILE = ".clawd-project.json";
@@ -67300,19 +67447,19 @@ var ProjectStore = class {
67300
67447
  }
67301
67448
  /** projects/<name>/.clawd-project.json 路径 */
67302
67449
  metaPath(name) {
67303
- return (0, import_node_path72.join)(this.projectsRoot(), name, META_FILE);
67450
+ return (0, import_node_path73.join)(this.projectsRoot(), name, META_FILE);
67304
67451
  }
67305
67452
  /** projects/<name>/ 目录路径(cwd 用) */
67306
67453
  projectDir(name) {
67307
- return (0, import_node_path72.join)(this.projectsRoot(), name);
67454
+ return (0, import_node_path73.join)(this.projectsRoot(), name);
67308
67455
  }
67309
67456
  projectsRoot() {
67310
- return (0, import_node_path72.join)(this.root, PROJECTS_DIR);
67457
+ return (0, import_node_path73.join)(this.root, PROJECTS_DIR);
67311
67458
  }
67312
67459
  async list() {
67313
67460
  let entries;
67314
67461
  try {
67315
- entries = await import_node_fs53.promises.readdir(this.projectsRoot());
67462
+ entries = await import_node_fs54.promises.readdir(this.projectsRoot());
67316
67463
  } catch (err) {
67317
67464
  if (err.code === "ENOENT") return [];
67318
67465
  throw err;
@@ -67320,7 +67467,7 @@ var ProjectStore = class {
67320
67467
  const out = [];
67321
67468
  for (const name of entries) {
67322
67469
  try {
67323
- const raw = await import_node_fs53.promises.readFile(this.metaPath(name), "utf8");
67470
+ const raw = await import_node_fs54.promises.readFile(this.metaPath(name), "utf8");
67324
67471
  const json = JSON.parse(raw);
67325
67472
  let migrated = false;
67326
67473
  if (typeof json.devCommand !== "string" || json.devCommand.length === 0) {
@@ -67331,7 +67478,7 @@ var ProjectStore = class {
67331
67478
  if (parsed.success) {
67332
67479
  out.push(parsed.data);
67333
67480
  if (migrated) {
67334
- void import_node_fs53.promises.writeFile(this.metaPath(name), JSON.stringify(parsed.data, null, 2) + "\n", "utf8").catch(() => {
67481
+ void import_node_fs54.promises.writeFile(this.metaPath(name), JSON.stringify(parsed.data, null, 2) + "\n", "utf8").catch(() => {
67335
67482
  });
67336
67483
  }
67337
67484
  }
@@ -67375,8 +67522,8 @@ var ProjectStore = class {
67375
67522
  throw new Error(`invalid name "${name}": ${validated.error.message}`);
67376
67523
  }
67377
67524
  const dir = this.projectDir(name);
67378
- await import_node_fs53.promises.mkdir(dir, { recursive: true });
67379
- await import_node_fs53.promises.writeFile(this.metaPath(name), JSON.stringify(meta, null, 2) + "\n", "utf8");
67525
+ await import_node_fs54.promises.mkdir(dir, { recursive: true });
67526
+ await import_node_fs54.promises.writeFile(this.metaPath(name), JSON.stringify(meta, null, 2) + "\n", "utf8");
67380
67527
  return meta;
67381
67528
  }
67382
67529
  /**
@@ -67421,7 +67568,7 @@ var ProjectStore = class {
67421
67568
  }
67422
67569
  async delete(name) {
67423
67570
  const dir = this.projectDir(name);
67424
- await import_node_fs53.promises.rm(dir, { recursive: true, force: true });
67571
+ await import_node_fs54.promises.rm(dir, { recursive: true, force: true });
67425
67572
  }
67426
67573
  async updatePort(name, newPort) {
67427
67574
  if (newPort < PROJECT_PORT_MIN || newPort > PROJECT_PORT_MAX) {
@@ -67438,7 +67585,7 @@ var ProjectStore = class {
67438
67585
  throw new Error(`port ${newPort} already used / \u5DF2\u88AB project "${conflict.name}" \u5360\u7528`);
67439
67586
  }
67440
67587
  const updated = { ...target, port: newPort };
67441
- await import_node_fs53.promises.writeFile(this.metaPath(name), JSON.stringify(updated, null, 2) + "\n", "utf8");
67588
+ await import_node_fs54.promises.writeFile(this.metaPath(name), JSON.stringify(updated, null, 2) + "\n", "utf8");
67442
67589
  return updated;
67443
67590
  });
67444
67591
  }
@@ -67457,7 +67604,7 @@ var ProjectStore = class {
67457
67604
  if (!validated.success) {
67458
67605
  throw new Error(`invalid prodUrl "${url}": ${validated.error.message}`);
67459
67606
  }
67460
- await import_node_fs53.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
67607
+ await import_node_fs54.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
67461
67608
  return validated.data;
67462
67609
  });
67463
67610
  }
@@ -67480,7 +67627,7 @@ var ProjectStore = class {
67480
67627
  if (!validated.success) {
67481
67628
  throw new Error(`invalid publishJob: ${validated.error.message}`);
67482
67629
  }
67483
- await import_node_fs53.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
67630
+ await import_node_fs54.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
67484
67631
  return validated.data;
67485
67632
  });
67486
67633
  }
@@ -67497,7 +67644,7 @@ var ProjectStore = class {
67497
67644
  if (!validated.success) {
67498
67645
  throw new Error(`failed to clear publishJob: ${validated.error.message}`);
67499
67646
  }
67500
- await import_node_fs53.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
67647
+ await import_node_fs54.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
67501
67648
  return validated.data;
67502
67649
  });
67503
67650
  }
@@ -67812,8 +67959,8 @@ var PublishJobRegistry = class {
67812
67959
 
67813
67960
  // src/app-builder-plugin/publish-job-runner.ts
67814
67961
  var import_node_child_process22 = require("child_process");
67815
- var import_node_fs54 = require("fs");
67816
- var import_node_path73 = require("path");
67962
+ var import_node_fs55 = require("fs");
67963
+ var import_node_path74 = require("path");
67817
67964
 
67818
67965
  // src/app-builder-plugin/publish-stage-parser.ts
67819
67966
  var STAGE_RE = /^\s*::stage::(build|deploy|verify)\s*$/;
@@ -67845,10 +67992,10 @@ async function startPublishJob(deps, args) {
67845
67992
  return { jobId: registry2.get(args.name).jobId, status: "already-publishing" };
67846
67993
  }
67847
67994
  const projDir = projectDir(args.name);
67848
- const logPath = (0, import_node_path73.join)(projDir, ".publish.log");
67995
+ const logPath = (0, import_node_path74.join)(projDir, ".publish.log");
67849
67996
  let logStream = null;
67850
67997
  try {
67851
- logStream = (0, import_node_fs54.createWriteStream)(logPath, { flags: "w" });
67998
+ logStream = (0, import_node_fs55.createWriteStream)(logPath, { flags: "w" });
67852
67999
  } catch {
67853
68000
  logStream = null;
67854
68001
  }
@@ -68191,10 +68338,10 @@ async function recoverInterruptedPublishJobs(store, logger) {
68191
68338
  }
68192
68339
 
68193
68340
  // src/app-builder-plugin/mcp-config.ts
68194
- var import_node_fs55 = __toESM(require("fs"), 1);
68195
- var import_node_path74 = __toESM(require("path"), 1);
68341
+ var import_node_fs56 = __toESM(require("fs"), 1);
68342
+ var import_node_path75 = __toESM(require("path"), 1);
68196
68343
  function appBuilderMcpConfigPath(dataDir) {
68197
- return import_node_path74.default.join(dataDir, "app-builder.mcp.json");
68344
+ return import_node_path75.default.join(dataDir, "app-builder.mcp.json");
68198
68345
  }
68199
68346
  function writeAppBuilderMcpConfig(args) {
68200
68347
  const cfgPath = appBuilderMcpConfigPath(args.dataDir);
@@ -68208,15 +68355,15 @@ function writeAppBuilderMcpConfig(args) {
68208
68355
  env: {
68209
68356
  CLAWD_DAEMON_TOKEN: args.daemonToken,
68210
68357
  CLAWD_DAEMON_URL: args.daemonUrl,
68211
- CLAWD_APP_BUILDER_SCAFFOLD_SCRIPT: import_node_path74.default.join(args.deployKitScriptsDir, "new-extension.sh"),
68212
- CLAWD_APP_BUILDER_PUBLISH_SCRIPT: import_node_path74.default.join(args.deployKitScriptsDir, "publish.sh"),
68358
+ CLAWD_APP_BUILDER_SCAFFOLD_SCRIPT: import_node_path75.default.join(args.deployKitScriptsDir, "new-extension.sh"),
68359
+ CLAWD_APP_BUILDER_PUBLISH_SCRIPT: import_node_path75.default.join(args.deployKitScriptsDir, "publish.sh"),
68213
68360
  ...args.logPath ? { CLAWD_APP_BUILDER_LOG: args.logPath } : {}
68214
68361
  }
68215
68362
  }
68216
68363
  }
68217
68364
  };
68218
- import_node_fs55.default.mkdirSync(args.dataDir, { recursive: true });
68219
- import_node_fs55.default.writeFileSync(cfgPath, JSON.stringify(cfg, null, 2), "utf8");
68365
+ import_node_fs56.default.mkdirSync(args.dataDir, { recursive: true });
68366
+ import_node_fs56.default.writeFileSync(cfgPath, JSON.stringify(cfg, null, 2), "utf8");
68220
68367
  return cfgPath;
68221
68368
  }
68222
68369
 
@@ -68257,7 +68404,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
68257
68404
 
68258
68405
  // src/extension/runtime.ts
68259
68406
  var import_node_child_process24 = require("child_process");
68260
- var import_node_path75 = __toESM(require("path"), 1);
68407
+ var import_node_path76 = __toESM(require("path"), 1);
68261
68408
  var import_promises18 = require("timers/promises");
68262
68409
 
68263
68410
  // src/extension/port-allocator.ts
@@ -68358,7 +68505,7 @@ var Runtime = class {
68358
68505
  /\$CLAWOS_EXT_PORT/g,
68359
68506
  String(port)
68360
68507
  );
68361
- const dir = import_node_path75.default.join(this.root, extId);
68508
+ const dir = import_node_path76.default.join(this.root, extId);
68362
68509
  const env = {
68363
68510
  ...process.env,
68364
68511
  CLAWOS_EXT_PORT: String(port),
@@ -68470,7 +68617,7 @@ ${handle.stderrTail}`
68470
68617
 
68471
68618
  // src/extension/published-channels.ts
68472
68619
  var import_promises19 = __toESM(require("fs/promises"), 1);
68473
- var import_node_path76 = __toESM(require("path"), 1);
68620
+ var import_node_path77 = __toESM(require("path"), 1);
68474
68621
  init_zod();
68475
68622
  var PublishedChannelsError = class extends Error {
68476
68623
  constructor(code, message) {
@@ -68569,7 +68716,7 @@ var PublishedChannelStore = class {
68569
68716
  )
68570
68717
  };
68571
68718
  const tmp = `${this.filePath}.tmp`;
68572
- await import_promises19.default.mkdir(import_node_path76.default.dirname(this.filePath), { recursive: true });
68719
+ await import_promises19.default.mkdir(import_node_path77.default.dirname(this.filePath), { recursive: true });
68573
68720
  await import_promises19.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
68574
68721
  await import_promises19.default.rename(tmp, this.filePath);
68575
68722
  }
@@ -68577,7 +68724,7 @@ var PublishedChannelStore = class {
68577
68724
 
68578
68725
  // src/extension/bundle-cache.ts
68579
68726
  var import_promises20 = __toESM(require("fs/promises"), 1);
68580
- var import_node_path77 = __toESM(require("path"), 1);
68727
+ var import_node_path78 = __toESM(require("path"), 1);
68581
68728
  var BundleCache = class {
68582
68729
  constructor(rootDir) {
68583
68730
  this.rootDir = rootDir;
@@ -68586,14 +68733,14 @@ var BundleCache = class {
68586
68733
  /** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
68587
68734
  async write(snapshotHash, buffer) {
68588
68735
  await import_promises20.default.mkdir(this.rootDir, { recursive: true });
68589
- const file = import_node_path77.default.join(this.rootDir, `${snapshotHash}.zip`);
68736
+ const file = import_node_path78.default.join(this.rootDir, `${snapshotHash}.zip`);
68590
68737
  const tmp = `${file}.tmp`;
68591
68738
  await import_promises20.default.writeFile(tmp, buffer, { mode: 384 });
68592
68739
  await import_promises20.default.rename(tmp, file);
68593
68740
  }
68594
68741
  /** Returns the bundle bytes, or null when the file doesn't exist. */
68595
68742
  async read(snapshotHash) {
68596
- const file = import_node_path77.default.join(this.rootDir, `${snapshotHash}.zip`);
68743
+ const file = import_node_path78.default.join(this.rootDir, `${snapshotHash}.zip`);
68597
68744
  try {
68598
68745
  return await import_promises20.default.readFile(file);
68599
68746
  } catch (e) {
@@ -68603,7 +68750,7 @@ var BundleCache = class {
68603
68750
  }
68604
68751
  /** Idempotent — missing file is not an error. */
68605
68752
  async delete(snapshotHash) {
68606
- const file = import_node_path77.default.join(this.rootDir, `${snapshotHash}.zip`);
68753
+ const file = import_node_path78.default.join(this.rootDir, `${snapshotHash}.zip`);
68607
68754
  await import_promises20.default.rm(file, { force: true });
68608
68755
  }
68609
68756
  };
@@ -68624,26 +68771,26 @@ async function startDaemon(config) {
68624
68771
  },
68625
68772
  source: "daemon",
68626
68773
  sampling: logShippingCfg.sampling,
68627
- homeDir: import_node_os26.default.homedir()
68774
+ homeDir: import_node_os27.default.homedir()
68628
68775
  });
68629
- const logDir = import_node_path78.default.join(config.dataDir, "log");
68630
- import_node_fs56.default.mkdirSync(logDir, { recursive: true });
68776
+ const logDir = import_node_path79.default.join(config.dataDir, "log");
68777
+ import_node_fs57.default.mkdirSync(logDir, { recursive: true });
68631
68778
  const logger = createLogger({
68632
68779
  level: config.logLevel,
68633
- file: import_node_path78.default.join(logDir, "clawd.log"),
68780
+ file: import_node_path79.default.join(logDir, "clawd.log"),
68634
68781
  logClient
68635
68782
  });
68636
68783
  logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
68637
68784
  const screenIdleProbeLogger = createFileOnlyLogger({
68638
- file: import_node_path78.default.join(logDir, "screen-idle-probe.log"),
68785
+ file: import_node_path79.default.join(logDir, "screen-idle-probe.log"),
68639
68786
  level: "debug"
68640
68787
  });
68641
68788
  logger.info("screen-idle probe logger enabled", {
68642
- file: import_node_path78.default.join(logDir, "screen-idle-probe.log")
68789
+ file: import_node_path79.default.join(logDir, "screen-idle-probe.log")
68643
68790
  });
68644
68791
  const CAP_TARGETS = [
68645
- import_node_path78.default.join(logDir, "clawd.log"),
68646
- import_node_path78.default.join(logDir, "screen-idle-probe.log")
68792
+ import_node_path79.default.join(logDir, "clawd.log"),
68793
+ import_node_path79.default.join(logDir, "screen-idle-probe.log")
68647
68794
  ];
68648
68795
  const LOG_CAP_MAX_BYTES = 10 * 1024 * 1024;
68649
68796
  const LOG_CAP_KEEP_BYTES = 5 * 1024 * 1024;
@@ -68765,8 +68912,8 @@ async function startDaemon(config) {
68765
68912
  const agents = new AgentsScanner();
68766
68913
  const history = new ClaudeHistoryReader();
68767
68914
  let transport = null;
68768
- const personaStore = new PersonaStore(import_node_path78.default.join(config.dataDir, "personas"));
68769
- const usersRoot = import_node_path78.default.join(config.dataDir, "users");
68915
+ const personaStore = new PersonaStore(import_node_path79.default.join(config.dataDir, "personas"));
68916
+ const usersRoot = import_node_path79.default.join(config.dataDir, "users");
68770
68917
  const defaultsRoot = findDefaultsRoot(logger);
68771
68918
  if (defaultsRoot) {
68772
68919
  seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
@@ -68790,7 +68937,7 @@ async function startDaemon(config) {
68790
68937
  retirePersonaBuilder({ store: personaStore, logger });
68791
68938
  const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
68792
68939
  const dispatchStore = createDispatchStore({
68793
- filePath: import_node_path78.default.join(config.dataDir, "dispatch.json"),
68940
+ filePath: import_node_path79.default.join(config.dataDir, "dispatch.json"),
68794
68941
  now: () => Date.now(),
68795
68942
  onFlushError: (err) => logger.error("dispatch store flush failed", {
68796
68943
  reason: err instanceof Error ? err.message : String(err)
@@ -68799,7 +68946,7 @@ async function startDaemon(config) {
68799
68946
  await dispatchStore.load();
68800
68947
  dispatchStore.markInterruptedAsFailed((/* @__PURE__ */ new Date()).toISOString());
68801
68948
  const channelStore = createChannelStore({
68802
- filePath: import_node_path78.default.join(config.dataDir, "channels.json"),
68949
+ filePath: import_node_path79.default.join(config.dataDir, "channels.json"),
68803
68950
  now: () => Date.now(),
68804
68951
  genId: () => `ch-${(0, import_node_crypto22.randomUUID)().slice(0, 8)}`,
68805
68952
  onFlushError: (err) => logger.error("channel store flush failed", {
@@ -68808,7 +68955,7 @@ async function startDaemon(config) {
68808
68955
  });
68809
68956
  await channelStore.load();
68810
68957
  const topicStore = createTopicStore({
68811
- filePath: import_node_path78.default.join(config.dataDir, "topics.json"),
68958
+ filePath: import_node_path79.default.join(config.dataDir, "topics.json"),
68812
68959
  now: () => Date.now(),
68813
68960
  genId: () => `tp-${(0, import_node_crypto22.randomUUID)().slice(0, 8)}`,
68814
68961
  onFlushError: (err) => logger.error("topic store flush failed", {
@@ -68835,28 +68982,28 @@ async function startDaemon(config) {
68835
68982
  });
68836
68983
  }
68837
68984
  });
68838
- const here = typeof __dirname === "string" ? __dirname : import_node_path78.default.dirname((0, import_node_url5.fileURLToPath)(import_meta8.url));
68985
+ const here = typeof __dirname === "string" ? __dirname : import_node_path79.default.dirname((0, import_node_url5.fileURLToPath)(import_meta8.url));
68839
68986
  const mcpConfigs = [];
68840
68987
  const secretsBundleRoot = findSecretsBundleRoot(logger);
68841
- const localSecretsDir = import_node_path78.default.join(config.dataDir, LOCAL_SECRETS_DIRNAME);
68988
+ const localSecretsDir = import_node_path79.default.join(config.dataDir, LOCAL_SECRETS_DIRNAME);
68842
68989
  const readSecrets = () => readSecretTable({ bundleRoot: secretsBundleRoot, overrideDir: localSecretsDir, logger });
68843
68990
  const resolvePersonaMcpConfig = (personaId2) => renderPersonaMcpSecrets({
68844
68991
  personaId: personaId2,
68845
- personaDir: import_node_path78.default.join(config.dataDir, "personas", personaId2),
68992
+ personaDir: import_node_path79.default.join(config.dataDir, "personas", personaId2),
68846
68993
  secrets: readSecrets(),
68847
- outDir: import_node_path78.default.join(config.dataDir, "persona-mcp"),
68994
+ outDir: import_node_path79.default.join(config.dataDir, "persona-mcp"),
68848
68995
  logger
68849
68996
  });
68850
68997
  const mcpDaemonUrl = `http://127.0.0.1:${config.port}`;
68851
68998
  const dispatchServerCandidates = [
68852
- import_node_path78.default.join(here, "dispatch", "mcp-server.cjs"),
68999
+ import_node_path79.default.join(here, "dispatch", "mcp-server.cjs"),
68853
69000
  // 生产 dist/index → dist/dispatch/mcp-server.cjs
68854
- import_node_path78.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
69001
+ import_node_path79.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
68855
69002
  // dev tsx src/index → ../dist/dispatch/mcp-server.cjs
68856
69003
  ];
68857
- const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs56.default.existsSync(p2));
69004
+ const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs57.default.existsSync(p2));
68858
69005
  if (dispatchServerScriptPath) {
68859
- const dispatchLogPath = import_node_path78.default.join(logDir, "dispatch-mcp-server.log");
69006
+ const dispatchLogPath = import_node_path79.default.join(logDir, "dispatch-mcp-server.log");
68860
69007
  const dispatchCfgPath = writeDispatchMcpConfig({
68861
69008
  dataDir: config.dataDir,
68862
69009
  serverScriptPath: dispatchServerScriptPath,
@@ -68876,12 +69023,12 @@ async function startDaemon(config) {
68876
69023
  });
68877
69024
  }
68878
69025
  const ticketServerCandidates = [
68879
- import_node_path78.default.join(here, "ticket", "mcp-server.cjs"),
68880
- import_node_path78.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
69026
+ import_node_path79.default.join(here, "ticket", "mcp-server.cjs"),
69027
+ import_node_path79.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
68881
69028
  ];
68882
- const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs56.default.existsSync(p2));
69029
+ const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs57.default.existsSync(p2));
68883
69030
  if (ticketServerScriptPath) {
68884
- const ticketLogPath = import_node_path78.default.join(logDir, "ticket-mcp-server.log");
69031
+ const ticketLogPath = import_node_path79.default.join(logDir, "ticket-mcp-server.log");
68885
69032
  const ticketCfgPath = writeTicketMcpConfig({
68886
69033
  dataDir: config.dataDir,
68887
69034
  serverScriptPath: ticketServerScriptPath,
@@ -68903,12 +69050,12 @@ async function startDaemon(config) {
68903
69050
  });
68904
69051
  }
68905
69052
  const shiftServerCandidates = [
68906
- import_node_path78.default.join(here, "shift", "mcp-server.cjs"),
68907
- import_node_path78.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
69053
+ import_node_path79.default.join(here, "shift", "mcp-server.cjs"),
69054
+ import_node_path79.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
68908
69055
  ];
68909
- const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs56.default.existsSync(p2));
69056
+ const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs57.default.existsSync(p2));
68910
69057
  if (shiftServerScriptPath) {
68911
- const shiftLogPath = import_node_path78.default.join(logDir, "shift-mcp-server.log");
69058
+ const shiftLogPath = import_node_path79.default.join(logDir, "shift-mcp-server.log");
68912
69059
  const shiftCfgPath = await writeShiftMcpConfig({
68913
69060
  dataDir: config.dataDir,
68914
69061
  serverScriptPath: shiftServerScriptPath,
@@ -68929,12 +69076,12 @@ async function startDaemon(config) {
68929
69076
  );
68930
69077
  }
68931
69078
  const inboxServerCandidates = [
68932
- import_node_path78.default.join(here, "inbox", "mcp-server.cjs"),
68933
- import_node_path78.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
69079
+ import_node_path79.default.join(here, "inbox", "mcp-server.cjs"),
69080
+ import_node_path79.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
68934
69081
  ];
68935
- const inboxServerScriptPath = inboxServerCandidates.find((p2) => import_node_fs56.default.existsSync(p2));
69082
+ const inboxServerScriptPath = inboxServerCandidates.find((p2) => import_node_fs57.default.existsSync(p2));
68936
69083
  if (inboxServerScriptPath) {
68937
- const inboxLogPath = import_node_path78.default.join(logDir, "inbox-mcp-server.log");
69084
+ const inboxLogPath = import_node_path79.default.join(logDir, "inbox-mcp-server.log");
68938
69085
  const inboxCfgPath = await writeInboxMcpConfig({
68939
69086
  dataDir: config.dataDir,
68940
69087
  serverScriptPath: inboxServerScriptPath,
@@ -68955,10 +69102,10 @@ async function startDaemon(config) {
68955
69102
  );
68956
69103
  }
68957
69104
  const peerOpsServerCandidates = [
68958
- import_node_path78.default.join(here, "peer-ops", "mcp-server.cjs"),
68959
- import_node_path78.default.join(here, "..", "dist", "peer-ops", "mcp-server.cjs")
69105
+ import_node_path79.default.join(here, "peer-ops", "mcp-server.cjs"),
69106
+ import_node_path79.default.join(here, "..", "dist", "peer-ops", "mcp-server.cjs")
68960
69107
  ];
68961
- const peerOpsServerScriptPath = peerOpsServerCandidates.find((p2) => import_node_fs56.default.existsSync(p2));
69108
+ const peerOpsServerScriptPath = peerOpsServerCandidates.find((p2) => import_node_fs57.default.existsSync(p2));
68962
69109
  if (peerOpsServerScriptPath) {
68963
69110
  const peerOpsCfgPath = writePeerOpsMcpConfig({
68964
69111
  dataDir: config.dataDir,
@@ -68978,12 +69125,12 @@ async function startDaemon(config) {
68978
69125
  );
68979
69126
  }
68980
69127
  const rpcToolServerCandidates = [
68981
- import_node_path78.default.join(here, "rpc-tool", "mcp-server.cjs"),
68982
- import_node_path78.default.join(here, "..", "dist", "rpc-tool", "mcp-server.cjs")
69128
+ import_node_path79.default.join(here, "rpc-tool", "mcp-server.cjs"),
69129
+ import_node_path79.default.join(here, "..", "dist", "rpc-tool", "mcp-server.cjs")
68983
69130
  ];
68984
- const rpcToolServerScriptPath = rpcToolServerCandidates.find((p2) => import_node_fs56.default.existsSync(p2));
69131
+ const rpcToolServerScriptPath = rpcToolServerCandidates.find((p2) => import_node_fs57.default.existsSync(p2));
68985
69132
  if (rpcToolServerScriptPath) {
68986
- const rpcToolLogPath = import_node_path78.default.join(logDir, "rpc-tool-mcp-server.log");
69133
+ const rpcToolLogPath = import_node_path79.default.join(logDir, "rpc-tool-mcp-server.log");
68987
69134
  const rpcToolCfgPath = writeRpcToolMcpConfig({
68988
69135
  dataDir: config.dataDir,
68989
69136
  serverScriptPath: rpcToolServerScriptPath,
@@ -69004,18 +69151,18 @@ async function startDaemon(config) {
69004
69151
  );
69005
69152
  }
69006
69153
  const appBuilderServerCandidates = [
69007
- import_node_path78.default.join(here, "app-builder-plugin", "mcp-server.cjs"),
69008
- import_node_path78.default.join(here, "..", "dist", "app-builder-plugin", "mcp-server.cjs")
69154
+ import_node_path79.default.join(here, "app-builder-plugin", "mcp-server.cjs"),
69155
+ import_node_path79.default.join(here, "..", "dist", "app-builder-plugin", "mcp-server.cjs")
69009
69156
  ];
69010
- const appBuilderServerScriptPath = appBuilderServerCandidates.find((p2) => import_node_fs56.default.existsSync(p2));
69157
+ const appBuilderServerScriptPath = appBuilderServerCandidates.find((p2) => import_node_fs57.default.existsSync(p2));
69011
69158
  if (appBuilderServerScriptPath) {
69012
- const appBuilderLogPath = import_node_path78.default.join(logDir, "app-builder-mcp-server.log");
69159
+ const appBuilderLogPath = import_node_path79.default.join(logDir, "app-builder-mcp-server.log");
69013
69160
  const appBuilderCfgPath = writeAppBuilderMcpConfig({
69014
69161
  dataDir: config.dataDir,
69015
69162
  serverScriptPath: appBuilderServerScriptPath,
69016
69163
  daemonToken: resolvedAuthToken,
69017
69164
  daemonUrl: mcpDaemonUrl,
69018
- deployKitScriptsDir: import_node_path78.default.join(config.dataDir, "deploy-kit", "scripts"),
69165
+ deployKitScriptsDir: import_node_path79.default.join(config.dataDir, "deploy-kit", "scripts"),
69019
69166
  logPath: appBuilderLogPath
69020
69167
  });
69021
69168
  mcpConfigs.push({ id: "app-builder", path: appBuilderCfgPath, personas: APP_BUILDER_PERSONAS });
@@ -69031,7 +69178,7 @@ async function startDaemon(config) {
69031
69178
  );
69032
69179
  }
69033
69180
  const shiftStore = createShiftStore({
69034
- filePath: import_node_path78.default.join(config.dataDir, "shift.json"),
69181
+ filePath: import_node_path79.default.join(config.dataDir, "shift.json"),
69035
69182
  ownerIdProvider: () => ownerPrincipalId,
69036
69183
  now: () => Date.now()
69037
69184
  });
@@ -69053,7 +69200,7 @@ async function startDaemon(config) {
69053
69200
  getAdapter,
69054
69201
  historyReader: history,
69055
69202
  dataDir: config.dataDir,
69056
- personaRoot: import_node_path78.default.join(config.dataDir, "personas"),
69203
+ personaRoot: import_node_path79.default.join(config.dataDir, "personas"),
69057
69204
  // dispatch / shift 自动化 spawn 按 persona 绑定 tool 起 B session(codex persona 用 codex)。
69058
69205
  // personaRegistry 声明在 manager 之后(同作用域 const,调用时机在启动完成后,无 TDZ 风险)。
69059
69206
  getPersonaDefaults: (personaId2) => personaRegistry.get(personaId2),
@@ -69110,10 +69257,10 @@ async function startDaemon(config) {
69110
69257
  // 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
69111
69258
  attachmentGroup: {
69112
69259
  onFileEdit: (input) => {
69113
- const absPath = import_node_path78.default.isAbsolute(input.relPath) ? input.relPath : import_node_path78.default.join(input.cwd, input.relPath);
69260
+ const absPath = import_node_path79.default.isAbsolute(input.relPath) ? input.relPath : import_node_path79.default.join(input.cwd, input.relPath);
69114
69261
  let size = 0;
69115
69262
  try {
69116
- size = import_node_fs56.default.statSync(absPath).size;
69263
+ size = import_node_fs57.default.statSync(absPath).size;
69117
69264
  } catch (err) {
69118
69265
  logger.warn("attachment.onFileEdit stat failed", {
69119
69266
  sessionId: input.sessionId,
@@ -69143,9 +69290,9 @@ async function startDaemon(config) {
69143
69290
  logger.info("projects.seed-dropped", { dropped: droppedSeed.dropped, backup: droppedSeed.backup });
69144
69291
  }
69145
69292
  const projectsStore = new ProjectsStore({
69146
- file: import_node_path78.default.join(config.dataDir, "projects.json"),
69293
+ file: import_node_path79.default.join(config.dataDir, "projects.json"),
69147
69294
  clawdDir: config.dataDir,
69148
- codexStateFile: import_node_path78.default.join(import_node_os26.default.homedir(), ".codex", ".codex-global-state.json"),
69295
+ codexStateFile: import_node_path79.default.join(import_node_os27.default.homedir(), ".codex", ".codex-global-state.json"),
69149
69296
  logger
69150
69297
  });
69151
69298
  const observer = new SessionObserver({
@@ -69205,13 +69352,13 @@ async function startDaemon(config) {
69205
69352
  screenIdleProbeLogger
69206
69353
  }) : new ClaudeAdapter({ logger, historyReader: new ClaudeHistoryReader() });
69207
69354
  registerAdapter("claude", claudeAdapter);
69208
- const codexIsolatedHome = import_node_path78.default.join(config.dataDir, "codex-home");
69355
+ const codexIsolatedHome = import_node_path79.default.join(config.dataDir, "codex-home");
69209
69356
  try {
69210
- import_node_fs56.default.mkdirSync(codexIsolatedHome, { recursive: true });
69357
+ import_node_fs57.default.mkdirSync(codexIsolatedHome, { recursive: true });
69211
69358
  for (const f of ["auth.json", "config.toml"]) {
69212
- const link = import_node_path78.default.join(codexIsolatedHome, f);
69213
- const target = import_node_path78.default.join(import_node_os26.default.homedir(), ".codex", f);
69214
- if (!import_node_fs56.default.existsSync(link) && import_node_fs56.default.existsSync(target)) import_node_fs56.default.symlinkSync(target, link);
69359
+ const link = import_node_path79.default.join(codexIsolatedHome, f);
69360
+ const target = import_node_path79.default.join(import_node_os27.default.homedir(), ".codex", f);
69361
+ if (!import_node_fs57.default.existsSync(link) && import_node_fs57.default.existsSync(target)) import_node_fs57.default.symlinkSync(target, link);
69215
69362
  }
69216
69363
  } catch (err) {
69217
69364
  logger.warn("codex isolated home setup failed", { err: String(err) });
@@ -69224,11 +69371,11 @@ async function startDaemon(config) {
69224
69371
  // projectPaths 每次调用现取 —— 用户新建 project 后立即生效,不用重启 daemon
69225
69372
  codexHomeFor: (cwd) => resolveCodexHome({
69226
69373
  cwd,
69227
- personaRoot: import_node_path78.default.join(config.dataDir, "personas"),
69374
+ personaRoot: import_node_path79.default.join(config.dataDir, "personas"),
69228
69375
  // 必须用 listMerged(Codex registry ∪ 叠加层):只用本地 list() 的话,用户在
69229
69376
  // Codex 里建的 project 不在表里,在它下面开的会话会被误判成隔离 → Codex 侧看不到
69230
69377
  projectPaths: projectsStore.listMerged().map((x) => x.path),
69231
- sharedHome: import_node_path78.default.join(import_node_os26.default.homedir(), ".codex"),
69378
+ sharedHome: import_node_path79.default.join(import_node_os27.default.homedir(), ".codex"),
69232
69379
  isolatedHome: codexIsolatedHome
69233
69380
  })
69234
69381
  })
@@ -69513,11 +69660,11 @@ async function startDaemon(config) {
69513
69660
  // 'persona/<pid>/owner',default 走 'default'。
69514
69661
  getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
69515
69662
  // guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
69516
- personaRoot: import_node_path78.default.join(config.dataDir, "personas"),
69663
+ personaRoot: import_node_path79.default.join(config.dataDir, "personas"),
69517
69664
  usersRoot
69518
69665
  },
69519
69666
  // workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
69520
- personaRoot: import_node_path78.default.join(config.dataDir, "personas"),
69667
+ personaRoot: import_node_path79.default.join(config.dataDir, "personas"),
69521
69668
  // v2 多人 persona 隔离:handler 派生 guest user-dir 放行
69522
69669
  usersRoot,
69523
69670
  // v2 Phase 6: whoami handler 装在 owner principal.displayName + persona 解析
@@ -69624,11 +69771,11 @@ async function startDaemon(config) {
69624
69771
  // 发布上线脚手架化 (spec 2026-06-03 §5.2):
69625
69772
  // appBuilderPersonaRoot 用于拼 publish.sh 绝对路径(persona-app-builder 安装在
69626
69773
  // dataDir/personas/persona-app-builder 之下,extension-kit/scripts/publish.sh 是相对路径)。
69627
- appBuilderPersonaRoot: import_node_path78.default.join(config.dataDir, "personas", "persona-app-builder"),
69774
+ appBuilderPersonaRoot: import_node_path79.default.join(config.dataDir, "personas", "persona-app-builder"),
69628
69775
  // 共享 deploy-kit 根:scaffold/publish 脚本骨架 + 阿里云凭证单一真源。
69629
- deployKitRoot: import_node_path78.default.join(config.dataDir, "deploy-kit"),
69776
+ deployKitRoot: import_node_path79.default.join(config.dataDir, "deploy-kit"),
69630
69777
  // scaffold/publish 按当前 session 的 persona 解析其安装根,让每个 persona 用自己的模板/注入配置。
69631
- resolvePersonaRoot: (personaId2) => import_node_path78.default.join(config.dataDir, "personas", personaId2),
69778
+ resolvePersonaRoot: (personaId2) => import_node_path79.default.join(config.dataDir, "personas", personaId2),
69632
69779
  // 凭据表(M1b Step 5):与 MCP 那条同一张表、同一个来源,只是交付给另一个子进程。
69633
69780
  readSecrets,
69634
69781
  // 发布上线脚手架化 (spec 2026-06-03 §5.2.2):
@@ -69685,7 +69832,7 @@ async function startDaemon(config) {
69685
69832
  sourceSessionId: args.sourceSessionId
69686
69833
  });
69687
69834
  const sourceFile = manager.findOwnedSession(args.sourceSessionId);
69688
- const sourceJsonlPath = resolveSourceJsonlPath(sourceFile, import_node_os26.default.homedir());
69835
+ const sourceJsonlPath = resolveSourceJsonlPath(sourceFile, import_node_os27.default.homedir());
69689
69836
  logger.info("dispatch.spawnB.source-resolved", {
69690
69837
  dispatchId: args.dispatchId,
69691
69838
  sourceJsonlPath,
@@ -69812,7 +69959,7 @@ async function startDaemon(config) {
69812
69959
  });
69813
69960
  shiftScheduler.start();
69814
69961
  logger.info("shift scheduler started", { shiftCount: shiftStore.list().length });
69815
- const larkBotStore = createLarkBotBindingStore(import_node_path78.default.join(config.dataDir, "personas"));
69962
+ const larkBotStore = createLarkBotBindingStore(import_node_path79.default.join(config.dataDir, "personas"));
69816
69963
  const larkBotCloud = createLarkBotCloudClient({
69817
69964
  api: config.clawosApi ?? DEFAULT_CLAWOS_API,
69818
69965
  apiKey: resolveClawdTicketsApiKey(),
@@ -69826,7 +69973,7 @@ async function startDaemon(config) {
69826
69973
  store: larkBotStore,
69827
69974
  fetchResource: (appId, messageId, fileKey, maxBytes, type) => larkBotCloud.fetchResource(appId, messageId, fileKey, maxBytes, type),
69828
69975
  // 图片落 guest userWorkDir 下(capId = lark-<chat_id>):CC 经 --add-dir + allowRead carve 可 Read
69829
- mediaRootFor: (chatId) => import_node_path78.default.join(deriveUserWorkDir(`lark-${chatId}`, usersRoot), "lark-media"),
69976
+ mediaRootFor: (chatId) => import_node_path79.default.join(deriveUserWorkDir(`lark-${chatId}`, usersRoot), "lark-media"),
69830
69977
  isShuttingDown: () => larkDraining,
69831
69978
  logger: {
69832
69979
  warn: (msg) => logger.warn(msg),
@@ -70131,8 +70278,8 @@ async function startDaemon(config) {
70131
70278
  const lines = [
70132
70279
  `Tunnel: ${r.url}`,
70133
70280
  ...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
70134
- `Frpc config: ${import_node_path78.default.join(config.dataDir, "frpc.toml")}`,
70135
- `Frpc log: ${import_node_path78.default.join(logDir, "frpc.log")}`
70281
+ `Frpc config: ${import_node_path79.default.join(config.dataDir, "frpc.toml")}`,
70282
+ `Frpc log: ${import_node_path79.default.join(logDir, "frpc.log")}`
70136
70283
  ];
70137
70284
  const width2 = Math.max(...lines.map((l) => l.length));
70138
70285
  const bar = "\u2550".repeat(width2 + 4);
@@ -70145,8 +70292,8 @@ ${bar}
70145
70292
 
70146
70293
  `);
70147
70294
  try {
70148
- const connectPath = import_node_path78.default.join(config.dataDir, "connect.txt");
70149
- import_node_fs56.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
70295
+ const connectPath = import_node_path79.default.join(config.dataDir, "connect.txt");
70296
+ import_node_fs57.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
70150
70297
  } catch {
70151
70298
  }
70152
70299
  } catch (err) {
@@ -70233,9 +70380,9 @@ ${bar}
70233
70380
  };
70234
70381
  }
70235
70382
  function migrateDropPersonsDir(dataDir) {
70236
- const dir = import_node_path78.default.join(dataDir, "persons");
70383
+ const dir = import_node_path79.default.join(dataDir, "persons");
70237
70384
  try {
70238
- import_node_fs56.default.rmSync(dir, { recursive: true, force: true });
70385
+ import_node_fs57.default.rmSync(dir, { recursive: true, force: true });
70239
70386
  } catch {
70240
70387
  }
70241
70388
  }