@clawos-dev/clawd 0.2.485 → 0.2.486

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() {
@@ -7603,7 +7603,12 @@ var init_schemas = __esm({
7603
7603
  // 缺省 = 该 tool 的 effort 与模型无关(claude 即此情形),消费方回落到 configSchema 里
7604
7604
  // name==='effort' 那条字段的 options。
7605
7605
  efforts: external_exports.array(SelectOptionSchema).optional(),
7606
- defaultEffort: external_exports.string().optional()
7606
+ defaultEffort: external_exports.string().optional(),
7607
+ // 下拉分组标题(codex:模型家族名 GPT / Gemini / Claude…,由 daemon 从 model id 派生)。
7608
+ // 缺省 = 该 tool 的模型不分组(claude 即此情形),消费方平铺渲染、不出标题。
7609
+ // 全表只落在一个家族时 daemon 也不填——一个横跨全表的标题没有信息量。
7610
+ // 消费方假定同 group 的条目已连续排好(排序在 daemon 侧,见 codex-model-list.mergeProviderModels)。
7611
+ group: external_exports.string().optional()
7607
7612
  });
7608
7613
  ModeInfoSchema = external_exports.object({
7609
7614
  id: external_exports.string().min(1),
@@ -9919,8 +9924,8 @@ var require_req = __commonJS({
9919
9924
  if (req.originalUrl) {
9920
9925
  _req.url = req.originalUrl;
9921
9926
  } else {
9922
- const path97 = req.path;
9923
- _req.url = typeof path97 === "string" ? path97 : req.url ? req.url.path || req.url : void 0;
9927
+ const path98 = req.path;
9928
+ _req.url = typeof path98 === "string" ? path98 : req.url ? req.url.path || req.url : void 0;
9924
9929
  }
9925
9930
  if (req.query) {
9926
9931
  _req.query = req.query;
@@ -10085,14 +10090,14 @@ var require_redact = __commonJS({
10085
10090
  }
10086
10091
  return obj;
10087
10092
  }
10088
- function parsePath(path97) {
10093
+ function parsePath(path98) {
10089
10094
  const parts = [];
10090
10095
  let current = "";
10091
10096
  let inBrackets = false;
10092
10097
  let inQuotes = false;
10093
10098
  let quoteChar = "";
10094
- for (let i = 0; i < path97.length; i++) {
10095
- const char = path97[i];
10099
+ for (let i = 0; i < path98.length; i++) {
10100
+ const char = path98[i];
10096
10101
  if (!inBrackets && char === ".") {
10097
10102
  if (current) {
10098
10103
  parts.push(current);
@@ -10223,10 +10228,10 @@ var require_redact = __commonJS({
10223
10228
  return current;
10224
10229
  }
10225
10230
  function redactPaths(obj, paths, censor, remove = false) {
10226
- for (const path97 of paths) {
10227
- const parts = parsePath(path97);
10231
+ for (const path98 of paths) {
10232
+ const parts = parsePath(path98);
10228
10233
  if (parts.includes("*")) {
10229
- redactWildcardPath(obj, parts, censor, path97, remove);
10234
+ redactWildcardPath(obj, parts, censor, path98, remove);
10230
10235
  } else {
10231
10236
  if (remove) {
10232
10237
  removeKey(obj, parts);
@@ -10311,8 +10316,8 @@ var require_redact = __commonJS({
10311
10316
  }
10312
10317
  } else {
10313
10318
  if (afterWildcard.includes("*")) {
10314
- const wrappedCensor = typeof censor === "function" ? (value, path97) => {
10315
- const fullPath = [...pathArray.slice(0, pathLength), ...path97];
10319
+ const wrappedCensor = typeof censor === "function" ? (value, path98) => {
10320
+ const fullPath = [...pathArray.slice(0, pathLength), ...path98];
10316
10321
  return censor(value, fullPath);
10317
10322
  } : censor;
10318
10323
  redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
@@ -10347,8 +10352,8 @@ var require_redact = __commonJS({
10347
10352
  return null;
10348
10353
  }
10349
10354
  const pathStructure = /* @__PURE__ */ new Map();
10350
- for (const path97 of pathsToClone) {
10351
- const parts = parsePath(path97);
10355
+ for (const path98 of pathsToClone) {
10356
+ const parts = parsePath(path98);
10352
10357
  let current = pathStructure;
10353
10358
  for (let i = 0; i < parts.length; i++) {
10354
10359
  const part = parts[i];
@@ -10400,24 +10405,24 @@ var require_redact = __commonJS({
10400
10405
  }
10401
10406
  return cloneSelectively(obj, pathStructure);
10402
10407
  }
10403
- function validatePath(path97) {
10404
- if (typeof path97 !== "string") {
10408
+ function validatePath(path98) {
10409
+ if (typeof path98 !== "string") {
10405
10410
  throw new Error("Paths must be (non-empty) strings");
10406
10411
  }
10407
- if (path97 === "") {
10412
+ if (path98 === "") {
10408
10413
  throw new Error("Invalid redaction path ()");
10409
10414
  }
10410
- if (path97.includes("..")) {
10411
- throw new Error(`Invalid redaction path (${path97})`);
10415
+ if (path98.includes("..")) {
10416
+ throw new Error(`Invalid redaction path (${path98})`);
10412
10417
  }
10413
- if (path97.includes(",")) {
10414
- throw new Error(`Invalid redaction path (${path97})`);
10418
+ if (path98.includes(",")) {
10419
+ throw new Error(`Invalid redaction path (${path98})`);
10415
10420
  }
10416
10421
  let bracketCount = 0;
10417
10422
  let inQuotes = false;
10418
10423
  let quoteChar = "";
10419
- for (let i = 0; i < path97.length; i++) {
10420
- const char = path97[i];
10424
+ for (let i = 0; i < path98.length; i++) {
10425
+ const char = path98[i];
10421
10426
  if ((char === '"' || char === "'") && bracketCount > 0) {
10422
10427
  if (!inQuotes) {
10423
10428
  inQuotes = true;
@@ -10431,20 +10436,20 @@ var require_redact = __commonJS({
10431
10436
  } else if (char === "]" && !inQuotes) {
10432
10437
  bracketCount--;
10433
10438
  if (bracketCount < 0) {
10434
- throw new Error(`Invalid redaction path (${path97})`);
10439
+ throw new Error(`Invalid redaction path (${path98})`);
10435
10440
  }
10436
10441
  }
10437
10442
  }
10438
10443
  if (bracketCount !== 0) {
10439
- throw new Error(`Invalid redaction path (${path97})`);
10444
+ throw new Error(`Invalid redaction path (${path98})`);
10440
10445
  }
10441
10446
  }
10442
10447
  function validatePaths(paths) {
10443
10448
  if (!Array.isArray(paths)) {
10444
10449
  throw new TypeError("paths must be an array");
10445
10450
  }
10446
- for (const path97 of paths) {
10447
- validatePath(path97);
10451
+ for (const path98 of paths) {
10452
+ validatePath(path98);
10448
10453
  }
10449
10454
  }
10450
10455
  function slowRedact(options = {}) {
@@ -10612,8 +10617,8 @@ var require_redaction = __commonJS({
10612
10617
  if (shape[k2] === null) {
10613
10618
  o[k2] = (value) => topCensor(value, [k2]);
10614
10619
  } else {
10615
- const wrappedCensor = typeof censor === "function" ? (value, path97) => {
10616
- return censor(value, [k2, ...path97]);
10620
+ const wrappedCensor = typeof censor === "function" ? (value, path98) => {
10621
+ return censor(value, [k2, ...path98]);
10617
10622
  } : censor;
10618
10623
  o[k2] = Redact({
10619
10624
  paths: shape[k2],
@@ -10831,10 +10836,10 @@ var require_atomic_sleep = __commonJS({
10831
10836
  var require_sonic_boom = __commonJS({
10832
10837
  "../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
10833
10838
  "use strict";
10834
- var fs85 = require("fs");
10839
+ var fs86 = require("fs");
10835
10840
  var EventEmitter3 = require("events");
10836
10841
  var inherits = require("util").inherits;
10837
- var path97 = require("path");
10842
+ var path98 = require("path");
10838
10843
  var sleep2 = require_atomic_sleep();
10839
10844
  var assert = require("assert");
10840
10845
  var BUSY_WRITE_TIMEOUT = 100;
@@ -10888,20 +10893,20 @@ var require_sonic_boom = __commonJS({
10888
10893
  const mode = sonic.mode;
10889
10894
  if (sonic.sync) {
10890
10895
  try {
10891
- if (sonic.mkdir) fs85.mkdirSync(path97.dirname(file), { recursive: true });
10892
- const fd = fs85.openSync(file, flags, mode);
10896
+ if (sonic.mkdir) fs86.mkdirSync(path98.dirname(file), { recursive: true });
10897
+ const fd = fs86.openSync(file, flags, mode);
10893
10898
  fileOpened(null, fd);
10894
10899
  } catch (err) {
10895
10900
  fileOpened(err);
10896
10901
  throw err;
10897
10902
  }
10898
10903
  } else if (sonic.mkdir) {
10899
- fs85.mkdir(path97.dirname(file), { recursive: true }, (err) => {
10904
+ fs86.mkdir(path98.dirname(file), { recursive: true }, (err) => {
10900
10905
  if (err) return fileOpened(err);
10901
- fs85.open(file, flags, mode, fileOpened);
10906
+ fs86.open(file, flags, mode, fileOpened);
10902
10907
  });
10903
10908
  } else {
10904
- fs85.open(file, flags, mode, fileOpened);
10909
+ fs86.open(file, flags, mode, fileOpened);
10905
10910
  }
10906
10911
  }
10907
10912
  function SonicBoom(opts) {
@@ -10942,8 +10947,8 @@ var require_sonic_boom = __commonJS({
10942
10947
  this.flush = flushBuffer;
10943
10948
  this.flushSync = flushBufferSync;
10944
10949
  this._actualWrite = actualWriteBuffer;
10945
- fsWriteSync = () => fs85.writeSync(this.fd, this._writingBuf);
10946
- fsWrite = () => fs85.write(this.fd, this._writingBuf, this.release);
10950
+ fsWriteSync = () => fs86.writeSync(this.fd, this._writingBuf);
10951
+ fsWrite = () => fs86.write(this.fd, this._writingBuf, this.release);
10947
10952
  } else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
10948
10953
  this._writingBuf = "";
10949
10954
  this.write = write;
@@ -10952,15 +10957,15 @@ var require_sonic_boom = __commonJS({
10952
10957
  this._actualWrite = actualWrite;
10953
10958
  fsWriteSync = () => {
10954
10959
  if (Buffer.isBuffer(this._writingBuf)) {
10955
- return fs85.writeSync(this.fd, this._writingBuf);
10960
+ return fs86.writeSync(this.fd, this._writingBuf);
10956
10961
  }
10957
- return fs85.writeSync(this.fd, this._writingBuf, "utf8");
10962
+ return fs86.writeSync(this.fd, this._writingBuf, "utf8");
10958
10963
  };
10959
10964
  fsWrite = () => {
10960
10965
  if (Buffer.isBuffer(this._writingBuf)) {
10961
- return fs85.write(this.fd, this._writingBuf, this.release);
10966
+ return fs86.write(this.fd, this._writingBuf, this.release);
10962
10967
  }
10963
- return fs85.write(this.fd, this._writingBuf, "utf8", this.release);
10968
+ return fs86.write(this.fd, this._writingBuf, "utf8", this.release);
10964
10969
  };
10965
10970
  } else {
10966
10971
  throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
@@ -11017,7 +11022,7 @@ var require_sonic_boom = __commonJS({
11017
11022
  }
11018
11023
  }
11019
11024
  if (this._fsync) {
11020
- fs85.fsyncSync(this.fd);
11025
+ fs86.fsyncSync(this.fd);
11021
11026
  }
11022
11027
  const len = this._len;
11023
11028
  if (this._reopening) {
@@ -11131,7 +11136,7 @@ var require_sonic_boom = __commonJS({
11131
11136
  const onDrain = () => {
11132
11137
  if (!this._fsync) {
11133
11138
  try {
11134
- fs85.fsync(this.fd, (err) => {
11139
+ fs86.fsync(this.fd, (err) => {
11135
11140
  this._flushPending = false;
11136
11141
  cb(err);
11137
11142
  });
@@ -11233,7 +11238,7 @@ var require_sonic_boom = __commonJS({
11233
11238
  const fd = this.fd;
11234
11239
  this.once("ready", () => {
11235
11240
  if (fd !== this.fd) {
11236
- fs85.close(fd, (err) => {
11241
+ fs86.close(fd, (err) => {
11237
11242
  if (err) {
11238
11243
  return this.emit("error", err);
11239
11244
  }
@@ -11282,7 +11287,7 @@ var require_sonic_boom = __commonJS({
11282
11287
  buf = this._bufs[0];
11283
11288
  }
11284
11289
  try {
11285
- const n = Buffer.isBuffer(buf) ? fs85.writeSync(this.fd, buf) : fs85.writeSync(this.fd, buf, "utf8");
11290
+ const n = Buffer.isBuffer(buf) ? fs86.writeSync(this.fd, buf) : fs86.writeSync(this.fd, buf, "utf8");
11286
11291
  const releasedBufObj = releaseWritingBuf(buf, this._len, n);
11287
11292
  buf = releasedBufObj.writingBuf;
11288
11293
  this._len = releasedBufObj.len;
@@ -11298,7 +11303,7 @@ var require_sonic_boom = __commonJS({
11298
11303
  }
11299
11304
  }
11300
11305
  try {
11301
- fs85.fsyncSync(this.fd);
11306
+ fs86.fsyncSync(this.fd);
11302
11307
  } catch {
11303
11308
  }
11304
11309
  }
@@ -11319,7 +11324,7 @@ var require_sonic_boom = __commonJS({
11319
11324
  buf = mergeBuf(this._bufs[0], this._lens[0]);
11320
11325
  }
11321
11326
  try {
11322
- const n = fs85.writeSync(this.fd, buf);
11327
+ const n = fs86.writeSync(this.fd, buf);
11323
11328
  buf = buf.subarray(n);
11324
11329
  this._len = Math.max(this._len - n, 0);
11325
11330
  if (buf.length <= 0) {
@@ -11347,13 +11352,13 @@ var require_sonic_boom = __commonJS({
11347
11352
  this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
11348
11353
  if (this.sync) {
11349
11354
  try {
11350
- const written = Buffer.isBuffer(this._writingBuf) ? fs85.writeSync(this.fd, this._writingBuf) : fs85.writeSync(this.fd, this._writingBuf, "utf8");
11355
+ const written = Buffer.isBuffer(this._writingBuf) ? fs86.writeSync(this.fd, this._writingBuf) : fs86.writeSync(this.fd, this._writingBuf, "utf8");
11351
11356
  release2(null, written);
11352
11357
  } catch (err) {
11353
11358
  release2(err);
11354
11359
  }
11355
11360
  } else {
11356
- fs85.write(this.fd, this._writingBuf, release2);
11361
+ fs86.write(this.fd, this._writingBuf, release2);
11357
11362
  }
11358
11363
  }
11359
11364
  function actualWriteBuffer() {
@@ -11362,7 +11367,7 @@ var require_sonic_boom = __commonJS({
11362
11367
  this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
11363
11368
  if (this.sync) {
11364
11369
  try {
11365
- const written = fs85.writeSync(this.fd, this._writingBuf);
11370
+ const written = fs86.writeSync(this.fd, this._writingBuf);
11366
11371
  release2(null, written);
11367
11372
  } catch (err) {
11368
11373
  release2(err);
@@ -11371,7 +11376,7 @@ var require_sonic_boom = __commonJS({
11371
11376
  if (kCopyBuffer) {
11372
11377
  this._writingBuf = Buffer.from(this._writingBuf);
11373
11378
  }
11374
- fs85.write(this.fd, this._writingBuf, release2);
11379
+ fs86.write(this.fd, this._writingBuf, release2);
11375
11380
  }
11376
11381
  }
11377
11382
  function actualClose(sonic) {
@@ -11387,12 +11392,12 @@ var require_sonic_boom = __commonJS({
11387
11392
  sonic._lens = [];
11388
11393
  assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
11389
11394
  try {
11390
- fs85.fsync(sonic.fd, closeWrapped);
11395
+ fs86.fsync(sonic.fd, closeWrapped);
11391
11396
  } catch {
11392
11397
  }
11393
11398
  function closeWrapped() {
11394
11399
  if (sonic.fd !== 1 && sonic.fd !== 2) {
11395
- fs85.close(sonic.fd, done);
11400
+ fs86.close(sonic.fd, done);
11396
11401
  } else {
11397
11402
  done();
11398
11403
  }
@@ -13756,7 +13761,7 @@ var require_multistream = __commonJS({
13756
13761
  var require_pino = __commonJS({
13757
13762
  "../node_modules/.pnpm/pino@9.14.0/node_modules/pino/pino.js"(exports2, module2) {
13758
13763
  "use strict";
13759
- var os31 = require("os");
13764
+ var os32 = require("os");
13760
13765
  var stdSerializers = require_pino_std_serializers();
13761
13766
  var caller = require_caller();
13762
13767
  var redaction = require_redaction();
@@ -13803,7 +13808,7 @@ var require_pino = __commonJS({
13803
13808
  } = symbols;
13804
13809
  var { epochTime, nullTime } = time;
13805
13810
  var { pid } = process;
13806
- var hostname = os31.hostname();
13811
+ var hostname = os32.hostname();
13807
13812
  var defaultErrorSerializer = stdSerializers.err;
13808
13813
  var defaultOptions2 = {
13809
13814
  level: "info",
@@ -14527,11 +14532,11 @@ var init_lib = __esm({
14527
14532
  }
14528
14533
  }
14529
14534
  },
14530
- addToPath: function addToPath(path97, added, removed, oldPosInc, options) {
14531
- var last = path97.lastComponent;
14535
+ addToPath: function addToPath(path98, added, removed, oldPosInc, options) {
14536
+ var last = path98.lastComponent;
14532
14537
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
14533
14538
  return {
14534
- oldPos: path97.oldPos + oldPosInc,
14539
+ oldPos: path98.oldPos + oldPosInc,
14535
14540
  lastComponent: {
14536
14541
  count: last.count + 1,
14537
14542
  added,
@@ -14541,7 +14546,7 @@ var init_lib = __esm({
14541
14546
  };
14542
14547
  } else {
14543
14548
  return {
14544
- oldPos: path97.oldPos + oldPosInc,
14549
+ oldPos: path98.oldPos + oldPosInc,
14545
14550
  lastComponent: {
14546
14551
  count: 1,
14547
14552
  added,
@@ -15123,10 +15128,10 @@ function attachmentToHistoryMessage(o, ts) {
15123
15128
  const memories = raw.map((m2) => {
15124
15129
  if (!m2 || typeof m2 !== "object") return null;
15125
15130
  const rec4 = m2;
15126
- const path97 = typeof rec4.path === "string" ? rec4.path : null;
15131
+ const path98 = typeof rec4.path === "string" ? rec4.path : null;
15127
15132
  const content = typeof rec4.content === "string" ? rec4.content : null;
15128
- if (!path97 || content == null) return null;
15129
- const entry = { path: path97, content };
15133
+ if (!path98 || content == null) return null;
15134
+ const entry = { path: path98, content };
15130
15135
  if (typeof rec4.mtimeMs === "number") entry.mtimeMs = rec4.mtimeMs;
15131
15136
  return entry;
15132
15137
  }).filter((m2) => m2 !== null);
@@ -15992,10 +15997,10 @@ function parseAttachment(obj) {
15992
15997
  const memories = raw.map((m2) => {
15993
15998
  if (!m2 || typeof m2 !== "object") return null;
15994
15999
  const rec4 = m2;
15995
- const path97 = typeof rec4.path === "string" ? rec4.path : null;
16000
+ const path98 = typeof rec4.path === "string" ? rec4.path : null;
15996
16001
  const content = typeof rec4.content === "string" ? rec4.content : null;
15997
- if (!path97 || content == null) return null;
15998
- const out = { path: path97, content };
16002
+ if (!path98 || content == null) return null;
16003
+ const out = { path: path98, content };
15999
16004
  if (typeof rec4.mtimeMs === "number") out.mtimeMs = rec4.mtimeMs;
16000
16005
  return out;
16001
16006
  }).filter((m2) => m2 !== null);
@@ -36969,8 +36974,8 @@ var require_utils = __commonJS({
36969
36974
  var result = transform[inputType][outputType](input);
36970
36975
  return result;
36971
36976
  };
36972
- exports2.resolve = function(path97) {
36973
- var parts = path97.split("/");
36977
+ exports2.resolve = function(path98) {
36978
+ var parts = path98.split("/");
36974
36979
  var result = [];
36975
36980
  for (var index = 0; index < parts.length; index++) {
36976
36981
  var part = parts[index];
@@ -42823,18 +42828,18 @@ var require_object = __commonJS({
42823
42828
  var object = new ZipObject(name, zipObjectContent, o);
42824
42829
  this.files[name] = object;
42825
42830
  };
42826
- var parentFolder = function(path97) {
42827
- if (path97.slice(-1) === "/") {
42828
- path97 = path97.substring(0, path97.length - 1);
42831
+ var parentFolder = function(path98) {
42832
+ if (path98.slice(-1) === "/") {
42833
+ path98 = path98.substring(0, path98.length - 1);
42829
42834
  }
42830
- var lastSlash = path97.lastIndexOf("/");
42831
- return lastSlash > 0 ? path97.substring(0, lastSlash) : "";
42835
+ var lastSlash = path98.lastIndexOf("/");
42836
+ return lastSlash > 0 ? path98.substring(0, lastSlash) : "";
42832
42837
  };
42833
- var forceTrailingSlash = function(path97) {
42834
- if (path97.slice(-1) !== "/") {
42835
- path97 += "/";
42838
+ var forceTrailingSlash = function(path98) {
42839
+ if (path98.slice(-1) !== "/") {
42840
+ path98 += "/";
42836
42841
  }
42837
- return path97;
42842
+ return path98;
42838
42843
  };
42839
42844
  var folderAdd = function(name, createFolders) {
42840
42845
  createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
@@ -43836,7 +43841,7 @@ var require_lib3 = __commonJS({
43836
43841
  // src/run-case/recorder.ts
43837
43842
  function startRunCaseRecorder(opts) {
43838
43843
  const now = opts.now ?? Date.now;
43839
- const dir = import_node_path79.default.dirname(opts.recordPath);
43844
+ const dir = import_node_path80.default.dirname(opts.recordPath);
43840
43845
  let stream = null;
43841
43846
  let closing = false;
43842
43847
  let closedSettled = false;
@@ -43850,8 +43855,8 @@ function startRunCaseRecorder(opts) {
43850
43855
  });
43851
43856
  const ensureStream = () => {
43852
43857
  if (stream) return stream;
43853
- import_node_fs57.default.mkdirSync(dir, { recursive: true });
43854
- stream = import_node_fs57.default.createWriteStream(opts.recordPath, { flags: "a" });
43858
+ import_node_fs58.default.mkdirSync(dir, { recursive: true });
43859
+ stream = import_node_fs58.default.createWriteStream(opts.recordPath, { flags: "a" });
43855
43860
  stream.on("close", () => closedResolve());
43856
43861
  return stream;
43857
43862
  };
@@ -43876,12 +43881,12 @@ function startRunCaseRecorder(opts) {
43876
43881
  };
43877
43882
  return { tap, close, closed };
43878
43883
  }
43879
- var import_node_fs57, import_node_path79;
43884
+ var import_node_fs58, import_node_path80;
43880
43885
  var init_recorder = __esm({
43881
43886
  "src/run-case/recorder.ts"() {
43882
43887
  "use strict";
43883
- import_node_fs57 = __toESM(require("fs"), 1);
43884
- import_node_path79 = __toESM(require("path"), 1);
43888
+ import_node_fs58 = __toESM(require("fs"), 1);
43889
+ import_node_path80 = __toESM(require("path"), 1);
43885
43890
  }
43886
43891
  });
43887
43892
 
@@ -43924,7 +43929,7 @@ var init_wire = __esm({
43924
43929
  // src/run-case/controller.ts
43925
43930
  async function runController(opts) {
43926
43931
  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-"));
43932
+ const cwd = opts.cwd ?? (0, import_node_fs59.mkdtempSync)(import_node_path81.default.join(import_node_os28.default.tmpdir(), "clawd-runcase-"));
43928
43933
  const ownsCwd = opts.cwd === void 0;
43929
43934
  const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
43930
43935
  const spawnCtx = { cwd };
@@ -44085,19 +44090,19 @@ async function runController(opts) {
44085
44090
  if (sigintHandler) process.off("SIGINT", sigintHandler);
44086
44091
  if (ownsCwd) {
44087
44092
  try {
44088
- (0, import_node_fs58.rmSync)(cwd, { recursive: true, force: true });
44093
+ (0, import_node_fs59.rmSync)(cwd, { recursive: true, force: true });
44089
44094
  } catch {
44090
44095
  }
44091
44096
  }
44092
44097
  return exitCode ?? 0;
44093
44098
  }
44094
- var import_node_fs58, import_node_os27, import_node_path80;
44099
+ var import_node_fs59, import_node_os28, import_node_path81;
44095
44100
  var init_controller = __esm({
44096
44101
  "src/run-case/controller.ts"() {
44097
44102
  "use strict";
44098
- import_node_fs58 = require("fs");
44099
- import_node_os27 = __toESM(require("os"), 1);
44100
- import_node_path80 = __toESM(require("path"), 1);
44103
+ import_node_fs59 = require("fs");
44104
+ import_node_os28 = __toESM(require("os"), 1);
44105
+ import_node_path81 = __toESM(require("path"), 1);
44101
44106
  init_claude();
44102
44107
  init_stdout_splitter();
44103
44108
  init_permission_stdio();
@@ -44372,9 +44377,9 @@ Env (advanced):
44372
44377
  `;
44373
44378
 
44374
44379
  // 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);
44380
+ var import_node_path79 = __toESM(require("path"), 1);
44381
+ var import_node_fs57 = __toESM(require("fs"), 1);
44382
+ var import_node_os27 = __toESM(require("os"), 1);
44378
44383
  var import_node_crypto22 = require("crypto");
44379
44384
  var import_node_url5 = require("url");
44380
44385
 
@@ -51157,7 +51162,7 @@ init_claude();
51157
51162
 
51158
51163
  // src/tools/codex.ts
51159
51164
  var import_node_child_process6 = require("child_process");
51160
- var import_node_fs19 = __toESM(require("fs"), 1);
51165
+ var import_node_fs20 = __toESM(require("fs"), 1);
51161
51166
 
51162
51167
  // src/tools/codex-session.ts
51163
51168
  var import_node_child_process4 = require("child_process");
@@ -51630,8 +51635,8 @@ function turnStartInput(text) {
51630
51635
  const items = [];
51631
51636
  let leftover = text;
51632
51637
  for (const m2 of text.matchAll(SKILL_RE)) {
51633
- const [marker, name, path97] = m2;
51634
- items.push({ type: "skill", name, path: path97 });
51638
+ const [marker, name, path98] = m2;
51639
+ items.push({ type: "skill", name, path: path98 });
51635
51640
  leftover = leftover.replace(marker, "");
51636
51641
  }
51637
51642
  for (const m2 of text.matchAll(ATTACHMENT_RE2)) {
@@ -52020,6 +52025,105 @@ function mapModelList(raw) {
52020
52025
  }
52021
52026
  return models;
52022
52027
  }
52028
+ function modelFamily(id) {
52029
+ const head = (id.split("-")[0] || id).toLowerCase();
52030
+ if (head === "gpt") return "GPT";
52031
+ return head.charAt(0).toUpperCase() + head.slice(1);
52032
+ }
52033
+ function familyRank(family) {
52034
+ return family === "GPT" ? 0 : 1;
52035
+ }
52036
+ function mergeProviderModels(native, provider) {
52037
+ const nativeOrder = new Map(native.map((m2, i) => [m2.id, i]));
52038
+ const extras = provider.filter((p2) => !nativeOrder.has(p2.id)).map((p2) => ({ id: p2.id, label: p2.id, contextWindowSize: CODEX_CONTEXT_WINDOW }));
52039
+ const sorted = [...native, ...extras].sort((a, b2) => {
52040
+ const fa = modelFamily(a.id);
52041
+ const fb = modelFamily(b2.id);
52042
+ if (fa !== fb) return familyRank(fa) - familyRank(fb) || fa.localeCompare(fb);
52043
+ const ia = nativeOrder.get(a.id);
52044
+ const ib = nativeOrder.get(b2.id);
52045
+ if (ia !== void 0 && ib !== void 0) return ia - ib;
52046
+ if (ia !== void 0) return -1;
52047
+ if (ib !== void 0) return 1;
52048
+ return a.id.localeCompare(b2.id);
52049
+ });
52050
+ if (new Set(sorted.map((m2) => modelFamily(m2.id))).size <= 1) return sorted;
52051
+ return sorted.map((m2) => ({ ...m2, group: modelFamily(m2.id) }));
52052
+ }
52053
+
52054
+ // src/tools/codex-provider-models.ts
52055
+ var import_node_fs19 = __toESM(require("fs"), 1);
52056
+ var import_node_os7 = __toESM(require("os"), 1);
52057
+ var import_node_path18 = __toESM(require("path"), 1);
52058
+ var PROVIDER_FETCH_TIMEOUT_MS = 3e3;
52059
+ function asRecord(v2) {
52060
+ return v2 && typeof v2 === "object" && !Array.isArray(v2) ? v2 : null;
52061
+ }
52062
+ function readAuthKey(codexHome) {
52063
+ try {
52064
+ const raw = JSON.parse(import_node_fs19.default.readFileSync(import_node_path18.default.join(codexHome, "auth.json"), "utf8"));
52065
+ const key = asRecord(raw)?.OPENAI_API_KEY;
52066
+ return typeof key === "string" && key ? key : void 0;
52067
+ } catch {
52068
+ return void 0;
52069
+ }
52070
+ }
52071
+ function resolveProviderEndpoint(rawConfig, deps = {}) {
52072
+ const config = asRecord(asRecord(rawConfig)?.config);
52073
+ if (!config) return null;
52074
+ const name = config.model_provider;
52075
+ if (typeof name !== "string" || !name) return null;
52076
+ const entry = asRecord(asRecord(config.model_providers)?.[name]);
52077
+ if (!entry) return null;
52078
+ const baseUrl = entry.base_url;
52079
+ if (typeof baseUrl !== "string" || !baseUrl) return null;
52080
+ const env = deps.env ?? process.env;
52081
+ const codexHome = deps.codexHome ?? env.CODEX_HOME ?? import_node_path18.default.join(import_node_os7.default.homedir(), ".codex");
52082
+ const envKey = typeof entry.env_key === "string" && entry.env_key ? entry.env_key : null;
52083
+ const token = envKey ? env[envKey] : readAuthKey(codexHome);
52084
+ if (!token) {
52085
+ deps.logger?.warn?.(
52086
+ 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`
52087
+ );
52088
+ }
52089
+ return {
52090
+ baseUrl,
52091
+ headers: {
52092
+ Accept: "application/json",
52093
+ ...token ? { Authorization: `Bearer ${token}` } : {}
52094
+ }
52095
+ };
52096
+ }
52097
+ async function fetchProviderModels(endpoint, deps = {}) {
52098
+ const fetchImpl = deps.fetchImpl ?? fetch;
52099
+ const controller = new AbortController();
52100
+ const timer = setTimeout(() => controller.abort(), deps.timeoutMs ?? PROVIDER_FETCH_TIMEOUT_MS);
52101
+ const url = `${endpoint.baseUrl.replace(/\/$/, "")}/models`;
52102
+ try {
52103
+ const res = await fetchImpl(url, { headers: endpoint.headers, signal: controller.signal });
52104
+ if (!res.ok) {
52105
+ deps.logger?.warn?.(`provider model list failed: HTTP ${res.status} from ${url}`);
52106
+ return [];
52107
+ }
52108
+ const data = asRecord(await res.json())?.data;
52109
+ if (!Array.isArray(data)) {
52110
+ deps.logger?.warn?.(`provider model list: \`data\` is not an array (${url})`);
52111
+ return [];
52112
+ }
52113
+ const out = [];
52114
+ for (const item of data) {
52115
+ const e = asRecord(item);
52116
+ if (!e || typeof e.id !== "string" || !e.id) continue;
52117
+ out.push({ id: e.id, ...typeof e.owned_by === "string" ? { ownedBy: e.owned_by } : {} });
52118
+ }
52119
+ return out;
52120
+ } catch (err) {
52121
+ deps.logger?.warn?.(`provider model list failed: ${err.message}`);
52122
+ return [];
52123
+ } finally {
52124
+ clearTimeout(timer);
52125
+ }
52126
+ }
52023
52127
 
52024
52128
  // src/tools/codex.ts
52025
52129
  init_claude();
@@ -52084,14 +52188,13 @@ function buildCapabilities(models) {
52084
52188
  function sanitizeCodexModel(model) {
52085
52189
  if (model === void 0) return void 0;
52086
52190
  if (CLAUDE_MODEL_IDS.includes(model)) return void 0;
52087
- if (model.startsWith("claude-")) return void 0;
52088
52191
  return model;
52089
52192
  }
52090
52193
  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 };
52194
+ if (env.CODEX_BIN && import_node_fs20.default.existsSync(env.CODEX_BIN)) return { available: true, path: env.CODEX_BIN };
52092
52195
  try {
52093
52196
  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 };
52197
+ if (out && import_node_fs20.default.existsSync(out)) return { available: true, path: out };
52095
52198
  } catch {
52096
52199
  }
52097
52200
  return { available: false };
@@ -52104,6 +52207,8 @@ var CodexAdapter = class {
52104
52207
  logger;
52105
52208
  probeOverride;
52106
52209
  queryOverride;
52210
+ configQueryOverride;
52211
+ fetchImpl;
52107
52212
  /** CODEX_HOME 归属解析(spec 2026-08-18-codex-project-alignment §3.1),由 index.ts 注入 */
52108
52213
  codexHomeFor;
52109
52214
  // capabilities 的进程级 memo。**回落结果同样被缓存**——否则 codex 没装时每次开弹窗都
@@ -52115,6 +52220,8 @@ var CodexAdapter = class {
52115
52220
  this.probeOverride = opts.probeOverride;
52116
52221
  this.historyReader = opts.historyReader;
52117
52222
  this.queryOverride = opts.queryOverride;
52223
+ this.configQueryOverride = opts.configQueryOverride;
52224
+ this.fetchImpl = opts.fetchImpl;
52118
52225
  this.codexHomeFor = opts.codexHomeFor;
52119
52226
  }
52120
52227
  async probe() {
@@ -52127,14 +52234,46 @@ var CodexAdapter = class {
52127
52234
  return this.capsPromise;
52128
52235
  }
52129
52236
  async loadCapabilities() {
52237
+ const [native, providerModels] = await Promise.all([
52238
+ this.loadNativeModels(),
52239
+ this.loadProviderModels()
52240
+ ]);
52241
+ if (native.length === 0 && providerModels.length === 0) {
52242
+ return buildCapabilities([CODEX_DEFAULT_MODEL_ENTRY]);
52243
+ }
52244
+ const base = native.length > 0 ? [] : [CODEX_DEFAULT_MODEL_ENTRY];
52245
+ return buildCapabilities([...base, ...mergeProviderModels(native, providerModels)]);
52246
+ }
52247
+ /** codex 内置型号表。失败返回 [],由 loadCapabilities 决定怎么降级 */
52248
+ async loadNativeModels() {
52130
52249
  try {
52131
52250
  const raw = this.queryOverride ? await this.queryOverride() : await queryCodexAppServer(process.cwd(), "model/list", {});
52132
- return buildCapabilities(mapModelList(raw));
52251
+ return mapModelList(raw);
52133
52252
  } 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]);
52253
+ this.logger?.warn?.(`codex model/list failed: ${err.message}`);
52254
+ return [];
52255
+ }
52256
+ }
52257
+ /**
52258
+ * provider 订阅侧全集。未配自定义 provider(官方用户)或任何失败都返回 []。
52259
+ * 见 codex-provider-models.ts —— model/list 只报 codex 内置型号,代理转发的模型全靠这里。
52260
+ */
52261
+ async loadProviderModels() {
52262
+ try {
52263
+ const raw = this.configQueryOverride ? await this.configQueryOverride() : await queryCodexAppServer(process.cwd(), "config/read", {}, {
52264
+ timeoutMs: PROVIDER_FETCH_TIMEOUT_MS
52265
+ });
52266
+ const endpoint = resolveProviderEndpoint(raw, {
52267
+ ...this.logger ? { logger: this.logger } : {}
52268
+ });
52269
+ if (!endpoint) return [];
52270
+ return await fetchProviderModels(endpoint, {
52271
+ ...this.fetchImpl ? { fetchImpl: this.fetchImpl } : {},
52272
+ ...this.logger ? { logger: this.logger } : {}
52273
+ });
52274
+ } catch (err) {
52275
+ this.logger?.warn?.(`codex provider model list failed: ${err.message}`);
52276
+ return [];
52138
52277
  }
52139
52278
  }
52140
52279
  // 纯函数、无 IO。所有 codex 模型共用同一静态窗口值(model/list 不给 contextWindow),
@@ -52164,9 +52303,9 @@ var CodexAdapter = class {
52164
52303
 
52165
52304
  // src/tools/claude-tui.ts
52166
52305
  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);
52306
+ var import_node_fs21 = __toESM(require("fs"), 1);
52307
+ var import_node_os8 = __toESM(require("os"), 1);
52308
+ var import_node_path19 = __toESM(require("path"), 1);
52170
52309
  var import_headless = __toESM(require_xterm_headless(), 1);
52171
52310
 
52172
52311
  // ../node_modules/.pnpm/@xterm+addon-serialize@0.14.0/node_modules/@xterm/addon-serialize/lib/addon-serialize.mjs
@@ -53391,10 +53530,10 @@ function buildTuiSpawnArgs(ctx, isResume = false) {
53391
53530
  }
53392
53531
  function jsonlExistsForCtx(ctx) {
53393
53532
  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`);
53533
+ const home = import_node_os8.default.homedir();
53534
+ const file = import_node_path19.default.join(home, ".claude", "projects", cwdToHashDir(ctx.cwd), `${ctx.toolSessionId}.jsonl`);
53396
53535
  try {
53397
- return import_node_fs20.default.statSync(file).isFile();
53536
+ return import_node_fs21.default.statSync(file).isFile();
53398
53537
  } catch {
53399
53538
  return false;
53400
53539
  }
@@ -53478,7 +53617,7 @@ var PersonaDispatchManager = class {
53478
53617
 
53479
53618
  // src/dispatch/store.ts
53480
53619
  var import_promises = __toESM(require("fs/promises"), 1);
53481
- var import_node_path19 = __toESM(require("path"), 1);
53620
+ var import_node_path20 = __toESM(require("path"), 1);
53482
53621
 
53483
53622
  // src/shift/constants.ts
53484
53623
  var MAX_RUNS_PER_SHIFT = 30;
@@ -53516,7 +53655,7 @@ function createDispatchStore(deps) {
53516
53655
  flushTimer = null;
53517
53656
  }
53518
53657
  const content = { version: 1, records };
53519
- await import_promises.default.mkdir(import_node_path19.default.dirname(deps.filePath), { recursive: true });
53658
+ await import_promises.default.mkdir(import_node_path20.default.dirname(deps.filePath), { recursive: true });
53520
53659
  const tmp = `${deps.filePath}.tmp-${deps.now()}-${Math.floor(Math.random() * 1e6)}`;
53521
53660
  await import_promises.default.writeFile(tmp, JSON.stringify(content, null, 2), "utf8");
53522
53661
  await import_promises.default.rename(tmp, deps.filePath);
@@ -53582,7 +53721,7 @@ function createDispatchStore(deps) {
53582
53721
 
53583
53722
  // src/channel/json-store.ts
53584
53723
  var import_promises2 = __toESM(require("fs/promises"), 1);
53585
- var import_node_path20 = __toESM(require("path"), 1);
53724
+ var import_node_path21 = __toESM(require("path"), 1);
53586
53725
  function createJsonStore(deps) {
53587
53726
  let items = [];
53588
53727
  let flushTimer = null;
@@ -53593,7 +53732,7 @@ function createJsonStore(deps) {
53593
53732
  flushTimer = null;
53594
53733
  }
53595
53734
  const content = { version: version2, [deps.key]: items };
53596
- await import_promises2.default.mkdir(import_node_path20.default.dirname(deps.filePath), { recursive: true });
53735
+ await import_promises2.default.mkdir(import_node_path21.default.dirname(deps.filePath), { recursive: true });
53597
53736
  const tmp = `${deps.filePath}.tmp-${deps.now()}-${Math.floor(Math.random() * 1e6)}`;
53598
53737
  await import_promises2.default.writeFile(tmp, JSON.stringify(content, null, 2), "utf8");
53599
53738
  await import_promises2.default.rename(tmp, deps.filePath);
@@ -53885,10 +54024,10 @@ function createTopicStore(deps) {
53885
54024
  }
53886
54025
 
53887
54026
  // src/dispatch/mcp-config.ts
53888
- var import_node_fs21 = __toESM(require("fs"), 1);
53889
- var import_node_path21 = __toESM(require("path"), 1);
54027
+ var import_node_fs22 = __toESM(require("fs"), 1);
54028
+ var import_node_path22 = __toESM(require("path"), 1);
53890
54029
  function dispatchMcpConfigPath(dataDir) {
53891
- return import_node_path21.default.join(dataDir, "dispatch.mcp.json");
54030
+ return import_node_path22.default.join(dataDir, "dispatch.mcp.json");
53892
54031
  }
53893
54032
  function writeDispatchMcpConfig(args) {
53894
54033
  const cfgPath = dispatchMcpConfigPath(args.dataDir);
@@ -53907,16 +54046,16 @@ function writeDispatchMcpConfig(args) {
53907
54046
  }
53908
54047
  }
53909
54048
  };
53910
- import_node_fs21.default.mkdirSync(args.dataDir, { recursive: true });
53911
- import_node_fs21.default.writeFileSync(cfgPath, JSON.stringify(content, null, 2), "utf8");
54049
+ import_node_fs22.default.mkdirSync(args.dataDir, { recursive: true });
54050
+ import_node_fs22.default.writeFileSync(cfgPath, JSON.stringify(content, null, 2), "utf8");
53912
54051
  return cfgPath;
53913
54052
  }
53914
54053
 
53915
54054
  // src/ticket/mcp-config.ts
53916
- var import_node_fs22 = __toESM(require("fs"), 1);
53917
- var import_node_path22 = __toESM(require("path"), 1);
54055
+ var import_node_fs23 = __toESM(require("fs"), 1);
54056
+ var import_node_path23 = __toESM(require("path"), 1);
53918
54057
  function ticketMcpConfigPath(dataDir) {
53919
- return import_node_path22.default.join(dataDir, "ticket.mcp.json");
54058
+ return import_node_path23.default.join(dataDir, "ticket.mcp.json");
53920
54059
  }
53921
54060
  function writeTicketMcpConfig(args) {
53922
54061
  const cfgPath = ticketMcpConfigPath(args.dataDir);
@@ -53938,16 +54077,16 @@ function writeTicketMcpConfig(args) {
53938
54077
  }
53939
54078
  }
53940
54079
  };
53941
- import_node_fs22.default.mkdirSync(args.dataDir, { recursive: true });
53942
- import_node_fs22.default.writeFileSync(cfgPath, JSON.stringify(content, null, 2), "utf8");
54080
+ import_node_fs23.default.mkdirSync(args.dataDir, { recursive: true });
54081
+ import_node_fs23.default.writeFileSync(cfgPath, JSON.stringify(content, null, 2), "utf8");
53943
54082
  return cfgPath;
53944
54083
  }
53945
54084
 
53946
54085
  // src/shift/mcp-config.ts
53947
- var import_node_fs23 = __toESM(require("fs"), 1);
53948
- var import_node_path23 = __toESM(require("path"), 1);
54086
+ var import_node_fs24 = __toESM(require("fs"), 1);
54087
+ var import_node_path24 = __toESM(require("path"), 1);
53949
54088
  function shiftMcpConfigPath(dataDir) {
53950
- return import_node_path23.default.join(dataDir, "shift.mcp.json");
54089
+ return import_node_path24.default.join(dataDir, "shift.mcp.json");
53951
54090
  }
53952
54091
  async function writeShiftMcpConfig(args) {
53953
54092
  const cfgPath = shiftMcpConfigPath(args.dataDir);
@@ -53966,16 +54105,16 @@ async function writeShiftMcpConfig(args) {
53966
54105
  }
53967
54106
  }
53968
54107
  };
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");
54108
+ await import_node_fs24.default.promises.mkdir(args.dataDir, { recursive: true });
54109
+ await import_node_fs24.default.promises.writeFile(cfgPath, JSON.stringify(content, null, 2), "utf8");
53971
54110
  return cfgPath;
53972
54111
  }
53973
54112
 
53974
54113
  // src/inbox/mcp-config.ts
53975
- var import_node_fs24 = __toESM(require("fs"), 1);
53976
- var import_node_path24 = __toESM(require("path"), 1);
54114
+ var import_node_fs25 = __toESM(require("fs"), 1);
54115
+ var import_node_path25 = __toESM(require("path"), 1);
53977
54116
  function inboxMcpConfigPath(dataDir) {
53978
- return import_node_path24.default.join(dataDir, "inbox.mcp.json");
54117
+ return import_node_path25.default.join(dataDir, "inbox.mcp.json");
53979
54118
  }
53980
54119
  async function writeInboxMcpConfig(args) {
53981
54120
  const cfgPath = inboxMcpConfigPath(args.dataDir);
@@ -53994,16 +54133,16 @@ async function writeInboxMcpConfig(args) {
53994
54133
  }
53995
54134
  }
53996
54135
  };
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");
54136
+ await import_node_fs25.default.promises.mkdir(args.dataDir, { recursive: true });
54137
+ await import_node_fs25.default.promises.writeFile(cfgPath, JSON.stringify(content, null, 2), "utf8");
53999
54138
  return cfgPath;
54000
54139
  }
54001
54140
 
54002
54141
  // src/peer-ops/mcp-config.ts
54003
- var import_node_fs25 = __toESM(require("fs"), 1);
54004
- var import_node_path25 = __toESM(require("path"), 1);
54142
+ var import_node_fs26 = __toESM(require("fs"), 1);
54143
+ var import_node_path26 = __toESM(require("path"), 1);
54005
54144
  function peerOpsMcpConfigPath(dataDir) {
54006
- return import_node_path25.default.join(dataDir, "peer-ops.mcp.json");
54145
+ return import_node_path26.default.join(dataDir, "peer-ops.mcp.json");
54007
54146
  }
54008
54147
  function writePeerOpsMcpConfig(args) {
54009
54148
  const cfgPath = peerOpsMcpConfigPath(args.dataDir);
@@ -54020,16 +54159,16 @@ function writePeerOpsMcpConfig(args) {
54020
54159
  }
54021
54160
  }
54022
54161
  };
54023
- import_node_fs25.default.mkdirSync(args.dataDir, { recursive: true });
54024
- import_node_fs25.default.writeFileSync(cfgPath, JSON.stringify(cfg, null, 2));
54162
+ import_node_fs26.default.mkdirSync(args.dataDir, { recursive: true });
54163
+ import_node_fs26.default.writeFileSync(cfgPath, JSON.stringify(cfg, null, 2));
54025
54164
  return cfgPath;
54026
54165
  }
54027
54166
 
54028
54167
  // src/rpc-tool/mcp-config.ts
54029
- var import_node_fs26 = __toESM(require("fs"), 1);
54030
- var import_node_path26 = __toESM(require("path"), 1);
54168
+ var import_node_fs27 = __toESM(require("fs"), 1);
54169
+ var import_node_path27 = __toESM(require("path"), 1);
54031
54170
  function rpcToolMcpConfigPath(dataDir) {
54032
- return import_node_path26.default.join(dataDir, "rpc-tool.mcp.json");
54171
+ return import_node_path27.default.join(dataDir, "rpc-tool.mcp.json");
54033
54172
  }
54034
54173
  function writeRpcToolMcpConfig(args) {
54035
54174
  const cfgPath = rpcToolMcpConfigPath(args.dataDir);
@@ -54048,29 +54187,29 @@ function writeRpcToolMcpConfig(args) {
54048
54187
  }
54049
54188
  }
54050
54189
  };
54051
- import_node_fs26.default.mkdirSync(args.dataDir, { recursive: true });
54052
- import_node_fs26.default.writeFileSync(cfgPath, JSON.stringify(content, null, 2), "utf8");
54190
+ import_node_fs27.default.mkdirSync(args.dataDir, { recursive: true });
54191
+ import_node_fs27.default.writeFileSync(cfgPath, JSON.stringify(content, null, 2), "utf8");
54053
54192
  return cfgPath;
54054
54193
  }
54055
54194
 
54056
54195
  // src/deploy/secret-table.ts
54057
- var import_node_fs27 = __toESM(require("fs"), 1);
54058
- var import_node_path27 = __toESM(require("path"), 1);
54196
+ var import_node_fs28 = __toESM(require("fs"), 1);
54197
+ var import_node_path28 = __toESM(require("path"), 1);
54059
54198
  var import_node_url4 = require("url");
54060
54199
  var import_meta4 = {};
54061
54200
  var LOCAL_SECRETS_DIRNAME = "secrets";
54062
54201
  function findSecretsBundleRoot(logger) {
54063
54202
  const candidates = [];
54064
54203
  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"));
54204
+ const here = import_node_path28.default.dirname((0, import_node_url4.fileURLToPath)(import_meta4.url));
54205
+ candidates.push(import_node_path28.default.resolve(here, "..", "secrets"));
54067
54206
  } catch {
54068
54207
  }
54069
54208
  const fromArgv = bundleSiblingFromArgv(process.argv[1], "secrets");
54070
54209
  if (fromArgv) candidates.push(fromArgv);
54071
54210
  for (const c of candidates) {
54072
54211
  try {
54073
- if (import_node_fs27.default.statSync(c).isDirectory()) return c;
54212
+ if (import_node_fs28.default.statSync(c).isDirectory()) return c;
54074
54213
  } catch {
54075
54214
  }
54076
54215
  }
@@ -54096,7 +54235,7 @@ function readDir(dir, logger) {
54096
54235
  const out = {};
54097
54236
  let files;
54098
54237
  try {
54099
- files = import_node_fs27.default.readdirSync(dir).filter((f) => f.endsWith(".env")).sort();
54238
+ files = import_node_fs28.default.readdirSync(dir).filter((f) => f.endsWith(".env")).sort();
54100
54239
  } catch (e) {
54101
54240
  const code = e.code;
54102
54241
  if (code !== "ENOENT") logger?.warn("secrets.dir-unreadable", { dir, code: code ?? "unknown" });
@@ -54104,9 +54243,9 @@ function readDir(dir, logger) {
54104
54243
  }
54105
54244
  for (const f of files) {
54106
54245
  try {
54107
- Object.assign(out, parseEnvFile(import_node_fs27.default.readFileSync(import_node_path27.default.join(dir, f), "utf8")));
54246
+ Object.assign(out, parseEnvFile(import_node_fs28.default.readFileSync(import_node_path28.default.join(dir, f), "utf8")));
54108
54247
  } catch (e) {
54109
- logger?.warn("secrets.file-unreadable", { file: import_node_path27.default.join(dir, f), error: e.message });
54248
+ logger?.warn("secrets.file-unreadable", { file: import_node_path28.default.join(dir, f), error: e.message });
54110
54249
  }
54111
54250
  }
54112
54251
  return out;
@@ -54116,7 +54255,7 @@ function collectKitPlaceholders(kitDir) {
54116
54255
  const scan = (file, re) => {
54117
54256
  let text;
54118
54257
  try {
54119
- text = import_node_fs27.default.readFileSync(file, "utf8");
54258
+ text = import_node_fs28.default.readFileSync(file, "utf8");
54120
54259
  } catch {
54121
54260
  return;
54122
54261
  }
@@ -54126,20 +54265,20 @@ function collectKitPlaceholders(kitDir) {
54126
54265
  if (depth > 6) return [];
54127
54266
  let entries;
54128
54267
  try {
54129
- entries = import_node_fs27.default.readdirSync(dir, { withFileTypes: true });
54268
+ entries = import_node_fs28.default.readdirSync(dir, { withFileTypes: true });
54130
54269
  } catch {
54131
54270
  return [];
54132
54271
  }
54133
54272
  return entries.flatMap((e) => {
54134
54273
  if (e.name === "node_modules") return [];
54135
- const p2 = import_node_path27.default.join(dir, e.name);
54274
+ const p2 = import_node_path28.default.join(dir, e.name);
54136
54275
  return e.isDirectory() ? walk2(p2, depth + 1) : [p2];
54137
54276
  });
54138
54277
  };
54139
- for (const f of walk2(import_node_path27.default.join(kitDir, "contract"), 0)) {
54278
+ for (const f of walk2(import_node_path28.default.join(kitDir, "contract"), 0)) {
54140
54279
  if (f.endsWith(".tmpl")) scan(f, /__([A-Z0-9_]+)__/g);
54141
54280
  }
54142
- for (const f of walk2(import_node_path27.default.join(kitDir, "examples"), 0)) {
54281
+ for (const f of walk2(import_node_path28.default.join(kitDir, "examples"), 0)) {
54143
54282
  if (f.endsWith(".env.example")) scan(f, /\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g);
54144
54283
  }
54145
54284
  return out;
@@ -54157,12 +54296,12 @@ function readSecretTable(args) {
54157
54296
  }
54158
54297
 
54159
54298
  // src/dispatch/source-transcript.ts
54160
- var import_node_path28 = __toESM(require("path"), 1);
54299
+ var import_node_path29 = __toESM(require("path"), 1);
54161
54300
  init_claude_history();
54162
54301
  var NO_SOURCE_TRANSCRIPT = "(no transcript yet \u2014 operate from the task description alone)";
54163
54302
  function resolveSourceJsonlPath(sourceFile, home) {
54164
54303
  if (!sourceFile?.toolSessionId) return NO_SOURCE_TRANSCRIPT;
54165
- return import_node_path28.default.join(
54304
+ return import_node_path29.default.join(
54166
54305
  home,
54167
54306
  ".claude",
54168
54307
  "projects",
@@ -54173,7 +54312,7 @@ function resolveSourceJsonlPath(sourceFile, home) {
54173
54312
 
54174
54313
  // src/shift/store.ts
54175
54314
  var import_promises3 = __toESM(require("fs/promises"), 1);
54176
- var import_node_path29 = __toESM(require("path"), 1);
54315
+ var import_node_path30 = __toESM(require("path"), 1);
54177
54316
  var import_node_crypto6 = require("crypto");
54178
54317
 
54179
54318
  // src/shift/schedule.ts
@@ -54248,7 +54387,7 @@ function createShiftStore(deps) {
54248
54387
  flushTimer = null;
54249
54388
  }
54250
54389
  const content = { version: 1, shifts };
54251
- await import_promises3.default.mkdir(import_node_path29.default.dirname(deps.filePath), { recursive: true });
54390
+ await import_promises3.default.mkdir(import_node_path30.default.dirname(deps.filePath), { recursive: true });
54252
54391
  const tmp = `${deps.filePath}.tmp-${deps.now()}-${Math.floor(Math.random() * 1e6)}`;
54253
54392
  await import_promises3.default.writeFile(tmp, JSON.stringify(content, null, 2), "utf8");
54254
54393
  await import_promises3.default.rename(tmp, deps.filePath);
@@ -54696,10 +54835,10 @@ function redactEvidence(evidence) {
54696
54835
 
54697
54836
  // src/deploy/deploy-file.ts
54698
54837
  var import_promises4 = __toESM(require("fs/promises"), 1);
54699
- var import_node_path30 = __toESM(require("path"), 1);
54838
+ var import_node_path31 = __toESM(require("path"), 1);
54700
54839
  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");
54840
+ var DEPLOY_FILE = import_node_path31.default.join(".clawd", "deploy.json");
54841
+ var SCAN_FILE = import_node_path31.default.join(".clawd", "deploy-scan.json");
54703
54842
  async function readJson(file) {
54704
54843
  let raw;
54705
54844
  try {
@@ -54715,14 +54854,14 @@ async function readJson(file) {
54715
54854
  }
54716
54855
  }
54717
54856
  async function writeJson(file, value) {
54718
- await import_promises4.default.mkdir(import_node_path30.default.dirname(file), { recursive: true });
54857
+ await import_promises4.default.mkdir(import_node_path31.default.dirname(file), { recursive: true });
54719
54858
  const tmp = `${file}.tmp-${process.pid}`;
54720
54859
  await import_promises4.default.writeFile(tmp, `${JSON.stringify(value, null, 2)}
54721
54860
  `);
54722
54861
  await import_promises4.default.rename(tmp, file);
54723
54862
  }
54724
54863
  async function readDeployFile(dir) {
54725
- const raw = await readJson(import_node_path30.default.join(dir, DEPLOY_FILE));
54864
+ const raw = await readJson(import_node_path31.default.join(dir, DEPLOY_FILE));
54726
54865
  if (raw === void 0) return void 0;
54727
54866
  const parsed = DeployFileSchema.safeParse(raw);
54728
54867
  if (!parsed.success) {
@@ -54732,10 +54871,10 @@ async function readDeployFile(dir) {
54732
54871
  return parsed.data;
54733
54872
  }
54734
54873
  async function writeDeployFile(dir, file) {
54735
- await writeJson(import_node_path30.default.join(dir, DEPLOY_FILE), DeployFileSchema.parse(file));
54874
+ await writeJson(import_node_path31.default.join(dir, DEPLOY_FILE), DeployFileSchema.parse(file));
54736
54875
  }
54737
54876
  async function readScan(dir) {
54738
- const raw = await readJson(import_node_path30.default.join(dir, SCAN_FILE));
54877
+ const raw = await readJson(import_node_path31.default.join(dir, SCAN_FILE));
54739
54878
  if (raw === void 0) return void 0;
54740
54879
  const parsed = DeployScanSchema.safeParse(raw);
54741
54880
  if (!parsed.success) {
@@ -54745,7 +54884,7 @@ async function readScan(dir) {
54745
54884
  return parsed.data;
54746
54885
  }
54747
54886
  async function writeScan(dir, scan) {
54748
- await writeJson(import_node_path30.default.join(dir, SCAN_FILE), DeployScanSchema.parse(scan));
54887
+ await writeJson(import_node_path31.default.join(dir, SCAN_FILE), DeployScanSchema.parse(scan));
54749
54888
  }
54750
54889
  function emptyDeployFile() {
54751
54890
  return { version: 1, manifest: { version: 1, clis: [], secrets: [], assets: [] } };
@@ -54775,7 +54914,7 @@ function requiredEnvNames(file) {
54775
54914
  // src/deploy/repo.ts
54776
54915
  var import_node_child_process8 = require("child_process");
54777
54916
  var import_promises5 = __toESM(require("fs/promises"), 1);
54778
- var import_node_path31 = __toESM(require("path"), 1);
54917
+ var import_node_path32 = __toESM(require("path"), 1);
54779
54918
  init_protocol();
54780
54919
 
54781
54920
  // src/deploy/templates.ts
@@ -55069,7 +55208,7 @@ async function samePath(a, b2) {
55069
55208
  try {
55070
55209
  return await import_promises5.default.realpath(x);
55071
55210
  } catch {
55072
- return import_node_path31.default.resolve(x);
55211
+ return import_node_path32.default.resolve(x);
55073
55212
  }
55074
55213
  };
55075
55214
  return await real(a) === await real(b2);
@@ -55095,7 +55234,7 @@ async function identityArgs(exec, dir) {
55095
55234
  return ["-c", "user.name=clawd", "-c", "user.email=clawd@clawos.local"];
55096
55235
  }
55097
55236
  async function writeTemplates(dir) {
55098
- const gi = import_node_path31.default.join(dir, ".gitignore");
55237
+ const gi = import_node_path32.default.join(dir, ".gitignore");
55099
55238
  let existing;
55100
55239
  try {
55101
55240
  existing = await import_promises5.default.readFile(gi, "utf8");
@@ -55103,8 +55242,8 @@ async function writeTemplates(dir) {
55103
55242
  existing = void 0;
55104
55243
  }
55105
55244
  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 });
55245
+ const wf = import_node_path32.default.join(dir, WORKFLOW_PATH);
55246
+ await import_promises5.default.mkdir(import_node_path32.default.dirname(wf), { recursive: true });
55108
55247
  await import_promises5.default.writeFile(wf, WORKFLOW_TEMPLATE);
55109
55248
  }
55110
55249
  async function ensureRepo(exec, args) {
@@ -55208,8 +55347,8 @@ function runStatusOf(status) {
55208
55347
  if (status === "queued" || status === "waiting" || status === "requested" || status === "pending") return "queued";
55209
55348
  return "running";
55210
55349
  }
55211
- async function ghJson(exec, path97) {
55212
- const r = await exec("gh", ["api", path97], { timeoutMs: TIMEOUT_MS });
55350
+ async function ghJson(exec, path98) {
55351
+ const r = await exec("gh", ["api", path98], { timeoutMs: TIMEOUT_MS });
55213
55352
  if (r.spawnError || r.code !== 0) return void 0;
55214
55353
  try {
55215
55354
  return JSON.parse(r.stdout);
@@ -55269,12 +55408,12 @@ async function rerunJob(exec, slug, runId, jobId) {
55269
55408
  }
55270
55409
 
55271
55410
  // src/deploy/scan-task.ts
55272
- var import_node_path32 = __toESM(require("path"), 1);
55411
+ var import_node_path33 = __toESM(require("path"), 1);
55273
55412
  var BUTLER_PERSONA_ID = "persona-clawd-butler";
55274
55413
  var SCANNABLE_ASSETS = [
55275
55414
  {
55276
55415
  name: "deploy-kit",
55277
- path: (dataDir) => import_node_path32.default.join(dataDir, "deploy-kit"),
55416
+ path: (dataDir) => import_node_path33.default.join(dataDir, "deploy-kit"),
55278
55417
  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
55418
  },
55280
55419
  {
@@ -55978,15 +56117,15 @@ async function refreshTunnelUrlOnStartup(deps) {
55978
56117
  }
55979
56118
 
55980
56119
  // 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);
56120
+ var import_node_fs29 = __toESM(require("fs"), 1);
56121
+ var import_node_path34 = __toESM(require("path"), 1);
55983
56122
  function createLarkBotBindingStore(personaRoot) {
55984
- const filePath = (personaId2) => import_node_path33.default.join(personaRoot, safeFileName(personaId2), ".clawd", "lark-bot.json");
56123
+ const filePath = (personaId2) => import_node_path34.default.join(personaRoot, safeFileName(personaId2), ".clawd", "lark-bot.json");
55985
56124
  const read = (personaId2) => {
55986
56125
  const file = filePath(personaId2);
55987
- if (!import_node_fs28.default.existsSync(file)) return null;
56126
+ if (!import_node_fs29.default.existsSync(file)) return null;
55988
56127
  try {
55989
- const raw = JSON.parse(import_node_fs28.default.readFileSync(file, "utf8"));
56128
+ const raw = JSON.parse(import_node_fs29.default.readFileSync(file, "utf8"));
55990
56129
  if (typeof raw?.appId !== "string" || raw.appId.length === 0) return null;
55991
56130
  return raw;
55992
56131
  } catch {
@@ -55995,16 +56134,16 @@ function createLarkBotBindingStore(personaRoot) {
55995
56134
  };
55996
56135
  const write = (personaId2, meta) => {
55997
56136
  const file = filePath(personaId2);
55998
- import_node_fs28.default.mkdirSync(import_node_path33.default.dirname(file), { recursive: true });
56137
+ import_node_fs29.default.mkdirSync(import_node_path34.default.dirname(file), { recursive: true });
55999
56138
  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);
56139
+ import_node_fs29.default.writeFileSync(tmp, JSON.stringify(meta, null, 2), { mode: 384 });
56140
+ import_node_fs29.default.renameSync(tmp, file);
56002
56141
  };
56003
56142
  return {
56004
56143
  read,
56005
56144
  write,
56006
56145
  remove(personaId2) {
56007
- import_node_fs28.default.rmSync(filePath(personaId2), { force: true });
56146
+ import_node_fs29.default.rmSync(filePath(personaId2), { force: true });
56008
56147
  },
56009
56148
  addRemovedChat(personaId2, chatId) {
56010
56149
  const meta = read(personaId2);
@@ -56162,8 +56301,8 @@ function createLarkBotCloudClient(opts) {
56162
56301
  }
56163
56302
 
56164
56303
  // 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);
56304
+ var import_node_fs30 = __toESM(require("fs"), 1);
56305
+ var import_node_path35 = __toESM(require("path"), 1);
56167
56306
  init_protocol();
56168
56307
  var ERROR_REPLY_TEXT = "\u5904\u7406\u51FA\u9519\u4E86\uFF0C\u8BF7\u91CD\u8BD5";
56169
56308
  var LOCAL_TURN_RETRIES = 2;
@@ -56229,9 +56368,9 @@ function createLarkChatRouter(deps) {
56229
56368
  continue;
56230
56369
  }
56231
56370
  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);
56371
+ import_node_fs30.default.mkdirSync(dir, { recursive: true });
56372
+ const p2 = import_node_path35.default.join(dir, `${safeMediaName(ownerMessageId)}-${i}.${ext}`);
56373
+ import_node_fs30.default.writeFileSync(p2, r.data);
56235
56374
  lines.push(`[\u56FE\u7247: ${p2}]\uFF08\u7528 Read \u5DE5\u5177\u67E5\u770B\uFF09`);
56236
56375
  } catch (err) {
56237
56376
  deps.logger?.warn(`larkBot image fetch failed ${key}: ${err.message}`);
@@ -56252,9 +56391,9 @@ function createLarkChatRouter(deps) {
56252
56391
  continue;
56253
56392
  }
56254
56393
  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);
56394
+ import_node_fs30.default.mkdirSync(dir, { recursive: true });
56395
+ const p2 = import_node_path35.default.join(dir, `${safeMediaName(ownerMessageId)}-${i}-${safeAttachmentName(f.name)}`);
56396
+ import_node_fs30.default.writeFileSync(p2, r.data);
56258
56397
  lines.push(`[\u6587\u4EF6: ${p2}]\uFF08\u7528 Read \u5DE5\u5177\u67E5\u770B\uFF09`);
56259
56398
  } catch (err) {
56260
56399
  deps.logger?.warn(`larkBot file fetch failed ${f.key}: ${err.message}`);
@@ -57343,7 +57482,7 @@ var CodexHistoryReader = class {
57343
57482
  };
57344
57483
 
57345
57484
  // src/tools/codex-skills.ts
57346
- var import_node_path35 = __toESM(require("path"), 1);
57485
+ var import_node_path36 = __toESM(require("path"), 1);
57347
57486
  function str3(v2) {
57348
57487
  return typeof v2 === "string" ? v2 : void 0;
57349
57488
  }
@@ -57358,13 +57497,13 @@ function mapSkillsListResponse(res) {
57358
57497
  const r = s ?? {};
57359
57498
  const name = str3(r.name);
57360
57499
  if (!name) continue;
57361
- const path97 = str3(r.path);
57500
+ const path98 = str3(r.path);
57362
57501
  const description = str3(r.description);
57363
57502
  const isPlugin = name.includes(":");
57364
57503
  out.push({
57365
57504
  name,
57366
57505
  source: isPlugin ? "plugin" : "project",
57367
- ...path97 ? { path: path97 } : {},
57506
+ ...path98 ? { path: path98 } : {},
57368
57507
  ...description ? { description } : {},
57369
57508
  ...isPlugin ? { plugin: name.split(":")[0] } : {}
57370
57509
  });
@@ -57380,7 +57519,7 @@ async function listCodexSkills(cwd, deps = {}) {
57380
57519
  // 先写 extraRoots 再写 list(stdio 按写入顺序处理,fire-and-forget 不 await 回包;
57381
57520
  // codex-session.ts ready 序列同款,两处保持一致)。失败不阻塞 list。
57382
57521
  beforeRequest: (client) => {
57383
- void client.request("skills/extraRoots/set", { extraRoots: [import_node_path35.default.join(cwd, ".claude", "skills")] }).catch(() => void 0);
57522
+ void client.request("skills/extraRoots/set", { extraRoots: [import_node_path36.default.join(cwd, ".claude", "skills")] }).catch(() => void 0);
57384
57523
  }
57385
57524
  });
57386
57525
  return mapSkillsListResponse(res);
@@ -57465,23 +57604,23 @@ function str4(v2) {
57465
57604
  }
57466
57605
 
57467
57606
  // 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);
57607
+ var import_node_fs31 = __toESM(require("fs"), 1);
57608
+ var import_node_os9 = __toESM(require("os"), 1);
57609
+ var import_node_path37 = __toESM(require("path"), 1);
57471
57610
  init_protocol();
57472
57611
  var MAX_FILE_BYTES2 = 2 * 1024 * 1024;
57473
57612
  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)) {
57613
+ const absCwd = import_node_path37.default.resolve(cwd);
57614
+ const joined = import_node_path37.default.resolve(absCwd, subpath ?? ".");
57615
+ const rel = import_node_path37.default.relative(absCwd, joined);
57616
+ if (rel.startsWith("..") || import_node_path37.default.isAbsolute(rel)) {
57478
57617
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
57479
57618
  }
57480
57619
  return joined;
57481
57620
  }
57482
57621
  function ensureCwd(cwd) {
57483
57622
  try {
57484
- const stat = import_node_fs30.default.statSync(cwd);
57623
+ const stat = import_node_fs31.default.statSync(cwd);
57485
57624
  if (!stat.isDirectory()) {
57486
57625
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${cwd}`);
57487
57626
  }
@@ -57492,10 +57631,10 @@ function ensureCwd(cwd) {
57492
57631
  }
57493
57632
  var WorkspaceBrowser = class {
57494
57633
  list(args) {
57495
- const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os8.default.homedir();
57634
+ const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os9.default.homedir();
57496
57635
  ensureCwd(cwd);
57497
57636
  const full = resolveInsideCwd(cwd, args.path);
57498
- const dirents = import_node_fs30.default.readdirSync(full, { withFileTypes: true });
57637
+ const dirents = import_node_fs31.default.readdirSync(full, { withFileTypes: true });
57499
57638
  const entries = [];
57500
57639
  for (const d of dirents) {
57501
57640
  if (!args.showHidden && d.name.startsWith(".")) continue;
@@ -57505,7 +57644,7 @@ var WorkspaceBrowser = class {
57505
57644
  mtime: ""
57506
57645
  };
57507
57646
  try {
57508
- const st = import_node_fs30.default.statSync(import_node_path36.default.join(full, d.name));
57647
+ const st = import_node_fs31.default.statSync(import_node_path37.default.join(full, d.name));
57509
57648
  entry.mtime = new Date(st.mtimeMs).toISOString();
57510
57649
  if (d.isFile()) entry.size = st.size;
57511
57650
  } catch {
@@ -57521,14 +57660,14 @@ var WorkspaceBrowser = class {
57521
57660
  read(args) {
57522
57661
  ensureCwd(args.cwd);
57523
57662
  const full = resolveInsideCwd(args.cwd, args.path);
57524
- const st = import_node_fs30.default.statSync(full);
57663
+ const st = import_node_fs31.default.statSync(full);
57525
57664
  if (!st.isFile()) {
57526
57665
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `not a file: ${args.path}`);
57527
57666
  }
57528
57667
  if (st.size > MAX_FILE_BYTES2) {
57529
57668
  throw new ClawdError(ERROR_CODES.FILE_TOO_LARGE, `file > ${MAX_FILE_BYTES2} bytes`);
57530
57669
  }
57531
- const buf = import_node_fs30.default.readFileSync(full);
57670
+ const buf = import_node_fs31.default.readFileSync(full);
57532
57671
  const isBinary = buf.includes(0);
57533
57672
  if (isBinary) {
57534
57673
  return {
@@ -57550,20 +57689,20 @@ var WorkspaceBrowser = class {
57550
57689
  };
57551
57690
 
57552
57691
  // 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);
57692
+ var import_node_fs32 = __toESM(require("fs"), 1);
57693
+ var import_node_os10 = __toESM(require("os"), 1);
57694
+ var import_node_path38 = __toESM(require("path"), 1);
57556
57695
  var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
57557
57696
  function isDirLikeSync2(p2) {
57558
57697
  try {
57559
- return import_node_fs31.default.statSync(p2).isDirectory();
57698
+ return import_node_fs32.default.statSync(p2).isDirectory();
57560
57699
  } catch {
57561
57700
  return false;
57562
57701
  }
57563
57702
  }
57564
57703
  function fileExistsSync(p2) {
57565
57704
  try {
57566
- return import_node_fs31.default.statSync(p2).isFile();
57705
+ return import_node_fs32.default.statSync(p2).isFile();
57567
57706
  } catch {
57568
57707
  return false;
57569
57708
  }
@@ -57571,7 +57710,7 @@ function fileExistsSync(p2) {
57571
57710
  function parseAgentFile(filePath) {
57572
57711
  let content;
57573
57712
  try {
57574
- content = import_node_fs31.default.readFileSync(filePath, "utf8");
57713
+ content = import_node_fs32.default.readFileSync(filePath, "utf8");
57575
57714
  } catch {
57576
57715
  return {};
57577
57716
  }
@@ -57584,16 +57723,16 @@ function parseAgentFile(filePath) {
57584
57723
  function scanAgentsDir(dir, source, seen, out) {
57585
57724
  let entries;
57586
57725
  try {
57587
- entries = import_node_fs31.default.readdirSync(dir, { withFileTypes: true });
57726
+ entries = import_node_fs32.default.readdirSync(dir, { withFileTypes: true });
57588
57727
  } catch {
57589
57728
  return;
57590
57729
  }
57591
57730
  for (const ent of entries) {
57592
57731
  if (!ent.name.endsWith(".md")) continue;
57593
- if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path37.default.join(dir, ent.name)))) {
57732
+ if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path38.default.join(dir, ent.name)))) {
57594
57733
  continue;
57595
57734
  }
57596
- const filePath = import_node_path37.default.join(dir, ent.name);
57735
+ const filePath = import_node_path38.default.join(dir, ent.name);
57597
57736
  const baseName = ent.name.replace(/\.md$/, "");
57598
57737
  if (seen.has(baseName)) continue;
57599
57738
  seen.add(baseName);
@@ -57611,12 +57750,12 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
57611
57750
  function walk2(dir, namespaces) {
57612
57751
  let entries;
57613
57752
  try {
57614
- entries = import_node_fs31.default.readdirSync(dir, { withFileTypes: true });
57753
+ entries = import_node_fs32.default.readdirSync(dir, { withFileTypes: true });
57615
57754
  } catch {
57616
57755
  return;
57617
57756
  }
57618
57757
  for (const ent of entries) {
57619
- const childPath = import_node_path37.default.join(dir, ent.name);
57758
+ const childPath = import_node_path38.default.join(dir, ent.name);
57620
57759
  if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
57621
57760
  walk2(childPath, [...namespaces, ent.name]);
57622
57761
  continue;
@@ -57641,13 +57780,13 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
57641
57780
  walk2(root, []);
57642
57781
  }
57643
57782
  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");
57783
+ const pluginsDir = import_node_path38.default.join(home, ".claude", "plugins");
57784
+ const v2 = import_node_path38.default.join(pluginsDir, "installed_plugins_v2.json");
57785
+ const v1 = import_node_path38.default.join(pluginsDir, "installed_plugins.json");
57647
57786
  let raw = null;
57648
57787
  for (const candidate of [v2, v1]) {
57649
57788
  try {
57650
- raw = import_node_fs31.default.readFileSync(candidate, "utf8");
57789
+ raw = import_node_fs32.default.readFileSync(candidate, "utf8");
57651
57790
  break;
57652
57791
  } catch {
57653
57792
  }
@@ -57672,19 +57811,19 @@ function readInstalledPlugins2(home) {
57672
57811
  return out;
57673
57812
  }
57674
57813
  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;
57814
+ let cur = import_node_path38.default.resolve(startCwd);
57815
+ const fsRoot = import_node_path38.default.parse(cur).root;
57677
57816
  while (true) {
57678
- scanAgentsDir(import_node_path37.default.join(cur, ".claude", "agents"), "project", seen, out);
57817
+ scanAgentsDir(import_node_path38.default.join(cur, ".claude", "agents"), "project", seen, out);
57679
57818
  let hasGit = false;
57680
57819
  try {
57681
- hasGit = import_node_fs31.default.existsSync(import_node_path37.default.join(cur, ".git"));
57820
+ hasGit = import_node_fs32.default.existsSync(import_node_path38.default.join(cur, ".git"));
57682
57821
  } catch {
57683
57822
  }
57684
57823
  if (hasGit) return;
57685
57824
  if (cur === home) return;
57686
57825
  if (cur === fsRoot) return;
57687
- const parent = import_node_path37.default.dirname(cur);
57826
+ const parent = import_node_path38.default.dirname(cur);
57688
57827
  if (parent === cur) return;
57689
57828
  cur = parent;
57690
57829
  }
@@ -57694,7 +57833,7 @@ var AgentsScanner = class {
57694
57833
  extraPluginRoots;
57695
57834
  policyDir;
57696
57835
  constructor(opts = {}) {
57697
- this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os9.default.homedir();
57836
+ this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os10.default.homedir();
57698
57837
  this.extraPluginRoots = opts.extraPluginRoots ?? [];
57699
57838
  if (opts.policyDir !== void 0) {
57700
57839
  this.policyDir = opts.policyDir;
@@ -57719,7 +57858,7 @@ var AgentsScanner = class {
57719
57858
  }
57720
57859
  const fsBlock = [];
57721
57860
  scanAgentsDir(
57722
- import_node_path37.default.join(this.home, ".claude", "agents"),
57861
+ import_node_path38.default.join(this.home, ".claude", "agents"),
57723
57862
  "global",
57724
57863
  seen,
57725
57864
  fsBlock
@@ -57733,7 +57872,7 @@ var AgentsScanner = class {
57733
57872
  ...this.extraPluginRoots
57734
57873
  ];
57735
57874
  for (const { name, root } of plugins) {
57736
- const agentsRoot = import_node_path37.default.join(root, "agents");
57875
+ const agentsRoot = import_node_path38.default.join(root, "agents");
57737
57876
  scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
57738
57877
  }
57739
57878
  return [...builtinBlock, ...fsBlock];
@@ -57741,28 +57880,28 @@ var AgentsScanner = class {
57741
57880
  };
57742
57881
 
57743
57882
  // 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);
57883
+ var import_node_fs34 = __toESM(require("fs"), 1);
57884
+ var import_node_os12 = __toESM(require("os"), 1);
57885
+ var import_node_path40 = __toESM(require("path"), 1);
57747
57886
  init_claude_history();
57748
57887
 
57749
57888
  // 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);
57889
+ var import_node_fs33 = __toESM(require("fs"), 1);
57890
+ var import_node_os11 = __toESM(require("os"), 1);
57891
+ var import_node_path39 = __toESM(require("path"), 1);
57753
57892
  init_claude_history();
57754
57893
  var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
57755
57894
  var SubagentMetaObserver = class {
57756
57895
  constructor(opts) {
57757
57896
  this.opts = opts;
57758
- this.home = opts.home ?? import_node_os10.default.homedir();
57897
+ this.home = opts.home ?? import_node_os11.default.homedir();
57759
57898
  }
57760
57899
  opts;
57761
57900
  home;
57762
57901
  watches = /* @__PURE__ */ new Map();
57763
57902
  // public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
57764
57903
  resolveSubagentDir(cwd, toolSessionId) {
57765
- return import_node_path38.default.join(
57904
+ return import_node_path39.default.join(
57766
57905
  this.home,
57767
57906
  ".claude",
57768
57907
  "projects",
@@ -57792,7 +57931,7 @@ var SubagentMetaObserver = class {
57792
57931
  attachWatcher(w2) {
57793
57932
  if (w2.watcher) return;
57794
57933
  try {
57795
- w2.watcher = import_node_fs32.default.watch(w2.dirPath, { persistent: false }, (_evt, name) => {
57934
+ w2.watcher = import_node_fs33.default.watch(w2.dirPath, { persistent: false }, (_evt, name) => {
57796
57935
  if (!name) return;
57797
57936
  const m2 = META_RE.exec(String(name));
57798
57937
  if (!m2) return;
@@ -57804,7 +57943,7 @@ var SubagentMetaObserver = class {
57804
57943
  scan(w2) {
57805
57944
  let entries;
57806
57945
  try {
57807
- entries = import_node_fs32.default.readdirSync(w2.dirPath);
57946
+ entries = import_node_fs33.default.readdirSync(w2.dirPath);
57808
57947
  } catch {
57809
57948
  return;
57810
57949
  }
@@ -57818,10 +57957,10 @@ var SubagentMetaObserver = class {
57818
57957
  if (!m2) return;
57819
57958
  const agentId = m2[1];
57820
57959
  if (w2.emitted.has(agentId)) return;
57821
- const file = import_node_path38.default.join(w2.dirPath, name);
57960
+ const file = import_node_path39.default.join(w2.dirPath, name);
57822
57961
  let raw;
57823
57962
  try {
57824
- raw = import_node_fs32.default.readFileSync(file, "utf8");
57963
+ raw = import_node_fs33.default.readFileSync(file, "utf8");
57825
57964
  } catch {
57826
57965
  return;
57827
57966
  }
@@ -57866,7 +58005,7 @@ var SubagentMetaObserver = class {
57866
58005
  var SessionObserver = class {
57867
58006
  constructor(opts) {
57868
58007
  this.opts = opts;
57869
- this.home = opts.home ?? import_node_os11.default.homedir();
58008
+ this.home = opts.home ?? import_node_os12.default.homedir();
57870
58009
  this.metaObserver = opts.enableSubagentMetaObserver ? new SubagentMetaObserver({ home: this.home, onEvent: opts.onEvent }) : null;
57871
58010
  }
57872
58011
  opts;
@@ -57878,14 +58017,14 @@ var SessionObserver = class {
57878
58017
  metaObserver;
57879
58018
  resolveJsonlPath(cwd, toolSessionId, override) {
57880
58019
  if (override) return override;
57881
- return import_node_path39.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
58020
+ return import_node_path40.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
57882
58021
  }
57883
58022
  start(args) {
57884
58023
  this.stop(args.sessionId);
57885
58024
  const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
57886
58025
  let size = 0;
57887
58026
  try {
57888
- size = import_node_fs33.default.statSync(filePath).size;
58027
+ size = import_node_fs34.default.statSync(filePath).size;
57889
58028
  } catch {
57890
58029
  }
57891
58030
  const w2 = {
@@ -57898,16 +58037,16 @@ var SessionObserver = class {
57898
58037
  adapter: args.adapter,
57899
58038
  prevIsRejectSentinel: false,
57900
58039
  toolSessionId: args.toolSessionId,
57901
- sawFile: import_node_fs33.default.existsSync(filePath),
58040
+ sawFile: import_node_fs34.default.existsSync(filePath),
57902
58041
  lastRelocateScanMs: 0,
57903
58042
  pendingCwdDerive: false,
57904
58043
  lastDeriveMs: 0
57905
58044
  };
57906
58045
  try {
57907
- import_node_fs33.default.mkdirSync(import_node_path39.default.dirname(filePath), { recursive: true });
58046
+ import_node_fs34.default.mkdirSync(import_node_path40.default.dirname(filePath), { recursive: true });
57908
58047
  } catch {
57909
58048
  }
57910
- w2.watcher = import_node_fs33.default.watch(import_node_path39.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
58049
+ w2.watcher = import_node_fs34.default.watch(import_node_path40.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
57911
58050
  if (!changedName || !w2.filePath.endsWith(changedName)) return;
57912
58051
  this.poll(w2);
57913
58052
  });
@@ -57930,7 +58069,7 @@ var SessionObserver = class {
57930
58069
  // 异常静默吞,不阻塞 watcher 启动
57931
58070
  hydrateMetaTail(w2, maxLines = 200) {
57932
58071
  try {
57933
- const raw = import_node_fs33.default.readFileSync(w2.filePath, "utf8");
58072
+ const raw = import_node_fs34.default.readFileSync(w2.filePath, "utf8");
57934
58073
  if (!raw) return;
57935
58074
  const allLines = raw.split("\n").filter((l) => l.trim().length > 0);
57936
58075
  if (allLines.length === 0) return;
@@ -57954,7 +58093,7 @@ var SessionObserver = class {
57954
58093
  poll(w2) {
57955
58094
  let size = 0;
57956
58095
  try {
57957
- size = import_node_fs33.default.statSync(w2.filePath).size;
58096
+ size = import_node_fs34.default.statSync(w2.filePath).size;
57958
58097
  } catch {
57959
58098
  if (w2.sawFile) this.maybeRelocate(w2);
57960
58099
  return;
@@ -57965,11 +58104,11 @@ var SessionObserver = class {
57965
58104
  w2.buf = "";
57966
58105
  }
57967
58106
  if (size === w2.lastSize) return;
57968
- const fd = import_node_fs33.default.openSync(w2.filePath, "r");
58107
+ const fd = import_node_fs34.default.openSync(w2.filePath, "r");
57969
58108
  try {
57970
58109
  const len = size - w2.lastSize;
57971
58110
  const buf = Buffer.alloc(len);
57972
- import_node_fs33.default.readSync(fd, buf, 0, len, w2.lastSize);
58111
+ import_node_fs34.default.readSync(fd, buf, 0, len, w2.lastSize);
57973
58112
  w2.lastSize = size;
57974
58113
  w2.buf += buf.toString("utf8");
57975
58114
  let newlineIndex;
@@ -57992,7 +58131,7 @@ var SessionObserver = class {
57992
58131
  }
57993
58132
  }
57994
58133
  } finally {
57995
- import_node_fs33.default.closeSync(fd);
58134
+ import_node_fs34.default.closeSync(fd);
57996
58135
  }
57997
58136
  if (w2.pendingCwdDerive) this.maybeDeriveCwd(w2);
57998
58137
  }
@@ -58004,7 +58143,7 @@ var SessionObserver = class {
58004
58143
  const now = Date.now();
58005
58144
  if (now - w2.lastRelocateScanMs < 1e3) return;
58006
58145
  w2.lastRelocateScanMs = now;
58007
- const projectsRoot = import_node_path39.default.join(this.home, ".claude", "projects");
58146
+ const projectsRoot = import_node_path40.default.join(this.home, ".claude", "projects");
58008
58147
  const found = findTranscriptByToolSessionId(projectsRoot, w2.toolSessionId);
58009
58148
  if (!found || found === w2.filePath) return;
58010
58149
  try {
@@ -58013,7 +58152,7 @@ var SessionObserver = class {
58013
58152
  }
58014
58153
  w2.filePath = found;
58015
58154
  try {
58016
- w2.watcher = import_node_fs33.default.watch(import_node_path39.default.dirname(found), { persistent: false }, (_event, changedName) => {
58155
+ w2.watcher = import_node_fs34.default.watch(import_node_path40.default.dirname(found), { persistent: false }, (_event, changedName) => {
58017
58156
  if (!changedName || !w2.filePath.endsWith(changedName)) return;
58018
58157
  this.poll(w2);
58019
58158
  });
@@ -58134,9 +58273,9 @@ function listRegistered() {
58134
58273
 
58135
58274
  // src/tools/title-generator.ts
58136
58275
  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);
58276
+ var import_node_fs35 = __toESM(require("fs"), 1);
58277
+ var import_node_os13 = __toESM(require("os"), 1);
58278
+ var import_node_path41 = __toESM(require("path"), 1);
58140
58279
  var TITLE_GEN_DIR_PREFIX = "clawd-title-";
58141
58280
  var TITLE_MODEL_BY_TOOL = {
58142
58281
  claude: "haiku",
@@ -58207,21 +58346,21 @@ async function generateSessionTitle(tool, firstMessage, deps = {}) {
58207
58346
  if (!text) return null;
58208
58347
  let workDir;
58209
58348
  try {
58210
- workDir = import_node_fs34.default.mkdtempSync(import_node_path40.default.join(import_node_os12.default.tmpdir(), TITLE_GEN_DIR_PREFIX));
58349
+ workDir = import_node_fs35.default.mkdtempSync(import_node_path41.default.join(import_node_os13.default.tmpdir(), TITLE_GEN_DIR_PREFIX));
58211
58350
  } catch {
58212
58351
  return null;
58213
58352
  }
58214
58353
  const cleanupWorkDir = () => {
58215
58354
  try {
58216
- import_node_fs34.default.rmSync(workDir, { recursive: true, force: true });
58355
+ import_node_fs35.default.rmSync(workDir, { recursive: true, force: true });
58217
58356
  } catch {
58218
58357
  }
58219
58358
  };
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");
58359
+ const outFile = import_node_path41.default.join(workDir, `codex-title-${process.pid}-${++outFileSeq}-${Date.now()}.txt`);
58360
+ const schemaFile = import_node_path41.default.join(workDir, "title-schema.json");
58222
58361
  if (tool === "codex") {
58223
58362
  try {
58224
- import_node_fs34.default.writeFileSync(schemaFile, CODEX_TITLE_SCHEMA);
58363
+ import_node_fs35.default.writeFileSync(schemaFile, CODEX_TITLE_SCHEMA);
58225
58364
  } catch {
58226
58365
  cleanupWorkDir();
58227
58366
  return null;
@@ -58271,7 +58410,7 @@ async function generateSessionTitle(tool, firstMessage, deps = {}) {
58271
58410
  if (tool === "claude") return finish(parseTitleJson(stdout));
58272
58411
  let fileText = "";
58273
58412
  try {
58274
- fileText = import_node_fs34.default.readFileSync(outFile, "utf8");
58413
+ fileText = import_node_fs35.default.readFileSync(outFile, "utf8");
58275
58414
  } catch {
58276
58415
  return finish(null);
58277
58416
  }
@@ -58981,8 +59120,8 @@ async function authenticate(token, deps) {
58981
59120
  }
58982
59121
 
58983
59122
  // src/legacy-cleanup.ts
58984
- var fs45 = __toESM(require("fs/promises"), 1);
58985
- var path48 = __toESM(require("path"), 1);
59123
+ var fs46 = __toESM(require("fs/promises"), 1);
59124
+ var path49 = __toESM(require("path"), 1);
58986
59125
  var LEGACY_FILES = [
58987
59126
  "personal-capability.json",
58988
59127
  "received-capabilities.json",
@@ -58991,9 +59130,9 @@ var LEGACY_FILES = [
58991
59130
  async function cleanupLegacyCapabilityFiles(dataDir, logger) {
58992
59131
  const removed = [];
58993
59132
  for (const name of LEGACY_FILES) {
58994
- const p2 = path48.join(dataDir, name);
59133
+ const p2 = path49.join(dataDir, name);
58995
59134
  try {
58996
- await fs45.unlink(p2);
59135
+ await fs46.unlink(p2);
58997
59136
  removed.push(name);
58998
59137
  logger.debug("legacy capability file removed", { file: name });
58999
59138
  } catch (err) {
@@ -59005,13 +59144,13 @@ async function cleanupLegacyCapabilityFiles(dataDir, logger) {
59005
59144
  }
59006
59145
 
59007
59146
  // src/inbox/inbox-store.ts
59008
- var fs46 = __toESM(require("fs"), 1);
59009
- var path49 = __toESM(require("path"), 1);
59147
+ var fs47 = __toESM(require("fs"), 1);
59148
+ var path50 = __toESM(require("path"), 1);
59010
59149
  var INBOX_SUBDIR = "inbox";
59011
59150
  var InboxStore = class {
59012
59151
  constructor(dataDir) {
59013
59152
  this.dataDir = dataDir;
59014
- fs46.mkdirSync(this.dirPath(), { recursive: true });
59153
+ fs47.mkdirSync(this.dirPath(), { recursive: true });
59015
59154
  }
59016
59155
  dataDir;
59017
59156
  /**
@@ -59023,7 +59162,7 @@ var InboxStore = class {
59023
59162
  const file = this.filePath(peerDeviceId);
59024
59163
  let raw;
59025
59164
  try {
59026
- raw = fs46.readFileSync(file, "utf8");
59165
+ raw = fs47.readFileSync(file, "utf8");
59027
59166
  } catch (err) {
59028
59167
  if (err?.code === "ENOENT") return [];
59029
59168
  return [];
@@ -59039,7 +59178,7 @@ var InboxStore = class {
59039
59178
  const dir = this.dirPath();
59040
59179
  let entries;
59041
59180
  try {
59042
- entries = fs46.readdirSync(dir);
59181
+ entries = fs47.readdirSync(dir);
59043
59182
  } catch (err) {
59044
59183
  if (err?.code === "ENOENT") return [];
59045
59184
  return [];
@@ -59055,9 +59194,9 @@ var InboxStore = class {
59055
59194
  if (existing.some((m2) => m2.id === message.id)) return;
59056
59195
  const file = this.filePath(message.peerDeviceId);
59057
59196
  const line = JSON.stringify(message) + "\n";
59058
- fs46.appendFileSync(file, line, { mode: 384 });
59197
+ fs47.appendFileSync(file, line, { mode: 384 });
59059
59198
  try {
59060
- fs46.chmodSync(file, 384);
59199
+ fs47.chmodSync(file, 384);
59061
59200
  } catch {
59062
59201
  }
59063
59202
  }
@@ -59087,7 +59226,7 @@ var InboxStore = class {
59087
59226
  removeByPeerDeviceId(peerDeviceId) {
59088
59227
  const file = this.filePath(peerDeviceId);
59089
59228
  try {
59090
- fs46.unlinkSync(file);
59229
+ fs47.unlinkSync(file);
59091
59230
  } catch (err) {
59092
59231
  if (err?.code === "ENOENT") return;
59093
59232
  }
@@ -59096,18 +59235,18 @@ var InboxStore = class {
59096
59235
  const file = this.filePath(peerDeviceId);
59097
59236
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
59098
59237
  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);
59238
+ fs47.writeFileSync(tmp, content, { mode: 384 });
59239
+ fs47.renameSync(tmp, file);
59101
59240
  try {
59102
- fs46.chmodSync(file, 384);
59241
+ fs47.chmodSync(file, 384);
59103
59242
  } catch {
59104
59243
  }
59105
59244
  }
59106
59245
  dirPath() {
59107
- return path49.join(this.dataDir, INBOX_SUBDIR);
59246
+ return path50.join(this.dataDir, INBOX_SUBDIR);
59108
59247
  }
59109
59248
  filePath(peerDeviceId) {
59110
- return path49.join(this.dirPath(), `${peerDeviceId}.jsonl`);
59249
+ return path50.join(this.dirPath(), `${peerDeviceId}.jsonl`);
59111
59250
  }
59112
59251
  };
59113
59252
  function parseAllLines(raw) {
@@ -59195,8 +59334,8 @@ var InboxManager = class {
59195
59334
  };
59196
59335
 
59197
59336
  // src/state/contact-store.ts
59198
- var fs47 = __toESM(require("fs"), 1);
59199
- var path50 = __toESM(require("path"), 1);
59337
+ var fs48 = __toESM(require("fs"), 1);
59338
+ var path51 = __toESM(require("path"), 1);
59200
59339
  var FILE_NAME = "contacts.json";
59201
59340
  var ContactStore = class {
59202
59341
  constructor(dataDir) {
@@ -59206,10 +59345,10 @@ var ContactStore = class {
59206
59345
  contacts = /* @__PURE__ */ new Map();
59207
59346
  load() {
59208
59347
  this.contacts.clear();
59209
- const file = path50.join(this.dataDir, FILE_NAME);
59348
+ const file = path51.join(this.dataDir, FILE_NAME);
59210
59349
  let raw;
59211
59350
  try {
59212
- raw = fs47.readFileSync(file, "utf8");
59351
+ raw = fs48.readFileSync(file, "utf8");
59213
59352
  } catch (err) {
59214
59353
  if (err?.code !== "ENOENT") this.renameBak(file);
59215
59354
  return;
@@ -59290,20 +59429,20 @@ var ContactStore = class {
59290
59429
  return true;
59291
59430
  }
59292
59431
  flush() {
59293
- const file = path50.join(this.dataDir, FILE_NAME);
59432
+ const file = path51.join(this.dataDir, FILE_NAME);
59294
59433
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
59295
59434
  const content = JSON.stringify(
59296
59435
  { contacts: Array.from(this.contacts.values()) },
59297
59436
  null,
59298
59437
  2
59299
59438
  );
59300
- fs47.mkdirSync(this.dataDir, { recursive: true });
59301
- fs47.writeFileSync(tmp, content, { mode: 384 });
59302
- fs47.renameSync(tmp, file);
59439
+ fs48.mkdirSync(this.dataDir, { recursive: true });
59440
+ fs48.writeFileSync(tmp, content, { mode: 384 });
59441
+ fs48.renameSync(tmp, file);
59303
59442
  }
59304
59443
  renameBak(file) {
59305
59444
  try {
59306
- fs47.renameSync(file, `${file}.bak`);
59445
+ fs48.renameSync(file, `${file}.bak`);
59307
59446
  } catch {
59308
59447
  }
59309
59448
  }
@@ -59411,61 +59550,61 @@ async function connectRemote(args) {
59411
59550
  }
59412
59551
 
59413
59552
  // src/migrations/2026-05-20-flatten-sessions.ts
59414
- var fs48 = __toESM(require("fs"), 1);
59415
- var path51 = __toESM(require("path"), 1);
59553
+ var fs49 = __toESM(require("fs"), 1);
59554
+ var path52 = __toESM(require("path"), 1);
59416
59555
  var MIGRATION_FLAG_NAME = ".migration.v1.done";
59417
59556
  function migrateFlattenSessions(opts) {
59418
59557
  const dataDir = opts.dataDir;
59419
59558
  const now = opts.now ?? Date.now;
59420
- const sessionsDir = path51.join(dataDir, "sessions");
59421
- const flagPath = path51.join(sessionsDir, MIGRATION_FLAG_NAME);
59559
+ const sessionsDir = path52.join(dataDir, "sessions");
59560
+ const flagPath = path52.join(sessionsDir, MIGRATION_FLAG_NAME);
59422
59561
  if (existsSync3(flagPath)) {
59423
59562
  return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
59424
59563
  }
59425
59564
  let movedBare = 0;
59426
59565
  let movedVmOwner = 0;
59427
59566
  let archivedListener = 0;
59428
- const defaultDir = path51.join(sessionsDir, "default");
59567
+ const defaultDir = path52.join(sessionsDir, "default");
59429
59568
  if (existsSync3(defaultDir)) {
59430
59569
  for (const entry of readdirSafe(defaultDir)) {
59431
59570
  if (!entry.endsWith(".json")) continue;
59432
- const src = path51.join(defaultDir, entry);
59433
- const dst = path51.join(sessionsDir, entry);
59434
- fs48.renameSync(src, dst);
59571
+ const src = path52.join(defaultDir, entry);
59572
+ const dst = path52.join(sessionsDir, entry);
59573
+ fs49.renameSync(src, dst);
59435
59574
  movedBare += 1;
59436
59575
  }
59437
59576
  rmdirIfEmpty(defaultDir);
59438
59577
  }
59439
59578
  for (const pid of readdirSafe(sessionsDir)) {
59440
- const personaDir = path51.join(sessionsDir, pid);
59579
+ const personaDir = path52.join(sessionsDir, pid);
59441
59580
  if (!isDir(personaDir)) continue;
59442
59581
  if (pid === "default") continue;
59443
- const ownerSrc = path51.join(personaDir, "owner");
59582
+ const ownerSrc = path52.join(personaDir, "owner");
59444
59583
  if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
59445
- const ownerDst = path51.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
59446
- fs48.mkdirSync(ownerDst, { recursive: true });
59584
+ const ownerDst = path52.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
59585
+ fs49.mkdirSync(ownerDst, { recursive: true });
59447
59586
  for (const file of readdirSafe(ownerSrc)) {
59448
59587
  if (!file.endsWith(".json")) continue;
59449
- fs48.renameSync(path51.join(ownerSrc, file), path51.join(ownerDst, file));
59588
+ fs49.renameSync(path52.join(ownerSrc, file), path52.join(ownerDst, file));
59450
59589
  movedVmOwner += 1;
59451
59590
  }
59452
59591
  rmdirIfEmpty(ownerSrc);
59453
59592
  }
59454
- const listenerSrc = path51.join(personaDir, "listener");
59593
+ const listenerSrc = path52.join(personaDir, "listener");
59455
59594
  if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
59456
- const archiveDst = path51.join(dataDir, ".legacy", `listener-${pid}`);
59457
- fs48.mkdirSync(archiveDst, { recursive: true });
59595
+ const archiveDst = path52.join(dataDir, ".legacy", `listener-${pid}`);
59596
+ fs49.mkdirSync(archiveDst, { recursive: true });
59458
59597
  for (const file of readdirSafe(listenerSrc)) {
59459
59598
  if (!file.endsWith(".json")) continue;
59460
- fs48.renameSync(path51.join(listenerSrc, file), path51.join(archiveDst, file));
59599
+ fs49.renameSync(path52.join(listenerSrc, file), path52.join(archiveDst, file));
59461
59600
  archivedListener += 1;
59462
59601
  }
59463
59602
  rmdirIfEmpty(listenerSrc);
59464
59603
  }
59465
59604
  rmdirIfEmpty(personaDir);
59466
59605
  }
59467
- fs48.mkdirSync(sessionsDir, { recursive: true });
59468
- fs48.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
59606
+ fs49.mkdirSync(sessionsDir, { recursive: true });
59607
+ fs49.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
59469
59608
  return {
59470
59609
  skipped: false,
59471
59610
  flagWritten: true,
@@ -59476,7 +59615,7 @@ function migrateFlattenSessions(opts) {
59476
59615
  }
59477
59616
  function existsSync3(p2) {
59478
59617
  try {
59479
- fs48.statSync(p2);
59618
+ fs49.statSync(p2);
59480
59619
  return true;
59481
59620
  } catch {
59482
59621
  return false;
@@ -59484,61 +59623,61 @@ function existsSync3(p2) {
59484
59623
  }
59485
59624
  function isDir(p2) {
59486
59625
  try {
59487
- return fs48.statSync(p2).isDirectory();
59626
+ return fs49.statSync(p2).isDirectory();
59488
59627
  } catch {
59489
59628
  return false;
59490
59629
  }
59491
59630
  }
59492
59631
  function readdirSafe(p2) {
59493
59632
  try {
59494
- return fs48.readdirSync(p2);
59633
+ return fs49.readdirSync(p2);
59495
59634
  } catch {
59496
59635
  return [];
59497
59636
  }
59498
59637
  }
59499
59638
  function rmdirIfEmpty(p2) {
59500
59639
  try {
59501
- fs48.rmdirSync(p2);
59640
+ fs49.rmdirSync(p2);
59502
59641
  } catch {
59503
59642
  }
59504
59643
  }
59505
59644
 
59506
59645
  // src/migrations/2026-08-18-drop-seeded-projects.ts
59507
- var fs49 = __toESM(require("fs"), 1);
59508
- var path52 = __toESM(require("path"), 1);
59646
+ var fs50 = __toESM(require("fs"), 1);
59647
+ var path53 = __toESM(require("path"), 1);
59509
59648
  var DROP_SEEDED_PROJECTS_FLAG = ".projects-seed-dropped.v1.done";
59510
59649
  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");
59650
+ fs50.mkdirSync(opts.dataDir, { recursive: true });
59651
+ const flag = path53.join(opts.dataDir, DROP_SEEDED_PROJECTS_FLAG);
59652
+ if (fs50.existsSync(flag)) return { skipped: true, dropped: 0, backup: null };
59653
+ const file = path53.join(opts.dataDir, "projects.json");
59515
59654
  let raw = null;
59516
59655
  let dropped = 0;
59517
59656
  try {
59518
- raw = fs49.readFileSync(file, "utf8");
59657
+ raw = fs50.readFileSync(file, "utf8");
59519
59658
  dropped = JSON.parse(raw).projects?.length ?? 0;
59520
59659
  } catch {
59521
59660
  }
59522
59661
  let backup = null;
59523
59662
  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);
59663
+ const dir = path53.join(opts.dataDir, "backups");
59664
+ fs50.mkdirSync(dir, { recursive: true });
59665
+ backup = path53.join(dir, `projects.seed-dropped.${(opts.now ?? Date.now)()}.json`);
59666
+ fs50.writeFileSync(backup, raw);
59528
59667
  }
59529
59668
  if (raw != null || dropped > 0) {
59530
- fs49.writeFileSync(file, JSON.stringify({ projects: [] }, null, 2));
59669
+ fs50.writeFileSync(file, JSON.stringify({ projects: [] }, null, 2));
59531
59670
  }
59532
- fs49.writeFileSync(flag, (/* @__PURE__ */ new Date()).toISOString());
59671
+ fs50.writeFileSync(flag, (/* @__PURE__ */ new Date()).toISOString());
59533
59672
  return { skipped: false, dropped, backup };
59534
59673
  }
59535
59674
 
59536
59675
  // src/transport/http-router.ts
59537
- var import_node_fs36 = __toESM(require("fs"), 1);
59538
- var import_node_path44 = __toESM(require("path"), 1);
59676
+ var import_node_fs37 = __toESM(require("fs"), 1);
59677
+ var import_node_path45 = __toESM(require("path"), 1);
59539
59678
 
59540
59679
  // src/attachment/mime.ts
59541
- var import_node_path41 = __toESM(require("path"), 1);
59680
+ var import_node_path42 = __toESM(require("path"), 1);
59542
59681
  var TEXT_PLAIN = "text/plain; charset=utf-8";
59543
59682
  var EXT_TO_NATIVE_MIME = {
59544
59683
  // 图片
@@ -59645,7 +59784,7 @@ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
59645
59784
  ".mk"
59646
59785
  ]);
59647
59786
  function lookupMime(filePathOrName) {
59648
- const ext = import_node_path41.default.extname(filePathOrName).toLowerCase();
59787
+ const ext = import_node_path42.default.extname(filePathOrName).toLowerCase();
59649
59788
  if (EXT_TO_NATIVE_MIME[ext]) return EXT_TO_NATIVE_MIME[ext];
59650
59789
  if (TEXT_EXTENSIONS.has(ext)) return TEXT_PLAIN;
59651
59790
  return "application/octet-stream";
@@ -59715,8 +59854,8 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
59715
59854
  }
59716
59855
 
59717
59856
  // src/attachment/upload.ts
59718
- var import_node_fs35 = __toESM(require("fs"), 1);
59719
- var import_node_path42 = __toESM(require("path"), 1);
59857
+ var import_node_fs36 = __toESM(require("fs"), 1);
59858
+ var import_node_path43 = __toESM(require("path"), 1);
59720
59859
  var import_node_crypto10 = __toESM(require("crypto"), 1);
59721
59860
  var import_promises7 = require("stream/promises");
59722
59861
  var UploadError = class extends Error {
@@ -59728,22 +59867,22 @@ var UploadError = class extends Error {
59728
59867
  code;
59729
59868
  };
59730
59869
  function assertValidFileName(fileName) {
59731
- if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path42.default.basename(fileName)) {
59870
+ if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path43.default.basename(fileName)) {
59732
59871
  throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
59733
59872
  }
59734
59873
  }
59735
59874
  var HASH_PREFIX_LEN = 16;
59736
59875
  async function writeUploadedAttachment(args) {
59737
59876
  assertValidFileName(args.fileName);
59738
- const attachmentsRoot = import_node_path42.default.join(args.baseDir, ".attachments");
59877
+ const attachmentsRoot = import_node_path43.default.join(args.baseDir, ".attachments");
59739
59878
  try {
59740
- import_node_fs35.default.mkdirSync(attachmentsRoot, { recursive: true });
59879
+ import_node_fs36.default.mkdirSync(attachmentsRoot, { recursive: true });
59741
59880
  } catch (err) {
59742
59881
  throw new UploadError("STORAGE_ERROR", `mkdir failed: ${err.message}`);
59743
59882
  }
59744
59883
  const hasher = import_node_crypto10.default.createHash("sha256");
59745
59884
  let actualSize = 0;
59746
- const tmpPath = import_node_path42.default.join(
59885
+ const tmpPath = import_node_path43.default.join(
59747
59886
  attachmentsRoot,
59748
59887
  `.upload-${process.pid}-${Date.now()}-${import_node_crypto10.default.randomBytes(4).toString("hex")}`
59749
59888
  );
@@ -59758,18 +59897,18 @@ async function writeUploadedAttachment(args) {
59758
59897
  yield buf;
59759
59898
  }
59760
59899
  },
59761
- import_node_fs35.default.createWriteStream(tmpPath, { mode: 384 })
59900
+ import_node_fs36.default.createWriteStream(tmpPath, { mode: 384 })
59762
59901
  );
59763
59902
  } catch (err) {
59764
59903
  try {
59765
- import_node_fs35.default.unlinkSync(tmpPath);
59904
+ import_node_fs36.default.unlinkSync(tmpPath);
59766
59905
  } catch {
59767
59906
  }
59768
59907
  throw new UploadError("STORAGE_ERROR", `write failed: ${err.message}`);
59769
59908
  }
59770
59909
  if (actualSize !== args.contentLength) {
59771
59910
  try {
59772
- import_node_fs35.default.unlinkSync(tmpPath);
59911
+ import_node_fs36.default.unlinkSync(tmpPath);
59773
59912
  } catch {
59774
59913
  }
59775
59914
  throw new UploadError(
@@ -59778,34 +59917,34 @@ async function writeUploadedAttachment(args) {
59778
59917
  );
59779
59918
  }
59780
59919
  const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
59781
- const hashDir = import_node_path42.default.join(attachmentsRoot, attachmentId);
59920
+ const hashDir = import_node_path43.default.join(attachmentsRoot, attachmentId);
59782
59921
  let finalFileName;
59783
59922
  let hashDirExists = false;
59784
59923
  try {
59785
- hashDirExists = import_node_fs35.default.statSync(hashDir).isDirectory();
59924
+ hashDirExists = import_node_fs36.default.statSync(hashDir).isDirectory();
59786
59925
  } catch {
59787
59926
  }
59788
59927
  if (hashDirExists) {
59789
- const existing = import_node_fs35.default.readdirSync(hashDir).filter((n) => !n.startsWith("."));
59928
+ const existing = import_node_fs36.default.readdirSync(hashDir).filter((n) => !n.startsWith("."));
59790
59929
  finalFileName = existing[0] ?? args.fileName;
59791
59930
  try {
59792
- import_node_fs35.default.unlinkSync(tmpPath);
59931
+ import_node_fs36.default.unlinkSync(tmpPath);
59793
59932
  } catch {
59794
59933
  }
59795
59934
  } else {
59796
59935
  try {
59797
- import_node_fs35.default.mkdirSync(hashDir, { recursive: true });
59936
+ import_node_fs36.default.mkdirSync(hashDir, { recursive: true });
59798
59937
  finalFileName = args.fileName;
59799
- import_node_fs35.default.renameSync(tmpPath, import_node_path42.default.join(hashDir, finalFileName));
59938
+ import_node_fs36.default.renameSync(tmpPath, import_node_path43.default.join(hashDir, finalFileName));
59800
59939
  } catch (err) {
59801
59940
  try {
59802
- import_node_fs35.default.unlinkSync(tmpPath);
59941
+ import_node_fs36.default.unlinkSync(tmpPath);
59803
59942
  } catch {
59804
59943
  }
59805
59944
  throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
59806
59945
  }
59807
59946
  }
59808
- const absPath = import_node_path42.default.join(hashDir, finalFileName);
59947
+ const absPath = import_node_path43.default.join(hashDir, finalFileName);
59809
59948
  const relPath = absPath;
59810
59949
  args.groupFileStore.upsert(args.scope, args.sessionId, {
59811
59950
  relPath: absPath,
@@ -59820,8 +59959,8 @@ async function writeUploadedAttachment(args) {
59820
59959
 
59821
59960
  // src/extension/import.ts
59822
59961
  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);
59962
+ var import_node_path44 = __toESM(require("path"), 1);
59963
+ var import_node_os14 = __toESM(require("os"), 1);
59825
59964
  var import_jszip = __toESM(require_lib3(), 1);
59826
59965
  var ImportError = class extends Error {
59827
59966
  constructor(code, message) {
@@ -59838,7 +59977,7 @@ async function importZip(buf, root) {
59838
59977
  throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
59839
59978
  }
59840
59979
  for (const name of Object.keys(zip.files)) {
59841
- if (name.includes("..") || name.startsWith("/") || import_node_path43.default.isAbsolute(name)) {
59980
+ if (name.includes("..") || name.startsWith("/") || import_node_path44.default.isAbsolute(name)) {
59842
59981
  throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
59843
59982
  }
59844
59983
  }
@@ -59871,7 +60010,7 @@ async function importZip(buf, root) {
59871
60010
  );
59872
60011
  }
59873
60012
  }
59874
- const destDir = import_node_path43.default.join(root, manifest.id);
60013
+ const destDir = import_node_path44.default.join(root, manifest.id);
59875
60014
  let destExists = false;
59876
60015
  try {
59877
60016
  await import_promises8.default.access(destDir);
@@ -59881,15 +60020,15 @@ async function importZip(buf, root) {
59881
60020
  if (destExists) {
59882
60021
  throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
59883
60022
  }
59884
- const stage = await import_promises8.default.mkdtemp(import_node_path43.default.join(import_node_os13.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
60023
+ const stage = await import_promises8.default.mkdtemp(import_node_path44.default.join(import_node_os14.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
59885
60024
  try {
59886
60025
  for (const [name, entry] of Object.entries(zip.files)) {
59887
- const dest = import_node_path43.default.join(stage, name);
60026
+ const dest = import_node_path44.default.join(stage, name);
59888
60027
  if (entry.dir) {
59889
60028
  await import_promises8.default.mkdir(dest, { recursive: true });
59890
60029
  continue;
59891
60030
  }
59892
- await import_promises8.default.mkdir(import_node_path43.default.dirname(dest), { recursive: true });
60031
+ await import_promises8.default.mkdir(import_node_path44.default.dirname(dest), { recursive: true });
59893
60032
  const content = await entry.async("nodebuffer");
59894
60033
  await import_promises8.default.writeFile(dest, content);
59895
60034
  }
@@ -59919,7 +60058,7 @@ var SHARE_UI_ASSET_MIME = {
59919
60058
  ".wasm": "application/wasm"
59920
60059
  };
59921
60060
  function shareUiAssetMime(filePath) {
59922
- const ext = import_node_path44.default.extname(filePath).toLowerCase();
60061
+ const ext = import_node_path45.default.extname(filePath).toLowerCase();
59923
60062
  return SHARE_UI_ASSET_MIME[ext] ?? lookupMime(filePath);
59924
60063
  }
59925
60064
  var AUTHED_RPC_ROUTE_PREFIX = "/rpc/";
@@ -60018,7 +60157,7 @@ function isValidUploadFileName(fileName) {
60018
60157
  if (fileName === "." || fileName === "..") return false;
60019
60158
  if (fileName.startsWith(".")) return false;
60020
60159
  if (fileName.includes("/") || fileName.includes("\\")) return false;
60021
- return fileName === import_node_path44.default.basename(fileName);
60160
+ return fileName === import_node_path45.default.basename(fileName);
60022
60161
  }
60023
60162
  function createHttpRouter(deps) {
60024
60163
  return async (req, res) => {
@@ -60106,7 +60245,7 @@ function createHttpRouter(deps) {
60106
60245
  }
60107
60246
  let buf;
60108
60247
  try {
60109
- buf = await import_node_fs36.default.promises.readFile(abs);
60248
+ buf = await import_node_fs37.default.promises.readFile(abs);
60110
60249
  } catch {
60111
60250
  sendJson(res, 404, { code: "NOT_FOUND", message: "asset not found" });
60112
60251
  return true;
@@ -60254,7 +60393,7 @@ function createHttpRouter(deps) {
60254
60393
  sendHtml(res, statusByCode[r.code], loader.renderErrorHtml(r.code, msgByCode[r.code]));
60255
60394
  return true;
60256
60395
  }
60257
- sendHtml(res, 200, loader.renderViewerHtml(import_node_path44.default.basename(r.absPath)));
60396
+ sendHtml(res, 200, loader.renderViewerHtml(import_node_path45.default.basename(r.absPath)));
60258
60397
  return true;
60259
60398
  }
60260
60399
  const ctx = deps.authResolver.resolveFromHeader(
@@ -60375,7 +60514,7 @@ function createHttpRouter(deps) {
60375
60514
  return true;
60376
60515
  }
60377
60516
  let absPath;
60378
- if (import_node_path44.default.isAbsolute(pathParam)) {
60517
+ if (import_node_path45.default.isAbsolute(pathParam)) {
60379
60518
  absPath = pathParam;
60380
60519
  } else if (deps.sessionStore) {
60381
60520
  const file = deps.sessionStore.read(sid);
@@ -60383,7 +60522,7 @@ function createHttpRouter(deps) {
60383
60522
  sendJson(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
60384
60523
  return true;
60385
60524
  }
60386
- absPath = import_node_path44.default.join(file.cwd, pathParam);
60525
+ absPath = import_node_path45.default.join(file.cwd, pathParam);
60387
60526
  } else {
60388
60527
  sendJson(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
60389
60528
  return true;
@@ -60470,7 +60609,7 @@ function withCtx(ctx, body) {
60470
60609
  function streamFile(res, absPath, logger) {
60471
60610
  let stat;
60472
60611
  try {
60473
- stat = import_node_fs36.default.statSync(absPath);
60612
+ stat = import_node_fs37.default.statSync(absPath);
60474
60613
  } catch (err) {
60475
60614
  const code = err?.code;
60476
60615
  if (code === "ENOENT") {
@@ -60485,7 +60624,7 @@ function streamFile(res, absPath, logger) {
60485
60624
  return;
60486
60625
  }
60487
60626
  const mime = lookupMime(absPath);
60488
- const basename2 = import_node_path44.default.basename(absPath);
60627
+ const basename2 = import_node_path45.default.basename(absPath);
60489
60628
  res.writeHead(200, {
60490
60629
  "Content-Type": mime,
60491
60630
  "Content-Length": String(stat.size),
@@ -60493,7 +60632,7 @@ function streamFile(res, absPath, logger) {
60493
60632
  // 防止浏览器把任意 mime 当 html 渲染
60494
60633
  "X-Content-Type-Options": "nosniff"
60495
60634
  });
60496
- const stream = import_node_fs36.default.createReadStream(absPath);
60635
+ const stream = import_node_fs37.default.createReadStream(absPath);
60497
60636
  stream.on("error", (err) => {
60498
60637
  logger?.warn("streamFile read error", { absPath, err: err.message });
60499
60638
  res.destroy();
@@ -60502,8 +60641,8 @@ function streamFile(res, absPath, logger) {
60502
60641
  }
60503
60642
 
60504
60643
  // src/attachment/gc.ts
60505
- var import_node_fs37 = __toESM(require("fs"), 1);
60506
- var import_node_path45 = __toESM(require("path"), 1);
60644
+ var import_node_fs38 = __toESM(require("fs"), 1);
60645
+ var import_node_path46 = __toESM(require("path"), 1);
60507
60646
  var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
60508
60647
  function runAttachmentGc(args) {
60509
60648
  const now = (args.now ?? Date.now)();
@@ -60512,12 +60651,12 @@ function runAttachmentGc(args) {
60512
60651
  for (const { scope, sessionId } of args.sessionScopes) {
60513
60652
  for (const entry of args.groupFileStore.list(scope, sessionId)) {
60514
60653
  if (entry.stale) continue;
60515
- if (import_node_path45.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
60654
+ if (import_node_path46.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
60516
60655
  }
60517
60656
  }
60518
60657
  const visited = /* @__PURE__ */ new Set();
60519
60658
  for (const { scope, sessionId } of args.sessionScopes) {
60520
- const legacyDir = args.getSessionCwd?.(sessionId) ?? import_node_path45.default.join(
60659
+ const legacyDir = args.getSessionCwd?.(sessionId) ?? import_node_path46.default.join(
60521
60660
  args.dataDir,
60522
60661
  "sessions",
60523
60662
  ...scopeSubPath(scope).map(safeFileName),
@@ -60530,28 +60669,28 @@ function runAttachmentGc(args) {
60530
60669
  return true;
60531
60670
  });
60532
60671
  for (const rootDir of roots) {
60533
- const attRoot = import_node_path45.default.join(rootDir, ".attachments");
60672
+ const attRoot = import_node_path46.default.join(rootDir, ".attachments");
60534
60673
  let hashDirs;
60535
60674
  try {
60536
- hashDirs = import_node_fs37.default.readdirSync(attRoot);
60675
+ hashDirs = import_node_fs38.default.readdirSync(attRoot);
60537
60676
  } catch (err) {
60538
60677
  if (err.code === "ENOENT") continue;
60539
60678
  args.logger?.warn("attachment gc: readdir failed", { attRoot, err: err.message });
60540
60679
  continue;
60541
60680
  }
60542
60681
  for (const hashDir of hashDirs) {
60543
- const hashDirAbs = import_node_path45.default.join(attRoot, hashDir);
60682
+ const hashDirAbs = import_node_path46.default.join(attRoot, hashDir);
60544
60683
  let files;
60545
60684
  try {
60546
- files = import_node_fs37.default.readdirSync(hashDirAbs);
60685
+ files = import_node_fs38.default.readdirSync(hashDirAbs);
60547
60686
  } catch {
60548
60687
  continue;
60549
60688
  }
60550
60689
  for (const name of files) {
60551
- const file = import_node_path45.default.join(hashDirAbs, name);
60690
+ const file = import_node_path46.default.join(hashDirAbs, name);
60552
60691
  let stat;
60553
60692
  try {
60554
- stat = import_node_fs37.default.statSync(file);
60693
+ stat = import_node_fs38.default.statSync(file);
60555
60694
  } catch {
60556
60695
  continue;
60557
60696
  }
@@ -60560,18 +60699,18 @@ function runAttachmentGc(args) {
60560
60699
  if (age < ttlMs) continue;
60561
60700
  if (liveAbs.has(file)) continue;
60562
60701
  try {
60563
- import_node_fs37.default.unlinkSync(file);
60702
+ import_node_fs38.default.unlinkSync(file);
60564
60703
  } catch (err) {
60565
60704
  args.logger?.warn("attachment gc: unlink failed", { file, err: err.message });
60566
60705
  }
60567
60706
  }
60568
60707
  try {
60569
- if (import_node_fs37.default.readdirSync(hashDirAbs).length === 0) import_node_fs37.default.rmdirSync(hashDirAbs);
60708
+ if (import_node_fs38.default.readdirSync(hashDirAbs).length === 0) import_node_fs38.default.rmdirSync(hashDirAbs);
60570
60709
  } catch {
60571
60710
  }
60572
60711
  }
60573
60712
  try {
60574
- if (import_node_fs37.default.readdirSync(attRoot).length === 0) import_node_fs37.default.rmdirSync(attRoot);
60713
+ if (import_node_fs38.default.readdirSync(attRoot).length === 0) import_node_fs38.default.rmdirSync(attRoot);
60575
60714
  } catch {
60576
60715
  }
60577
60716
  }
@@ -60579,8 +60718,8 @@ function runAttachmentGc(args) {
60579
60718
  }
60580
60719
 
60581
60720
  // src/attachment/group.ts
60582
- var import_node_fs38 = __toESM(require("fs"), 1);
60583
- var import_node_path46 = __toESM(require("path"), 1);
60721
+ var import_node_fs39 = __toESM(require("fs"), 1);
60722
+ var import_node_path47 = __toESM(require("path"), 1);
60584
60723
  var import_node_crypto11 = __toESM(require("crypto"), 1);
60585
60724
  init_protocol();
60586
60725
  var GroupFileStore = class {
@@ -60592,11 +60731,11 @@ var GroupFileStore = class {
60592
60731
  this.logger = opts.logger;
60593
60732
  }
60594
60733
  rootForScope(scope) {
60595
- return import_node_path46.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
60734
+ return import_node_path47.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
60596
60735
  }
60597
60736
  /** 与 SessionStore.filePath 平级,扩展名 .group-files.json */
60598
60737
  filePath(scope, sessionId) {
60599
- return import_node_path46.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
60738
+ return import_node_path47.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
60600
60739
  }
60601
60740
  cacheKey(scope, sessionId) {
60602
60741
  return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
@@ -60605,7 +60744,7 @@ var GroupFileStore = class {
60605
60744
  readFile(scope, sessionId) {
60606
60745
  const file = this.filePath(scope, sessionId);
60607
60746
  try {
60608
- const raw = import_node_fs38.default.readFileSync(file, "utf8");
60747
+ const raw = import_node_fs39.default.readFileSync(file, "utf8");
60609
60748
  const parsed = JSON.parse(raw);
60610
60749
  if (!Array.isArray(parsed)) {
60611
60750
  this.logger?.warn("GroupFileStore.readFile: not an array; resetting session entries", {
@@ -60631,10 +60770,10 @@ var GroupFileStore = class {
60631
60770
  }
60632
60771
  writeFile(scope, sessionId, entries) {
60633
60772
  const file = this.filePath(scope, sessionId);
60634
- import_node_fs38.default.mkdirSync(import_node_path46.default.dirname(file), { recursive: true });
60773
+ import_node_fs39.default.mkdirSync(import_node_path47.default.dirname(file), { recursive: true });
60635
60774
  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);
60775
+ import_node_fs39.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
60776
+ import_node_fs39.default.renameSync(tmp, file);
60638
60777
  }
60639
60778
  /** 拉一份当前 session 的清单。读盘 → cache;之后调用复用 cache */
60640
60779
  list(scope, sessionId) {
@@ -60720,10 +60859,10 @@ var GroupFileStore = class {
60720
60859
  };
60721
60860
 
60722
60861
  // src/discovery/state-file.ts
60723
- var import_node_fs39 = __toESM(require("fs"), 1);
60724
- var import_node_path47 = __toESM(require("path"), 1);
60862
+ var import_node_fs40 = __toESM(require("fs"), 1);
60863
+ var import_node_path48 = __toESM(require("path"), 1);
60725
60864
  function defaultStateFilePath(dataDir) {
60726
- return import_node_path47.default.join(dataDir, "state.json");
60865
+ return import_node_path48.default.join(dataDir, "state.json");
60727
60866
  }
60728
60867
  function isPidAlive(pid) {
60729
60868
  if (!Number.isFinite(pid) || pid <= 0) return false;
@@ -60745,7 +60884,7 @@ var StateFileManager = class {
60745
60884
  }
60746
60885
  read() {
60747
60886
  try {
60748
- const raw = import_node_fs39.default.readFileSync(this.file, "utf8");
60887
+ const raw = import_node_fs40.default.readFileSync(this.file, "utf8");
60749
60888
  const parsed = JSON.parse(raw);
60750
60889
  return parsed;
60751
60890
  } catch {
@@ -60759,20 +60898,20 @@ var StateFileManager = class {
60759
60898
  return { status: "stale", existing };
60760
60899
  }
60761
60900
  write(state) {
60762
- import_node_fs39.default.mkdirSync(import_node_path47.default.dirname(this.file), { recursive: true });
60901
+ import_node_fs40.default.mkdirSync(import_node_path48.default.dirname(this.file), { recursive: true });
60763
60902
  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);
60903
+ import_node_fs40.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
60904
+ import_node_fs40.default.renameSync(tmp, this.file);
60766
60905
  if (process.platform !== "win32") {
60767
60906
  try {
60768
- import_node_fs39.default.chmodSync(this.file, 384);
60907
+ import_node_fs40.default.chmodSync(this.file, 384);
60769
60908
  } catch {
60770
60909
  }
60771
60910
  }
60772
60911
  }
60773
60912
  delete() {
60774
60913
  try {
60775
- import_node_fs39.default.unlinkSync(this.file);
60914
+ import_node_fs40.default.unlinkSync(this.file);
60776
60915
  } catch {
60777
60916
  }
60778
60917
  }
@@ -60786,14 +60925,14 @@ function readSpawnedByDesktopFromEnv(env = process.env) {
60786
60925
  }
60787
60926
 
60788
60927
  // src/tunnel/tunnel-manager.ts
60789
- var import_node_fs43 = __toESM(require("fs"), 1);
60790
- var import_node_path51 = __toESM(require("path"), 1);
60928
+ var import_node_fs44 = __toESM(require("fs"), 1);
60929
+ var import_node_path52 = __toESM(require("path"), 1);
60791
60930
  var import_node_crypto12 = __toESM(require("crypto"), 1);
60792
60931
  var import_node_child_process12 = require("child_process");
60793
60932
 
60794
60933
  // src/tunnel/tunnel-store.ts
60795
- var import_node_fs40 = __toESM(require("fs"), 1);
60796
- var import_node_path48 = __toESM(require("path"), 1);
60934
+ var import_node_fs41 = __toESM(require("fs"), 1);
60935
+ var import_node_path49 = __toESM(require("path"), 1);
60797
60936
  var TunnelStore = class {
60798
60937
  constructor(filePath) {
60799
60938
  this.filePath = filePath;
@@ -60801,7 +60940,7 @@ var TunnelStore = class {
60801
60940
  filePath;
60802
60941
  async get() {
60803
60942
  try {
60804
- const raw = await import_node_fs40.default.promises.readFile(this.filePath, "utf8");
60943
+ const raw = await import_node_fs41.default.promises.readFile(this.filePath, "utf8");
60805
60944
  const obj = JSON.parse(raw);
60806
60945
  if (!isPersistedTunnel(obj)) return null;
60807
60946
  return obj;
@@ -60812,22 +60951,22 @@ var TunnelStore = class {
60812
60951
  }
60813
60952
  }
60814
60953
  async set(v2) {
60815
- const dir = import_node_path48.default.dirname(this.filePath);
60816
- await import_node_fs40.default.promises.mkdir(dir, { recursive: true });
60954
+ const dir = import_node_path49.default.dirname(this.filePath);
60955
+ await import_node_fs41.default.promises.mkdir(dir, { recursive: true });
60817
60956
  const data = JSON.stringify(v2, null, 2);
60818
60957
  const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
60819
- await import_node_fs40.default.promises.writeFile(tmp, data, { mode: 384 });
60958
+ await import_node_fs41.default.promises.writeFile(tmp, data, { mode: 384 });
60820
60959
  if (process.platform !== "win32") {
60821
60960
  try {
60822
- await import_node_fs40.default.promises.chmod(tmp, 384);
60961
+ await import_node_fs41.default.promises.chmod(tmp, 384);
60823
60962
  } catch {
60824
60963
  }
60825
60964
  }
60826
- await import_node_fs40.default.promises.rename(tmp, this.filePath);
60965
+ await import_node_fs41.default.promises.rename(tmp, this.filePath);
60827
60966
  }
60828
60967
  async clear() {
60829
60968
  try {
60830
- await import_node_fs40.default.promises.unlink(this.filePath);
60969
+ await import_node_fs41.default.promises.unlink(this.filePath);
60831
60970
  } catch (err) {
60832
60971
  const code = err?.code;
60833
60972
  if (code !== "ENOENT") throw err;
@@ -60922,9 +61061,9 @@ function escape(v2) {
60922
61061
  }
60923
61062
 
60924
61063
  // 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);
61064
+ var import_node_fs42 = __toESM(require("fs"), 1);
61065
+ var import_node_os15 = __toESM(require("os"), 1);
61066
+ var import_node_path50 = __toESM(require("path"), 1);
60928
61067
  var import_node_child_process10 = require("child_process");
60929
61068
  var import_node_stream3 = require("stream");
60930
61069
  var import_promises9 = require("stream/promises");
@@ -60956,20 +61095,20 @@ function frpcDownloadUrl(version2, p2) {
60956
61095
  }
60957
61096
  async function ensureFrpcBinary(opts) {
60958
61097
  if (opts.override) {
60959
- if (!import_node_fs41.default.existsSync(opts.override)) {
61098
+ if (!import_node_fs42.default.existsSync(opts.override)) {
60960
61099
  throw new Error(`frpc binary not found at override path: ${opts.override}`);
60961
61100
  }
60962
61101
  return opts.override;
60963
61102
  }
60964
61103
  const version2 = opts.version ?? FRPC_VERSION;
60965
61104
  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 });
61105
+ const binDir = import_node_path50.default.join(opts.dataDir, "bin");
61106
+ import_node_fs42.default.mkdirSync(binDir, { recursive: true });
60968
61107
  cleanupStaleArtifacts(binDir);
60969
- const stableBin = import_node_path49.default.join(binDir, "frpc");
60970
- if (import_node_fs41.default.existsSync(stableBin)) return stableBin;
61108
+ const stableBin = import_node_path50.default.join(binDir, "frpc");
61109
+ if (import_node_fs42.default.existsSync(stableBin)) return stableBin;
60971
61110
  const partialBin = `${stableBin}.partial`;
60972
- const tarballPath = import_node_path49.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
61111
+ const tarballPath = import_node_path50.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
60973
61112
  try {
60974
61113
  const url = frpcDownloadUrl(version2, platform);
60975
61114
  await downloadToFile(url, tarballPath, opts.fetchImpl);
@@ -60978,8 +61117,8 @@ async function ensureFrpcBinary(opts) {
60978
61117
  } else {
60979
61118
  await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
60980
61119
  }
60981
- import_node_fs41.default.chmodSync(partialBin, 493);
60982
- import_node_fs41.default.renameSync(partialBin, stableBin);
61120
+ import_node_fs42.default.chmodSync(partialBin, 493);
61121
+ import_node_fs42.default.renameSync(partialBin, stableBin);
60983
61122
  } finally {
60984
61123
  safeUnlink(tarballPath);
60985
61124
  safeUnlink(partialBin);
@@ -60989,15 +61128,15 @@ async function ensureFrpcBinary(opts) {
60989
61128
  function cleanupStaleArtifacts(binDir) {
60990
61129
  let entries;
60991
61130
  try {
60992
- entries = import_node_fs41.default.readdirSync(binDir);
61131
+ entries = import_node_fs42.default.readdirSync(binDir);
60993
61132
  } catch {
60994
61133
  return;
60995
61134
  }
60996
61135
  for (const name of entries) {
60997
61136
  if (name.endsWith(".partial") || name.startsWith("extract-")) {
60998
- const full = import_node_path49.default.join(binDir, name);
61137
+ const full = import_node_path50.default.join(binDir, name);
60999
61138
  try {
61000
- import_node_fs41.default.rmSync(full, { recursive: true, force: true });
61139
+ import_node_fs42.default.rmSync(full, { recursive: true, force: true });
61001
61140
  } catch {
61002
61141
  }
61003
61142
  }
@@ -61005,7 +61144,7 @@ function cleanupStaleArtifacts(binDir) {
61005
61144
  }
61006
61145
  function safeUnlink(p2) {
61007
61146
  try {
61008
- import_node_fs41.default.unlinkSync(p2);
61147
+ import_node_fs42.default.unlinkSync(p2);
61009
61148
  } catch {
61010
61149
  }
61011
61150
  }
@@ -61016,13 +61155,13 @@ async function downloadToFile(url, dest, fetchImpl) {
61016
61155
  if (!res.ok || !res.body) {
61017
61156
  throw new Error(`download failed: ${res.status} ${res.statusText}`);
61018
61157
  }
61019
- const out = import_node_fs41.default.createWriteStream(dest);
61158
+ const out = import_node_fs42.default.createWriteStream(dest);
61020
61159
  const nodeStream = import_node_stream3.Readable.fromWeb(res.body);
61021
61160
  await (0, import_promises9.pipeline)(nodeStream, out);
61022
61161
  }
61023
61162
  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 });
61163
+ const work = import_node_path50.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
61164
+ import_node_fs42.default.mkdirSync(work, { recursive: true });
61026
61165
  try {
61027
61166
  await new Promise((resolve9, reject) => {
61028
61167
  const proc = (0, import_node_child_process10.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
@@ -61030,32 +61169,32 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
61030
61169
  proc.on("exit", (code) => code === 0 ? resolve9() : reject(new Error(`tar exited ${code}`)));
61031
61170
  });
61032
61171
  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)) {
61172
+ const src = import_node_path50.default.join(work, dirName, "frpc");
61173
+ if (!import_node_fs42.default.existsSync(src)) {
61035
61174
  throw new Error(`frpc not found inside tarball at ${src}`);
61036
61175
  }
61037
- import_node_fs41.default.copyFileSync(src, destBin);
61176
+ import_node_fs42.default.copyFileSync(src, destBin);
61038
61177
  } finally {
61039
- import_node_fs41.default.rmSync(work, { recursive: true, force: true });
61178
+ import_node_fs42.default.rmSync(work, { recursive: true, force: true });
61040
61179
  }
61041
61180
  }
61042
61181
 
61043
61182
  // src/tunnel/frpc-process.ts
61044
- var import_node_fs42 = __toESM(require("fs"), 1);
61045
- var import_node_path50 = __toESM(require("path"), 1);
61183
+ var import_node_fs43 = __toESM(require("fs"), 1);
61184
+ var import_node_path51 = __toESM(require("path"), 1);
61046
61185
  var import_node_child_process11 = require("child_process");
61047
61186
  function frpcPidFilePath(dataDir) {
61048
- return import_node_path50.default.join(dataDir, "frpc.pid");
61187
+ return import_node_path51.default.join(dataDir, "frpc.pid");
61049
61188
  }
61050
61189
  function writeFrpcPid(dataDir, pid) {
61051
61190
  try {
61052
- import_node_fs42.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
61191
+ import_node_fs43.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
61053
61192
  } catch {
61054
61193
  }
61055
61194
  }
61056
61195
  function clearFrpcPid(dataDir) {
61057
61196
  try {
61058
- import_node_fs42.default.unlinkSync(frpcPidFilePath(dataDir));
61197
+ import_node_fs43.default.unlinkSync(frpcPidFilePath(dataDir));
61059
61198
  } catch {
61060
61199
  }
61061
61200
  }
@@ -61071,7 +61210,7 @@ function defaultIsPidAlive(pid) {
61071
61210
  }
61072
61211
  function defaultReadPidFile(file) {
61073
61212
  try {
61074
- return import_node_fs42.default.readFileSync(file, "utf8");
61213
+ return import_node_fs43.default.readFileSync(file, "utf8");
61075
61214
  } catch {
61076
61215
  return null;
61077
61216
  }
@@ -61087,7 +61226,7 @@ function defaultSleep2(ms) {
61087
61226
  }
61088
61227
  async function killStaleFrpc(deps) {
61089
61228
  const pidFile = frpcPidFilePath(deps.dataDir);
61090
- const tomlPath = import_node_path50.default.join(deps.dataDir, "frpc.toml");
61229
+ const tomlPath = import_node_path51.default.join(deps.dataDir, "frpc.toml");
61091
61230
  const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
61092
61231
  const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
61093
61232
  const killPid = deps.killPidImpl ?? defaultKillPid;
@@ -61111,7 +61250,7 @@ async function killStaleFrpc(deps) {
61111
61250
  }
61112
61251
  if (victims.size === 0) {
61113
61252
  try {
61114
- import_node_fs42.default.unlinkSync(pidFile);
61253
+ import_node_fs43.default.unlinkSync(pidFile);
61115
61254
  } catch {
61116
61255
  }
61117
61256
  return;
@@ -61122,7 +61261,7 @@ async function killStaleFrpc(deps) {
61122
61261
  }
61123
61262
  await sleep2(deps.reapWaitMs ?? 300);
61124
61263
  try {
61125
- import_node_fs42.default.unlinkSync(pidFile);
61264
+ import_node_fs43.default.unlinkSync(pidFile);
61126
61265
  } catch {
61127
61266
  }
61128
61267
  }
@@ -61159,7 +61298,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
61159
61298
  var TunnelManager = class {
61160
61299
  constructor(deps) {
61161
61300
  this.deps = deps;
61162
- this.store = deps.store ?? new TunnelStore(import_node_path51.default.join(deps.dataDir, "tunnel.json"));
61301
+ this.store = deps.store ?? new TunnelStore(import_node_path52.default.join(deps.dataDir, "tunnel.json"));
61163
61302
  this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
61164
61303
  this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
61165
61304
  }
@@ -61286,7 +61425,7 @@ var TunnelManager = class {
61286
61425
  dataDir: this.deps.dataDir,
61287
61426
  override: this.deps.frpcBinaryOverride ?? void 0
61288
61427
  });
61289
- const tomlPath = import_node_path51.default.join(this.deps.dataDir, "frpc.toml");
61428
+ const tomlPath = import_node_path52.default.join(this.deps.dataDir, "frpc.toml");
61290
61429
  const proxyName = `clawd-${t.subdomain}-${localPort}-${import_node_crypto12.default.randomBytes(3).toString("hex")}`;
61291
61430
  const toml = buildFrpcToml({
61292
61431
  serverAddr: t.frpsHost,
@@ -61297,14 +61436,14 @@ var TunnelManager = class {
61297
61436
  localPort,
61298
61437
  logLevel: "info"
61299
61438
  });
61300
- await import_node_fs43.default.promises.writeFile(tomlPath, toml, { mode: 384 });
61439
+ await import_node_fs44.default.promises.writeFile(tomlPath, toml, { mode: 384 });
61301
61440
  const proc = (this.deps.spawnImpl ?? import_node_child_process12.spawn)(frpcBin, ["-c", tomlPath], {
61302
61441
  stdio: ["ignore", "pipe", "pipe"]
61303
61442
  });
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 });
61443
+ const logDir = import_node_path52.default.join(this.deps.dataDir, "log");
61444
+ import_node_fs44.default.mkdirSync(logDir, { recursive: true });
61445
+ const logFilePath = import_node_path52.default.join(logDir, "frpc.log");
61446
+ const logStream = import_node_fs44.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
61308
61447
  logStream.on("error", () => {
61309
61448
  });
61310
61449
  const tee = (chunk) => {
@@ -61386,28 +61525,28 @@ async function waitForFrpcReady(proc, timeoutMs) {
61386
61525
  }
61387
61526
 
61388
61527
  // src/tunnel/device-key.ts
61389
- var import_node_os15 = __toESM(require("os"), 1);
61390
- var import_node_path52 = __toESM(require("path"), 1);
61528
+ var import_node_os16 = __toESM(require("os"), 1);
61529
+ var import_node_path53 = __toESM(require("path"), 1);
61391
61530
  var import_node_crypto13 = __toESM(require("crypto"), 1);
61392
61531
  var DERIVE_SALT = "clawd-tunnel-device-v1";
61393
61532
  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;
61533
+ const hostname = opts.hostname ?? import_node_os16.default.hostname();
61534
+ const uid = opts.uid ?? (typeof import_node_os16.default.userInfo === "function" ? import_node_os16.default.userInfo().uid : 0);
61535
+ const home = opts.home ?? import_node_os16.default.homedir();
61536
+ const defaultDataDir = import_node_path53.default.resolve(import_node_path53.default.join(home, ".clawd"));
61537
+ const normalizedDataDir = opts.dataDir ? import_node_path53.default.resolve(opts.dataDir) : null;
61399
61538
  const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
61400
61539
  const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
61401
61540
  return import_node_crypto13.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
61402
61541
  }
61403
61542
 
61404
61543
  // src/auth-store.ts
61405
- var import_node_fs44 = __toESM(require("fs"), 1);
61406
- var import_node_path53 = __toESM(require("path"), 1);
61544
+ var import_node_fs45 = __toESM(require("fs"), 1);
61545
+ var import_node_path54 = __toESM(require("path"), 1);
61407
61546
  var import_node_crypto14 = __toESM(require("crypto"), 1);
61408
61547
  var AUTH_FILE_NAME = "auth.json";
61409
61548
  function authFilePath(dataDir) {
61410
- return import_node_path53.default.join(dataDir, AUTH_FILE_NAME);
61549
+ return import_node_path54.default.join(dataDir, AUTH_FILE_NAME);
61411
61550
  }
61412
61551
  function loadOrCreateAuthFile(opts) {
61413
61552
  const file = authFilePath(opts.dataDir);
@@ -61439,7 +61578,7 @@ function defaultGenerateOwnerPrincipalId() {
61439
61578
  }
61440
61579
  function readAuthFile(file) {
61441
61580
  try {
61442
- const raw = import_node_fs44.default.readFileSync(file, "utf8");
61581
+ const raw = import_node_fs45.default.readFileSync(file, "utf8");
61443
61582
  const parsed = JSON.parse(raw);
61444
61583
  if (typeof parsed?.token !== "string" || parsed.token.length === 0) {
61445
61584
  return null;
@@ -61459,26 +61598,26 @@ function readAuthFile(file) {
61459
61598
  }
61460
61599
  }
61461
61600
  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 });
61601
+ import_node_fs45.default.mkdirSync(import_node_path54.default.dirname(file), { recursive: true });
61602
+ import_node_fs45.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
61464
61603
  try {
61465
- import_node_fs44.default.chmodSync(file, 384);
61604
+ import_node_fs45.default.chmodSync(file, 384);
61466
61605
  } catch {
61467
61606
  }
61468
61607
  }
61469
61608
 
61470
61609
  // 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);
61610
+ var import_node_fs46 = __toESM(require("fs"), 1);
61611
+ var import_node_os17 = __toESM(require("os"), 1);
61612
+ var import_node_path55 = __toESM(require("path"), 1);
61474
61613
  var PROFILE_FILENAME = "profile.json";
61475
61614
  function profilePath(dataDir) {
61476
- return import_node_path54.default.join(dataDir, PROFILE_FILENAME);
61615
+ return import_node_path55.default.join(dataDir, PROFILE_FILENAME);
61477
61616
  }
61478
61617
  function loadOwnerProfile(dataDir) {
61479
61618
  let raw;
61480
61619
  try {
61481
- raw = import_node_fs45.default.readFileSync(profilePath(dataDir), "utf8");
61620
+ raw = import_node_fs46.default.readFileSync(profilePath(dataDir), "utf8");
61482
61621
  } catch {
61483
61622
  return {};
61484
61623
  }
@@ -61494,11 +61633,11 @@ function loadOwnerProfile(dataDir) {
61494
61633
  }
61495
61634
  function patchOwnerProfile(dataDir, patch) {
61496
61635
  const merged = { ...loadOwnerProfile(dataDir), ...patch };
61497
- import_node_fs45.default.writeFileSync(profilePath(dataDir), JSON.stringify(merged, null, 2), { encoding: "utf8", mode: 384 });
61636
+ import_node_fs46.default.writeFileSync(profilePath(dataDir), JSON.stringify(merged, null, 2), { encoding: "utf8", mode: 384 });
61498
61637
  return merged;
61499
61638
  }
61500
61639
  function loadOwnerDisplayName(dataDir) {
61501
- const fallback = import_node_os16.default.userInfo().username;
61640
+ const fallback = import_node_os17.default.userInfo().username;
61502
61641
  const displayName = loadOwnerProfile(dataDir).displayName;
61503
61642
  if (typeof displayName !== "string" || displayName.length === 0) {
61504
61643
  if (displayName !== void 0) {
@@ -61510,18 +61649,18 @@ function loadOwnerDisplayName(dataDir) {
61510
61649
  }
61511
61650
 
61512
61651
  // 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);
61652
+ var import_node_fs47 = __toESM(require("fs"), 1);
61653
+ var import_node_path56 = __toESM(require("path"), 1);
61515
61654
  var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
61516
61655
  var OwnerIdentityStore = class {
61517
61656
  file;
61518
61657
  constructor(dataDir) {
61519
- this.file = import_node_path55.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
61658
+ this.file = import_node_path56.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
61520
61659
  }
61521
61660
  read() {
61522
61661
  let raw;
61523
61662
  try {
61524
- raw = import_node_fs46.default.readFileSync(this.file, "utf8");
61663
+ raw = import_node_fs47.default.readFileSync(this.file, "utf8");
61525
61664
  } catch {
61526
61665
  return null;
61527
61666
  }
@@ -61549,16 +61688,16 @@ var OwnerIdentityStore = class {
61549
61688
  };
61550
61689
  }
61551
61690
  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 });
61691
+ import_node_fs47.default.mkdirSync(import_node_path56.default.dirname(this.file), { recursive: true });
61692
+ import_node_fs47.default.writeFileSync(this.file, JSON.stringify(record3, null, 2), { mode: 384 });
61554
61693
  try {
61555
- import_node_fs46.default.chmodSync(this.file, 384);
61694
+ import_node_fs47.default.chmodSync(this.file, 384);
61556
61695
  } catch {
61557
61696
  }
61558
61697
  }
61559
61698
  clear() {
61560
61699
  try {
61561
- import_node_fs46.default.unlinkSync(this.file);
61700
+ import_node_fs47.default.unlinkSync(this.file);
61562
61701
  } catch (err) {
61563
61702
  const code = err?.code;
61564
61703
  if (code !== "ENOENT") throw err;
@@ -61695,9 +61834,9 @@ var CentralClientError = class extends Error {
61695
61834
  code;
61696
61835
  cause;
61697
61836
  };
61698
- async function centralRequest(opts, path97, init) {
61837
+ async function centralRequest(opts, path98, init) {
61699
61838
  const f = opts.fetchImpl ?? globalThis.fetch;
61700
- const url = `${opts.api.replace(/\/+$/, "")}${path97}`;
61839
+ const url = `${opts.api.replace(/\/+$/, "")}${path98}`;
61701
61840
  const ctrl = new AbortController();
61702
61841
  const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
61703
61842
  let res;
@@ -62168,8 +62307,8 @@ function verifyConnectToken(args) {
62168
62307
  }
62169
62308
 
62170
62309
  // src/feishu-auth/server-key.ts
62171
- var fs63 = __toESM(require("fs"), 1);
62172
- var path68 = __toESM(require("path"), 1);
62310
+ var fs64 = __toESM(require("fs"), 1);
62311
+ var path69 = __toESM(require("path"), 1);
62173
62312
  var FILE_NAME2 = "server-signing-key.json";
62174
62313
  var ServerKeyStore = class {
62175
62314
  constructor(dataDir) {
@@ -62177,12 +62316,12 @@ var ServerKeyStore = class {
62177
62316
  }
62178
62317
  dataDir;
62179
62318
  filePath() {
62180
- return path68.join(this.dataDir, FILE_NAME2);
62319
+ return path69.join(this.dataDir, FILE_NAME2);
62181
62320
  }
62182
62321
  /** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
62183
62322
  read() {
62184
62323
  try {
62185
- const raw = fs63.readFileSync(this.filePath(), "utf8");
62324
+ const raw = fs64.readFileSync(this.filePath(), "utf8");
62186
62325
  const parsed = JSON.parse(raw);
62187
62326
  if (typeof parsed.publicKeyPem === "string" && parsed.publicKeyPem.includes("PUBLIC KEY")) {
62188
62327
  return parsed.publicKeyPem;
@@ -62197,12 +62336,12 @@ var ServerKeyStore = class {
62197
62336
  publicKeyPem,
62198
62337
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
62199
62338
  };
62200
- fs63.mkdirSync(this.dataDir, { recursive: true });
62201
- fs63.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
62339
+ fs64.mkdirSync(this.dataDir, { recursive: true });
62340
+ fs64.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
62202
62341
  }
62203
62342
  clear() {
62204
62343
  try {
62205
- fs63.unlinkSync(this.filePath());
62344
+ fs64.unlinkSync(this.filePath());
62206
62345
  } catch {
62207
62346
  }
62208
62347
  }
@@ -62212,19 +62351,19 @@ var ServerKeyStore = class {
62212
62351
  init_protocol();
62213
62352
 
62214
62353
  // src/handlers/index.ts
62215
- var import_node_path71 = __toESM(require("path"), 1);
62354
+ var import_node_path72 = __toESM(require("path"), 1);
62216
62355
 
62217
62356
  // src/handlers/session.ts
62218
62357
  init_protocol();
62219
62358
 
62220
62359
  // 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);
62360
+ var import_node_fs48 = __toESM(require("fs"), 1);
62361
+ var import_node_os18 = __toESM(require("os"), 1);
62362
+ var import_node_path57 = __toESM(require("path"), 1);
62224
62363
  var import_node_crypto16 = require("crypto");
62225
62364
  init_claude_history();
62226
62365
  function readJsonlEntries(file) {
62227
- const raw = import_node_fs47.default.readFileSync(file, "utf8");
62366
+ const raw = import_node_fs48.default.readFileSync(file, "utf8");
62228
62367
  const out = [];
62229
62368
  for (const line of raw.split("\n")) {
62230
62369
  const t = line.trim();
@@ -62237,19 +62376,19 @@ function readJsonlEntries(file) {
62237
62376
  return out;
62238
62377
  }
62239
62378
  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)) {
62379
+ const baseDir = input.baseDir ?? import_node_path57.default.join(import_node_os18.default.homedir(), ".claude");
62380
+ let projectDir = import_node_path57.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
62381
+ let sourceFile = import_node_path57.default.join(projectDir, `${input.toolSessionId}.jsonl`);
62382
+ if (!import_node_fs48.default.existsSync(sourceFile)) {
62244
62383
  const found = findTranscriptByToolSessionId(
62245
- import_node_path56.default.join(baseDir, "projects"),
62384
+ import_node_path57.default.join(baseDir, "projects"),
62246
62385
  input.toolSessionId
62247
62386
  );
62248
62387
  if (!found) {
62249
62388
  throw new Error(`fork: source transcript not found: ${sourceFile}`);
62250
62389
  }
62251
62390
  sourceFile = found;
62252
- projectDir = import_node_path56.default.dirname(found);
62391
+ projectDir = import_node_path57.default.dirname(found);
62253
62392
  }
62254
62393
  const entries = readJsonlEntries(sourceFile);
62255
62394
  const mainEntries = entries.filter((e) => e.isSidechain !== true);
@@ -62278,27 +62417,27 @@ function forkSession(input) {
62278
62417
  }
62279
62418
  forkedLines.push(JSON.stringify(forked));
62280
62419
  }
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 });
62420
+ const outDir = input.targetCwd ? import_node_path57.default.join(baseDir, "projects", cwdToHashDir(input.targetCwd)) : projectDir;
62421
+ const forkedFilePath = import_node_path57.default.join(outDir, `${forkedToolSessionId}.jsonl`);
62422
+ import_node_fs48.default.mkdirSync(outDir, { recursive: true });
62423
+ import_node_fs48.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
62285
62424
  return { forkedToolSessionId, forkedFilePath };
62286
62425
  }
62287
62426
 
62288
62427
  // src/session/external-scan.ts
62289
- var import_node_fs48 = __toESM(require("fs"), 1);
62428
+ var import_node_fs49 = __toESM(require("fs"), 1);
62290
62429
  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);
62430
+ var import_node_os19 = __toESM(require("os"), 1);
62431
+ var import_node_path58 = __toESM(require("path"), 1);
62293
62432
  var import_node_module = require("module");
62294
62433
  var import_node_child_process13 = require("child_process");
62295
62434
  var import_meta5 = {};
62296
62435
  function defaultRoots() {
62297
- const home = import_node_os18.default.homedir();
62436
+ const home = import_node_os19.default.homedir();
62298
62437
  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")
62438
+ claudeProjectsDir: import_node_path58.default.join(home, ".claude", "projects"),
62439
+ codexDir: import_node_path58.default.join(home, ".codex"),
62440
+ clawdDir: import_node_path58.default.join(home, ".clawd")
62302
62441
  };
62303
62442
  }
62304
62443
  function width(s) {
@@ -62349,7 +62488,7 @@ function userText(msg) {
62349
62488
  }
62350
62489
  function isDir2(p2) {
62351
62490
  try {
62352
- return import_node_fs48.default.statSync(p2).isDirectory();
62491
+ return import_node_fs49.default.statSync(p2).isDirectory();
62353
62492
  } catch {
62354
62493
  return false;
62355
62494
  }
@@ -62358,7 +62497,7 @@ async function scanClaude(roots) {
62358
62497
  const out = [];
62359
62498
  let dirs;
62360
62499
  try {
62361
- dirs = import_node_fs48.default.readdirSync(roots.claudeProjectsDir, { withFileTypes: true });
62500
+ dirs = import_node_fs49.default.readdirSync(roots.claudeProjectsDir, { withFileTypes: true });
62362
62501
  } catch {
62363
62502
  return out;
62364
62503
  }
@@ -62366,16 +62505,16 @@ async function scanClaude(roots) {
62366
62505
  if (!d.isDirectory()) continue;
62367
62506
  let files;
62368
62507
  try {
62369
- files = import_node_fs48.default.readdirSync(import_node_path57.default.join(roots.claudeProjectsDir, d.name));
62508
+ files = import_node_fs49.default.readdirSync(import_node_path58.default.join(roots.claudeProjectsDir, d.name));
62370
62509
  } catch {
62371
62510
  continue;
62372
62511
  }
62373
62512
  for (const name of files) {
62374
62513
  if (!name.endsWith(".jsonl")) continue;
62375
- const file = import_node_path57.default.join(roots.claudeProjectsDir, d.name, name);
62514
+ const file = import_node_path58.default.join(roots.claudeProjectsDir, d.name, name);
62376
62515
  let st;
62377
62516
  try {
62378
- st = import_node_fs48.default.statSync(file);
62517
+ st = import_node_fs49.default.statSync(file);
62379
62518
  } catch {
62380
62519
  continue;
62381
62520
  }
@@ -62428,7 +62567,7 @@ async function scanClaude(roots) {
62428
62567
  return out;
62429
62568
  }
62430
62569
  async function countCodexTurns(rolloutPath) {
62431
- if (!rolloutPath || !import_node_fs48.default.existsSync(rolloutPath)) return { turns: 0, first: "" };
62570
+ if (!rolloutPath || !import_node_fs49.default.existsSync(rolloutPath)) return { turns: 0, first: "" };
62432
62571
  let turns = 0;
62433
62572
  let first = "";
62434
62573
  for await (const rec4 of jsonLines(rolloutPath)) {
@@ -62502,7 +62641,7 @@ async function codexFromRows(rows) {
62502
62641
  async function scanCodex(roots) {
62503
62642
  let dbs = [];
62504
62643
  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));
62644
+ 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
62645
  } catch {
62507
62646
  }
62508
62647
  if (!dbs.length) return [];
@@ -62511,14 +62650,14 @@ async function scanCodex(roots) {
62511
62650
  }
62512
62651
  async function scanExternalSessions(rootsIn) {
62513
62652
  const roots = { ...defaultRoots(), ...rootsIn };
62514
- const personaRoot = import_node_path57.default.join(roots.clawdDir, "personas");
62653
+ const personaRoot = import_node_path58.default.join(roots.clawdDir, "personas");
62515
62654
  const all = [...await scanClaude(roots), ...await scanCodex(roots)];
62516
62655
  const out = [];
62517
62656
  for (const c of all) {
62518
62657
  if (c.skip) continue;
62519
62658
  if (c.turns < 1) continue;
62520
62659
  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)) {
62660
+ 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
62661
  continue;
62523
62662
  }
62524
62663
  out.push({
@@ -62535,13 +62674,13 @@ async function scanExternalSessions(rootsIn) {
62535
62674
  }
62536
62675
 
62537
62676
  // src/session/import-ledger.ts
62538
- var import_node_fs49 = __toESM(require("fs"), 1);
62539
- var import_node_path58 = __toESM(require("path"), 1);
62677
+ var import_node_fs50 = __toESM(require("fs"), 1);
62678
+ var import_node_path59 = __toESM(require("path"), 1);
62540
62679
  var LEDGER_FILENAME = "session-import-ledger.json";
62541
62680
  function readImportLedger(dataDir) {
62542
62681
  try {
62543
62682
  const parsed = JSON.parse(
62544
- import_node_fs49.default.readFileSync(import_node_path58.default.join(dataDir, LEDGER_FILENAME), "utf8")
62683
+ import_node_fs50.default.readFileSync(import_node_path59.default.join(dataDir, LEDGER_FILENAME), "utf8")
62545
62684
  );
62546
62685
  return Array.isArray(parsed) ? parsed : [];
62547
62686
  } catch {
@@ -62549,26 +62688,26 @@ function readImportLedger(dataDir) {
62549
62688
  }
62550
62689
  }
62551
62690
  function appendImportLedger(dataDir, entry) {
62552
- const file = import_node_path58.default.join(dataDir, LEDGER_FILENAME);
62691
+ const file = import_node_path59.default.join(dataDir, LEDGER_FILENAME);
62553
62692
  const entries = readImportLedger(dataDir);
62554
62693
  entries.push(entry);
62555
- import_node_fs49.default.writeFileSync(file, JSON.stringify(entries, null, 2), { encoding: "utf8", mode: 384 });
62694
+ import_node_fs50.default.writeFileSync(file, JSON.stringify(entries, null, 2), { encoding: "utf8", mode: 384 });
62556
62695
  }
62557
62696
 
62558
62697
  // src/tools/transcript-search.ts
62559
- var import_node_fs50 = __toESM(require("fs"), 1);
62560
- var import_node_path59 = __toESM(require("path"), 1);
62698
+ var import_node_fs51 = __toESM(require("fs"), 1);
62699
+ var import_node_path60 = __toESM(require("path"), 1);
62561
62700
  var SNIPPET_PAD = 60;
62562
62701
  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
62702
  var CODEX_WRAPPER_RE = /<(related-dir|environment_context|user_instructions)>[\s\S]*?<\/\1>/g;
62564
- function asRecord(v2) {
62703
+ function asRecord2(v2) {
62565
62704
  return typeof v2 === "object" && v2 !== null ? v2 : null;
62566
62705
  }
62567
62706
  function textOfBlocks(content, types) {
62568
62707
  if (!Array.isArray(content)) return null;
62569
62708
  const parts = [];
62570
62709
  for (const block of content) {
62571
- const b2 = asRecord(block);
62710
+ const b2 = asRecord2(block);
62572
62711
  if (!b2 || typeof b2.type !== "string" || !types.includes(b2.type)) continue;
62573
62712
  const text = b2.text;
62574
62713
  if (typeof text === "string" && text !== "") parts.push(text);
@@ -62576,10 +62715,10 @@ function textOfBlocks(content, types) {
62576
62715
  return parts.length > 0 ? parts.join("\n") : null;
62577
62716
  }
62578
62717
  function lineToSearchableText(raw) {
62579
- const line = asRecord(raw);
62718
+ const line = asRecord2(raw);
62580
62719
  if (!line) return null;
62581
62720
  if (line.type === "response_item") {
62582
- const payload = asRecord(line.payload);
62721
+ const payload = asRecord2(line.payload);
62583
62722
  if (!payload || payload.type !== "message") return null;
62584
62723
  const role = payload.role;
62585
62724
  if (role !== "user" && role !== "assistant") return null;
@@ -62591,7 +62730,7 @@ function lineToSearchableText(raw) {
62591
62730
  return INJECTED_ENVELOPE_RE.test(stripped) ? null : stripped;
62592
62731
  }
62593
62732
  if (line.type !== "user" && line.type !== "assistant") return null;
62594
- const message = asRecord(line.message);
62733
+ const message = asRecord2(line.message);
62595
62734
  if (!message) return null;
62596
62735
  const content = message.content;
62597
62736
  const text = typeof content === "string" && content !== "" ? content : textOfBlocks(content, ["text"]);
@@ -62612,7 +62751,7 @@ function makeSnippet(text, at2, needleLength) {
62612
62751
  function searchTranscriptFile(file, query) {
62613
62752
  let buf;
62614
62753
  try {
62615
- buf = import_node_fs50.default.readFileSync(file);
62754
+ buf = import_node_fs51.default.readFileSync(file);
62616
62755
  } catch {
62617
62756
  return null;
62618
62757
  }
@@ -62645,12 +62784,12 @@ function createCodexRolloutLocator(roots) {
62645
62784
  const walk2 = (dir, into) => {
62646
62785
  let entries;
62647
62786
  try {
62648
- entries = import_node_fs50.default.readdirSync(dir, { withFileTypes: true });
62787
+ entries = import_node_fs51.default.readdirSync(dir, { withFileTypes: true });
62649
62788
  } catch {
62650
62789
  return;
62651
62790
  }
62652
62791
  for (const entry of entries) {
62653
- const full = import_node_path59.default.join(dir, entry.name);
62792
+ const full = import_node_path60.default.join(dir, entry.name);
62654
62793
  if (entry.isDirectory()) {
62655
62794
  walk2(full, into);
62656
62795
  continue;
@@ -62670,16 +62809,16 @@ function createCodexRolloutLocator(roots) {
62670
62809
 
62671
62810
  // src/handlers/session.ts
62672
62811
  init_protocol();
62673
- var import_node_os19 = __toESM(require("os"), 1);
62674
- var import_node_path60 = __toESM(require("path"), 1);
62812
+ var import_node_os20 = __toESM(require("os"), 1);
62813
+ var import_node_path61 = __toESM(require("path"), 1);
62675
62814
  function canReadSearchHit(ctx, file) {
62676
62815
  if (!ctx || ctx.principal.kind === "owner") return true;
62677
62816
  return canAccessPersona(ctx.grants, file.ownerPersonaId, "read") && file.creatorPrincipalId === ctx.principal.id;
62678
62817
  }
62679
62818
  var DEFAULT_SEARCH_LIMIT = 9;
62680
62819
  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"));
62820
+ const roots = [import_node_path61.default.join(import_node_os20.default.homedir(), ".codex", "sessions")];
62821
+ if (dataDir) roots.push(import_node_path61.default.join(dataDir, "codex-home", "sessions"));
62683
62822
  return roots;
62684
62823
  }
62685
62824
  function buildSessionHandlers(deps) {
@@ -63228,7 +63367,7 @@ function buildPermissionHandlers(deps) {
63228
63367
  }
63229
63368
 
63230
63369
  // src/handlers/history.ts
63231
- var path75 = __toESM(require("path"), 1);
63370
+ var path76 = __toESM(require("path"), 1);
63232
63371
  init_protocol();
63233
63372
 
63234
63373
  // src/session/recent-dirs.ts
@@ -63246,7 +63385,7 @@ function listRecentDirs(store, limit = 50) {
63246
63385
  }
63247
63386
 
63248
63387
  // src/permission/persona-paths.ts
63249
- var path74 = __toESM(require("path"), 1);
63388
+ var path75 = __toESM(require("path"), 1);
63250
63389
  function getAllowedPersonaIds(grants, action) {
63251
63390
  const ids = /* @__PURE__ */ new Set();
63252
63391
  for (const g2 of grants) {
@@ -63259,42 +63398,42 @@ function getAllowedPersonaIds(grants, action) {
63259
63398
  return ids;
63260
63399
  }
63261
63400
  function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
63262
- const target = path74.resolve(absPath);
63401
+ const target = path75.resolve(absPath);
63263
63402
  if (userWorkDir) {
63264
- const u = path74.resolve(userWorkDir);
63265
- const usep = u.endsWith(path74.sep) ? "" : path74.sep;
63403
+ const u = path75.resolve(userWorkDir);
63404
+ const usep = u.endsWith(path75.sep) ? "" : path75.sep;
63266
63405
  if (target === u || target.startsWith(u + usep)) return true;
63267
63406
  }
63268
- const root = path74.resolve(personaRoot);
63269
- const sep4 = root.endsWith(path74.sep) ? "" : path74.sep;
63407
+ const root = path75.resolve(personaRoot);
63408
+ const sep4 = root.endsWith(path75.sep) ? "" : path75.sep;
63270
63409
  if (!target.startsWith(root + sep4)) return false;
63271
- const rel = path74.relative(root, target);
63410
+ const rel = path75.relative(root, target);
63272
63411
  if (!rel || rel.startsWith("..")) return false;
63273
- const personaId2 = rel.split(path74.sep)[0];
63412
+ const personaId2 = rel.split(path75.sep)[0];
63274
63413
  if (!personaId2) return false;
63275
63414
  const allowed = getAllowedPersonaIds(grants, action);
63276
63415
  if (allowed === "*") return true;
63277
63416
  return allowed.has(personaId2);
63278
63417
  }
63279
63418
  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;
63419
+ const root = path75.resolve(personaRoot);
63420
+ const target = path75.resolve(absPath);
63421
+ const sep4 = root.endsWith(path75.sep) ? "" : path75.sep;
63283
63422
  if (!target.startsWith(root + sep4)) return null;
63284
- const rel = path74.relative(root, target);
63423
+ const rel = path75.relative(root, target);
63285
63424
  if (!rel || rel.startsWith("..")) return null;
63286
- const id = rel.split(path74.sep)[0];
63425
+ const id = rel.split(path75.sep)[0];
63287
63426
  return id || null;
63288
63427
  }
63289
63428
  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;
63429
+ const d = path75.resolve(dir);
63430
+ const t = path75.resolve(absPath);
63431
+ const sep4 = d.endsWith(path75.sep) ? "" : path75.sep;
63293
63432
  return t === d || t.startsWith(d + sep4);
63294
63433
  }
63295
63434
  function isPathInGuestBoundary(personaRoot, personaId2, userWorkDir, absPath) {
63296
63435
  if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
63297
- return personaIdFromPath(path74.resolve(absPath), personaRoot) === personaId2;
63436
+ return personaIdFromPath(path75.resolve(absPath), personaRoot) === personaId2;
63298
63437
  }
63299
63438
 
63300
63439
  // src/handlers/history.ts
@@ -63347,7 +63486,7 @@ function buildHistoryHandlers(deps) {
63347
63486
  if (!pid) return false;
63348
63487
  return isGuestPathAllowed(
63349
63488
  ctx.grants,
63350
- path75.join(personaRoot, pid),
63489
+ path76.join(personaRoot, pid),
63351
63490
  personaRoot,
63352
63491
  "read",
63353
63492
  userWorkDir
@@ -63359,7 +63498,7 @@ function buildHistoryHandlers(deps) {
63359
63498
  };
63360
63499
  const list = async (frame, _client, ctx) => {
63361
63500
  const args = HistoryListArgs.parse(frame);
63362
- assertGuestPath(ctx, path75.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
63501
+ assertGuestPath(ctx, path76.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
63363
63502
  const sessions = await history.listSessions(args);
63364
63503
  return { response: { type: "history:list", sessions } };
63365
63504
  };
@@ -63407,14 +63546,14 @@ function buildHistoryHandlers(deps) {
63407
63546
  };
63408
63547
  const subagents = async (frame, _client, ctx) => {
63409
63548
  const args = HistorySubagentsArgs.parse(frame);
63410
- assertGuestPath(ctx, path75.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
63549
+ assertGuestPath(ctx, path76.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
63411
63550
  assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagents");
63412
63551
  const subs = await historyReaderForToolSession(args.toolSessionId).listSubagents(args);
63413
63552
  return { response: { type: "history:subagents", subagents: subs } };
63414
63553
  };
63415
63554
  const subagentRead = async (frame, _client, ctx) => {
63416
63555
  const args = HistorySubagentReadArgs.parse(frame);
63417
- assertGuestPath(ctx, path75.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
63556
+ assertGuestPath(ctx, path76.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
63418
63557
  assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagent-read");
63419
63558
  const res = await historyReaderForToolSession(args.toolSessionId).readSubagent(args);
63420
63559
  return { response: { type: "history:subagent-read", ...res } };
@@ -63424,7 +63563,7 @@ function buildHistoryHandlers(deps) {
63424
63563
  if (ctx?.principal.kind === "guest" && personaRoot) {
63425
63564
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
63426
63565
  const filtered = dirs.filter(
63427
- (d) => isGuestPathAllowed(ctx.grants, path75.resolve(d.cwd), personaRoot, "read", userWorkDir)
63566
+ (d) => isGuestPathAllowed(ctx.grants, path76.resolve(d.cwd), personaRoot, "read", userWorkDir)
63428
63567
  );
63429
63568
  return { response: { type: "history:recentDirs", dirs: filtered } };
63430
63569
  }
@@ -63441,17 +63580,17 @@ function buildHistoryHandlers(deps) {
63441
63580
  }
63442
63581
 
63443
63582
  // 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);
63583
+ var fs69 = __toESM(require("fs"), 1);
63584
+ var os22 = __toESM(require("os"), 1);
63585
+ var path77 = __toESM(require("path"), 1);
63447
63586
  var import_node_child_process14 = require("child_process");
63448
63587
  init_protocol();
63449
- var DEFAULT_PROJECTS_ROOT = path76.join(os21.homedir(), "Documents", "ChatGPT");
63588
+ var DEFAULT_PROJECTS_ROOT = path77.join(os22.homedir(), "Documents", "ChatGPT");
63450
63589
  function allocateDir(root, name) {
63451
- let candidate = path76.join(root, name);
63590
+ let candidate = path77.join(root, name);
63452
63591
  let n = 2;
63453
- while (fs68.existsSync(candidate)) {
63454
- candidate = path76.join(root, `${name} ${n}`);
63592
+ while (fs69.existsSync(candidate)) {
63593
+ candidate = path77.join(root, `${name} ${n}`);
63455
63594
  n += 1;
63456
63595
  }
63457
63596
  return candidate;
@@ -63479,7 +63618,7 @@ function buildProjectHandlers(deps) {
63479
63618
  throw new ClawdError(ERROR_CODES.INVALID_CWD, "project:reveal \u4EC5\u652F\u6301 macOS");
63480
63619
  }
63481
63620
  try {
63482
- if (!fs68.statSync(args.path).isDirectory()) throw new Error("not dir");
63621
+ if (!fs69.statSync(args.path).isDirectory()) throw new Error("not dir");
63483
63622
  } catch {
63484
63623
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
63485
63624
  }
@@ -63495,7 +63634,7 @@ function buildProjectHandlers(deps) {
63495
63634
  let target;
63496
63635
  if (args.path) {
63497
63636
  try {
63498
- if (!fs68.statSync(args.path).isDirectory()) throw new Error("not dir");
63637
+ if (!fs69.statSync(args.path).isDirectory()) throw new Error("not dir");
63499
63638
  } catch {
63500
63639
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
63501
63640
  }
@@ -63503,15 +63642,15 @@ function buildProjectHandlers(deps) {
63503
63642
  } else {
63504
63643
  const name = args.name;
63505
63644
  try {
63506
- fs68.mkdirSync(root, { recursive: true });
63645
+ fs69.mkdirSync(root, { recursive: true });
63507
63646
  target = allocateDir(root, name);
63508
- fs68.mkdirSync(target);
63647
+ fs69.mkdirSync(target);
63509
63648
  } catch (err) {
63510
63649
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `\u521B\u5EFA\u9879\u76EE\u76EE\u5F55\u5931\u8D25: ${String(err)}`);
63511
63650
  }
63512
63651
  const git2 = (0, import_node_child_process14.spawnSync)("git", ["init"], { cwd: target, stdio: "ignore" });
63513
63652
  if (git2.status !== 0) {
63514
- fs68.rmSync(target, { recursive: true, force: true });
63653
+ fs69.rmSync(target, { recursive: true, force: true });
63515
63654
  throw new ClawdError(
63516
63655
  ERROR_CODES.INVALID_CWD,
63517
63656
  `git init \u5931\u8D25\uFF08${git2.error ? String(git2.error) : `exit ${git2.status}`}\uFF09: ${target}`
@@ -63536,8 +63675,8 @@ function buildProjectHandlers(deps) {
63536
63675
  }
63537
63676
 
63538
63677
  // src/handlers/workspace.ts
63539
- var path77 = __toESM(require("path"), 1);
63540
- var os22 = __toESM(require("os"), 1);
63678
+ var path78 = __toESM(require("path"), 1);
63679
+ var os23 = __toESM(require("os"), 1);
63541
63680
  init_protocol();
63542
63681
  init_protocol();
63543
63682
  function buildEnabledPluginNames(personaManager, personaId2) {
@@ -63577,23 +63716,23 @@ function buildWorkspaceHandlers(deps) {
63577
63716
  const list = async (frame, _client, ctx) => {
63578
63717
  const args = WorkspaceListArgs.parse(frame);
63579
63718
  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;
63719
+ const fallbackCwd = isGuest && personaRoot ? personaRoot : os23.homedir();
63720
+ const resolvedCwd = path78.resolve(args.cwd ?? fallbackCwd);
63721
+ const target = args.path ? path78.resolve(resolvedCwd, args.path) : resolvedCwd;
63583
63722
  assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
63584
63723
  const res = workspace.list({ ...args, cwd: resolvedCwd });
63585
63724
  return { response: { type: "workspace:list", ...res } };
63586
63725
  };
63587
63726
  const read = async (frame, _client, ctx) => {
63588
63727
  const args = WorkspaceReadArgs.parse(frame);
63589
- const target = path77.isAbsolute(args.path) ? path77.resolve(args.path) : path77.resolve(args.cwd, args.path);
63728
+ const target = path78.isAbsolute(args.path) ? path78.resolve(args.path) : path78.resolve(args.cwd, args.path);
63590
63729
  assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
63591
63730
  const res = workspace.read(args);
63592
63731
  return { response: { type: "workspace:read", ...res } };
63593
63732
  };
63594
63733
  const skillsList = async (frame, _client, ctx) => {
63595
63734
  const args = SkillsListArgs.parse(frame);
63596
- const cwdAbs = path77.resolve(args.cwd);
63735
+ const cwdAbs = path78.resolve(args.cwd);
63597
63736
  assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
63598
63737
  const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
63599
63738
  if (ctx?.principal.kind === "guest" && personaRoot) {
@@ -63605,7 +63744,7 @@ function buildWorkspaceHandlers(deps) {
63605
63744
  };
63606
63745
  const agentsList = async (frame, _client, ctx) => {
63607
63746
  const args = AgentsListArgs.parse(frame);
63608
- const cwdAbs = path77.resolve(args.cwd);
63747
+ const cwdAbs = path78.resolve(args.cwd);
63609
63748
  assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
63610
63749
  if (args.tool === "codex") {
63611
63750
  return { response: { type: "agents:list", agents: [] } };
@@ -63627,20 +63766,20 @@ function buildWorkspaceHandlers(deps) {
63627
63766
  }
63628
63767
 
63629
63768
  // src/handlers/git.ts
63630
- var path79 = __toESM(require("path"), 1);
63769
+ var path80 = __toESM(require("path"), 1);
63631
63770
  init_protocol();
63632
63771
  init_protocol();
63633
63772
 
63634
63773
  // src/workspace/git.ts
63635
63774
  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);
63775
+ var import_node_fs52 = __toESM(require("fs"), 1);
63776
+ var import_node_path62 = __toESM(require("path"), 1);
63638
63777
  var import_node_util = require("util");
63639
63778
  var pexec = (0, import_node_util.promisify)(import_node_child_process15.execFile);
63640
63779
  function normalizePath(p2) {
63641
- const resolved = import_node_path61.default.resolve(p2);
63780
+ const resolved = import_node_path62.default.resolve(p2);
63642
63781
  try {
63643
- return import_node_fs51.default.realpathSync(resolved);
63782
+ return import_node_fs52.default.realpathSync(resolved);
63644
63783
  } catch {
63645
63784
  return resolved;
63646
63785
  }
@@ -63714,7 +63853,7 @@ async function listGitBranches(cwd) {
63714
63853
  function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
63715
63854
  if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
63716
63855
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
63717
- if (!isGuestPathAllowed(ctx.grants, path79.resolve(cwd), personaRoot, "read", userWorkDir)) {
63856
+ if (!isGuestPathAllowed(ctx.grants, path80.resolve(cwd), personaRoot, "read", userWorkDir)) {
63718
63857
  throw new ClawdError(
63719
63858
  ERROR_CODES.UNAUTHORIZED,
63720
63859
  `guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
@@ -64284,7 +64423,7 @@ function buildFeishuAuthHandlers(deps) {
64284
64423
  }
64285
64424
 
64286
64425
  // src/handlers/meta.ts
64287
- var import_node_os20 = __toESM(require("os"), 1);
64426
+ var import_node_os21 = __toESM(require("os"), 1);
64288
64427
  init_protocol();
64289
64428
 
64290
64429
  // src/handlers/method-grants.ts
@@ -64587,21 +64726,21 @@ function computeMethodAccess(args) {
64587
64726
  }
64588
64727
 
64589
64728
  // src/version.ts
64590
- var version = "0.2.485".length > 0 ? "0.2.485" : "dev";
64729
+ var version = "0.2.486".length > 0 ? "0.2.486" : "dev";
64591
64730
 
64592
64731
  // src/cli-probe/probe.ts
64593
- var fs70 = __toESM(require("fs"), 1);
64594
- var path80 = __toESM(require("path"), 1);
64732
+ var fs71 = __toESM(require("fs"), 1);
64733
+ var path81 = __toESM(require("path"), 1);
64595
64734
  var PKG_NAME = "@clawos-dev/clawd";
64596
64735
  var BIN_NAME = "clawd";
64597
64736
  var MAX_PARENT_HOPS = 5;
64598
64737
  function probeGlobalCli(pathEnv) {
64599
64738
  if (!pathEnv) return null;
64600
- for (const dir of pathEnv.split(path80.delimiter)) {
64739
+ for (const dir of pathEnv.split(path81.delimiter)) {
64601
64740
  if (!dir) continue;
64602
64741
  let real;
64603
64742
  try {
64604
- real = fs70.realpathSync(path80.join(dir, BIN_NAME));
64743
+ real = fs71.realpathSync(path81.join(dir, BIN_NAME));
64605
64744
  } catch {
64606
64745
  continue;
64607
64746
  }
@@ -64611,15 +64750,15 @@ function probeGlobalCli(pathEnv) {
64611
64750
  return null;
64612
64751
  }
64613
64752
  function readOwnPackageVersion(entryPath) {
64614
- let dir = path80.dirname(entryPath);
64753
+ let dir = path81.dirname(entryPath);
64615
64754
  for (let i = 0; i < MAX_PARENT_HOPS; i++) {
64616
64755
  try {
64617
- const raw = fs70.readFileSync(path80.join(dir, "package.json"), "utf8");
64756
+ const raw = fs71.readFileSync(path81.join(dir, "package.json"), "utf8");
64618
64757
  const pkg = JSON.parse(raw);
64619
64758
  if (pkg.name !== PKG_NAME) return null;
64620
64759
  return typeof pkg.version === "string" && pkg.version ? pkg.version : null;
64621
64760
  } catch {
64622
- const parent = path80.dirname(dir);
64761
+ const parent = path81.dirname(dir);
64623
64762
  if (parent === dir) return null;
64624
64763
  dir = parent;
64625
64764
  }
@@ -64655,7 +64794,7 @@ function buildReadyFrame(deps, client) {
64655
64794
  return {
64656
64795
  version,
64657
64796
  protocolVersion: PROTOCOL_VERSION,
64658
- hostname: import_node_os20.default.hostname(),
64797
+ hostname: import_node_os21.default.hostname(),
64659
64798
  os: process.platform,
64660
64799
  tools,
64661
64800
  runningSessions: info.runningSessions,
@@ -64791,7 +64930,7 @@ function buildPersonaHandlers(deps) {
64791
64930
  }
64792
64931
 
64793
64932
  // src/handlers/attachment.ts
64794
- var import_node_path62 = __toESM(require("path"), 1);
64933
+ var import_node_path63 = __toESM(require("path"), 1);
64795
64934
  init_protocol();
64796
64935
  init_protocol();
64797
64936
  var DEFAULT_TTL_SECONDS = 24 * 3600;
@@ -64871,12 +65010,12 @@ function buildAttachmentHandlers(deps) {
64871
65010
  `session ${args.sessionId} scope unresolved`
64872
65011
  );
64873
65012
  }
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);
65013
+ const cwdAbs = import_node_path63.default.resolve(sessionFile.cwd);
65014
+ 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
65015
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
64877
65016
  const entries = deps.groupFileStore.list(scope, args.sessionId);
64878
65017
  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);
65018
+ 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
65019
  return storedAbs === candidateAbs && !e.stale;
64881
65020
  });
64882
65021
  if (!entry) {
@@ -64901,7 +65040,7 @@ function buildAttachmentHandlers(deps) {
64901
65040
  if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
64902
65041
  const f = deps.sessionStore.read(sessionId);
64903
65042
  if (!f) return;
64904
- assertGuestAttachmentPath(ctx, import_node_path62.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
65043
+ assertGuestAttachmentPath(ctx, import_node_path63.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
64905
65044
  }
64906
65045
  const groupAdd = async (frame, _client, ctx) => {
64907
65046
  if (!deps.groupFileStore || !deps.getSessionScope) {
@@ -64916,8 +65055,8 @@ function buildAttachmentHandlers(deps) {
64916
65055
  if (!scope) {
64917
65056
  throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
64918
65057
  }
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);
65058
+ const cwdAbs = import_node_path63.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
65059
+ 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
65060
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
64922
65061
  const from = args.origin === "agent" ? "agent" : ctx?.principal.kind === "owner" ? "owner" : "agent";
64923
65062
  const size = 0;
@@ -64976,19 +65115,19 @@ function buildAttachmentHandlers(deps) {
64976
65115
 
64977
65116
  // src/handlers/extension.ts
64978
65117
  var import_promises14 = __toESM(require("fs/promises"), 1);
64979
- var import_node_path67 = __toESM(require("path"), 1);
65118
+ var import_node_path68 = __toESM(require("path"), 1);
64980
65119
  init_protocol();
64981
65120
 
64982
65121
  // src/extension/bundle-zip.ts
64983
65122
  var import_promises11 = __toESM(require("fs/promises"), 1);
64984
- var import_node_path63 = __toESM(require("path"), 1);
65123
+ var import_node_path64 = __toESM(require("path"), 1);
64985
65124
  var import_node_crypto17 = __toESM(require("crypto"), 1);
64986
65125
  var import_jszip2 = __toESM(require_lib3(), 1);
64987
65126
  async function bundleExtensionDir(dir) {
64988
65127
  const entries = await listFilesSorted(dir);
64989
65128
  const zip = new import_jszip2.default();
64990
65129
  for (const rel of entries) {
64991
- const abs = import_node_path63.default.join(dir, rel);
65130
+ const abs = import_node_path64.default.join(dir, rel);
64992
65131
  const content = await import_promises11.default.readFile(abs);
64993
65132
  zip.file(rel, content, { date: FIXED_DATE });
64994
65133
  }
@@ -65009,7 +65148,7 @@ async function listFilesSorted(rootDir) {
65009
65148
  return out;
65010
65149
  }
65011
65150
  async function walk(absRoot, relPrefix, out) {
65012
- const dirAbs = import_node_path63.default.join(absRoot, relPrefix);
65151
+ const dirAbs = import_node_path64.default.join(absRoot, relPrefix);
65013
65152
  const entries = await import_promises11.default.readdir(dirAbs, { withFileTypes: true });
65014
65153
  for (const e of entries) {
65015
65154
  if (IGNORE_BASENAMES.has(e.name)) continue;
@@ -65063,25 +65202,25 @@ function computePublishCheck(args) {
65063
65202
 
65064
65203
  // src/extension/install-flow.ts
65065
65204
  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);
65205
+ var import_node_path66 = __toESM(require("path"), 1);
65206
+ var import_node_os23 = __toESM(require("os"), 1);
65068
65207
  var import_node_crypto18 = __toESM(require("crypto"), 1);
65069
65208
  var import_jszip3 = __toESM(require_lib3(), 1);
65070
65209
 
65071
65210
  // src/extension/paths.ts
65072
- var import_node_os21 = __toESM(require("os"), 1);
65073
- var import_node_path64 = __toESM(require("path"), 1);
65211
+ var import_node_os22 = __toESM(require("os"), 1);
65212
+ var import_node_path65 = __toESM(require("path"), 1);
65074
65213
  function clawdHomeRoot(override) {
65075
- return override ?? process.env.CLAWD_HOME ?? import_node_path64.default.join(import_node_os21.default.homedir(), ".clawd");
65214
+ return override ?? process.env.CLAWD_HOME ?? import_node_path65.default.join(import_node_os22.default.homedir(), ".clawd");
65076
65215
  }
65077
65216
  function extensionsRoot(override) {
65078
- return import_node_path64.default.join(clawdHomeRoot(override), "extensions");
65217
+ return import_node_path65.default.join(clawdHomeRoot(override), "extensions");
65079
65218
  }
65080
65219
  function publishedChannelsFile(override) {
65081
- return import_node_path64.default.join(clawdHomeRoot(override), "extensions-published.json");
65220
+ return import_node_path65.default.join(clawdHomeRoot(override), "extensions-published.json");
65082
65221
  }
65083
65222
  function bundleCacheRoot(override) {
65084
- return import_node_path64.default.join(clawdHomeRoot(override), "extension-bundles");
65223
+ return import_node_path65.default.join(clawdHomeRoot(override), "extension-bundles");
65085
65224
  }
65086
65225
 
65087
65226
  // src/extension/install-flow.ts
@@ -65108,7 +65247,7 @@ async function installFromChannel(args, deps) {
65108
65247
  throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
65109
65248
  }
65110
65249
  for (const name of Object.keys(zip.files)) {
65111
- if (name.includes("..") || name.startsWith("/") || import_node_path65.default.isAbsolute(name)) {
65250
+ if (name.includes("..") || name.startsWith("/") || import_node_path66.default.isAbsolute(name)) {
65112
65251
  throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
65113
65252
  }
65114
65253
  }
@@ -65140,7 +65279,7 @@ async function installFromChannel(args, deps) {
65140
65279
  );
65141
65280
  }
65142
65281
  const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
65143
- const destDir = import_node_path65.default.join(deps.extensionsRoot, localExtId);
65282
+ const destDir = import_node_path66.default.join(deps.extensionsRoot, localExtId);
65144
65283
  let destExists = false;
65145
65284
  try {
65146
65285
  await import_promises12.default.access(destDir);
@@ -65154,16 +65293,16 @@ async function installFromChannel(args, deps) {
65154
65293
  );
65155
65294
  }
65156
65295
  const stage = await import_promises12.default.mkdtemp(
65157
- import_node_path65.default.join(import_node_os22.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
65296
+ import_node_path66.default.join(import_node_os23.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
65158
65297
  );
65159
65298
  try {
65160
65299
  for (const [name, entry] of Object.entries(zip.files)) {
65161
- const dest = import_node_path65.default.join(stage, name);
65300
+ const dest = import_node_path66.default.join(stage, name);
65162
65301
  if (entry.dir) {
65163
65302
  await import_promises12.default.mkdir(dest, { recursive: true });
65164
65303
  continue;
65165
65304
  }
65166
- await import_promises12.default.mkdir(import_node_path65.default.dirname(dest), { recursive: true });
65305
+ await import_promises12.default.mkdir(import_node_path66.default.dirname(dest), { recursive: true });
65167
65306
  if (name === "manifest.json") {
65168
65307
  const rewritten = { ...parsed.data, id: localExtId };
65169
65308
  await import_promises12.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -65184,8 +65323,8 @@ async function installFromChannel(args, deps) {
65184
65323
 
65185
65324
  // src/extension/update-flow.ts
65186
65325
  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);
65326
+ var import_node_path67 = __toESM(require("path"), 1);
65327
+ var import_node_os24 = __toESM(require("os"), 1);
65189
65328
  var import_node_crypto19 = __toESM(require("crypto"), 1);
65190
65329
  var import_jszip4 = __toESM(require_lib3(), 1);
65191
65330
  var UpdateError = class extends Error {
@@ -65201,11 +65340,11 @@ async function updateFromChannel(args, deps) {
65201
65340
  channelRef.extId,
65202
65341
  channelRef.ownerPrincipalId
65203
65342
  );
65204
- const liveDir = import_node_path66.default.join(deps.extensionsRoot, localExtId);
65343
+ const liveDir = import_node_path67.default.join(deps.extensionsRoot, localExtId);
65205
65344
  const prevDir = `${liveDir}.prev`;
65206
65345
  let existingVersion;
65207
65346
  try {
65208
- const raw = await import_promises13.default.readFile(import_node_path66.default.join(liveDir, "manifest.json"), "utf8");
65347
+ const raw = await import_promises13.default.readFile(import_node_path67.default.join(liveDir, "manifest.json"), "utf8");
65209
65348
  const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
65210
65349
  if (!parsed2.success) {
65211
65350
  throw new UpdateError(
@@ -65238,7 +65377,7 @@ async function updateFromChannel(args, deps) {
65238
65377
  throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
65239
65378
  }
65240
65379
  for (const name of Object.keys(zip.files)) {
65241
- if (name.includes("..") || name.startsWith("/") || import_node_path66.default.isAbsolute(name)) {
65380
+ if (name.includes("..") || name.startsWith("/") || import_node_path67.default.isAbsolute(name)) {
65242
65381
  throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
65243
65382
  }
65244
65383
  }
@@ -65273,16 +65412,16 @@ async function updateFromChannel(args, deps) {
65273
65412
  await import_promises13.default.rm(prevDir, { recursive: true, force: true });
65274
65413
  await import_promises13.default.rename(liveDir, prevDir);
65275
65414
  const stage = await import_promises13.default.mkdtemp(
65276
- import_node_path66.default.join(import_node_os23.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
65415
+ import_node_path67.default.join(import_node_os24.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
65277
65416
  );
65278
65417
  try {
65279
65418
  for (const [name, entry] of Object.entries(zip.files)) {
65280
- const dest = import_node_path66.default.join(stage, name);
65419
+ const dest = import_node_path67.default.join(stage, name);
65281
65420
  if (entry.dir) {
65282
65421
  await import_promises13.default.mkdir(dest, { recursive: true });
65283
65422
  continue;
65284
65423
  }
65285
- await import_promises13.default.mkdir(import_node_path66.default.dirname(dest), { recursive: true });
65424
+ await import_promises13.default.mkdir(import_node_path67.default.dirname(dest), { recursive: true });
65286
65425
  if (name === "manifest.json") {
65287
65426
  const rewritten = { ...parsed.data, id: localExtId };
65288
65427
  await import_promises13.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -65349,7 +65488,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
65349
65488
  );
65350
65489
  }
65351
65490
  }
65352
- const manifestPath = import_node_path67.default.join(root, extId, "manifest.json");
65491
+ const manifestPath = import_node_path68.default.join(root, extId, "manifest.json");
65353
65492
  const manifest = await readManifest(root, extId);
65354
65493
  const next = { ...manifest, version: newVersion };
65355
65494
  const tmp = `${manifestPath}.tmp`;
@@ -65357,7 +65496,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
65357
65496
  await import_promises14.default.rename(tmp, manifestPath);
65358
65497
  }
65359
65498
  async function readManifest(root, extId) {
65360
- const file = import_node_path67.default.join(root, extId, "manifest.json");
65499
+ const file = import_node_path68.default.join(root, extId, "manifest.json");
65361
65500
  let raw;
65362
65501
  try {
65363
65502
  raw = await import_promises14.default.readFile(file, "utf8");
@@ -65441,7 +65580,7 @@ function buildExtensionHandlers(deps) {
65441
65580
  };
65442
65581
  async function buildSnapshotMeta(extId) {
65443
65582
  const manifest = await readManifest(deps.root, extId);
65444
- const { sha256, buffer } = await bundleExtensionDir(import_node_path67.default.join(deps.root, extId));
65583
+ const { sha256, buffer } = await bundleExtensionDir(import_node_path68.default.join(deps.root, extId));
65445
65584
  return { manifest, contentHash: sha256, buffer };
65446
65585
  }
65447
65586
  const publish = async (frame, _client, ctx) => {
@@ -65684,8 +65823,8 @@ var APP_BUILDER_PERSONAS = ["persona-app-builder", "persona-dataclaw-builder"];
65684
65823
 
65685
65824
  // src/handlers/app-builder.ts
65686
65825
  init_protocol();
65687
- var import_node_path68 = require("path");
65688
- var import_node_fs52 = require("fs");
65826
+ var import_node_path69 = require("path");
65827
+ var import_node_fs53 = require("fs");
65689
65828
  var DEFAULT_TEMPLATE = "nestjs-react";
65690
65829
  var DEV_SERVER_READY_TIMEOUT_MS = 3e4;
65691
65830
  function buildAppBuilderHandlers(deps) {
@@ -65758,7 +65897,7 @@ function buildAppBuilderHandlers(deps) {
65758
65897
  async function listAllUsersProjects() {
65759
65898
  if (!deps.usersRoot || !deps.getStore) return [];
65760
65899
  const getStore = deps.getStore;
65761
- const userIds = await import_node_fs52.promises.readdir(deps.usersRoot).catch(() => []);
65900
+ const userIds = await import_node_fs53.promises.readdir(deps.usersRoot).catch(() => []);
65762
65901
  const perUser = await Promise.all(
65763
65902
  userIds.map((uid) => getStore(uid).list().catch(() => []))
65764
65903
  );
@@ -65831,13 +65970,13 @@ function buildAppBuilderHandlers(deps) {
65831
65970
  const created = await deps.createProjectOnDisk({
65832
65971
  store: userStore,
65833
65972
  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"),
65973
+ templateSrcDir: (0, import_node_path69.join)(personaRoot, "extension-kit", "examples", DEFAULT_TEMPLATE),
65974
+ scaffoldScript: (0, import_node_path69.join)(deps.deployKitRoot, "scripts", "new-extension.sh"),
65836
65975
  reservedPorts,
65837
65976
  // 凭据只进 scaffold 子进程的 env,且**只给这个 persona 的 kit 模板声明要的那几个变量**
65838
65977
  // (M1b Step 5)。整表塞进去粒度只到「进程」——那会把 service-role key 交给一个用不到
65839
65978
  // 它的脚本。new-extension.sh 用它把模板的 `${VAR}` 渲成项目可跑的 server/.env。
65840
- extraEnv: secretsForKit(deps.readSecrets?.(), (0, import_node_path68.join)(personaRoot, "extension-kit")),
65979
+ extraEnv: secretsForKit(deps.readSecrets?.(), (0, import_node_path69.join)(personaRoot, "extension-kit")),
65841
65980
  ...deps.logger ? { logger: deps.logger } : {}
65842
65981
  });
65843
65982
  project = created.project;
@@ -66036,7 +66175,7 @@ function buildAppBuilderHandlers(deps) {
66036
66175
  await userStore.clearPublishJob(args.name);
66037
66176
  }
66038
66177
  const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(boundSession.ownerPersonaId ?? "") : deps.personaRoot;
66039
- const scriptPath = (0, import_node_path68.join)(deps.deployKitRoot, "scripts", "publish.sh");
66178
+ const scriptPath = (0, import_node_path69.join)(deps.deployKitRoot, "scripts", "publish.sh");
66040
66179
  deps.logger?.info("app-builder.publish.start", {
66041
66180
  name: args.name,
66042
66181
  sessionId: boundSession.sessionId,
@@ -66052,7 +66191,7 @@ function buildAppBuilderHandlers(deps) {
66052
66191
  // 凭据只进 publish.sh 这个子进程的 env,且只给它的 kit 模板声明要的那几个变量
66053
66192
  // (M1b Step 5)。那个进程里跑着 `eval "$BUILD_CMD"`——项目自带的构建命令会继承这份
66054
66193
  // env,多给一个变量就是多交一个凭据给它。personaRoot 上面已按绑定 session 的 persona 解析。
66055
- extraEnv: secretsForKit(deps.readSecrets?.(), (0, import_node_path68.join)(personaRoot, "extension-kit")),
66194
+ extraEnv: secretsForKit(deps.readSecrets?.(), (0, import_node_path69.join)(personaRoot, "extension-kit")),
66056
66195
  hooks: {
66057
66196
  // 元数据每次写盘(publishJob 起落 / prodUrl 回填)后重推一帧:UI 渲染 PublishProgress
66058
66197
  // 三段 checklist 依赖 project.publishJob.status==='in-flight',而 publishJob 字段只有
@@ -66585,20 +66724,20 @@ function mapPrState(state, isDraft) {
66585
66724
  if (state === "CLOSED") return "closed";
66586
66725
  return isDraft === true ? "draft" : "open";
66587
66726
  }
66588
- function asRecord2(v2) {
66727
+ function asRecord3(v2) {
66589
66728
  return typeof v2 === "object" && v2 !== null ? v2 : {};
66590
66729
  }
66591
66730
  function lastCommitRollup(node) {
66592
- const first = asRecord2(node.commits).nodes?.[0];
66593
- return asRecord2(asRecord2(first).commit).statusCheckRollup;
66731
+ const first = asRecord3(node.commits).nodes?.[0];
66732
+ return asRecord3(asRecord3(first).commit).statusCheckRollup;
66594
66733
  }
66595
66734
  function parsePrListResponse(json) {
66596
- const nodes = asRecord2(asRecord2(asRecord2(json).data).search).nodes ?? [];
66735
+ const nodes = asRecord3(asRecord3(asRecord3(json).data).search).nodes ?? [];
66597
66736
  const items = [];
66598
66737
  for (const raw of nodes) {
66599
- const n = asRecord2(raw);
66738
+ const n = asRecord3(raw);
66600
66739
  if (typeof n.number !== "number") continue;
66601
- const nameWithOwner = String(asRecord2(n.repository).nameWithOwner ?? "");
66740
+ const nameWithOwner = String(asRecord3(n.repository).nameWithOwner ?? "");
66602
66741
  const slash = nameWithOwner.indexOf("/");
66603
66742
  if (slash <= 0) continue;
66604
66743
  const rollup = lastCommitRollup(n);
@@ -66612,27 +66751,27 @@ function parsePrListResponse(json) {
66612
66751
  additions: typeof n.additions === "number" ? n.additions : 0,
66613
66752
  deletions: typeof n.deletions === "number" ? n.deletions : 0,
66614
66753
  updatedAt: String(n.updatedAt ?? ""),
66615
- author: String(asRecord2(n.author).login ?? ""),
66616
- checksRollup: rollup == null ? "none" : mapRollupState(asRecord2(rollup).state)
66754
+ author: String(asRecord3(n.author).login ?? ""),
66755
+ checksRollup: rollup == null ? "none" : mapRollupState(asRecord3(rollup).state)
66617
66756
  });
66618
66757
  }
66619
66758
  return items;
66620
66759
  }
66621
66760
  function parsePrDetailResponse(json, repoRef) {
66622
- const pr = asRecord2(asRecord2(asRecord2(json).data).repository).pullRequest;
66761
+ const pr = asRecord3(asRecord3(asRecord3(json).data).repository).pullRequest;
66623
66762
  if (pr == null || typeof pr !== "object") return null;
66624
- const n = asRecord2(pr);
66763
+ const n = asRecord3(pr);
66625
66764
  const rollup = lastCommitRollup(n);
66626
- const contextNodes = asRecord2(asRecord2(rollup).contexts).nodes ?? [];
66765
+ const contextNodes = asRecord3(asRecord3(rollup).contexts).nodes ?? [];
66627
66766
  const checks = [];
66628
66767
  for (const c of contextNodes) {
66629
- const mapped = mapCheckNode(asRecord2(c));
66768
+ const mapped = mapCheckNode(asRecord3(c));
66630
66769
  if (mapped) checks.push(mapped);
66631
66770
  }
66632
- const reviewerNodes = asRecord2(n.reviewRequests).nodes ?? [];
66633
- const reviewers = reviewerNodes.map((r) => String(asRecord2(asRecord2(r).requestedReviewer).login ?? "")).filter((s) => s !== "");
66771
+ const reviewerNodes = asRecord3(n.reviewRequests).nodes ?? [];
66772
+ const reviewers = reviewerNodes.map((r) => String(asRecord3(asRecord3(r).requestedReviewer).login ?? "")).filter((s) => s !== "");
66634
66773
  const mergeable = n.mergeable === "MERGEABLE" ? "mergeable" : n.mergeable === "CONFLICTING" ? "conflicting" : "unknown";
66635
- const commentCountRaw = asRecord2(n.comments).totalCount;
66774
+ const commentCountRaw = asRecord3(n.comments).totalCount;
66636
66775
  return {
66637
66776
  owner: repoRef.owner,
66638
66777
  repo: repoRef.repo,
@@ -66640,7 +66779,7 @@ function parsePrDetailResponse(json, repoRef) {
66640
66779
  title: String(n.title ?? ""),
66641
66780
  body: String(n.body ?? ""),
66642
66781
  state: mapPrState(n.state, n.isDraft),
66643
- author: String(asRecord2(n.author).login ?? ""),
66782
+ author: String(asRecord3(n.author).login ?? ""),
66644
66783
  updatedAt: String(n.updatedAt ?? ""),
66645
66784
  headRef: String(n.headRefName ?? ""),
66646
66785
  baseRef: String(n.baseRefName ?? ""),
@@ -66650,7 +66789,7 @@ function parsePrDetailResponse(json, repoRef) {
66650
66789
  mergeable,
66651
66790
  reviewers,
66652
66791
  commentCount: typeof commentCountRaw === "number" ? commentCountRaw : 0,
66653
- checksRollup: rollup == null ? "none" : mapRollupState(asRecord2(rollup).state),
66792
+ checksRollup: rollup == null ? "none" : mapRollupState(asRecord3(rollup).state),
66654
66793
  checks
66655
66794
  };
66656
66795
  }
@@ -66788,7 +66927,7 @@ function buildVisitorHandlers(deps) {
66788
66927
 
66789
66928
  // src/extension/registry.ts
66790
66929
  var import_promises16 = __toESM(require("fs/promises"), 1);
66791
- var import_node_path69 = __toESM(require("path"), 1);
66930
+ var import_node_path70 = __toESM(require("path"), 1);
66792
66931
  async function loadAll(root) {
66793
66932
  let entries;
66794
66933
  try {
@@ -66801,13 +66940,13 @@ async function loadAll(root) {
66801
66940
  for (const ent of entries) {
66802
66941
  if (!ent.isDirectory()) continue;
66803
66942
  if (ent.name.startsWith(".")) continue;
66804
- records.push(await loadOne(import_node_path69.default.join(root, ent.name), ent.name));
66943
+ records.push(await loadOne(import_node_path70.default.join(root, ent.name), ent.name));
66805
66944
  }
66806
66945
  records.sort((a, b2) => a.extId < b2.extId ? -1 : a.extId > b2.extId ? 1 : 0);
66807
66946
  return records;
66808
66947
  }
66809
66948
  async function loadOne(dir, dirName) {
66810
- const manifestPath = import_node_path69.default.join(dir, "manifest.json");
66949
+ const manifestPath = import_node_path70.default.join(dir, "manifest.json");
66811
66950
  let raw;
66812
66951
  try {
66813
66952
  raw = await import_promises16.default.readFile(manifestPath, "utf8");
@@ -66852,7 +66991,7 @@ async function loadOne(dir, dirName) {
66852
66991
 
66853
66992
  // src/extension/uninstall.ts
66854
66993
  var import_promises17 = __toESM(require("fs/promises"), 1);
66855
- var import_node_path70 = __toESM(require("path"), 1);
66994
+ var import_node_path71 = __toESM(require("path"), 1);
66856
66995
  var UninstallError = class extends Error {
66857
66996
  constructor(code, message) {
66858
66997
  super(message);
@@ -66861,7 +67000,7 @@ var UninstallError = class extends Error {
66861
67000
  code;
66862
67001
  };
66863
67002
  async function uninstall(deps) {
66864
- const dir = import_node_path70.default.join(deps.root, deps.extId);
67003
+ const dir = import_node_path71.default.join(deps.root, deps.extId);
66865
67004
  try {
66866
67005
  await import_promises17.default.access(dir);
66867
67006
  } catch {
@@ -66879,14 +67018,14 @@ init_protocol();
66879
67018
 
66880
67019
  // src/peer-ops/run-command.ts
66881
67020
  var import_node_child_process17 = require("child_process");
66882
- var import_node_os24 = __toESM(require("os"), 1);
67021
+ var import_node_os25 = __toESM(require("os"), 1);
66883
67022
  var DEFAULT_TIMEOUT_MS6 = 3e4;
66884
67023
  var MAX_TIMEOUT_MS = 3e5;
66885
67024
  var MAX_OUTPUT_BYTES = 1048576;
66886
67025
  function runCommand2(command, opts = {}) {
66887
67026
  const timeoutMs = Math.min(opts.timeoutMs ?? DEFAULT_TIMEOUT_MS6, MAX_TIMEOUT_MS);
66888
67027
  return new Promise((resolve9) => {
66889
- const child = (0, import_node_child_process17.spawn)("bash", ["-c", command], { cwd: import_node_os24.default.homedir() });
67028
+ const child = (0, import_node_child_process17.spawn)("bash", ["-c", command], { cwd: import_node_os25.default.homedir() });
66890
67029
  const out = [];
66891
67030
  const err = [];
66892
67031
  let outBytes = 0;
@@ -67097,7 +67236,7 @@ function buildMethodHandlers(deps) {
67097
67236
  broadcast: deps.broadcastToOwners
67098
67237
  }),
67099
67238
  ...buildMasterHandlers({
67100
- authorityTablePath: import_node_path71.default.join(deps.masterDataDir, "master-authority.json")
67239
+ authorityTablePath: import_node_path72.default.join(deps.masterDataDir, "master-authority.json")
67101
67240
  }),
67102
67241
  ...buildTopicHandlers({
67103
67242
  topicStore: deps.topicStore,
@@ -67133,18 +67272,18 @@ init_claude();
67133
67272
 
67134
67273
  // src/tools/shell-path.ts
67135
67274
  var import_node_child_process18 = require("child_process");
67136
- var import_node_os25 = __toESM(require("os"), 1);
67275
+ var import_node_os26 = __toESM(require("os"), 1);
67137
67276
  function refreshPathFromLoginShell() {
67138
67277
  if (process.platform === "win32") return;
67139
- const shell = process.env.SHELL ?? import_node_os25.default.userInfo().shell ?? "/bin/zsh";
67278
+ const shell = process.env.SHELL ?? import_node_os26.default.userInfo().shell ?? "/bin/zsh";
67140
67279
  try {
67141
67280
  const out = (0, import_node_child_process18.execFileSync)(shell, ["-ilc", 'command echo -n "$PATH"'], {
67142
67281
  encoding: "utf8",
67143
67282
  timeout: 3e3,
67144
67283
  stdio: ["ignore", "pipe", "ignore"]
67145
67284
  });
67146
- const path97 = out.trim();
67147
- if (path97) process.env.PATH = path97;
67285
+ const path98 = out.trim();
67286
+ if (path98) process.env.PATH = path98;
67148
67287
  } catch {
67149
67288
  }
67150
67289
  }
@@ -67268,9 +67407,9 @@ function buildOnboardingHandlers(deps) {
67268
67407
  }
67269
67408
 
67270
67409
  // src/app-builder-plugin/project-store.ts
67271
- var import_node_fs53 = require("fs");
67410
+ var import_node_fs54 = require("fs");
67272
67411
  var import_node_child_process20 = require("child_process");
67273
- var import_node_path72 = require("path");
67412
+ var import_node_path73 = require("path");
67274
67413
  init_protocol();
67275
67414
  var PROJECTS_DIR = "projects";
67276
67415
  var META_FILE = ".clawd-project.json";
@@ -67300,19 +67439,19 @@ var ProjectStore = class {
67300
67439
  }
67301
67440
  /** projects/<name>/.clawd-project.json 路径 */
67302
67441
  metaPath(name) {
67303
- return (0, import_node_path72.join)(this.projectsRoot(), name, META_FILE);
67442
+ return (0, import_node_path73.join)(this.projectsRoot(), name, META_FILE);
67304
67443
  }
67305
67444
  /** projects/<name>/ 目录路径(cwd 用) */
67306
67445
  projectDir(name) {
67307
- return (0, import_node_path72.join)(this.projectsRoot(), name);
67446
+ return (0, import_node_path73.join)(this.projectsRoot(), name);
67308
67447
  }
67309
67448
  projectsRoot() {
67310
- return (0, import_node_path72.join)(this.root, PROJECTS_DIR);
67449
+ return (0, import_node_path73.join)(this.root, PROJECTS_DIR);
67311
67450
  }
67312
67451
  async list() {
67313
67452
  let entries;
67314
67453
  try {
67315
- entries = await import_node_fs53.promises.readdir(this.projectsRoot());
67454
+ entries = await import_node_fs54.promises.readdir(this.projectsRoot());
67316
67455
  } catch (err) {
67317
67456
  if (err.code === "ENOENT") return [];
67318
67457
  throw err;
@@ -67320,7 +67459,7 @@ var ProjectStore = class {
67320
67459
  const out = [];
67321
67460
  for (const name of entries) {
67322
67461
  try {
67323
- const raw = await import_node_fs53.promises.readFile(this.metaPath(name), "utf8");
67462
+ const raw = await import_node_fs54.promises.readFile(this.metaPath(name), "utf8");
67324
67463
  const json = JSON.parse(raw);
67325
67464
  let migrated = false;
67326
67465
  if (typeof json.devCommand !== "string" || json.devCommand.length === 0) {
@@ -67331,7 +67470,7 @@ var ProjectStore = class {
67331
67470
  if (parsed.success) {
67332
67471
  out.push(parsed.data);
67333
67472
  if (migrated) {
67334
- void import_node_fs53.promises.writeFile(this.metaPath(name), JSON.stringify(parsed.data, null, 2) + "\n", "utf8").catch(() => {
67473
+ void import_node_fs54.promises.writeFile(this.metaPath(name), JSON.stringify(parsed.data, null, 2) + "\n", "utf8").catch(() => {
67335
67474
  });
67336
67475
  }
67337
67476
  }
@@ -67375,8 +67514,8 @@ var ProjectStore = class {
67375
67514
  throw new Error(`invalid name "${name}": ${validated.error.message}`);
67376
67515
  }
67377
67516
  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");
67517
+ await import_node_fs54.promises.mkdir(dir, { recursive: true });
67518
+ await import_node_fs54.promises.writeFile(this.metaPath(name), JSON.stringify(meta, null, 2) + "\n", "utf8");
67380
67519
  return meta;
67381
67520
  }
67382
67521
  /**
@@ -67421,7 +67560,7 @@ var ProjectStore = class {
67421
67560
  }
67422
67561
  async delete(name) {
67423
67562
  const dir = this.projectDir(name);
67424
- await import_node_fs53.promises.rm(dir, { recursive: true, force: true });
67563
+ await import_node_fs54.promises.rm(dir, { recursive: true, force: true });
67425
67564
  }
67426
67565
  async updatePort(name, newPort) {
67427
67566
  if (newPort < PROJECT_PORT_MIN || newPort > PROJECT_PORT_MAX) {
@@ -67438,7 +67577,7 @@ var ProjectStore = class {
67438
67577
  throw new Error(`port ${newPort} already used / \u5DF2\u88AB project "${conflict.name}" \u5360\u7528`);
67439
67578
  }
67440
67579
  const updated = { ...target, port: newPort };
67441
- await import_node_fs53.promises.writeFile(this.metaPath(name), JSON.stringify(updated, null, 2) + "\n", "utf8");
67580
+ await import_node_fs54.promises.writeFile(this.metaPath(name), JSON.stringify(updated, null, 2) + "\n", "utf8");
67442
67581
  return updated;
67443
67582
  });
67444
67583
  }
@@ -67457,7 +67596,7 @@ var ProjectStore = class {
67457
67596
  if (!validated.success) {
67458
67597
  throw new Error(`invalid prodUrl "${url}": ${validated.error.message}`);
67459
67598
  }
67460
- await import_node_fs53.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
67599
+ await import_node_fs54.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
67461
67600
  return validated.data;
67462
67601
  });
67463
67602
  }
@@ -67480,7 +67619,7 @@ var ProjectStore = class {
67480
67619
  if (!validated.success) {
67481
67620
  throw new Error(`invalid publishJob: ${validated.error.message}`);
67482
67621
  }
67483
- await import_node_fs53.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
67622
+ await import_node_fs54.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
67484
67623
  return validated.data;
67485
67624
  });
67486
67625
  }
@@ -67497,7 +67636,7 @@ var ProjectStore = class {
67497
67636
  if (!validated.success) {
67498
67637
  throw new Error(`failed to clear publishJob: ${validated.error.message}`);
67499
67638
  }
67500
- await import_node_fs53.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
67639
+ await import_node_fs54.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
67501
67640
  return validated.data;
67502
67641
  });
67503
67642
  }
@@ -67812,8 +67951,8 @@ var PublishJobRegistry = class {
67812
67951
 
67813
67952
  // src/app-builder-plugin/publish-job-runner.ts
67814
67953
  var import_node_child_process22 = require("child_process");
67815
- var import_node_fs54 = require("fs");
67816
- var import_node_path73 = require("path");
67954
+ var import_node_fs55 = require("fs");
67955
+ var import_node_path74 = require("path");
67817
67956
 
67818
67957
  // src/app-builder-plugin/publish-stage-parser.ts
67819
67958
  var STAGE_RE = /^\s*::stage::(build|deploy|verify)\s*$/;
@@ -67845,10 +67984,10 @@ async function startPublishJob(deps, args) {
67845
67984
  return { jobId: registry2.get(args.name).jobId, status: "already-publishing" };
67846
67985
  }
67847
67986
  const projDir = projectDir(args.name);
67848
- const logPath = (0, import_node_path73.join)(projDir, ".publish.log");
67987
+ const logPath = (0, import_node_path74.join)(projDir, ".publish.log");
67849
67988
  let logStream = null;
67850
67989
  try {
67851
- logStream = (0, import_node_fs54.createWriteStream)(logPath, { flags: "w" });
67990
+ logStream = (0, import_node_fs55.createWriteStream)(logPath, { flags: "w" });
67852
67991
  } catch {
67853
67992
  logStream = null;
67854
67993
  }
@@ -68191,10 +68330,10 @@ async function recoverInterruptedPublishJobs(store, logger) {
68191
68330
  }
68192
68331
 
68193
68332
  // 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);
68333
+ var import_node_fs56 = __toESM(require("fs"), 1);
68334
+ var import_node_path75 = __toESM(require("path"), 1);
68196
68335
  function appBuilderMcpConfigPath(dataDir) {
68197
- return import_node_path74.default.join(dataDir, "app-builder.mcp.json");
68336
+ return import_node_path75.default.join(dataDir, "app-builder.mcp.json");
68198
68337
  }
68199
68338
  function writeAppBuilderMcpConfig(args) {
68200
68339
  const cfgPath = appBuilderMcpConfigPath(args.dataDir);
@@ -68208,15 +68347,15 @@ function writeAppBuilderMcpConfig(args) {
68208
68347
  env: {
68209
68348
  CLAWD_DAEMON_TOKEN: args.daemonToken,
68210
68349
  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"),
68350
+ CLAWD_APP_BUILDER_SCAFFOLD_SCRIPT: import_node_path75.default.join(args.deployKitScriptsDir, "new-extension.sh"),
68351
+ CLAWD_APP_BUILDER_PUBLISH_SCRIPT: import_node_path75.default.join(args.deployKitScriptsDir, "publish.sh"),
68213
68352
  ...args.logPath ? { CLAWD_APP_BUILDER_LOG: args.logPath } : {}
68214
68353
  }
68215
68354
  }
68216
68355
  }
68217
68356
  };
68218
- import_node_fs55.default.mkdirSync(args.dataDir, { recursive: true });
68219
- import_node_fs55.default.writeFileSync(cfgPath, JSON.stringify(cfg, null, 2), "utf8");
68357
+ import_node_fs56.default.mkdirSync(args.dataDir, { recursive: true });
68358
+ import_node_fs56.default.writeFileSync(cfgPath, JSON.stringify(cfg, null, 2), "utf8");
68220
68359
  return cfgPath;
68221
68360
  }
68222
68361
 
@@ -68257,7 +68396,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
68257
68396
 
68258
68397
  // src/extension/runtime.ts
68259
68398
  var import_node_child_process24 = require("child_process");
68260
- var import_node_path75 = __toESM(require("path"), 1);
68399
+ var import_node_path76 = __toESM(require("path"), 1);
68261
68400
  var import_promises18 = require("timers/promises");
68262
68401
 
68263
68402
  // src/extension/port-allocator.ts
@@ -68358,7 +68497,7 @@ var Runtime = class {
68358
68497
  /\$CLAWOS_EXT_PORT/g,
68359
68498
  String(port)
68360
68499
  );
68361
- const dir = import_node_path75.default.join(this.root, extId);
68500
+ const dir = import_node_path76.default.join(this.root, extId);
68362
68501
  const env = {
68363
68502
  ...process.env,
68364
68503
  CLAWOS_EXT_PORT: String(port),
@@ -68470,7 +68609,7 @@ ${handle.stderrTail}`
68470
68609
 
68471
68610
  // src/extension/published-channels.ts
68472
68611
  var import_promises19 = __toESM(require("fs/promises"), 1);
68473
- var import_node_path76 = __toESM(require("path"), 1);
68612
+ var import_node_path77 = __toESM(require("path"), 1);
68474
68613
  init_zod();
68475
68614
  var PublishedChannelsError = class extends Error {
68476
68615
  constructor(code, message) {
@@ -68569,7 +68708,7 @@ var PublishedChannelStore = class {
68569
68708
  )
68570
68709
  };
68571
68710
  const tmp = `${this.filePath}.tmp`;
68572
- await import_promises19.default.mkdir(import_node_path76.default.dirname(this.filePath), { recursive: true });
68711
+ await import_promises19.default.mkdir(import_node_path77.default.dirname(this.filePath), { recursive: true });
68573
68712
  await import_promises19.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
68574
68713
  await import_promises19.default.rename(tmp, this.filePath);
68575
68714
  }
@@ -68577,7 +68716,7 @@ var PublishedChannelStore = class {
68577
68716
 
68578
68717
  // src/extension/bundle-cache.ts
68579
68718
  var import_promises20 = __toESM(require("fs/promises"), 1);
68580
- var import_node_path77 = __toESM(require("path"), 1);
68719
+ var import_node_path78 = __toESM(require("path"), 1);
68581
68720
  var BundleCache = class {
68582
68721
  constructor(rootDir) {
68583
68722
  this.rootDir = rootDir;
@@ -68586,14 +68725,14 @@ var BundleCache = class {
68586
68725
  /** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
68587
68726
  async write(snapshotHash, buffer) {
68588
68727
  await import_promises20.default.mkdir(this.rootDir, { recursive: true });
68589
- const file = import_node_path77.default.join(this.rootDir, `${snapshotHash}.zip`);
68728
+ const file = import_node_path78.default.join(this.rootDir, `${snapshotHash}.zip`);
68590
68729
  const tmp = `${file}.tmp`;
68591
68730
  await import_promises20.default.writeFile(tmp, buffer, { mode: 384 });
68592
68731
  await import_promises20.default.rename(tmp, file);
68593
68732
  }
68594
68733
  /** Returns the bundle bytes, or null when the file doesn't exist. */
68595
68734
  async read(snapshotHash) {
68596
- const file = import_node_path77.default.join(this.rootDir, `${snapshotHash}.zip`);
68735
+ const file = import_node_path78.default.join(this.rootDir, `${snapshotHash}.zip`);
68597
68736
  try {
68598
68737
  return await import_promises20.default.readFile(file);
68599
68738
  } catch (e) {
@@ -68603,7 +68742,7 @@ var BundleCache = class {
68603
68742
  }
68604
68743
  /** Idempotent — missing file is not an error. */
68605
68744
  async delete(snapshotHash) {
68606
- const file = import_node_path77.default.join(this.rootDir, `${snapshotHash}.zip`);
68745
+ const file = import_node_path78.default.join(this.rootDir, `${snapshotHash}.zip`);
68607
68746
  await import_promises20.default.rm(file, { force: true });
68608
68747
  }
68609
68748
  };
@@ -68624,26 +68763,26 @@ async function startDaemon(config) {
68624
68763
  },
68625
68764
  source: "daemon",
68626
68765
  sampling: logShippingCfg.sampling,
68627
- homeDir: import_node_os26.default.homedir()
68766
+ homeDir: import_node_os27.default.homedir()
68628
68767
  });
68629
- const logDir = import_node_path78.default.join(config.dataDir, "log");
68630
- import_node_fs56.default.mkdirSync(logDir, { recursive: true });
68768
+ const logDir = import_node_path79.default.join(config.dataDir, "log");
68769
+ import_node_fs57.default.mkdirSync(logDir, { recursive: true });
68631
68770
  const logger = createLogger({
68632
68771
  level: config.logLevel,
68633
- file: import_node_path78.default.join(logDir, "clawd.log"),
68772
+ file: import_node_path79.default.join(logDir, "clawd.log"),
68634
68773
  logClient
68635
68774
  });
68636
68775
  logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
68637
68776
  const screenIdleProbeLogger = createFileOnlyLogger({
68638
- file: import_node_path78.default.join(logDir, "screen-idle-probe.log"),
68777
+ file: import_node_path79.default.join(logDir, "screen-idle-probe.log"),
68639
68778
  level: "debug"
68640
68779
  });
68641
68780
  logger.info("screen-idle probe logger enabled", {
68642
- file: import_node_path78.default.join(logDir, "screen-idle-probe.log")
68781
+ file: import_node_path79.default.join(logDir, "screen-idle-probe.log")
68643
68782
  });
68644
68783
  const CAP_TARGETS = [
68645
- import_node_path78.default.join(logDir, "clawd.log"),
68646
- import_node_path78.default.join(logDir, "screen-idle-probe.log")
68784
+ import_node_path79.default.join(logDir, "clawd.log"),
68785
+ import_node_path79.default.join(logDir, "screen-idle-probe.log")
68647
68786
  ];
68648
68787
  const LOG_CAP_MAX_BYTES = 10 * 1024 * 1024;
68649
68788
  const LOG_CAP_KEEP_BYTES = 5 * 1024 * 1024;
@@ -68765,8 +68904,8 @@ async function startDaemon(config) {
68765
68904
  const agents = new AgentsScanner();
68766
68905
  const history = new ClaudeHistoryReader();
68767
68906
  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");
68907
+ const personaStore = new PersonaStore(import_node_path79.default.join(config.dataDir, "personas"));
68908
+ const usersRoot = import_node_path79.default.join(config.dataDir, "users");
68770
68909
  const defaultsRoot = findDefaultsRoot(logger);
68771
68910
  if (defaultsRoot) {
68772
68911
  seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
@@ -68790,7 +68929,7 @@ async function startDaemon(config) {
68790
68929
  retirePersonaBuilder({ store: personaStore, logger });
68791
68930
  const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
68792
68931
  const dispatchStore = createDispatchStore({
68793
- filePath: import_node_path78.default.join(config.dataDir, "dispatch.json"),
68932
+ filePath: import_node_path79.default.join(config.dataDir, "dispatch.json"),
68794
68933
  now: () => Date.now(),
68795
68934
  onFlushError: (err) => logger.error("dispatch store flush failed", {
68796
68935
  reason: err instanceof Error ? err.message : String(err)
@@ -68799,7 +68938,7 @@ async function startDaemon(config) {
68799
68938
  await dispatchStore.load();
68800
68939
  dispatchStore.markInterruptedAsFailed((/* @__PURE__ */ new Date()).toISOString());
68801
68940
  const channelStore = createChannelStore({
68802
- filePath: import_node_path78.default.join(config.dataDir, "channels.json"),
68941
+ filePath: import_node_path79.default.join(config.dataDir, "channels.json"),
68803
68942
  now: () => Date.now(),
68804
68943
  genId: () => `ch-${(0, import_node_crypto22.randomUUID)().slice(0, 8)}`,
68805
68944
  onFlushError: (err) => logger.error("channel store flush failed", {
@@ -68808,7 +68947,7 @@ async function startDaemon(config) {
68808
68947
  });
68809
68948
  await channelStore.load();
68810
68949
  const topicStore = createTopicStore({
68811
- filePath: import_node_path78.default.join(config.dataDir, "topics.json"),
68950
+ filePath: import_node_path79.default.join(config.dataDir, "topics.json"),
68812
68951
  now: () => Date.now(),
68813
68952
  genId: () => `tp-${(0, import_node_crypto22.randomUUID)().slice(0, 8)}`,
68814
68953
  onFlushError: (err) => logger.error("topic store flush failed", {
@@ -68835,28 +68974,28 @@ async function startDaemon(config) {
68835
68974
  });
68836
68975
  }
68837
68976
  });
68838
- const here = typeof __dirname === "string" ? __dirname : import_node_path78.default.dirname((0, import_node_url5.fileURLToPath)(import_meta8.url));
68977
+ const here = typeof __dirname === "string" ? __dirname : import_node_path79.default.dirname((0, import_node_url5.fileURLToPath)(import_meta8.url));
68839
68978
  const mcpConfigs = [];
68840
68979
  const secretsBundleRoot = findSecretsBundleRoot(logger);
68841
- const localSecretsDir = import_node_path78.default.join(config.dataDir, LOCAL_SECRETS_DIRNAME);
68980
+ const localSecretsDir = import_node_path79.default.join(config.dataDir, LOCAL_SECRETS_DIRNAME);
68842
68981
  const readSecrets = () => readSecretTable({ bundleRoot: secretsBundleRoot, overrideDir: localSecretsDir, logger });
68843
68982
  const resolvePersonaMcpConfig = (personaId2) => renderPersonaMcpSecrets({
68844
68983
  personaId: personaId2,
68845
- personaDir: import_node_path78.default.join(config.dataDir, "personas", personaId2),
68984
+ personaDir: import_node_path79.default.join(config.dataDir, "personas", personaId2),
68846
68985
  secrets: readSecrets(),
68847
- outDir: import_node_path78.default.join(config.dataDir, "persona-mcp"),
68986
+ outDir: import_node_path79.default.join(config.dataDir, "persona-mcp"),
68848
68987
  logger
68849
68988
  });
68850
68989
  const mcpDaemonUrl = `http://127.0.0.1:${config.port}`;
68851
68990
  const dispatchServerCandidates = [
68852
- import_node_path78.default.join(here, "dispatch", "mcp-server.cjs"),
68991
+ import_node_path79.default.join(here, "dispatch", "mcp-server.cjs"),
68853
68992
  // 生产 dist/index → dist/dispatch/mcp-server.cjs
68854
- import_node_path78.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
68993
+ import_node_path79.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
68855
68994
  // dev tsx src/index → ../dist/dispatch/mcp-server.cjs
68856
68995
  ];
68857
- const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs56.default.existsSync(p2));
68996
+ const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs57.default.existsSync(p2));
68858
68997
  if (dispatchServerScriptPath) {
68859
- const dispatchLogPath = import_node_path78.default.join(logDir, "dispatch-mcp-server.log");
68998
+ const dispatchLogPath = import_node_path79.default.join(logDir, "dispatch-mcp-server.log");
68860
68999
  const dispatchCfgPath = writeDispatchMcpConfig({
68861
69000
  dataDir: config.dataDir,
68862
69001
  serverScriptPath: dispatchServerScriptPath,
@@ -68876,12 +69015,12 @@ async function startDaemon(config) {
68876
69015
  });
68877
69016
  }
68878
69017
  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")
69018
+ import_node_path79.default.join(here, "ticket", "mcp-server.cjs"),
69019
+ import_node_path79.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
68881
69020
  ];
68882
- const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs56.default.existsSync(p2));
69021
+ const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs57.default.existsSync(p2));
68883
69022
  if (ticketServerScriptPath) {
68884
- const ticketLogPath = import_node_path78.default.join(logDir, "ticket-mcp-server.log");
69023
+ const ticketLogPath = import_node_path79.default.join(logDir, "ticket-mcp-server.log");
68885
69024
  const ticketCfgPath = writeTicketMcpConfig({
68886
69025
  dataDir: config.dataDir,
68887
69026
  serverScriptPath: ticketServerScriptPath,
@@ -68903,12 +69042,12 @@ async function startDaemon(config) {
68903
69042
  });
68904
69043
  }
68905
69044
  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")
69045
+ import_node_path79.default.join(here, "shift", "mcp-server.cjs"),
69046
+ import_node_path79.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
68908
69047
  ];
68909
- const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs56.default.existsSync(p2));
69048
+ const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs57.default.existsSync(p2));
68910
69049
  if (shiftServerScriptPath) {
68911
- const shiftLogPath = import_node_path78.default.join(logDir, "shift-mcp-server.log");
69050
+ const shiftLogPath = import_node_path79.default.join(logDir, "shift-mcp-server.log");
68912
69051
  const shiftCfgPath = await writeShiftMcpConfig({
68913
69052
  dataDir: config.dataDir,
68914
69053
  serverScriptPath: shiftServerScriptPath,
@@ -68929,12 +69068,12 @@ async function startDaemon(config) {
68929
69068
  );
68930
69069
  }
68931
69070
  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")
69071
+ import_node_path79.default.join(here, "inbox", "mcp-server.cjs"),
69072
+ import_node_path79.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
68934
69073
  ];
68935
- const inboxServerScriptPath = inboxServerCandidates.find((p2) => import_node_fs56.default.existsSync(p2));
69074
+ const inboxServerScriptPath = inboxServerCandidates.find((p2) => import_node_fs57.default.existsSync(p2));
68936
69075
  if (inboxServerScriptPath) {
68937
- const inboxLogPath = import_node_path78.default.join(logDir, "inbox-mcp-server.log");
69076
+ const inboxLogPath = import_node_path79.default.join(logDir, "inbox-mcp-server.log");
68938
69077
  const inboxCfgPath = await writeInboxMcpConfig({
68939
69078
  dataDir: config.dataDir,
68940
69079
  serverScriptPath: inboxServerScriptPath,
@@ -68955,10 +69094,10 @@ async function startDaemon(config) {
68955
69094
  );
68956
69095
  }
68957
69096
  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")
69097
+ import_node_path79.default.join(here, "peer-ops", "mcp-server.cjs"),
69098
+ import_node_path79.default.join(here, "..", "dist", "peer-ops", "mcp-server.cjs")
68960
69099
  ];
68961
- const peerOpsServerScriptPath = peerOpsServerCandidates.find((p2) => import_node_fs56.default.existsSync(p2));
69100
+ const peerOpsServerScriptPath = peerOpsServerCandidates.find((p2) => import_node_fs57.default.existsSync(p2));
68962
69101
  if (peerOpsServerScriptPath) {
68963
69102
  const peerOpsCfgPath = writePeerOpsMcpConfig({
68964
69103
  dataDir: config.dataDir,
@@ -68978,12 +69117,12 @@ async function startDaemon(config) {
68978
69117
  );
68979
69118
  }
68980
69119
  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")
69120
+ import_node_path79.default.join(here, "rpc-tool", "mcp-server.cjs"),
69121
+ import_node_path79.default.join(here, "..", "dist", "rpc-tool", "mcp-server.cjs")
68983
69122
  ];
68984
- const rpcToolServerScriptPath = rpcToolServerCandidates.find((p2) => import_node_fs56.default.existsSync(p2));
69123
+ const rpcToolServerScriptPath = rpcToolServerCandidates.find((p2) => import_node_fs57.default.existsSync(p2));
68985
69124
  if (rpcToolServerScriptPath) {
68986
- const rpcToolLogPath = import_node_path78.default.join(logDir, "rpc-tool-mcp-server.log");
69125
+ const rpcToolLogPath = import_node_path79.default.join(logDir, "rpc-tool-mcp-server.log");
68987
69126
  const rpcToolCfgPath = writeRpcToolMcpConfig({
68988
69127
  dataDir: config.dataDir,
68989
69128
  serverScriptPath: rpcToolServerScriptPath,
@@ -69004,18 +69143,18 @@ async function startDaemon(config) {
69004
69143
  );
69005
69144
  }
69006
69145
  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")
69146
+ import_node_path79.default.join(here, "app-builder-plugin", "mcp-server.cjs"),
69147
+ import_node_path79.default.join(here, "..", "dist", "app-builder-plugin", "mcp-server.cjs")
69009
69148
  ];
69010
- const appBuilderServerScriptPath = appBuilderServerCandidates.find((p2) => import_node_fs56.default.existsSync(p2));
69149
+ const appBuilderServerScriptPath = appBuilderServerCandidates.find((p2) => import_node_fs57.default.existsSync(p2));
69011
69150
  if (appBuilderServerScriptPath) {
69012
- const appBuilderLogPath = import_node_path78.default.join(logDir, "app-builder-mcp-server.log");
69151
+ const appBuilderLogPath = import_node_path79.default.join(logDir, "app-builder-mcp-server.log");
69013
69152
  const appBuilderCfgPath = writeAppBuilderMcpConfig({
69014
69153
  dataDir: config.dataDir,
69015
69154
  serverScriptPath: appBuilderServerScriptPath,
69016
69155
  daemonToken: resolvedAuthToken,
69017
69156
  daemonUrl: mcpDaemonUrl,
69018
- deployKitScriptsDir: import_node_path78.default.join(config.dataDir, "deploy-kit", "scripts"),
69157
+ deployKitScriptsDir: import_node_path79.default.join(config.dataDir, "deploy-kit", "scripts"),
69019
69158
  logPath: appBuilderLogPath
69020
69159
  });
69021
69160
  mcpConfigs.push({ id: "app-builder", path: appBuilderCfgPath, personas: APP_BUILDER_PERSONAS });
@@ -69031,7 +69170,7 @@ async function startDaemon(config) {
69031
69170
  );
69032
69171
  }
69033
69172
  const shiftStore = createShiftStore({
69034
- filePath: import_node_path78.default.join(config.dataDir, "shift.json"),
69173
+ filePath: import_node_path79.default.join(config.dataDir, "shift.json"),
69035
69174
  ownerIdProvider: () => ownerPrincipalId,
69036
69175
  now: () => Date.now()
69037
69176
  });
@@ -69053,7 +69192,7 @@ async function startDaemon(config) {
69053
69192
  getAdapter,
69054
69193
  historyReader: history,
69055
69194
  dataDir: config.dataDir,
69056
- personaRoot: import_node_path78.default.join(config.dataDir, "personas"),
69195
+ personaRoot: import_node_path79.default.join(config.dataDir, "personas"),
69057
69196
  // dispatch / shift 自动化 spawn 按 persona 绑定 tool 起 B session(codex persona 用 codex)。
69058
69197
  // personaRegistry 声明在 manager 之后(同作用域 const,调用时机在启动完成后,无 TDZ 风险)。
69059
69198
  getPersonaDefaults: (personaId2) => personaRegistry.get(personaId2),
@@ -69110,10 +69249,10 @@ async function startDaemon(config) {
69110
69249
  // 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
69111
69250
  attachmentGroup: {
69112
69251
  onFileEdit: (input) => {
69113
- const absPath = import_node_path78.default.isAbsolute(input.relPath) ? input.relPath : import_node_path78.default.join(input.cwd, input.relPath);
69252
+ const absPath = import_node_path79.default.isAbsolute(input.relPath) ? input.relPath : import_node_path79.default.join(input.cwd, input.relPath);
69114
69253
  let size = 0;
69115
69254
  try {
69116
- size = import_node_fs56.default.statSync(absPath).size;
69255
+ size = import_node_fs57.default.statSync(absPath).size;
69117
69256
  } catch (err) {
69118
69257
  logger.warn("attachment.onFileEdit stat failed", {
69119
69258
  sessionId: input.sessionId,
@@ -69143,9 +69282,9 @@ async function startDaemon(config) {
69143
69282
  logger.info("projects.seed-dropped", { dropped: droppedSeed.dropped, backup: droppedSeed.backup });
69144
69283
  }
69145
69284
  const projectsStore = new ProjectsStore({
69146
- file: import_node_path78.default.join(config.dataDir, "projects.json"),
69285
+ file: import_node_path79.default.join(config.dataDir, "projects.json"),
69147
69286
  clawdDir: config.dataDir,
69148
- codexStateFile: import_node_path78.default.join(import_node_os26.default.homedir(), ".codex", ".codex-global-state.json"),
69287
+ codexStateFile: import_node_path79.default.join(import_node_os27.default.homedir(), ".codex", ".codex-global-state.json"),
69149
69288
  logger
69150
69289
  });
69151
69290
  const observer = new SessionObserver({
@@ -69205,13 +69344,13 @@ async function startDaemon(config) {
69205
69344
  screenIdleProbeLogger
69206
69345
  }) : new ClaudeAdapter({ logger, historyReader: new ClaudeHistoryReader() });
69207
69346
  registerAdapter("claude", claudeAdapter);
69208
- const codexIsolatedHome = import_node_path78.default.join(config.dataDir, "codex-home");
69347
+ const codexIsolatedHome = import_node_path79.default.join(config.dataDir, "codex-home");
69209
69348
  try {
69210
- import_node_fs56.default.mkdirSync(codexIsolatedHome, { recursive: true });
69349
+ import_node_fs57.default.mkdirSync(codexIsolatedHome, { recursive: true });
69211
69350
  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);
69351
+ const link = import_node_path79.default.join(codexIsolatedHome, f);
69352
+ const target = import_node_path79.default.join(import_node_os27.default.homedir(), ".codex", f);
69353
+ if (!import_node_fs57.default.existsSync(link) && import_node_fs57.default.existsSync(target)) import_node_fs57.default.symlinkSync(target, link);
69215
69354
  }
69216
69355
  } catch (err) {
69217
69356
  logger.warn("codex isolated home setup failed", { err: String(err) });
@@ -69224,11 +69363,11 @@ async function startDaemon(config) {
69224
69363
  // projectPaths 每次调用现取 —— 用户新建 project 后立即生效,不用重启 daemon
69225
69364
  codexHomeFor: (cwd) => resolveCodexHome({
69226
69365
  cwd,
69227
- personaRoot: import_node_path78.default.join(config.dataDir, "personas"),
69366
+ personaRoot: import_node_path79.default.join(config.dataDir, "personas"),
69228
69367
  // 必须用 listMerged(Codex registry ∪ 叠加层):只用本地 list() 的话,用户在
69229
69368
  // Codex 里建的 project 不在表里,在它下面开的会话会被误判成隔离 → Codex 侧看不到
69230
69369
  projectPaths: projectsStore.listMerged().map((x) => x.path),
69231
- sharedHome: import_node_path78.default.join(import_node_os26.default.homedir(), ".codex"),
69370
+ sharedHome: import_node_path79.default.join(import_node_os27.default.homedir(), ".codex"),
69232
69371
  isolatedHome: codexIsolatedHome
69233
69372
  })
69234
69373
  })
@@ -69513,11 +69652,11 @@ async function startDaemon(config) {
69513
69652
  // 'persona/<pid>/owner',default 走 'default'。
69514
69653
  getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
69515
69654
  // guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
69516
- personaRoot: import_node_path78.default.join(config.dataDir, "personas"),
69655
+ personaRoot: import_node_path79.default.join(config.dataDir, "personas"),
69517
69656
  usersRoot
69518
69657
  },
69519
69658
  // workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
69520
- personaRoot: import_node_path78.default.join(config.dataDir, "personas"),
69659
+ personaRoot: import_node_path79.default.join(config.dataDir, "personas"),
69521
69660
  // v2 多人 persona 隔离:handler 派生 guest user-dir 放行
69522
69661
  usersRoot,
69523
69662
  // v2 Phase 6: whoami handler 装在 owner principal.displayName + persona 解析
@@ -69624,11 +69763,11 @@ async function startDaemon(config) {
69624
69763
  // 发布上线脚手架化 (spec 2026-06-03 §5.2):
69625
69764
  // appBuilderPersonaRoot 用于拼 publish.sh 绝对路径(persona-app-builder 安装在
69626
69765
  // dataDir/personas/persona-app-builder 之下,extension-kit/scripts/publish.sh 是相对路径)。
69627
- appBuilderPersonaRoot: import_node_path78.default.join(config.dataDir, "personas", "persona-app-builder"),
69766
+ appBuilderPersonaRoot: import_node_path79.default.join(config.dataDir, "personas", "persona-app-builder"),
69628
69767
  // 共享 deploy-kit 根:scaffold/publish 脚本骨架 + 阿里云凭证单一真源。
69629
- deployKitRoot: import_node_path78.default.join(config.dataDir, "deploy-kit"),
69768
+ deployKitRoot: import_node_path79.default.join(config.dataDir, "deploy-kit"),
69630
69769
  // scaffold/publish 按当前 session 的 persona 解析其安装根,让每个 persona 用自己的模板/注入配置。
69631
- resolvePersonaRoot: (personaId2) => import_node_path78.default.join(config.dataDir, "personas", personaId2),
69770
+ resolvePersonaRoot: (personaId2) => import_node_path79.default.join(config.dataDir, "personas", personaId2),
69632
69771
  // 凭据表(M1b Step 5):与 MCP 那条同一张表、同一个来源,只是交付给另一个子进程。
69633
69772
  readSecrets,
69634
69773
  // 发布上线脚手架化 (spec 2026-06-03 §5.2.2):
@@ -69685,7 +69824,7 @@ async function startDaemon(config) {
69685
69824
  sourceSessionId: args.sourceSessionId
69686
69825
  });
69687
69826
  const sourceFile = manager.findOwnedSession(args.sourceSessionId);
69688
- const sourceJsonlPath = resolveSourceJsonlPath(sourceFile, import_node_os26.default.homedir());
69827
+ const sourceJsonlPath = resolveSourceJsonlPath(sourceFile, import_node_os27.default.homedir());
69689
69828
  logger.info("dispatch.spawnB.source-resolved", {
69690
69829
  dispatchId: args.dispatchId,
69691
69830
  sourceJsonlPath,
@@ -69812,7 +69951,7 @@ async function startDaemon(config) {
69812
69951
  });
69813
69952
  shiftScheduler.start();
69814
69953
  logger.info("shift scheduler started", { shiftCount: shiftStore.list().length });
69815
- const larkBotStore = createLarkBotBindingStore(import_node_path78.default.join(config.dataDir, "personas"));
69954
+ const larkBotStore = createLarkBotBindingStore(import_node_path79.default.join(config.dataDir, "personas"));
69816
69955
  const larkBotCloud = createLarkBotCloudClient({
69817
69956
  api: config.clawosApi ?? DEFAULT_CLAWOS_API,
69818
69957
  apiKey: resolveClawdTicketsApiKey(),
@@ -69826,7 +69965,7 @@ async function startDaemon(config) {
69826
69965
  store: larkBotStore,
69827
69966
  fetchResource: (appId, messageId, fileKey, maxBytes, type) => larkBotCloud.fetchResource(appId, messageId, fileKey, maxBytes, type),
69828
69967
  // 图片落 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"),
69968
+ mediaRootFor: (chatId) => import_node_path79.default.join(deriveUserWorkDir(`lark-${chatId}`, usersRoot), "lark-media"),
69830
69969
  isShuttingDown: () => larkDraining,
69831
69970
  logger: {
69832
69971
  warn: (msg) => logger.warn(msg),
@@ -70131,8 +70270,8 @@ async function startDaemon(config) {
70131
70270
  const lines = [
70132
70271
  `Tunnel: ${r.url}`,
70133
70272
  ...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")}`
70273
+ `Frpc config: ${import_node_path79.default.join(config.dataDir, "frpc.toml")}`,
70274
+ `Frpc log: ${import_node_path79.default.join(logDir, "frpc.log")}`
70136
70275
  ];
70137
70276
  const width2 = Math.max(...lines.map((l) => l.length));
70138
70277
  const bar = "\u2550".repeat(width2 + 4);
@@ -70145,8 +70284,8 @@ ${bar}
70145
70284
 
70146
70285
  `);
70147
70286
  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 });
70287
+ const connectPath = import_node_path79.default.join(config.dataDir, "connect.txt");
70288
+ import_node_fs57.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
70150
70289
  } catch {
70151
70290
  }
70152
70291
  } catch (err) {
@@ -70233,9 +70372,9 @@ ${bar}
70233
70372
  };
70234
70373
  }
70235
70374
  function migrateDropPersonsDir(dataDir) {
70236
- const dir = import_node_path78.default.join(dataDir, "persons");
70375
+ const dir = import_node_path79.default.join(dataDir, "persons");
70237
70376
  try {
70238
- import_node_fs56.default.rmSync(dir, { recursive: true, force: true });
70377
+ import_node_fs57.default.rmSync(dir, { recursive: true, force: true });
70239
70378
  } catch {
70240
70379
  }
70241
70380
  }