@clawos-dev/clawd 0.2.616 → 0.2.618

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: path106, errorMaps, issueData } = params;
454
- const fullPath = [...path106, ...issueData.path || []];
453
+ const { data, path: path107, errorMaps, issueData } = params;
454
+ const fullPath = [...path107, ...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, path106, key) {
765
+ constructor(parent, value, path107, key) {
766
766
  this._cachedPath = [];
767
767
  this.parent = parent;
768
768
  this.data = value;
769
- this._path = path106;
769
+ this._path = path107;
770
770
  this._key = key;
771
771
  }
772
772
  get path() {
@@ -10356,8 +10356,8 @@ var require_req = __commonJS({
10356
10356
  if (req.originalUrl) {
10357
10357
  _req.url = req.originalUrl;
10358
10358
  } else {
10359
- const path106 = req.path;
10360
- _req.url = typeof path106 === "string" ? path106 : req.url ? req.url.path || req.url : void 0;
10359
+ const path107 = req.path;
10360
+ _req.url = typeof path107 === "string" ? path107 : req.url ? req.url.path || req.url : void 0;
10361
10361
  }
10362
10362
  if (req.query) {
10363
10363
  _req.query = req.query;
@@ -10522,14 +10522,14 @@ var require_redact = __commonJS({
10522
10522
  }
10523
10523
  return obj;
10524
10524
  }
10525
- function parsePath(path106) {
10525
+ function parsePath(path107) {
10526
10526
  const parts = [];
10527
10527
  let current = "";
10528
10528
  let inBrackets = false;
10529
10529
  let inQuotes = false;
10530
10530
  let quoteChar = "";
10531
- for (let i2 = 0; i2 < path106.length; i2++) {
10532
- const char = path106[i2];
10531
+ for (let i2 = 0; i2 < path107.length; i2++) {
10532
+ const char = path107[i2];
10533
10533
  if (!inBrackets && char === ".") {
10534
10534
  if (current) {
10535
10535
  parts.push(current);
@@ -10660,10 +10660,10 @@ var require_redact = __commonJS({
10660
10660
  return current;
10661
10661
  }
10662
10662
  function redactPaths(obj, paths, censor, remove = false) {
10663
- for (const path106 of paths) {
10664
- const parts = parsePath(path106);
10663
+ for (const path107 of paths) {
10664
+ const parts = parsePath(path107);
10665
10665
  if (parts.includes("*")) {
10666
- redactWildcardPath(obj, parts, censor, path106, remove);
10666
+ redactWildcardPath(obj, parts, censor, path107, remove);
10667
10667
  } else {
10668
10668
  if (remove) {
10669
10669
  removeKey(obj, parts);
@@ -10748,8 +10748,8 @@ var require_redact = __commonJS({
10748
10748
  }
10749
10749
  } else {
10750
10750
  if (afterWildcard.includes("*")) {
10751
- const wrappedCensor = typeof censor === "function" ? (value, path106) => {
10752
- const fullPath = [...pathArray.slice(0, pathLength), ...path106];
10751
+ const wrappedCensor = typeof censor === "function" ? (value, path107) => {
10752
+ const fullPath = [...pathArray.slice(0, pathLength), ...path107];
10753
10753
  return censor(value, fullPath);
10754
10754
  } : censor;
10755
10755
  redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
@@ -10784,8 +10784,8 @@ var require_redact = __commonJS({
10784
10784
  return null;
10785
10785
  }
10786
10786
  const pathStructure = /* @__PURE__ */ new Map();
10787
- for (const path106 of pathsToClone) {
10788
- const parts = parsePath(path106);
10787
+ for (const path107 of pathsToClone) {
10788
+ const parts = parsePath(path107);
10789
10789
  let current = pathStructure;
10790
10790
  for (let i2 = 0; i2 < parts.length; i2++) {
10791
10791
  const part = parts[i2];
@@ -10837,24 +10837,24 @@ var require_redact = __commonJS({
10837
10837
  }
10838
10838
  return cloneSelectively(obj, pathStructure);
10839
10839
  }
10840
- function validatePath(path106) {
10841
- if (typeof path106 !== "string") {
10840
+ function validatePath(path107) {
10841
+ if (typeof path107 !== "string") {
10842
10842
  throw new Error("Paths must be (non-empty) strings");
10843
10843
  }
10844
- if (path106 === "") {
10844
+ if (path107 === "") {
10845
10845
  throw new Error("Invalid redaction path ()");
10846
10846
  }
10847
- if (path106.includes("..")) {
10848
- throw new Error(`Invalid redaction path (${path106})`);
10847
+ if (path107.includes("..")) {
10848
+ throw new Error(`Invalid redaction path (${path107})`);
10849
10849
  }
10850
- if (path106.includes(",")) {
10851
- throw new Error(`Invalid redaction path (${path106})`);
10850
+ if (path107.includes(",")) {
10851
+ throw new Error(`Invalid redaction path (${path107})`);
10852
10852
  }
10853
10853
  let bracketCount = 0;
10854
10854
  let inQuotes = false;
10855
10855
  let quoteChar = "";
10856
- for (let i2 = 0; i2 < path106.length; i2++) {
10857
- const char = path106[i2];
10856
+ for (let i2 = 0; i2 < path107.length; i2++) {
10857
+ const char = path107[i2];
10858
10858
  if ((char === '"' || char === "'") && bracketCount > 0) {
10859
10859
  if (!inQuotes) {
10860
10860
  inQuotes = true;
@@ -10868,20 +10868,20 @@ var require_redact = __commonJS({
10868
10868
  } else if (char === "]" && !inQuotes) {
10869
10869
  bracketCount--;
10870
10870
  if (bracketCount < 0) {
10871
- throw new Error(`Invalid redaction path (${path106})`);
10871
+ throw new Error(`Invalid redaction path (${path107})`);
10872
10872
  }
10873
10873
  }
10874
10874
  }
10875
10875
  if (bracketCount !== 0) {
10876
- throw new Error(`Invalid redaction path (${path106})`);
10876
+ throw new Error(`Invalid redaction path (${path107})`);
10877
10877
  }
10878
10878
  }
10879
10879
  function validatePaths(paths) {
10880
10880
  if (!Array.isArray(paths)) {
10881
10881
  throw new TypeError("paths must be an array");
10882
10882
  }
10883
- for (const path106 of paths) {
10884
- validatePath(path106);
10883
+ for (const path107 of paths) {
10884
+ validatePath(path107);
10885
10885
  }
10886
10886
  }
10887
10887
  function slowRedact(options = {}) {
@@ -11049,8 +11049,8 @@ var require_redaction = __commonJS({
11049
11049
  if (shape[k3] === null) {
11050
11050
  o2[k3] = (value) => topCensor(value, [k3]);
11051
11051
  } else {
11052
- const wrappedCensor = typeof censor === "function" ? (value, path106) => {
11053
- return censor(value, [k3, ...path106]);
11052
+ const wrappedCensor = typeof censor === "function" ? (value, path107) => {
11053
+ return censor(value, [k3, ...path107]);
11054
11054
  } : censor;
11055
11055
  o2[k3] = Redact({
11056
11056
  paths: shape[k3],
@@ -11268,10 +11268,10 @@ var require_atomic_sleep = __commonJS({
11268
11268
  var require_sonic_boom = __commonJS({
11269
11269
  "../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
11270
11270
  "use strict";
11271
- var fs95 = require("fs");
11271
+ var fs96 = require("fs");
11272
11272
  var EventEmitter2 = require("events");
11273
11273
  var inherits = require("util").inherits;
11274
- var path106 = require("path");
11274
+ var path107 = require("path");
11275
11275
  var sleep2 = require_atomic_sleep();
11276
11276
  var assert = require("assert");
11277
11277
  var BUSY_WRITE_TIMEOUT = 100;
@@ -11325,20 +11325,20 @@ var require_sonic_boom = __commonJS({
11325
11325
  const mode = sonic.mode;
11326
11326
  if (sonic.sync) {
11327
11327
  try {
11328
- if (sonic.mkdir) fs95.mkdirSync(path106.dirname(file), { recursive: true });
11329
- const fd = fs95.openSync(file, flags, mode);
11328
+ if (sonic.mkdir) fs96.mkdirSync(path107.dirname(file), { recursive: true });
11329
+ const fd = fs96.openSync(file, flags, mode);
11330
11330
  fileOpened(null, fd);
11331
11331
  } catch (err) {
11332
11332
  fileOpened(err);
11333
11333
  throw err;
11334
11334
  }
11335
11335
  } else if (sonic.mkdir) {
11336
- fs95.mkdir(path106.dirname(file), { recursive: true }, (err) => {
11336
+ fs96.mkdir(path107.dirname(file), { recursive: true }, (err) => {
11337
11337
  if (err) return fileOpened(err);
11338
- fs95.open(file, flags, mode, fileOpened);
11338
+ fs96.open(file, flags, mode, fileOpened);
11339
11339
  });
11340
11340
  } else {
11341
- fs95.open(file, flags, mode, fileOpened);
11341
+ fs96.open(file, flags, mode, fileOpened);
11342
11342
  }
11343
11343
  }
11344
11344
  function SonicBoom(opts) {
@@ -11379,8 +11379,8 @@ var require_sonic_boom = __commonJS({
11379
11379
  this.flush = flushBuffer;
11380
11380
  this.flushSync = flushBufferSync;
11381
11381
  this._actualWrite = actualWriteBuffer;
11382
- fsWriteSync = () => fs95.writeSync(this.fd, this._writingBuf);
11383
- fsWrite = () => fs95.write(this.fd, this._writingBuf, this.release);
11382
+ fsWriteSync = () => fs96.writeSync(this.fd, this._writingBuf);
11383
+ fsWrite = () => fs96.write(this.fd, this._writingBuf, this.release);
11384
11384
  } else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
11385
11385
  this._writingBuf = "";
11386
11386
  this.write = write;
@@ -11389,15 +11389,15 @@ var require_sonic_boom = __commonJS({
11389
11389
  this._actualWrite = actualWrite;
11390
11390
  fsWriteSync = () => {
11391
11391
  if (Buffer.isBuffer(this._writingBuf)) {
11392
- return fs95.writeSync(this.fd, this._writingBuf);
11392
+ return fs96.writeSync(this.fd, this._writingBuf);
11393
11393
  }
11394
- return fs95.writeSync(this.fd, this._writingBuf, "utf8");
11394
+ return fs96.writeSync(this.fd, this._writingBuf, "utf8");
11395
11395
  };
11396
11396
  fsWrite = () => {
11397
11397
  if (Buffer.isBuffer(this._writingBuf)) {
11398
- return fs95.write(this.fd, this._writingBuf, this.release);
11398
+ return fs96.write(this.fd, this._writingBuf, this.release);
11399
11399
  }
11400
- return fs95.write(this.fd, this._writingBuf, "utf8", this.release);
11400
+ return fs96.write(this.fd, this._writingBuf, "utf8", this.release);
11401
11401
  };
11402
11402
  } else {
11403
11403
  throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
@@ -11454,7 +11454,7 @@ var require_sonic_boom = __commonJS({
11454
11454
  }
11455
11455
  }
11456
11456
  if (this._fsync) {
11457
- fs95.fsyncSync(this.fd);
11457
+ fs96.fsyncSync(this.fd);
11458
11458
  }
11459
11459
  const len = this._len;
11460
11460
  if (this._reopening) {
@@ -11568,7 +11568,7 @@ var require_sonic_boom = __commonJS({
11568
11568
  const onDrain = () => {
11569
11569
  if (!this._fsync) {
11570
11570
  try {
11571
- fs95.fsync(this.fd, (err) => {
11571
+ fs96.fsync(this.fd, (err) => {
11572
11572
  this._flushPending = false;
11573
11573
  cb(err);
11574
11574
  });
@@ -11670,7 +11670,7 @@ var require_sonic_boom = __commonJS({
11670
11670
  const fd = this.fd;
11671
11671
  this.once("ready", () => {
11672
11672
  if (fd !== this.fd) {
11673
- fs95.close(fd, (err) => {
11673
+ fs96.close(fd, (err) => {
11674
11674
  if (err) {
11675
11675
  return this.emit("error", err);
11676
11676
  }
@@ -11719,7 +11719,7 @@ var require_sonic_boom = __commonJS({
11719
11719
  buf = this._bufs[0];
11720
11720
  }
11721
11721
  try {
11722
- const n2 = Buffer.isBuffer(buf) ? fs95.writeSync(this.fd, buf) : fs95.writeSync(this.fd, buf, "utf8");
11722
+ const n2 = Buffer.isBuffer(buf) ? fs96.writeSync(this.fd, buf) : fs96.writeSync(this.fd, buf, "utf8");
11723
11723
  const releasedBufObj = releaseWritingBuf(buf, this._len, n2);
11724
11724
  buf = releasedBufObj.writingBuf;
11725
11725
  this._len = releasedBufObj.len;
@@ -11735,7 +11735,7 @@ var require_sonic_boom = __commonJS({
11735
11735
  }
11736
11736
  }
11737
11737
  try {
11738
- fs95.fsyncSync(this.fd);
11738
+ fs96.fsyncSync(this.fd);
11739
11739
  } catch {
11740
11740
  }
11741
11741
  }
@@ -11756,7 +11756,7 @@ var require_sonic_boom = __commonJS({
11756
11756
  buf = mergeBuf(this._bufs[0], this._lens[0]);
11757
11757
  }
11758
11758
  try {
11759
- const n2 = fs95.writeSync(this.fd, buf);
11759
+ const n2 = fs96.writeSync(this.fd, buf);
11760
11760
  buf = buf.subarray(n2);
11761
11761
  this._len = Math.max(this._len - n2, 0);
11762
11762
  if (buf.length <= 0) {
@@ -11784,13 +11784,13 @@ var require_sonic_boom = __commonJS({
11784
11784
  this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
11785
11785
  if (this.sync) {
11786
11786
  try {
11787
- const written = Buffer.isBuffer(this._writingBuf) ? fs95.writeSync(this.fd, this._writingBuf) : fs95.writeSync(this.fd, this._writingBuf, "utf8");
11787
+ const written = Buffer.isBuffer(this._writingBuf) ? fs96.writeSync(this.fd, this._writingBuf) : fs96.writeSync(this.fd, this._writingBuf, "utf8");
11788
11788
  release2(null, written);
11789
11789
  } catch (err) {
11790
11790
  release2(err);
11791
11791
  }
11792
11792
  } else {
11793
- fs95.write(this.fd, this._writingBuf, release2);
11793
+ fs96.write(this.fd, this._writingBuf, release2);
11794
11794
  }
11795
11795
  }
11796
11796
  function actualWriteBuffer() {
@@ -11799,7 +11799,7 @@ var require_sonic_boom = __commonJS({
11799
11799
  this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
11800
11800
  if (this.sync) {
11801
11801
  try {
11802
- const written = fs95.writeSync(this.fd, this._writingBuf);
11802
+ const written = fs96.writeSync(this.fd, this._writingBuf);
11803
11803
  release2(null, written);
11804
11804
  } catch (err) {
11805
11805
  release2(err);
@@ -11808,7 +11808,7 @@ var require_sonic_boom = __commonJS({
11808
11808
  if (kCopyBuffer) {
11809
11809
  this._writingBuf = Buffer.from(this._writingBuf);
11810
11810
  }
11811
- fs95.write(this.fd, this._writingBuf, release2);
11811
+ fs96.write(this.fd, this._writingBuf, release2);
11812
11812
  }
11813
11813
  }
11814
11814
  function actualClose(sonic) {
@@ -11824,12 +11824,12 @@ var require_sonic_boom = __commonJS({
11824
11824
  sonic._lens = [];
11825
11825
  assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
11826
11826
  try {
11827
- fs95.fsync(sonic.fd, closeWrapped);
11827
+ fs96.fsync(sonic.fd, closeWrapped);
11828
11828
  } catch {
11829
11829
  }
11830
11830
  function closeWrapped() {
11831
11831
  if (sonic.fd !== 1 && sonic.fd !== 2) {
11832
- fs95.close(sonic.fd, done);
11832
+ fs96.close(sonic.fd, done);
11833
11833
  } else {
11834
11834
  done();
11835
11835
  }
@@ -14964,11 +14964,11 @@ var init_lib = __esm({
14964
14964
  }
14965
14965
  }
14966
14966
  },
14967
- addToPath: function addToPath(path106, added, removed, oldPosInc, options) {
14968
- var last = path106.lastComponent;
14967
+ addToPath: function addToPath(path107, added, removed, oldPosInc, options) {
14968
+ var last = path107.lastComponent;
14969
14969
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
14970
14970
  return {
14971
- oldPos: path106.oldPos + oldPosInc,
14971
+ oldPos: path107.oldPos + oldPosInc,
14972
14972
  lastComponent: {
14973
14973
  count: last.count + 1,
14974
14974
  added,
@@ -14978,7 +14978,7 @@ var init_lib = __esm({
14978
14978
  };
14979
14979
  } else {
14980
14980
  return {
14981
- oldPos: path106.oldPos + oldPosInc,
14981
+ oldPos: path107.oldPos + oldPosInc,
14982
14982
  lastComponent: {
14983
14983
  count: 1,
14984
14984
  added,
@@ -15560,10 +15560,10 @@ function attachmentToHistoryMessage(o2, ts) {
15560
15560
  const memories = raw.map((m3) => {
15561
15561
  if (!m3 || typeof m3 !== "object") return null;
15562
15562
  const rec6 = m3;
15563
- const path106 = typeof rec6.path === "string" ? rec6.path : null;
15563
+ const path107 = typeof rec6.path === "string" ? rec6.path : null;
15564
15564
  const content = typeof rec6.content === "string" ? rec6.content : null;
15565
- if (!path106 || content == null) return null;
15566
- const entry = { path: path106, content };
15565
+ if (!path107 || content == null) return null;
15566
+ const entry = { path: path107, content };
15567
15567
  if (typeof rec6.mtimeMs === "number") entry.mtimeMs = rec6.mtimeMs;
15568
15568
  return entry;
15569
15569
  }).filter((m3) => m3 !== null);
@@ -16429,10 +16429,10 @@ function parseAttachment(obj) {
16429
16429
  const memories = raw.map((m3) => {
16430
16430
  if (!m3 || typeof m3 !== "object") return null;
16431
16431
  const rec6 = m3;
16432
- const path106 = typeof rec6.path === "string" ? rec6.path : null;
16432
+ const path107 = typeof rec6.path === "string" ? rec6.path : null;
16433
16433
  const content = typeof rec6.content === "string" ? rec6.content : null;
16434
- if (!path106 || content == null) return null;
16435
- const out = { path: path106, content };
16434
+ if (!path107 || content == null) return null;
16435
+ const out = { path: path107, content };
16436
16436
  if (typeof rec6.mtimeMs === "number") out.mtimeMs = rec6.mtimeMs;
16437
16437
  return out;
16438
16438
  }).filter((m3) => m3 !== null);
@@ -37406,8 +37406,8 @@ var require_utils = __commonJS({
37406
37406
  var result = transform[inputType][outputType](input);
37407
37407
  return result;
37408
37408
  };
37409
- exports2.resolve = function(path106) {
37410
- var parts = path106.split("/");
37409
+ exports2.resolve = function(path107) {
37410
+ var parts = path107.split("/");
37411
37411
  var result = [];
37412
37412
  for (var index = 0; index < parts.length; index++) {
37413
37413
  var part = parts[index];
@@ -43260,18 +43260,18 @@ var require_object = __commonJS({
43260
43260
  var object = new ZipObject(name, zipObjectContent, o2);
43261
43261
  this.files[name] = object;
43262
43262
  };
43263
- var parentFolder = function(path106) {
43264
- if (path106.slice(-1) === "/") {
43265
- path106 = path106.substring(0, path106.length - 1);
43263
+ var parentFolder = function(path107) {
43264
+ if (path107.slice(-1) === "/") {
43265
+ path107 = path107.substring(0, path107.length - 1);
43266
43266
  }
43267
- var lastSlash = path106.lastIndexOf("/");
43268
- return lastSlash > 0 ? path106.substring(0, lastSlash) : "";
43267
+ var lastSlash = path107.lastIndexOf("/");
43268
+ return lastSlash > 0 ? path107.substring(0, lastSlash) : "";
43269
43269
  };
43270
- var forceTrailingSlash = function(path106) {
43271
- if (path106.slice(-1) !== "/") {
43272
- path106 += "/";
43270
+ var forceTrailingSlash = function(path107) {
43271
+ if (path107.slice(-1) !== "/") {
43272
+ path107 += "/";
43273
43273
  }
43274
- return path106;
43274
+ return path107;
43275
43275
  };
43276
43276
  var folderAdd = function(name, createFolders) {
43277
43277
  createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
@@ -44273,7 +44273,7 @@ var require_lib3 = __commonJS({
44273
44273
  // src/run-case/recorder.ts
44274
44274
  function startRunCaseRecorder(opts) {
44275
44275
  const now = opts.now ?? Date.now;
44276
- const dir = import_node_path85.default.dirname(opts.recordPath);
44276
+ const dir = import_node_path86.default.dirname(opts.recordPath);
44277
44277
  let stream = null;
44278
44278
  let closing = false;
44279
44279
  let closedSettled = false;
@@ -44287,8 +44287,8 @@ function startRunCaseRecorder(opts) {
44287
44287
  });
44288
44288
  const ensureStream = () => {
44289
44289
  if (stream) return stream;
44290
- import_node_fs66.default.mkdirSync(dir, { recursive: true });
44291
- stream = import_node_fs66.default.createWriteStream(opts.recordPath, { flags: "a" });
44290
+ import_node_fs67.default.mkdirSync(dir, { recursive: true });
44291
+ stream = import_node_fs67.default.createWriteStream(opts.recordPath, { flags: "a" });
44292
44292
  stream.on("close", () => closedResolve());
44293
44293
  return stream;
44294
44294
  };
@@ -44313,12 +44313,12 @@ function startRunCaseRecorder(opts) {
44313
44313
  };
44314
44314
  return { tap, close, closed };
44315
44315
  }
44316
- var import_node_fs66, import_node_path85;
44316
+ var import_node_fs67, import_node_path86;
44317
44317
  var init_recorder = __esm({
44318
44318
  "src/run-case/recorder.ts"() {
44319
44319
  "use strict";
44320
- import_node_fs66 = __toESM(require("fs"), 1);
44321
- import_node_path85 = __toESM(require("path"), 1);
44320
+ import_node_fs67 = __toESM(require("fs"), 1);
44321
+ import_node_path86 = __toESM(require("path"), 1);
44322
44322
  }
44323
44323
  });
44324
44324
 
@@ -44361,7 +44361,7 @@ var init_wire = __esm({
44361
44361
  // src/run-case/controller.ts
44362
44362
  async function runController(opts) {
44363
44363
  const now = opts.now ?? Date.now;
44364
- const cwd = opts.cwd ?? (0, import_node_fs67.mkdtempSync)(import_node_path86.default.join(import_node_os32.default.tmpdir(), "clawd-runcase-"));
44364
+ const cwd = opts.cwd ?? (0, import_node_fs68.mkdtempSync)(import_node_path87.default.join(import_node_os32.default.tmpdir(), "clawd-runcase-"));
44365
44365
  const ownsCwd = opts.cwd === void 0;
44366
44366
  const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
44367
44367
  const spawnCtx = { cwd };
@@ -44522,19 +44522,19 @@ async function runController(opts) {
44522
44522
  if (sigintHandler) process.off("SIGINT", sigintHandler);
44523
44523
  if (ownsCwd) {
44524
44524
  try {
44525
- (0, import_node_fs67.rmSync)(cwd, { recursive: true, force: true });
44525
+ (0, import_node_fs68.rmSync)(cwd, { recursive: true, force: true });
44526
44526
  } catch {
44527
44527
  }
44528
44528
  }
44529
44529
  return exitCode ?? 0;
44530
44530
  }
44531
- var import_node_fs67, import_node_os32, import_node_path86;
44531
+ var import_node_fs68, import_node_os32, import_node_path87;
44532
44532
  var init_controller = __esm({
44533
44533
  "src/run-case/controller.ts"() {
44534
44534
  "use strict";
44535
- import_node_fs67 = require("fs");
44535
+ import_node_fs68 = require("fs");
44536
44536
  import_node_os32 = __toESM(require("os"), 1);
44537
- import_node_path86 = __toESM(require("path"), 1);
44537
+ import_node_path87 = __toESM(require("path"), 1);
44538
44538
  init_claude();
44539
44539
  init_stdout_splitter();
44540
44540
  init_permission_stdio();
@@ -44806,8 +44806,8 @@ Env (advanced):
44806
44806
  `;
44807
44807
 
44808
44808
  // src/index.ts
44809
- var import_node_path84 = __toESM(require("path"), 1);
44810
- var import_node_fs65 = __toESM(require("fs"), 1);
44809
+ var import_node_path85 = __toESM(require("path"), 1);
44810
+ var import_node_fs66 = __toESM(require("fs"), 1);
44811
44811
  var import_node_os31 = __toESM(require("os"), 1);
44812
44812
  var import_node_crypto27 = require("crypto");
44813
44813
  var import_node_url6 = require("url");
@@ -52906,9 +52906,9 @@ var CentralClientError = class extends Error {
52906
52906
  cause;
52907
52907
  status;
52908
52908
  };
52909
- async function centralRequest(opts, path106, init) {
52909
+ async function centralRequest(opts, path107, init) {
52910
52910
  const f2 = opts.fetchImpl ?? globalThis.fetch;
52911
- const url = `${opts.api.replace(/\/+$/, "")}${path106}`;
52911
+ const url = `${opts.api.replace(/\/+$/, "")}${path107}`;
52912
52912
  const ctrl = new AbortController();
52913
52913
  const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
52914
52914
  let res;
@@ -53944,8 +53944,8 @@ function turnStartInput(text, resolveImage) {
53944
53944
  const items = [];
53945
53945
  let leftover = text;
53946
53946
  for (const m3 of text.matchAll(SKILL_RE)) {
53947
- const [marker, name, path106] = m3;
53948
- items.push({ type: "skill", name, path: path106 });
53947
+ const [marker, name, path107] = m3;
53948
+ items.push({ type: "skill", name, path: path107 });
53949
53949
  leftover = leftover.replace(marker, "");
53950
53950
  }
53951
53951
  for (const m3 of text.matchAll(ATTACHMENT_RE2)) {
@@ -61320,10 +61320,10 @@ function createGithubApi(args) {
61320
61320
  const doFetch = args.fetch ?? fetch;
61321
61321
  const seal = args.seal ?? sealWithSodium;
61322
61322
  const timeoutMs = args.timeoutMs ?? TIMEOUT_MS;
61323
- async function request(method, path106, body) {
61323
+ async function request(method, path107, body) {
61324
61324
  let res;
61325
61325
  try {
61326
- res = await doFetch(`${API}${path106}`, {
61326
+ res = await doFetch(`${API}${path107}`, {
61327
61327
  method,
61328
61328
  headers: {
61329
61329
  Authorization: `Bearer ${args.token}`,
@@ -61348,8 +61348,8 @@ function createGithubApi(args) {
61348
61348
  }
61349
61349
  return { status: res.status, json };
61350
61350
  }
61351
- async function must(method, path106, what, body) {
61352
- const r2 = await request(method, path106, body);
61351
+ async function must(method, path107, what, body) {
61352
+ const r2 = await request(method, path107, body);
61353
61353
  if (r2.status < 200 || r2.status >= 300) throw new GithubApiError(r2.status, explain(r2.status, what, r2.json));
61354
61354
  return r2.json;
61355
61355
  }
@@ -61394,9 +61394,9 @@ function createGithubApi(args) {
61394
61394
  return { env: x2.name, ...Number.isFinite(at3) ? { setAt: at3 } : {} };
61395
61395
  });
61396
61396
  },
61397
- async getJson(path106) {
61397
+ async getJson(path107) {
61398
61398
  try {
61399
- const r2 = await request("GET", path106);
61399
+ const r2 = await request("GET", path107);
61400
61400
  return r2.status >= 200 && r2.status < 300 ? r2.json : void 0;
61401
61401
  } catch {
61402
61402
  return void 0;
@@ -62654,16 +62654,364 @@ function buildDeployHandlers(deps) {
62654
62654
  }
62655
62655
 
62656
62656
  // src/tools/subscription-channels-store.ts
62657
+ var import_node_fs36 = __toESM(require("fs"), 1);
62658
+ var import_node_os13 = __toESM(require("os"), 1);
62659
+ var import_node_path41 = __toESM(require("path"), 1);
62660
+
62661
+ // src/tools/subscription-channels-apply.ts
62657
62662
  var import_node_fs35 = __toESM(require("fs"), 1);
62658
62663
  var import_node_os12 = __toESM(require("os"), 1);
62659
62664
  var import_node_path40 = __toESM(require("path"), 1);
62665
+
62666
+ // src/tools/codex-config-toml.ts
62667
+ function parseKey(src, start) {
62668
+ const parts = [];
62669
+ let i2 = start;
62670
+ for (; ; ) {
62671
+ while (src[i2] === " " || src[i2] === " ") i2++;
62672
+ let part;
62673
+ if (src[i2] === '"') {
62674
+ let j2 = i2 + 1;
62675
+ while (j2 < src.length && src[j2] !== '"') j2 += src[j2] === "\\" ? 2 : 1;
62676
+ if (j2 >= src.length) return null;
62677
+ try {
62678
+ part = JSON.parse(src.slice(i2, j2 + 1));
62679
+ } catch {
62680
+ part = src.slice(i2 + 1, j2);
62681
+ }
62682
+ i2 = j2 + 1;
62683
+ } else if (src[i2] === "'") {
62684
+ const j2 = src.indexOf("'", i2 + 1);
62685
+ if (j2 < 0) return null;
62686
+ part = src.slice(i2 + 1, j2);
62687
+ i2 = j2 + 1;
62688
+ } else {
62689
+ const bare = /^[A-Za-z0-9_-]+/.exec(src.slice(i2));
62690
+ if (!bare) return null;
62691
+ part = bare[0];
62692
+ i2 += part.length;
62693
+ }
62694
+ parts.push(part);
62695
+ while (src[i2] === " " || src[i2] === " ") i2++;
62696
+ if (src[i2] !== ".") return { parts, end: i2 };
62697
+ i2++;
62698
+ }
62699
+ }
62700
+ function tableHeader(line) {
62701
+ const open = /^\s*(\[\[?)/.exec(line);
62702
+ if (!open) return null;
62703
+ const key = parseKey(line, open[0].length);
62704
+ if (!key) return null;
62705
+ const close = open[1] === "[[" ? "]]" : "]";
62706
+ if (!line.startsWith(close, key.end)) return null;
62707
+ return /^\s*(?:#.*)?$/.test(line.slice(key.end + close.length)) ? key.parts : null;
62708
+ }
62709
+ function keyLine(line) {
62710
+ const lead = /^\s*/.exec(line)[0].length;
62711
+ if (line[lead] === "[" || line[lead] === "#") return null;
62712
+ const key = parseKey(line, lead);
62713
+ return key && line[key.end] === "=" ? { parts: key.parts, valueStart: key.end + 1 } : null;
62714
+ }
62715
+ function scanValue(s2, start, st2) {
62716
+ let i2 = start;
62717
+ while (i2 < s2.length) {
62718
+ if (st2.ml) {
62719
+ if (st2.ml === '"""' && s2[i2] === "\\") {
62720
+ i2 += 2;
62721
+ continue;
62722
+ }
62723
+ if (s2.startsWith(st2.ml, i2)) {
62724
+ let j2 = i2 + 3;
62725
+ while (j2 < s2.length && j2 < i2 + 5 && s2[j2] === st2.ml[0]) j2++;
62726
+ st2.ml = null;
62727
+ i2 = j2;
62728
+ continue;
62729
+ }
62730
+ i2++;
62731
+ continue;
62732
+ }
62733
+ const c2 = s2[i2];
62734
+ if (c2 === "#") return;
62735
+ if (s2.startsWith('"""', i2) || s2.startsWith("'''", i2)) {
62736
+ st2.ml = s2.slice(i2, i2 + 3);
62737
+ i2 += 3;
62738
+ continue;
62739
+ }
62740
+ if (c2 === '"') {
62741
+ i2++;
62742
+ while (i2 < s2.length && s2[i2] !== '"') i2 += s2[i2] === "\\" ? 2 : 1;
62743
+ i2++;
62744
+ continue;
62745
+ }
62746
+ if (c2 === "'") {
62747
+ const j2 = s2.indexOf("'", i2 + 1);
62748
+ i2 = j2 < 0 ? s2.length : j2 + 1;
62749
+ continue;
62750
+ }
62751
+ if (c2 === "[" || c2 === "{") st2.depth++;
62752
+ else if ((c2 === "]" || c2 === "}") && st2.depth > 0) st2.depth--;
62753
+ i2++;
62754
+ }
62755
+ }
62756
+ function scanToml(text) {
62757
+ const out = [];
62758
+ const st2 = { ml: null, depth: 0 };
62759
+ let table = [];
62760
+ for (const line of text.split("\n")) {
62761
+ if (st2.ml || st2.depth > 0) {
62762
+ scanValue(line, 0, st2);
62763
+ out.push({ text: line, kind: "continuation", table });
62764
+ continue;
62765
+ }
62766
+ const header = tableHeader(line);
62767
+ if (header) {
62768
+ table = header;
62769
+ out.push({ text: line, kind: "header", table, key: header });
62770
+ continue;
62771
+ }
62772
+ const key = keyLine(line);
62773
+ if (key) {
62774
+ scanValue(line, key.valueStart, st2);
62775
+ out.push({ text: line, kind: "key", table, key: key.parts, value: line.slice(key.valueStart) });
62776
+ continue;
62777
+ }
62778
+ out.push({ text: line, kind: "other", table });
62779
+ }
62780
+ return out;
62781
+ }
62782
+ var UNREADABLE = /* @__PURE__ */ Symbol("unreadable TOML value");
62783
+ function parseTomlValue(raw) {
62784
+ const parsed = parseValueAt(raw, 0);
62785
+ if (!parsed) return void 0;
62786
+ return /^\s*(?:#[^\n]*)?\s*$/.test(raw.slice(parsed.end)) ? parsed.value : void 0;
62787
+ }
62788
+ function skipSeparators(s2, start) {
62789
+ let i2 = start;
62790
+ for (; ; ) {
62791
+ while (i2 < s2.length && " \r\n,".includes(s2[i2])) i2++;
62792
+ if (s2[i2] !== "#") return i2;
62793
+ const newline = s2.indexOf("\n", i2);
62794
+ i2 = newline < 0 ? s2.length : newline;
62795
+ }
62796
+ }
62797
+ function parseValueAt(s2, start) {
62798
+ let i2 = start;
62799
+ while (s2[i2] === " " || s2[i2] === " ") i2++;
62800
+ const c2 = s2[i2];
62801
+ if (c2 === '"') {
62802
+ if (s2.startsWith('"""', i2)) return null;
62803
+ let j2 = i2 + 1;
62804
+ while (j2 < s2.length && s2[j2] !== '"') j2 += s2[j2] === "\\" ? 2 : 1;
62805
+ if (j2 >= s2.length) return null;
62806
+ try {
62807
+ return { value: JSON.parse(s2.slice(i2, j2 + 1)), end: j2 + 1 };
62808
+ } catch {
62809
+ return null;
62810
+ }
62811
+ }
62812
+ if (c2 === "'") {
62813
+ if (s2.startsWith("'''", i2)) return null;
62814
+ const j2 = s2.indexOf("'", i2 + 1);
62815
+ return j2 < 0 ? null : { value: s2.slice(i2 + 1, j2), end: j2 + 1 };
62816
+ }
62817
+ if (c2 === "[") {
62818
+ const items = [];
62819
+ i2++;
62820
+ for (; ; ) {
62821
+ i2 = skipSeparators(s2, i2);
62822
+ if (s2[i2] === "]") return { value: items, end: i2 + 1 };
62823
+ const item = parseValueAt(s2, i2);
62824
+ if (!item) return null;
62825
+ items.push(item.value);
62826
+ i2 = item.end;
62827
+ }
62828
+ }
62829
+ if (c2 === "{") {
62830
+ const table = {};
62831
+ i2++;
62832
+ for (; ; ) {
62833
+ i2 = skipSeparators(s2, i2);
62834
+ if (s2[i2] === "}") return { value: table, end: i2 + 1 };
62835
+ const key = parseKey(s2, i2);
62836
+ if (!key || s2[key.end] !== "=") return null;
62837
+ const item = parseValueAt(s2, key.end + 1);
62838
+ if (!item) return null;
62839
+ setPath(table, key.parts, item.value);
62840
+ i2 = item.end;
62841
+ }
62842
+ }
62843
+ const bare = /^[^\s,\]}#]+/.exec(s2.slice(i2));
62844
+ return bare ? { value: bare[0], end: i2 + bare[0].length } : null;
62845
+ }
62846
+ function setPath(target, path107, value) {
62847
+ let node = target;
62848
+ for (const part of path107.slice(0, -1)) {
62849
+ const next = node[part];
62850
+ if (!next || typeof next !== "object" || Array.isArray(next)) node[part] = {};
62851
+ node = node[part];
62852
+ }
62853
+ const last = path107[path107.length - 1];
62854
+ const existing = node[last];
62855
+ if (existing && typeof existing === "object" && !Array.isArray(existing) && value && typeof value === "object" && !Array.isArray(value)) {
62856
+ Object.assign(existing, value);
62857
+ } else node[last] = value;
62858
+ }
62859
+ function readTomlTable(text, path107) {
62860
+ const result = {};
62861
+ let found = false;
62862
+ const within = (full) => full.length >= path107.length && path107.every((part, i2) => full[i2] === part);
62863
+ const lines = scanToml(text);
62864
+ for (let index = 0; index < lines.length; index++) {
62865
+ const line = lines[index];
62866
+ if (line.kind === "header" && within(line.key)) {
62867
+ found = true;
62868
+ if (line.key.length > path107.length) setPath(result, line.key.slice(path107.length), {});
62869
+ continue;
62870
+ }
62871
+ if (line.kind !== "key") continue;
62872
+ const full = [...line.table, ...line.key];
62873
+ if (!within(full)) continue;
62874
+ let raw = line.value;
62875
+ while (lines[index + 1]?.kind === "continuation") raw += `
62876
+ ${lines[++index].text}`;
62877
+ const parsed = parseTomlValue(raw);
62878
+ const value = parsed === void 0 ? UNREADABLE : parsed;
62879
+ found = true;
62880
+ if (full.length === path107.length) {
62881
+ if (value && typeof value === "object" && !Array.isArray(value)) Object.assign(result, value);
62882
+ } else setPath(result, full.slice(path107.length), value);
62883
+ }
62884
+ return found ? result : null;
62885
+ }
62886
+
62887
+ // src/tools/subscription-channels-apply.ts
62888
+ var PROVIDER_ID = "cliproxyapi";
62889
+ var isOwnProvider = (path107) => path107[0] === "model_providers" && path107[1] === PROVIDER_ID;
62890
+ function stripCodexProvider(text) {
62891
+ const out = [];
62892
+ let dropping = false;
62893
+ let droppingValue = false;
62894
+ for (const line of scanToml(text)) {
62895
+ if (line.kind === "header") {
62896
+ dropping = isOwnProvider(line.key);
62897
+ droppingValue = false;
62898
+ if (!dropping) out.push(line.text);
62899
+ continue;
62900
+ }
62901
+ if (line.kind === "continuation") {
62902
+ if (!dropping && !droppingValue) out.push(line.text);
62903
+ continue;
62904
+ }
62905
+ if (dropping) continue;
62906
+ if (line.kind === "key") {
62907
+ const full = [...line.table, ...line.key];
62908
+ droppingValue = full.length === 1 && full[0] === "model_provider" || isOwnProvider(full);
62909
+ if (!droppingValue) out.push(line.text);
62910
+ continue;
62911
+ }
62912
+ out.push(line.text);
62913
+ }
62914
+ return out.join("\n").trim();
62915
+ }
62916
+ function writeFileAtomic(file, data) {
62917
+ const target = import_node_fs35.default.existsSync(file) && import_node_fs35.default.lstatSync(file).isSymbolicLink() ? import_node_fs35.default.realpathSync(file) : file;
62918
+ const tmp = `${target}.tmp.${process.pid}.${Date.now()}`;
62919
+ import_node_fs35.default.writeFileSync(tmp, data, { mode: 384 });
62920
+ import_node_fs35.default.renameSync(tmp, target);
62921
+ }
62922
+ function snapshotFile(file) {
62923
+ const original = import_node_fs35.default.existsSync(file) ? import_node_fs35.default.readFileSync(file) : null;
62924
+ return () => {
62925
+ const current = import_node_fs35.default.existsSync(file) ? import_node_fs35.default.readFileSync(file) : null;
62926
+ if (original === null) {
62927
+ if (current !== null) import_node_fs35.default.rmSync(file, { force: true });
62928
+ return;
62929
+ }
62930
+ if (current !== null && current.equals(original)) return;
62931
+ writeFileAtomic(file, original);
62932
+ };
62933
+ }
62934
+ var resolveCodexHome2 = (codexHome) => codexHome || process.env.CODEX_HOME || import_node_path40.default.join(import_node_os12.default.homedir(), ".codex");
62935
+ var resolvePiAgentDir = (agentDir) => agentDir || process.env.PI_CODING_AGENT_DIR || import_node_path40.default.join(import_node_os12.default.homedir(), ".pi", "agent");
62936
+ var PI_SUBSCRIPTION_FILE = "cliproxyapi.json";
62937
+ function applyCodexSubscriptionChannel(opts) {
62938
+ const codexHome = resolveCodexHome2(opts.codexHome);
62939
+ import_node_fs35.default.mkdirSync(codexHome, { recursive: true });
62940
+ const configFile = import_node_path40.default.join(codexHome, "config.toml");
62941
+ const original = import_node_fs35.default.existsSync(configFile) ? import_node_fs35.default.readFileSync(configFile, "utf8") : "";
62942
+ const rest = stripCodexProvider(original);
62943
+ let content;
62944
+ if (opts.channel) {
62945
+ const ch = opts.channel;
62946
+ content = [
62947
+ `model_provider = "${PROVIDER_ID}"`,
62948
+ ...rest ? ["", rest] : [],
62949
+ "",
62950
+ `[model_providers.${PROVIDER_ID}]`,
62951
+ `name = "${PROVIDER_ID}"`,
62952
+ `base_url = ${JSON.stringify(ch.baseUrl)}`,
62953
+ 'wire_api = "responses"',
62954
+ `auth = { command = "echo", args = [${JSON.stringify(ch.apiKey)}] }`,
62955
+ ""
62956
+ ].join("\n");
62957
+ } else {
62958
+ content = [
62959
+ 'model_provider = "openai"',
62960
+ ...rest ? ["", rest] : [],
62961
+ ""
62962
+ ].join("\n");
62963
+ }
62964
+ writeFileAtomic(configFile, content);
62965
+ }
62966
+ function applyPiSubscriptionChannel(opts) {
62967
+ const agentDir = resolvePiAgentDir(opts.agentDir);
62968
+ if (!import_node_fs35.default.existsSync(agentDir)) return false;
62969
+ const configFile = import_node_path40.default.join(agentDir, PI_SUBSCRIPTION_FILE);
62970
+ if (opts.channel) {
62971
+ const data = { baseUrl: opts.channel.baseUrl, apiKey: opts.channel.apiKey };
62972
+ writeFileAtomic(configFile, JSON.stringify(data, null, 2) + "\n");
62973
+ return true;
62974
+ }
62975
+ return false;
62976
+ }
62977
+
62978
+ // src/tools/subscription-channels-store.ts
62660
62979
  var CHANNELS_FILE_NAME = "subscription-channels.json";
62980
+ function providerKey(provider, codexHome) {
62981
+ if ([provider.env_key, provider.experimental_bearer_token, provider.auth].includes(UNREADABLE)) return null;
62982
+ const envKey = typeof provider.env_key === "string" && provider.env_key ? provider.env_key : null;
62983
+ if (envKey) return process.env[envKey] || null;
62984
+ const inline = provider.experimental_bearer_token;
62985
+ if (typeof inline === "string" && inline) return inline;
62986
+ if (provider.auth !== void 0) {
62987
+ const auth = provider.auth;
62988
+ const args = auth?.args;
62989
+ if (auth?.command !== "echo" || !Array.isArray(args) || args.length !== 1) return null;
62990
+ const [arg] = args;
62991
+ if (typeof arg !== "string" || /^-[neE]+$/.test(arg)) return null;
62992
+ return arg.trim() || null;
62993
+ }
62994
+ return readAuthKey2(codexHome);
62995
+ }
62996
+ function readAuthKey2(codexHome) {
62997
+ try {
62998
+ const key = JSON.parse(import_node_fs36.default.readFileSync(import_node_path41.default.join(codexHome, "auth.json"), "utf8")).OPENAI_API_KEY;
62999
+ return typeof key === "string" && key ? key : null;
63000
+ } catch {
63001
+ return null;
63002
+ }
63003
+ }
62661
63004
  var SubscriptionChannelStore = class {
62662
63005
  filePath;
62663
63006
  codexHome;
62664
63007
  constructor(options) {
62665
- this.filePath = import_node_path40.default.join(options.dataDir, CHANNELS_FILE_NAME);
62666
- this.codexHome = options.codexHome || process.env.CODEX_HOME || import_node_path40.default.join(import_node_os12.default.homedir(), ".codex");
63008
+ this.filePath = import_node_path41.default.join(options.dataDir, CHANNELS_FILE_NAME);
63009
+ this.codexHome = options.codexHome || process.env.CODEX_HOME || import_node_path41.default.join(import_node_os13.default.homedir(), ".codex");
63010
+ }
63011
+ /** 存储文件的快照(首次初始化 / 迁移先落盘);返回的函数把它恢复成此刻的样子,通道切换失败时回滚用 */
63012
+ snapshot() {
63013
+ this.readOrCreate();
63014
+ return snapshotFile(this.filePath);
62667
63015
  }
62668
63016
  /** 获取列表与激活通道 ID(Key 经脱敏掩码) */
62669
63017
  list() {
@@ -62758,9 +63106,9 @@ var SubscriptionChannelStore = class {
62758
63106
  return target;
62759
63107
  }
62760
63108
  readOrCreate() {
62761
- if (import_node_fs35.default.existsSync(this.filePath)) {
63109
+ if (import_node_fs36.default.existsSync(this.filePath)) {
62762
63110
  try {
62763
- const raw = JSON.parse(import_node_fs35.default.readFileSync(this.filePath, "utf8"));
63111
+ const raw = JSON.parse(import_node_fs36.default.readFileSync(this.filePath, "utf8"));
62764
63112
  if (raw && Array.isArray(raw.channels)) {
62765
63113
  return {
62766
63114
  activeChannelId: typeof raw.activeChannelId === "string" ? raw.activeChannelId : null,
@@ -62780,19 +63128,21 @@ var SubscriptionChannelStore = class {
62780
63128
  }
62781
63129
  tryMigrateFromCodexConfig() {
62782
63130
  try {
62783
- const configPath = import_node_path40.default.join(this.codexHome, "config.toml");
62784
- if (!import_node_fs35.default.existsSync(configPath)) return null;
62785
- const content = import_node_fs35.default.readFileSync(configPath, "utf8");
62786
- if (!content.includes('model_provider = "cliproxyapi"')) return null;
62787
- const urlMatch = /base_url\s*=\s*["']([^"']+)["']/.exec(content);
62788
- const keyMatch = /args\s*=\s*\[\s*["']([^"']+)["']\s*\]/.exec(content) || /experimental_bearer_token\s*=\s*["']([^"']+)["']/.exec(content);
62789
- if (urlMatch && keyMatch) {
63131
+ const configPath = import_node_path41.default.join(this.codexHome, "config.toml");
63132
+ if (!import_node_fs36.default.existsSync(configPath)) return null;
63133
+ const content = import_node_fs36.default.readFileSync(configPath, "utf8");
63134
+ if (readTomlTable(content, [])?.model_provider !== "cliproxyapi") return null;
63135
+ const provider = readTomlTable(content, ["model_providers", "cliproxyapi"]);
63136
+ if (!provider) return null;
63137
+ const baseUrl = typeof provider.base_url === "string" && provider.base_url ? provider.base_url : null;
63138
+ const key = providerKey(provider, this.codexHome);
63139
+ if (baseUrl && key) {
62790
63140
  const id = "default-pool";
62791
63141
  const channel = {
62792
63142
  id,
62793
63143
  name: "\u9ED8\u8BA4\u56E2\u961F\u53F7\u6C60",
62794
- baseUrl: normalizeEngineBaseUrl(urlMatch[1]),
62795
- apiKey: keyMatch[1],
63144
+ baseUrl: normalizeEngineBaseUrl(baseUrl),
63145
+ apiKey: key,
62796
63146
  remark: "\u4ECE\u672C\u673A\u5DF2\u63A5\u5165\u7684\u53F7\u6C60\u914D\u7F6E\u81EA\u52A8\u8FC1\u79FB",
62797
63147
  createdAt: Date.now(),
62798
63148
  updatedAt: Date.now()
@@ -62807,89 +63157,12 @@ var SubscriptionChannelStore = class {
62807
63157
  return null;
62808
63158
  }
62809
63159
  write(data) {
62810
- const dir = import_node_path40.default.dirname(this.filePath);
62811
- import_node_fs35.default.mkdirSync(dir, { recursive: true });
62812
- const tmp = `${this.filePath}.tmp.${Date.now()}`;
62813
- import_node_fs35.default.writeFileSync(tmp, JSON.stringify(data, null, 2) + "\n", { mode: 384 });
62814
- import_node_fs35.default.renameSync(tmp, this.filePath);
63160
+ const dir = import_node_path41.default.dirname(this.filePath);
63161
+ import_node_fs36.default.mkdirSync(dir, { recursive: true });
63162
+ writeFileAtomic(this.filePath, JSON.stringify(data, null, 2) + "\n");
62815
63163
  }
62816
63164
  };
62817
63165
 
62818
- // src/tools/subscription-channels-apply.ts
62819
- var import_node_fs36 = __toESM(require("fs"), 1);
62820
- var import_node_os13 = __toESM(require("os"), 1);
62821
- var import_node_path41 = __toESM(require("path"), 1);
62822
- var TABLE_HEADER = /^\s*\[\[?\s*([A-Za-z0-9_.-]+)\s*\]\]?\s*(?:#.*)?$/;
62823
- var KEY_LINE = /^\s*([A-Za-z0-9_.-]+)\s*=/;
62824
- function stripCodexProvider(text) {
62825
- const out = [];
62826
- let inProviderSection = false;
62827
- for (const line of text.split("\n")) {
62828
- const headerMatch = TABLE_HEADER.exec(line);
62829
- if (headerMatch) {
62830
- const section = headerMatch[1].trim();
62831
- inProviderSection = section === "model_providers" || section.startsWith("model_providers.");
62832
- if (inProviderSection) continue;
62833
- out.push(line);
62834
- continue;
62835
- }
62836
- if (inProviderSection) continue;
62837
- const keyMatch = KEY_LINE.exec(line);
62838
- if (keyMatch) {
62839
- const key = keyMatch[1].trim();
62840
- if (key === "model_provider" || key.startsWith("model_providers.")) {
62841
- continue;
62842
- }
62843
- }
62844
- out.push(line);
62845
- }
62846
- return out.join("\n").trim();
62847
- }
62848
- function applyCodexSubscriptionChannel(opts) {
62849
- const codexHome = opts.codexHome || process.env.CODEX_HOME || import_node_path41.default.join(import_node_os13.default.homedir(), ".codex");
62850
- import_node_fs36.default.mkdirSync(codexHome, { recursive: true });
62851
- const configFile = import_node_path41.default.join(codexHome, "config.toml");
62852
- const original = import_node_fs36.default.existsSync(configFile) ? import_node_fs36.default.readFileSync(configFile, "utf8") : "";
62853
- const rest = stripCodexProvider(original);
62854
- let content;
62855
- if (opts.channel) {
62856
- const ch = opts.channel;
62857
- content = [
62858
- 'model_provider = "cliproxyapi"',
62859
- ...rest ? ["", rest] : [],
62860
- "",
62861
- "[model_providers.cliproxyapi]",
62862
- 'name = "cliproxyapi"',
62863
- `base_url = ${JSON.stringify(ch.baseUrl)}`,
62864
- 'wire_api = "responses"',
62865
- `auth = { command = "echo", args = [${JSON.stringify(ch.apiKey)}] }`,
62866
- ""
62867
- ].join("\n");
62868
- } else {
62869
- content = [
62870
- 'model_provider = "openai"',
62871
- ...rest ? ["", rest] : [],
62872
- ""
62873
- ].join("\n");
62874
- }
62875
- const tmpFile = `${configFile}.tmp.${Date.now()}`;
62876
- import_node_fs36.default.writeFileSync(tmpFile, content, { mode: 384 });
62877
- import_node_fs36.default.renameSync(tmpFile, configFile);
62878
- }
62879
- function applyPiSubscriptionChannel(opts) {
62880
- const agentDir = opts.agentDir || process.env.PI_CODING_AGENT_DIR || import_node_path41.default.join(import_node_os13.default.homedir(), ".pi", "agent");
62881
- if (!import_node_fs36.default.existsSync(agentDir)) return false;
62882
- const configFile = import_node_path41.default.join(agentDir, "cliproxyapi.json");
62883
- if (opts.channel) {
62884
- const data = { baseUrl: opts.channel.baseUrl, apiKey: opts.channel.apiKey };
62885
- const tmp = `${configFile}.tmp.${Date.now()}`;
62886
- import_node_fs36.default.writeFileSync(tmp, JSON.stringify(data, null, 2) + "\n", { mode: 384 });
62887
- import_node_fs36.default.renameSync(tmp, configFile);
62888
- return true;
62889
- }
62890
- return false;
62891
- }
62892
-
62893
63166
  // src/deploy/local-probe.ts
62894
63167
  function pickVersion(s2) {
62895
63168
  return /(\d+)\.(\d+)(?:\.(\d+))?/.exec(s2)?.[0];
@@ -62948,8 +63221,8 @@ function refreshPathFromLoginShell() {
62948
63221
  timeout: 3e3,
62949
63222
  stdio: ["ignore", "pipe", "ignore"]
62950
63223
  });
62951
- const path106 = out.trim();
62952
- if (path106) process.env.PATH = path106;
63224
+ const path107 = out.trim();
63225
+ if (path107) process.env.PATH = path107;
62953
63226
  } catch {
62954
63227
  }
62955
63228
  }
@@ -63751,10 +64024,10 @@ function createCloudPersonaBotClient(opts) {
63751
64024
  const f2 = opts.fetchImpl ?? fetch;
63752
64025
  const base = opts.api.replace(/\/+$/, "");
63753
64026
  const route = (personaId2) => `/api/lark-bot/cloud/${encodeURIComponent(personaId2)}`;
63754
- async function request(method, path106, body) {
64027
+ async function request(method, path107, body) {
63755
64028
  const pass = opts.getLoginPass();
63756
64029
  if (!pass) throw new LarkBotCloudError("\u98DE\u4E66\u767B\u5F55\u540E\u624D\u80FD\u7BA1\u7406\u4E91 Persona \u7684 Bot", 401);
63757
- const response = await f2(base + path106, {
64030
+ const response = await f2(base + path107, {
63758
64031
  method,
63759
64032
  headers: { authorization: `Bearer ${pass}`, "content-type": "application/json" },
63760
64033
  ...body ? { body: JSON.stringify(body) } : {},
@@ -63763,7 +64036,7 @@ function createCloudPersonaBotClient(opts) {
63763
64036
  const json = await response.json().catch(() => ({}));
63764
64037
  if (!response.ok) {
63765
64038
  const detail = typeof json.message === "string" ? json.message : `HTTP ${response.status}`;
63766
- throw new LarkBotCloudError(`cloud bot ${method} ${path106}: ${detail}`, response.status);
64039
+ throw new LarkBotCloudError(`cloud bot ${method} ${path107}: ${detail}`, response.status);
63767
64040
  }
63768
64041
  return json;
63769
64042
  }
@@ -65159,15 +65432,28 @@ function createCloudTurnSession(args) {
65159
65432
  const accepted = new Promise((resolve9) => {
65160
65433
  resolveAccepted = resolve9;
65161
65434
  });
65162
- stream.onEvents((events) => sink.pushEvents(events));
65163
- stream.onHistoryGap(() => sink.onHistoryGap?.(false));
65435
+ let turnOpen = true;
65436
+ let gap = false;
65437
+ stream.onEvents((events) => {
65438
+ for (const event of events) {
65439
+ if (event.kind === "turn_end") turnOpen = false;
65440
+ else if (event.kind !== "subagent_progress" && event.kind !== "session_init") turnOpen = true;
65441
+ }
65442
+ sink.pushEvents(events);
65443
+ });
65444
+ stream.onHistoryGap(() => {
65445
+ gap = true;
65446
+ sink.onHistoryGap?.(false);
65447
+ });
65164
65448
  stream.onState((state) => {
65165
65449
  resolveAccepted();
65166
65450
  if (state.status === "inqueue") sink.pushEvents([{ kind: "meta-text", text: "\u5DF2\u6392\u961F\uFF0C\u4E0A\u4E00\u8F6E\u7ED3\u675F\u540E\u6267\u884C" }]);
65167
65451
  if (state.status === "completed" || state.status === "failed" || state.status === "cancelled") {
65168
65452
  live.delete(commandId);
65169
65453
  streams.delete(commandId);
65454
+ if (state.status === "completed" && turnOpen) sink.pushEvents([{ kind: "turn_end", reason: "completed" }]);
65170
65455
  if (state.status === "completed" && state.threadId) sink.pushEvents([{ kind: "session_init", toolSessionId: state.threadId }]);
65456
+ if (state.status === "completed" && gap) sink.onHistoryGap?.(true);
65171
65457
  if (state.status === "failed") sink.pushEvents([{ kind: "error", message: `\u4E91\u4E0A\u6267\u884C\u5931\u8D25\uFF1A${state.errorCode ?? "TURN_FAILED"}` }]);
65172
65458
  if (state.status === "failed" || state.status === "cancelled") sink.pushEvents([{ kind: "turn_end", reason: "interrupted" }]);
65173
65459
  sink.onCloudTurnTerminal?.(commandId);
@@ -65565,6 +65851,7 @@ function drivePiSession(opts) {
65565
65851
  let turnOpen = false;
65566
65852
  const firstByte = createFirstByteClock(opts.now);
65567
65853
  let handshakeFailed = false;
65854
+ let interrupts = 0;
65568
65855
  let exited = false;
65569
65856
  const finish = (code) => {
65570
65857
  if (exited) return;
@@ -65639,12 +65926,20 @@ function drivePiSession(opts) {
65639
65926
  const session = {
65640
65927
  startTurn(text) {
65641
65928
  let opened = false;
65929
+ const askedAt = interrupts;
65642
65930
  void ready.then(async () => {
65643
65931
  if (handshakeFailed) {
65644
65932
  fail("pi session not ready (get_state failed)", false);
65645
65933
  return;
65646
65934
  }
65647
65935
  const input = await piPromptInput(text, { fetchImage: opts.fetchImage });
65936
+ if (interrupts !== askedAt) {
65937
+ if (!turnOpen) {
65938
+ sink.pushEvents([{ kind: "turn_end", reason: "interrupted" }]);
65939
+ opts.onTurnCompleted?.("interrupted");
65940
+ }
65941
+ return;
65942
+ }
65648
65943
  opened = !turnOpen;
65649
65944
  if (opened) {
65650
65945
  turnOpen = true;
@@ -65664,6 +65959,7 @@ function drivePiSession(opts) {
65664
65959
  logger?.warn("pi respondPermission ignored: pi has no approvals", { requestId });
65665
65960
  },
65666
65961
  interrupt() {
65962
+ interrupts++;
65667
65963
  st2.aborted = true;
65668
65964
  void client.request({ type: "abort" }).catch(() => {
65669
65965
  });
@@ -65835,7 +66131,18 @@ async function queryPiModels(deps = {}) {
65835
66131
  const proc = deps.spawnOverride ? deps.spawnOverride(cmd, args) : (0, import_node_child_process12.spawn)(cmd, args, { stdio: ["pipe", "pipe", "pipe"] });
65836
66132
  proc.stdin?.on("error", () => {
65837
66133
  });
65838
- const client = new PiRpcClient(piStdioLineStream(proc));
66134
+ let refreshingCliproxy = false;
66135
+ let refreshError;
66136
+ let cliproxyRefreshedCount;
66137
+ const client = new PiRpcClient(piStdioLineStream(proc), {
66138
+ onEvent: (event) => {
66139
+ if (!refreshingCliproxy || event.type !== "extension_ui_request" || event.method !== "notify") return;
66140
+ const message = str2(event.message);
66141
+ if (event.notifyType === "error" && message?.startsWith("Failed to refresh CLIProxyAPI models:")) refreshError = message;
66142
+ const count = /^Refreshed (\d+) CLIProxyAPI models from /.exec(message ?? "");
66143
+ if (count) cliproxyRefreshedCount = Number(count[1]);
66144
+ }
66145
+ });
65839
66146
  const timeoutMs = deps.timeoutMs ?? 15e3;
65840
66147
  let timer;
65841
66148
  let timedOut = false;
@@ -65848,6 +66155,19 @@ async function queryPiModels(deps = {}) {
65848
66155
  const spawnError = new Promise((_3, reject) => proc.on("error", reject));
65849
66156
  const race = (p3) => Promise.race([p3, timeout, spawnError]);
65850
66157
  try {
66158
+ if (deps.refresh) {
66159
+ const commands = await race(client.request({ type: "get_commands" }));
66160
+ if (!commands.success) throw new Error(commands.error ?? "get_commands failed");
66161
+ const hasCliproxyRefresh = arr(rec2(commands.data)?.commands).some((command) => str2(rec2(command)?.name) === "cliproxyapi-refresh");
66162
+ if (hasCliproxyRefresh) {
66163
+ refreshingCliproxy = true;
66164
+ const refreshed = await race(client.request({ type: "prompt", message: "/cliproxyapi-refresh" }));
66165
+ if (!refreshed.success) throw new Error(refreshed.error ?? "cliproxyapi-refresh failed");
66166
+ if (refreshError) throw new Error(refreshError);
66167
+ if (cliproxyRefreshedCount === 0) throw new Error("CLIProxyAPI model refresh returned no models");
66168
+ refreshingCliproxy = false;
66169
+ }
66170
+ }
65851
66171
  const r2 = await race(client.request({ type: "get_available_models" }));
65852
66172
  if (!r2.success) throw new Error(r2.error ?? "get_available_models failed");
65853
66173
  const models = arr(rec2(r2.data)?.models).map(rec2).filter((m3) => m3 !== void 0);
@@ -65897,21 +66217,22 @@ var PiAdapter = class {
65897
66217
  }
65898
66218
  async capabilities(opts) {
65899
66219
  if (opts?.refresh) {
65900
- const fresh = await this.loadCapabilities({ strict: true });
66220
+ const fresh = await this.loadCapabilities({ strict: true, refresh: true });
65901
66221
  this.capsPromise = Promise.resolve(fresh);
65902
66222
  return fresh;
65903
66223
  }
65904
- if (!this.capsPromise) this.capsPromise = this.loadCapabilities({ strict: false });
66224
+ if (!this.capsPromise) this.capsPromise = this.loadCapabilities({ strict: false, refresh: false });
65905
66225
  return this.capsPromise;
65906
66226
  }
65907
66227
  async loadCapabilities(opts) {
65908
66228
  let models = [];
65909
66229
  try {
65910
- models = mapPiModels(this.opts.queryOverride ? await this.opts.queryOverride() : await queryPiModels());
66230
+ models = mapPiModels(this.opts.queryOverride ? await this.opts.queryOverride({ refresh: opts.refresh }) : await queryPiModels({ refresh: opts.refresh }));
65911
66231
  } catch (err) {
65912
66232
  if (opts.strict) throw err;
65913
66233
  this.opts.logger?.warn?.(`pi get_available_models failed: ${err.message}`);
65914
66234
  }
66235
+ if (models.length === 0 && opts.strict) throw new Error("Pi model refresh returned no models");
65915
66236
  if (models.length === 0) models = [PI_DEFAULT_MODEL_ENTRY];
65916
66237
  for (const m3 of models) if (m3.id) this.windows.set(m3.id, m3.contextWindowSize);
65917
66238
  return buildPiCapabilities(models);
@@ -66045,13 +66366,13 @@ function mapSkillsListResponse(res) {
66045
66366
  const r2 = s2 ?? {};
66046
66367
  const name = str4(r2.name);
66047
66368
  if (!name) continue;
66048
- const path106 = str4(r2.path);
66369
+ const path107 = str4(r2.path);
66049
66370
  const description = str4(r2.description);
66050
66371
  const isPlugin = name.includes(":");
66051
66372
  out.push({
66052
66373
  name,
66053
66374
  source: isPlugin ? "plugin" : "project",
66054
- ...path106 ? { path: path106 } : {},
66375
+ ...path107 ? { path: path107 } : {},
66055
66376
  ...description ? { description } : {},
66056
66377
  ...isPlugin ? { plugin: name.split(":")[0] } : {}
66057
66378
  });
@@ -70661,7 +70982,7 @@ var ServerKeyStore = class {
70661
70982
  init_protocol();
70662
70983
 
70663
70984
  // src/handlers/index.ts
70664
- var import_node_path80 = __toESM(require("path"), 1);
70985
+ var import_node_path81 = __toESM(require("path"), 1);
70665
70986
 
70666
70987
  // src/handlers/session.ts
70667
70988
  init_protocol();
@@ -72488,45 +72809,65 @@ function buildEngineHandlers(deps, overrides = {}) {
72488
72809
  }
72489
72810
 
72490
72811
  // src/handlers/channels.ts
72812
+ var import_node_fs65 = __toESM(require("fs"), 1);
72813
+ var import_node_path72 = __toESM(require("path"), 1);
72491
72814
  function buildChannelsHandlers(deps) {
72815
+ let queue = Promise.resolve();
72816
+ const serialized = (fn) => (frame, context) => {
72817
+ const run = queue.then(() => fn(frame, context));
72818
+ queue = run.then(() => {
72819
+ }, () => {
72820
+ });
72821
+ return run;
72822
+ };
72823
+ async function transact(mutate) {
72824
+ const codexHome = resolveCodexHome2(deps.codexHome);
72825
+ const agentDir = resolvePiAgentDir(deps.agentDir);
72826
+ const restoreStore = deps.store.snapshot();
72827
+ const restoreCodex = snapshotFile(import_node_path72.default.join(codexHome, "config.toml"));
72828
+ const restorePi = import_node_fs65.default.existsSync(agentDir) ? snapshotFile(import_node_path72.default.join(agentDir, PI_SUBSCRIPTION_FILE)) : null;
72829
+ let next;
72830
+ try {
72831
+ next = mutate();
72832
+ if (next === void 0) return;
72833
+ applyCodexSubscriptionChannel({ codexHome, channel: next });
72834
+ applyPiSubscriptionChannel({ agentDir, channel: next });
72835
+ if (next) await deps.manager.getCapabilities("codex", { refresh: true });
72836
+ } catch (err) {
72837
+ restoreStore();
72838
+ restoreCodex();
72839
+ restorePi?.();
72840
+ if (next?.id === "default-pool" && err instanceof Error && /HTTP 401/.test(err.message)) {
72841
+ throw new Error("\u9ED8\u8BA4\u53F7\u6C60\u8BA4\u8BC1\u5931\u8D25\uFF08HTTP 401\uFF09\uFF1A\u8BF7\u7F16\u8F91\u300C\u9ED8\u8BA4\u56E2\u961F\u53F7\u6C60\u300D\u5E76\u91CD\u65B0\u586B\u5199\u53F7\u6C60 API Key\uFF0C\u518D\u8BBE\u4E3A\u5F53\u524D\u3002");
72842
+ }
72843
+ throw err;
72844
+ }
72845
+ }
72492
72846
  const get = async () => {
72493
72847
  return { response: deps.store.list() };
72494
72848
  };
72495
- const save = async (frame) => {
72849
+ const save = serialized(async (frame) => {
72496
72850
  const args = parseArgs2(SubscriptionChannelSaveArgsSchema, frame, "subscriptionChannel:save");
72497
- const channel = deps.store.save(args);
72498
- const state = deps.store.list();
72499
- if (state.activeChannelId === channel.id) {
72500
- applyCodexSubscriptionChannel({ codexHome: deps.codexHome, channel });
72501
- applyPiSubscriptionChannel({ agentDir: deps.agentDir, channel });
72502
- await deps.manager.getCapabilities("codex", { refresh: true });
72503
- }
72851
+ await transact(() => {
72852
+ const channel = deps.store.save(args);
72853
+ return deps.store.list().activeChannelId === channel.id ? channel : void 0;
72854
+ });
72504
72855
  return { response: deps.store.list() };
72505
- };
72506
- const del = async (frame) => {
72856
+ });
72857
+ const del = serialized(async (frame) => {
72507
72858
  const args = parseArgs2(SubscriptionChannelDeleteArgsSchema, frame, "subscriptionChannel:delete");
72508
- const wasActive = deps.store.list().activeChannelId === args.id;
72509
- deps.store.delete(args.id);
72510
- if (wasActive) {
72511
- const newActive = deps.store.getActive();
72512
- applyCodexSubscriptionChannel({ codexHome: deps.codexHome, channel: newActive });
72513
- applyPiSubscriptionChannel({ agentDir: deps.agentDir, channel: newActive });
72514
- if (newActive) {
72515
- await deps.manager.getCapabilities("codex", { refresh: true });
72516
- }
72517
- }
72859
+ await transact(() => {
72860
+ const wasActive = deps.store.list().activeChannelId === args.id;
72861
+ deps.store.delete(args.id);
72862
+ return wasActive ? deps.store.getActive() : void 0;
72863
+ });
72518
72864
  return { response: { ok: true } };
72519
- };
72520
- const activate = async (frame) => {
72865
+ });
72866
+ const activate = serialized(async (frame) => {
72521
72867
  const args = parseArgs2(SubscriptionChannelActivateArgsSchema, frame, "subscriptionChannel:activate");
72522
- const channel = deps.store.setActive(args.id);
72523
- applyCodexSubscriptionChannel({ codexHome: deps.codexHome, channel });
72524
- applyPiSubscriptionChannel({ agentDir: deps.agentDir, channel });
72525
- if (channel) {
72526
- await deps.manager.getCapabilities("codex", { refresh: true });
72527
- }
72868
+ await transact(() => deps.store.setActive(args.id));
72528
72869
  return { response: { ok: true } };
72529
- };
72870
+ });
72530
72871
  return {
72531
72872
  "subscriptionChannel:get": get,
72532
72873
  "subscriptionChannel:save": save,
@@ -73495,21 +73836,21 @@ function computeMethodAccess(args) {
73495
73836
  }
73496
73837
 
73497
73838
  // src/version.ts
73498
- var version = "0.2.616".length > 0 ? "0.2.616" : "dev";
73839
+ var version = "0.2.618".length > 0 ? "0.2.618" : "dev";
73499
73840
 
73500
73841
  // src/cli-probe/probe.ts
73501
- var fs83 = __toESM(require("fs"), 1);
73502
- var path90 = __toESM(require("path"), 1);
73842
+ var fs84 = __toESM(require("fs"), 1);
73843
+ var path91 = __toESM(require("path"), 1);
73503
73844
  var PKG_NAME = "@clawos-dev/clawd";
73504
73845
  var BIN_NAME = "clawd";
73505
73846
  var MAX_PARENT_HOPS = 5;
73506
73847
  function probeGlobalCli(pathEnv) {
73507
73848
  if (!pathEnv) return null;
73508
- for (const dir of pathEnv.split(path90.delimiter)) {
73849
+ for (const dir of pathEnv.split(path91.delimiter)) {
73509
73850
  if (!dir) continue;
73510
73851
  let real;
73511
73852
  try {
73512
- real = fs83.realpathSync(path90.join(dir, BIN_NAME));
73853
+ real = fs84.realpathSync(path91.join(dir, BIN_NAME));
73513
73854
  } catch {
73514
73855
  continue;
73515
73856
  }
@@ -73519,15 +73860,15 @@ function probeGlobalCli(pathEnv) {
73519
73860
  return null;
73520
73861
  }
73521
73862
  function readOwnPackageVersion(entryPath) {
73522
- let dir = path90.dirname(entryPath);
73863
+ let dir = path91.dirname(entryPath);
73523
73864
  for (let i2 = 0; i2 < MAX_PARENT_HOPS; i2++) {
73524
73865
  try {
73525
- const raw = fs83.readFileSync(path90.join(dir, "package.json"), "utf8");
73866
+ const raw = fs84.readFileSync(path91.join(dir, "package.json"), "utf8");
73526
73867
  const pkg = JSON.parse(raw);
73527
73868
  if (pkg.name !== PKG_NAME) return null;
73528
73869
  return typeof pkg.version === "string" && pkg.version ? pkg.version : null;
73529
73870
  } catch {
73530
- const parent = path90.dirname(dir);
73871
+ const parent = path91.dirname(dir);
73531
73872
  if (parent === dir) return null;
73532
73873
  dir = parent;
73533
73874
  }
@@ -73703,7 +74044,7 @@ function buildPersonaHandlers(deps) {
73703
74044
  }
73704
74045
 
73705
74046
  // src/handlers/attachment.ts
73706
- var import_node_path72 = __toESM(require("path"), 1);
74047
+ var import_node_path73 = __toESM(require("path"), 1);
73707
74048
  init_protocol();
73708
74049
  init_protocol();
73709
74050
  function assertGuestAttachmentPath(ctx, absPath, personaRoot, method, usersRoot) {
@@ -73782,12 +74123,12 @@ function buildAttachmentHandlers(deps) {
73782
74123
  `session ${args.sessionId} scope unresolved`
73783
74124
  );
73784
74125
  }
73785
- const cwdAbs = import_node_path72.default.resolve(sessionFile.cwd);
73786
- const candidateAbs = import_node_path72.default.isAbsolute(args.relPath) ? import_node_path72.default.resolve(args.relPath) : import_node_path72.default.resolve(cwdAbs, args.relPath);
74126
+ const cwdAbs = import_node_path73.default.resolve(sessionFile.cwd);
74127
+ const candidateAbs = import_node_path73.default.isAbsolute(args.relPath) ? import_node_path73.default.resolve(args.relPath) : import_node_path73.default.resolve(cwdAbs, args.relPath);
73787
74128
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
73788
74129
  const entries = deps.groupFileStore.list(scope, args.sessionId);
73789
74130
  const entry = entries.find((e) => {
73790
- const storedAbs = import_node_path72.default.isAbsolute(e.relPath) ? import_node_path72.default.resolve(e.relPath) : import_node_path72.default.resolve(cwdAbs, e.relPath);
74131
+ const storedAbs = import_node_path73.default.isAbsolute(e.relPath) ? import_node_path73.default.resolve(e.relPath) : import_node_path73.default.resolve(cwdAbs, e.relPath);
73791
74132
  return storedAbs === candidateAbs && !e.stale;
73792
74133
  });
73793
74134
  if (!entry) {
@@ -73811,7 +74152,7 @@ function buildAttachmentHandlers(deps) {
73811
74152
  if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
73812
74153
  const f2 = deps.sessionStore.read(sessionId);
73813
74154
  if (!f2) return;
73814
- assertGuestAttachmentPath(ctx, import_node_path72.default.resolve(f2.cwd), deps.personaRoot, method, deps.usersRoot);
74155
+ assertGuestAttachmentPath(ctx, import_node_path73.default.resolve(f2.cwd), deps.personaRoot, method, deps.usersRoot);
73815
74156
  }
73816
74157
  const groupAdd = async (frame, _client, ctx) => {
73817
74158
  if (!deps.groupFileStore || !deps.getSessionScope) {
@@ -73826,8 +74167,8 @@ function buildAttachmentHandlers(deps) {
73826
74167
  if (!scope) {
73827
74168
  throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
73828
74169
  }
73829
- const cwdAbs = import_node_path72.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
73830
- const candidateAbs = import_node_path72.default.isAbsolute(args.relPath) ? import_node_path72.default.resolve(args.relPath) : import_node_path72.default.resolve(cwdAbs, args.relPath);
74170
+ const cwdAbs = import_node_path73.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
74171
+ const candidateAbs = import_node_path73.default.isAbsolute(args.relPath) ? import_node_path73.default.resolve(args.relPath) : import_node_path73.default.resolve(cwdAbs, args.relPath);
73831
74172
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
73832
74173
  const from = args.origin === "agent" ? "agent" : ctx?.principal.kind === "owner" ? "owner" : "agent";
73833
74174
  const size = 0;
@@ -73886,19 +74227,19 @@ function buildAttachmentHandlers(deps) {
73886
74227
 
73887
74228
  // src/handlers/extension.ts
73888
74229
  var import_promises15 = __toESM(require("fs/promises"), 1);
73889
- var import_node_path77 = __toESM(require("path"), 1);
74230
+ var import_node_path78 = __toESM(require("path"), 1);
73890
74231
  init_protocol();
73891
74232
 
73892
74233
  // src/extension/bundle-zip.ts
73893
74234
  var import_promises12 = __toESM(require("fs/promises"), 1);
73894
- var import_node_path73 = __toESM(require("path"), 1);
74235
+ var import_node_path74 = __toESM(require("path"), 1);
73895
74236
  var import_node_crypto23 = __toESM(require("crypto"), 1);
73896
74237
  var import_jszip2 = __toESM(require_lib3(), 1);
73897
74238
  async function bundleExtensionDir(dir) {
73898
74239
  const entries = await listFilesSorted(dir);
73899
74240
  const zip = new import_jszip2.default();
73900
74241
  for (const rel of entries) {
73901
- const abs = import_node_path73.default.join(dir, rel);
74242
+ const abs = import_node_path74.default.join(dir, rel);
73902
74243
  const content = await import_promises12.default.readFile(abs);
73903
74244
  zip.file(rel, content, { date: FIXED_DATE });
73904
74245
  }
@@ -73919,7 +74260,7 @@ async function listFilesSorted(rootDir) {
73919
74260
  return out;
73920
74261
  }
73921
74262
  async function walk(absRoot, relPrefix, out) {
73922
- const dirAbs = import_node_path73.default.join(absRoot, relPrefix);
74263
+ const dirAbs = import_node_path74.default.join(absRoot, relPrefix);
73923
74264
  const entries = await import_promises12.default.readdir(dirAbs, { withFileTypes: true });
73924
74265
  for (const e of entries) {
73925
74266
  if (IGNORE_BASENAMES.has(e.name)) continue;
@@ -73973,25 +74314,25 @@ function computePublishCheck(args) {
73973
74314
 
73974
74315
  // src/extension/install-flow.ts
73975
74316
  var import_promises13 = __toESM(require("fs/promises"), 1);
73976
- var import_node_path75 = __toESM(require("path"), 1);
74317
+ var import_node_path76 = __toESM(require("path"), 1);
73977
74318
  var import_node_os28 = __toESM(require("os"), 1);
73978
74319
  var import_node_crypto24 = __toESM(require("crypto"), 1);
73979
74320
  var import_jszip3 = __toESM(require_lib3(), 1);
73980
74321
 
73981
74322
  // src/extension/paths.ts
73982
74323
  var import_node_os27 = __toESM(require("os"), 1);
73983
- var import_node_path74 = __toESM(require("path"), 1);
74324
+ var import_node_path75 = __toESM(require("path"), 1);
73984
74325
  function clawdHomeRoot(override) {
73985
- return override ?? process.env.CLAWD_HOME ?? import_node_path74.default.join(import_node_os27.default.homedir(), ".clawd");
74326
+ return override ?? process.env.CLAWD_HOME ?? import_node_path75.default.join(import_node_os27.default.homedir(), ".clawd");
73986
74327
  }
73987
74328
  function extensionsRoot(override) {
73988
- return import_node_path74.default.join(clawdHomeRoot(override), "extensions");
74329
+ return import_node_path75.default.join(clawdHomeRoot(override), "extensions");
73989
74330
  }
73990
74331
  function publishedChannelsFile(override) {
73991
- return import_node_path74.default.join(clawdHomeRoot(override), "extensions-published.json");
74332
+ return import_node_path75.default.join(clawdHomeRoot(override), "extensions-published.json");
73992
74333
  }
73993
74334
  function bundleCacheRoot(override) {
73994
- return import_node_path74.default.join(clawdHomeRoot(override), "extension-bundles");
74335
+ return import_node_path75.default.join(clawdHomeRoot(override), "extension-bundles");
73995
74336
  }
73996
74337
 
73997
74338
  // src/extension/install-flow.ts
@@ -74018,7 +74359,7 @@ async function installFromChannel(args, deps) {
74018
74359
  throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
74019
74360
  }
74020
74361
  for (const name of Object.keys(zip.files)) {
74021
- if (name.includes("..") || name.startsWith("/") || import_node_path75.default.isAbsolute(name)) {
74362
+ if (name.includes("..") || name.startsWith("/") || import_node_path76.default.isAbsolute(name)) {
74022
74363
  throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
74023
74364
  }
74024
74365
  }
@@ -74050,7 +74391,7 @@ async function installFromChannel(args, deps) {
74050
74391
  );
74051
74392
  }
74052
74393
  const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
74053
- const destDir = import_node_path75.default.join(deps.extensionsRoot, localExtId);
74394
+ const destDir = import_node_path76.default.join(deps.extensionsRoot, localExtId);
74054
74395
  let destExists = false;
74055
74396
  try {
74056
74397
  await import_promises13.default.access(destDir);
@@ -74064,16 +74405,16 @@ async function installFromChannel(args, deps) {
74064
74405
  );
74065
74406
  }
74066
74407
  const stage = await import_promises13.default.mkdtemp(
74067
- import_node_path75.default.join(import_node_os28.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
74408
+ import_node_path76.default.join(import_node_os28.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
74068
74409
  );
74069
74410
  try {
74070
74411
  for (const [name, entry] of Object.entries(zip.files)) {
74071
- const dest = import_node_path75.default.join(stage, name);
74412
+ const dest = import_node_path76.default.join(stage, name);
74072
74413
  if (entry.dir) {
74073
74414
  await import_promises13.default.mkdir(dest, { recursive: true });
74074
74415
  continue;
74075
74416
  }
74076
- await import_promises13.default.mkdir(import_node_path75.default.dirname(dest), { recursive: true });
74417
+ await import_promises13.default.mkdir(import_node_path76.default.dirname(dest), { recursive: true });
74077
74418
  if (name === "manifest.json") {
74078
74419
  const rewritten = { ...parsed.data, id: localExtId };
74079
74420
  await import_promises13.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -74094,7 +74435,7 @@ async function installFromChannel(args, deps) {
74094
74435
 
74095
74436
  // src/extension/update-flow.ts
74096
74437
  var import_promises14 = __toESM(require("fs/promises"), 1);
74097
- var import_node_path76 = __toESM(require("path"), 1);
74438
+ var import_node_path77 = __toESM(require("path"), 1);
74098
74439
  var import_node_os29 = __toESM(require("os"), 1);
74099
74440
  var import_node_crypto25 = __toESM(require("crypto"), 1);
74100
74441
  var import_jszip4 = __toESM(require_lib3(), 1);
@@ -74111,11 +74452,11 @@ async function updateFromChannel(args, deps) {
74111
74452
  channelRef.extId,
74112
74453
  channelRef.ownerPrincipalId
74113
74454
  );
74114
- const liveDir = import_node_path76.default.join(deps.extensionsRoot, localExtId);
74455
+ const liveDir = import_node_path77.default.join(deps.extensionsRoot, localExtId);
74115
74456
  const prevDir = `${liveDir}.prev`;
74116
74457
  let existingVersion;
74117
74458
  try {
74118
- const raw = await import_promises14.default.readFile(import_node_path76.default.join(liveDir, "manifest.json"), "utf8");
74459
+ const raw = await import_promises14.default.readFile(import_node_path77.default.join(liveDir, "manifest.json"), "utf8");
74119
74460
  const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
74120
74461
  if (!parsed2.success) {
74121
74462
  throw new UpdateError(
@@ -74148,7 +74489,7 @@ async function updateFromChannel(args, deps) {
74148
74489
  throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
74149
74490
  }
74150
74491
  for (const name of Object.keys(zip.files)) {
74151
- if (name.includes("..") || name.startsWith("/") || import_node_path76.default.isAbsolute(name)) {
74492
+ if (name.includes("..") || name.startsWith("/") || import_node_path77.default.isAbsolute(name)) {
74152
74493
  throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
74153
74494
  }
74154
74495
  }
@@ -74183,16 +74524,16 @@ async function updateFromChannel(args, deps) {
74183
74524
  await import_promises14.default.rm(prevDir, { recursive: true, force: true });
74184
74525
  await import_promises14.default.rename(liveDir, prevDir);
74185
74526
  const stage = await import_promises14.default.mkdtemp(
74186
- import_node_path76.default.join(import_node_os29.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
74527
+ import_node_path77.default.join(import_node_os29.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
74187
74528
  );
74188
74529
  try {
74189
74530
  for (const [name, entry] of Object.entries(zip.files)) {
74190
- const dest = import_node_path76.default.join(stage, name);
74531
+ const dest = import_node_path77.default.join(stage, name);
74191
74532
  if (entry.dir) {
74192
74533
  await import_promises14.default.mkdir(dest, { recursive: true });
74193
74534
  continue;
74194
74535
  }
74195
- await import_promises14.default.mkdir(import_node_path76.default.dirname(dest), { recursive: true });
74536
+ await import_promises14.default.mkdir(import_node_path77.default.dirname(dest), { recursive: true });
74196
74537
  if (name === "manifest.json") {
74197
74538
  const rewritten = { ...parsed.data, id: localExtId };
74198
74539
  await import_promises14.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -74259,7 +74600,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
74259
74600
  );
74260
74601
  }
74261
74602
  }
74262
- const manifestPath = import_node_path77.default.join(root, extId, "manifest.json");
74603
+ const manifestPath = import_node_path78.default.join(root, extId, "manifest.json");
74263
74604
  const manifest = await readManifest(root, extId);
74264
74605
  const next = { ...manifest, version: newVersion };
74265
74606
  const tmp = `${manifestPath}.tmp`;
@@ -74267,7 +74608,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
74267
74608
  await import_promises15.default.rename(tmp, manifestPath);
74268
74609
  }
74269
74610
  async function readManifest(root, extId) {
74270
- const file = import_node_path77.default.join(root, extId, "manifest.json");
74611
+ const file = import_node_path78.default.join(root, extId, "manifest.json");
74271
74612
  let raw;
74272
74613
  try {
74273
74614
  raw = await import_promises15.default.readFile(file, "utf8");
@@ -74351,7 +74692,7 @@ function buildExtensionHandlers(deps) {
74351
74692
  };
74352
74693
  async function buildSnapshotMeta(extId) {
74353
74694
  const manifest = await readManifest(deps.root, extId);
74354
- const { sha256, buffer } = await bundleExtensionDir(import_node_path77.default.join(deps.root, extId));
74695
+ const { sha256, buffer } = await bundleExtensionDir(import_node_path78.default.join(deps.root, extId));
74355
74696
  return { manifest, contentHash: sha256, buffer };
74356
74697
  }
74357
74698
  const publish = async (frame, _client, ctx) => {
@@ -75179,7 +75520,7 @@ function buildVisitorHandlers(deps) {
75179
75520
 
75180
75521
  // src/extension/registry.ts
75181
75522
  var import_promises17 = __toESM(require("fs/promises"), 1);
75182
- var import_node_path78 = __toESM(require("path"), 1);
75523
+ var import_node_path79 = __toESM(require("path"), 1);
75183
75524
  async function loadAll(root) {
75184
75525
  let entries;
75185
75526
  try {
@@ -75192,13 +75533,13 @@ async function loadAll(root) {
75192
75533
  for (const ent of entries) {
75193
75534
  if (!ent.isDirectory()) continue;
75194
75535
  if (ent.name.startsWith(".")) continue;
75195
- records.push(await loadOne(import_node_path78.default.join(root, ent.name), ent.name));
75536
+ records.push(await loadOne(import_node_path79.default.join(root, ent.name), ent.name));
75196
75537
  }
75197
75538
  records.sort((a2, b3) => a2.extId < b3.extId ? -1 : a2.extId > b3.extId ? 1 : 0);
75198
75539
  return records;
75199
75540
  }
75200
75541
  async function loadOne(dir, dirName) {
75201
- const manifestPath = import_node_path78.default.join(dir, "manifest.json");
75542
+ const manifestPath = import_node_path79.default.join(dir, "manifest.json");
75202
75543
  let raw;
75203
75544
  try {
75204
75545
  raw = await import_promises17.default.readFile(manifestPath, "utf8");
@@ -75243,7 +75584,7 @@ async function loadOne(dir, dirName) {
75243
75584
 
75244
75585
  // src/extension/uninstall.ts
75245
75586
  var import_promises18 = __toESM(require("fs/promises"), 1);
75246
- var import_node_path79 = __toESM(require("path"), 1);
75587
+ var import_node_path80 = __toESM(require("path"), 1);
75247
75588
  var UninstallError = class extends Error {
75248
75589
  constructor(code, message) {
75249
75590
  super(message);
@@ -75252,7 +75593,7 @@ var UninstallError = class extends Error {
75252
75593
  code;
75253
75594
  };
75254
75595
  async function uninstall(deps) {
75255
- const dir = import_node_path79.default.join(deps.root, deps.extId);
75596
+ const dir = import_node_path80.default.join(deps.root, deps.extId);
75256
75597
  try {
75257
75598
  await import_promises18.default.access(dir);
75258
75599
  } catch {
@@ -75470,7 +75811,7 @@ function buildMethodHandlers(deps) {
75470
75811
  broadcast: deps.broadcastToOwners
75471
75812
  }),
75472
75813
  ...buildMasterHandlers({
75473
- authorityTablePath: import_node_path80.default.join(deps.masterDataDir, "master-authority.json")
75814
+ authorityTablePath: import_node_path81.default.join(deps.masterDataDir, "master-authority.json")
75474
75815
  }),
75475
75816
  ...buildTopicHandlers({
75476
75817
  topicStore: deps.topicStore,
@@ -75613,7 +75954,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
75613
75954
 
75614
75955
  // src/extension/runtime.ts
75615
75956
  var import_node_child_process25 = require("child_process");
75616
- var import_node_path81 = __toESM(require("path"), 1);
75957
+ var import_node_path82 = __toESM(require("path"), 1);
75617
75958
  var import_promises19 = require("timers/promises");
75618
75959
 
75619
75960
  // src/extension/port-allocator.ts
@@ -75714,7 +76055,7 @@ var Runtime = class {
75714
76055
  /\$CLAWOS_EXT_PORT/g,
75715
76056
  String(port)
75716
76057
  );
75717
- const dir = import_node_path81.default.join(this.root, extId);
76058
+ const dir = import_node_path82.default.join(this.root, extId);
75718
76059
  const env = {
75719
76060
  ...process.env,
75720
76061
  CLAWOS_EXT_PORT: String(port),
@@ -75826,7 +76167,7 @@ ${handle.stderrTail}`
75826
76167
 
75827
76168
  // src/extension/published-channels.ts
75828
76169
  var import_promises20 = __toESM(require("fs/promises"), 1);
75829
- var import_node_path82 = __toESM(require("path"), 1);
76170
+ var import_node_path83 = __toESM(require("path"), 1);
75830
76171
  init_zod();
75831
76172
  var PublishedChannelsError = class extends Error {
75832
76173
  constructor(code, message) {
@@ -75925,7 +76266,7 @@ var PublishedChannelStore = class {
75925
76266
  )
75926
76267
  };
75927
76268
  const tmp = `${this.filePath}.tmp`;
75928
- await import_promises20.default.mkdir(import_node_path82.default.dirname(this.filePath), { recursive: true });
76269
+ await import_promises20.default.mkdir(import_node_path83.default.dirname(this.filePath), { recursive: true });
75929
76270
  await import_promises20.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
75930
76271
  await import_promises20.default.rename(tmp, this.filePath);
75931
76272
  }
@@ -75933,7 +76274,7 @@ var PublishedChannelStore = class {
75933
76274
 
75934
76275
  // src/extension/bundle-cache.ts
75935
76276
  var import_promises21 = __toESM(require("fs/promises"), 1);
75936
- var import_node_path83 = __toESM(require("path"), 1);
76277
+ var import_node_path84 = __toESM(require("path"), 1);
75937
76278
  var BundleCache = class {
75938
76279
  constructor(rootDir) {
75939
76280
  this.rootDir = rootDir;
@@ -75942,14 +76283,14 @@ var BundleCache = class {
75942
76283
  /** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
75943
76284
  async write(snapshotHash, buffer) {
75944
76285
  await import_promises21.default.mkdir(this.rootDir, { recursive: true });
75945
- const file = import_node_path83.default.join(this.rootDir, `${snapshotHash}.zip`);
76286
+ const file = import_node_path84.default.join(this.rootDir, `${snapshotHash}.zip`);
75946
76287
  const tmp = `${file}.tmp`;
75947
76288
  await import_promises21.default.writeFile(tmp, buffer, { mode: 384 });
75948
76289
  await import_promises21.default.rename(tmp, file);
75949
76290
  }
75950
76291
  /** Returns the bundle bytes, or null when the file doesn't exist. */
75951
76292
  async read(snapshotHash) {
75952
- const file = import_node_path83.default.join(this.rootDir, `${snapshotHash}.zip`);
76293
+ const file = import_node_path84.default.join(this.rootDir, `${snapshotHash}.zip`);
75953
76294
  try {
75954
76295
  return await import_promises21.default.readFile(file);
75955
76296
  } catch (e) {
@@ -75959,7 +76300,7 @@ var BundleCache = class {
75959
76300
  }
75960
76301
  /** Idempotent — missing file is not an error. */
75961
76302
  async delete(snapshotHash) {
75962
- const file = import_node_path83.default.join(this.rootDir, `${snapshotHash}.zip`);
76303
+ const file = import_node_path84.default.join(this.rootDir, `${snapshotHash}.zip`);
75963
76304
  await import_promises21.default.rm(file, { force: true });
75964
76305
  }
75965
76306
  };
@@ -75982,24 +76323,24 @@ async function startDaemon(config) {
75982
76323
  sampling: logShippingCfg.sampling,
75983
76324
  homeDir: import_node_os31.default.homedir()
75984
76325
  });
75985
- const logDir = import_node_path84.default.join(config.dataDir, "log");
75986
- import_node_fs65.default.mkdirSync(logDir, { recursive: true });
76326
+ const logDir = import_node_path85.default.join(config.dataDir, "log");
76327
+ import_node_fs66.default.mkdirSync(logDir, { recursive: true });
75987
76328
  const logger = createLogger({
75988
76329
  level: config.logLevel,
75989
- file: import_node_path84.default.join(logDir, "clawd.log"),
76330
+ file: import_node_path85.default.join(logDir, "clawd.log"),
75990
76331
  logClient
75991
76332
  });
75992
76333
  logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
75993
76334
  const screenIdleProbeLogger = createFileOnlyLogger({
75994
- file: import_node_path84.default.join(logDir, "screen-idle-probe.log"),
76335
+ file: import_node_path85.default.join(logDir, "screen-idle-probe.log"),
75995
76336
  level: "debug"
75996
76337
  });
75997
76338
  logger.info("screen-idle probe logger enabled", {
75998
- file: import_node_path84.default.join(logDir, "screen-idle-probe.log")
76339
+ file: import_node_path85.default.join(logDir, "screen-idle-probe.log")
75999
76340
  });
76000
76341
  const CAP_TARGETS = [
76001
- import_node_path84.default.join(logDir, "clawd.log"),
76002
- import_node_path84.default.join(logDir, "screen-idle-probe.log")
76342
+ import_node_path85.default.join(logDir, "clawd.log"),
76343
+ import_node_path85.default.join(logDir, "screen-idle-probe.log")
76003
76344
  ];
76004
76345
  const LOG_CAP_MAX_BYTES = 10 * 1024 * 1024;
76005
76346
  const LOG_CAP_KEEP_BYTES = 5 * 1024 * 1024;
@@ -76121,11 +76462,11 @@ async function startDaemon(config) {
76121
76462
  const agents = new AgentsScanner();
76122
76463
  const history = new ClaudeHistoryReader();
76123
76464
  let transport = null;
76124
- const personaStore = new PersonaStore(import_node_path84.default.join(config.dataDir, "personas"));
76465
+ const personaStore = new PersonaStore(import_node_path85.default.join(config.dataDir, "personas"));
76125
76466
  const subscriptionChannelStore = new SubscriptionChannelStore({ dataDir: config.dataDir });
76126
76467
  const activeSubscriptionChannel = subscriptionChannelStore.getActive();
76127
76468
  if (activeSubscriptionChannel) applyPiSubscriptionChannel({ channel: activeSubscriptionChannel });
76128
- const usersRoot = import_node_path84.default.join(config.dataDir, "users");
76469
+ const usersRoot = import_node_path85.default.join(config.dataDir, "users");
76129
76470
  const defaultsRoot = findDefaultsRoot(logger);
76130
76471
  if (defaultsRoot) {
76131
76472
  seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
@@ -76142,7 +76483,7 @@ async function startDaemon(config) {
76142
76483
  retirePersonaBuilder({ store: personaStore, logger });
76143
76484
  const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
76144
76485
  const dispatchStore = createDispatchStore({
76145
- filePath: import_node_path84.default.join(config.dataDir, "dispatch.json"),
76486
+ filePath: import_node_path85.default.join(config.dataDir, "dispatch.json"),
76146
76487
  now: () => Date.now(),
76147
76488
  onFlushError: (err) => logger.error("dispatch store flush failed", {
76148
76489
  reason: err instanceof Error ? err.message : String(err)
@@ -76151,7 +76492,7 @@ async function startDaemon(config) {
76151
76492
  await dispatchStore.load();
76152
76493
  dispatchStore.markInterruptedAsFailed((/* @__PURE__ */ new Date()).toISOString());
76153
76494
  const channelStore = createChannelStore({
76154
- filePath: import_node_path84.default.join(config.dataDir, "channels.json"),
76495
+ filePath: import_node_path85.default.join(config.dataDir, "channels.json"),
76155
76496
  now: () => Date.now(),
76156
76497
  genId: () => `ch-${(0, import_node_crypto27.randomUUID)().slice(0, 8)}`,
76157
76498
  onFlushError: (err) => logger.error("channel store flush failed", {
@@ -76160,7 +76501,7 @@ async function startDaemon(config) {
76160
76501
  });
76161
76502
  await channelStore.load();
76162
76503
  const topicStore = createTopicStore({
76163
- filePath: import_node_path84.default.join(config.dataDir, "topics.json"),
76504
+ filePath: import_node_path85.default.join(config.dataDir, "topics.json"),
76164
76505
  now: () => Date.now(),
76165
76506
  genId: () => `tp-${(0, import_node_crypto27.randomUUID)().slice(0, 8)}`,
76166
76507
  onFlushError: (err) => logger.error("topic store flush failed", {
@@ -76187,12 +76528,12 @@ async function startDaemon(config) {
76187
76528
  });
76188
76529
  }
76189
76530
  });
76190
- const here = typeof __dirname === "string" ? __dirname : import_node_path84.default.dirname((0, import_node_url6.fileURLToPath)(import_meta10.url));
76531
+ const here = typeof __dirname === "string" ? __dirname : import_node_path85.default.dirname((0, import_node_url6.fileURLToPath)(import_meta10.url));
76191
76532
  const mcpConfigs = [];
76192
76533
  const secretsBundleRoot = findSecretsBundleRoot(logger);
76193
- const localSecretsDir = import_node_path84.default.join(config.dataDir, LOCAL_SECRETS_DIRNAME);
76534
+ const localSecretsDir = import_node_path85.default.join(config.dataDir, LOCAL_SECRETS_DIRNAME);
76194
76535
  const readSecrets = () => readSecretTable({ bundleRoot: secretsBundleRoot, overrideDir: localSecretsDir, logger });
76195
- const githubTokenFile = import_node_path84.default.join(localSecretsDir, GITHUB_TOKEN_FILE);
76536
+ const githubTokenFile = import_node_path85.default.join(localSecretsDir, GITHUB_TOKEN_FILE);
76196
76537
  const githubIdentity = createGithubIdentity({
76197
76538
  resolve: () => resolveGithubAuth({ exec: runCommand, fileToken: () => readEnvFileVar(githubTokenFile, GITHUB_TOKEN_VAR) }),
76198
76539
  store: (token) => storeGithubAuth({
@@ -76230,22 +76571,22 @@ async function startDaemon(config) {
76230
76571
  void githubIdentity.refresh();
76231
76572
  return renderPersonaMcpSecrets({
76232
76573
  personaId: personaId2,
76233
- personaDir: import_node_path84.default.join(config.dataDir, "personas", personaId2),
76574
+ personaDir: import_node_path85.default.join(config.dataDir, "personas", personaId2),
76234
76575
  secrets,
76235
- outDir: import_node_path84.default.join(config.dataDir, "persona-mcp"),
76576
+ outDir: import_node_path85.default.join(config.dataDir, "persona-mcp"),
76236
76577
  logger
76237
76578
  });
76238
76579
  };
76239
76580
  const mcpDaemonUrl = `http://127.0.0.1:${config.port}`;
76240
76581
  const dispatchServerCandidates = [
76241
- import_node_path84.default.join(here, "dispatch", "mcp-server.cjs"),
76582
+ import_node_path85.default.join(here, "dispatch", "mcp-server.cjs"),
76242
76583
  // 生产 dist/index → dist/dispatch/mcp-server.cjs
76243
- import_node_path84.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
76584
+ import_node_path85.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
76244
76585
  // dev tsx src/index → ../dist/dispatch/mcp-server.cjs
76245
76586
  ];
76246
- const dispatchServerScriptPath = dispatchServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
76587
+ const dispatchServerScriptPath = dispatchServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76247
76588
  if (dispatchServerScriptPath) {
76248
- const dispatchLogPath = import_node_path84.default.join(logDir, "dispatch-mcp-server.log");
76589
+ const dispatchLogPath = import_node_path85.default.join(logDir, "dispatch-mcp-server.log");
76249
76590
  const dispatchCfgPath = writeDispatchMcpConfig({
76250
76591
  dataDir: config.dataDir,
76251
76592
  serverScriptPath: dispatchServerScriptPath,
@@ -76265,12 +76606,12 @@ async function startDaemon(config) {
76265
76606
  });
76266
76607
  }
76267
76608
  const ticketServerCandidates = [
76268
- import_node_path84.default.join(here, "ticket", "mcp-server.cjs"),
76269
- import_node_path84.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
76609
+ import_node_path85.default.join(here, "ticket", "mcp-server.cjs"),
76610
+ import_node_path85.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
76270
76611
  ];
76271
- const ticketServerScriptPath = ticketServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
76612
+ const ticketServerScriptPath = ticketServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76272
76613
  if (ticketServerScriptPath) {
76273
- const ticketLogPath = import_node_path84.default.join(logDir, "ticket-mcp-server.log");
76614
+ const ticketLogPath = import_node_path85.default.join(logDir, "ticket-mcp-server.log");
76274
76615
  const ticketCfgPath = writeTicketMcpConfig({
76275
76616
  dataDir: config.dataDir,
76276
76617
  serverScriptPath: ticketServerScriptPath,
@@ -76292,12 +76633,12 @@ async function startDaemon(config) {
76292
76633
  });
76293
76634
  }
76294
76635
  const shiftServerCandidates = [
76295
- import_node_path84.default.join(here, "shift", "mcp-server.cjs"),
76296
- import_node_path84.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
76636
+ import_node_path85.default.join(here, "shift", "mcp-server.cjs"),
76637
+ import_node_path85.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
76297
76638
  ];
76298
- const shiftServerScriptPath = shiftServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
76639
+ const shiftServerScriptPath = shiftServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76299
76640
  if (shiftServerScriptPath) {
76300
- const shiftLogPath = import_node_path84.default.join(logDir, "shift-mcp-server.log");
76641
+ const shiftLogPath = import_node_path85.default.join(logDir, "shift-mcp-server.log");
76301
76642
  const shiftCfgPath = await writeShiftMcpConfig({
76302
76643
  dataDir: config.dataDir,
76303
76644
  serverScriptPath: shiftServerScriptPath,
@@ -76318,12 +76659,12 @@ async function startDaemon(config) {
76318
76659
  );
76319
76660
  }
76320
76661
  const inboxServerCandidates = [
76321
- import_node_path84.default.join(here, "inbox", "mcp-server.cjs"),
76322
- import_node_path84.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
76662
+ import_node_path85.default.join(here, "inbox", "mcp-server.cjs"),
76663
+ import_node_path85.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
76323
76664
  ];
76324
- const inboxServerScriptPath = inboxServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
76665
+ const inboxServerScriptPath = inboxServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76325
76666
  if (inboxServerScriptPath) {
76326
- const inboxLogPath = import_node_path84.default.join(logDir, "inbox-mcp-server.log");
76667
+ const inboxLogPath = import_node_path85.default.join(logDir, "inbox-mcp-server.log");
76327
76668
  const inboxCfgPath = await writeInboxMcpConfig({
76328
76669
  dataDir: config.dataDir,
76329
76670
  serverScriptPath: inboxServerScriptPath,
@@ -76344,10 +76685,10 @@ async function startDaemon(config) {
76344
76685
  );
76345
76686
  }
76346
76687
  const peerOpsServerCandidates = [
76347
- import_node_path84.default.join(here, "peer-ops", "mcp-server.cjs"),
76348
- import_node_path84.default.join(here, "..", "dist", "peer-ops", "mcp-server.cjs")
76688
+ import_node_path85.default.join(here, "peer-ops", "mcp-server.cjs"),
76689
+ import_node_path85.default.join(here, "..", "dist", "peer-ops", "mcp-server.cjs")
76349
76690
  ];
76350
- const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
76691
+ const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76351
76692
  if (peerOpsServerScriptPath) {
76352
76693
  const peerOpsCfgPath = writePeerOpsMcpConfig({
76353
76694
  dataDir: config.dataDir,
@@ -76367,12 +76708,12 @@ async function startDaemon(config) {
76367
76708
  );
76368
76709
  }
76369
76710
  const rpcToolServerCandidates = [
76370
- import_node_path84.default.join(here, "rpc-tool", "mcp-server.cjs"),
76371
- import_node_path84.default.join(here, "..", "dist", "rpc-tool", "mcp-server.cjs")
76711
+ import_node_path85.default.join(here, "rpc-tool", "mcp-server.cjs"),
76712
+ import_node_path85.default.join(here, "..", "dist", "rpc-tool", "mcp-server.cjs")
76372
76713
  ];
76373
- const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
76714
+ const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76374
76715
  if (rpcToolServerScriptPath) {
76375
- const rpcToolLogPath = import_node_path84.default.join(logDir, "rpc-tool-mcp-server.log");
76716
+ const rpcToolLogPath = import_node_path85.default.join(logDir, "rpc-tool-mcp-server.log");
76376
76717
  const rpcToolCfgPath = writeRpcToolMcpConfig({
76377
76718
  dataDir: config.dataDir,
76378
76719
  serverScriptPath: rpcToolServerScriptPath,
@@ -76393,7 +76734,7 @@ async function startDaemon(config) {
76393
76734
  );
76394
76735
  }
76395
76736
  const shiftStore = createShiftStore({
76396
- filePath: import_node_path84.default.join(config.dataDir, "shift.json"),
76737
+ filePath: import_node_path85.default.join(config.dataDir, "shift.json"),
76397
76738
  ownerIdProvider: () => ownerPrincipalId,
76398
76739
  now: () => Date.now()
76399
76740
  });
@@ -76415,7 +76756,7 @@ async function startDaemon(config) {
76415
76756
  getAdapter,
76416
76757
  historyReader: history,
76417
76758
  dataDir: config.dataDir,
76418
- personaRoot: import_node_path84.default.join(config.dataDir, "personas"),
76759
+ personaRoot: import_node_path85.default.join(config.dataDir, "personas"),
76419
76760
  // dispatch / shift 自动化 spawn 按 persona 绑定 tool 起 B session(codex persona 用 codex)。
76420
76761
  // personaRegistry 声明在 manager 之后(同作用域 const,调用时机在启动完成后,无 TDZ 风险)。
76421
76762
  getPersonaDefaults: (personaId2) => personaRegistry.get(personaId2),
@@ -76476,10 +76817,10 @@ async function startDaemon(config) {
76476
76817
  // 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
76477
76818
  attachmentGroup: {
76478
76819
  onFileEdit: (input) => {
76479
- const absPath = import_node_path84.default.isAbsolute(input.relPath) ? input.relPath : import_node_path84.default.join(input.cwd, input.relPath);
76820
+ const absPath = import_node_path85.default.isAbsolute(input.relPath) ? input.relPath : import_node_path85.default.join(input.cwd, input.relPath);
76480
76821
  let size = 0;
76481
76822
  try {
76482
- size = import_node_fs65.default.statSync(absPath).size;
76823
+ size = import_node_fs66.default.statSync(absPath).size;
76483
76824
  } catch (err) {
76484
76825
  logger.warn("attachment.onFileEdit stat failed", {
76485
76826
  sessionId: input.sessionId,
@@ -76520,9 +76861,9 @@ async function startDaemon(config) {
76520
76861
  logger.info("projects.seed-dropped", { dropped: droppedSeed.dropped, backup: droppedSeed.backup });
76521
76862
  }
76522
76863
  const projectsStore = new ProjectsStore({
76523
- file: import_node_path84.default.join(config.dataDir, "projects.json"),
76864
+ file: import_node_path85.default.join(config.dataDir, "projects.json"),
76524
76865
  clawdDir: config.dataDir,
76525
- codexStateFile: import_node_path84.default.join(import_node_os31.default.homedir(), ".codex", ".codex-global-state.json"),
76866
+ codexStateFile: import_node_path85.default.join(import_node_os31.default.homedir(), ".codex", ".codex-global-state.json"),
76526
76867
  logger
76527
76868
  });
76528
76869
  const observer = new SessionObserver({
@@ -76597,13 +76938,13 @@ async function startDaemon(config) {
76597
76938
  runner?.confirmCloudCancelled();
76598
76939
  });
76599
76940
  registerAdapter("claude", claudeAdapter);
76600
- const codexIsolatedHome = import_node_path84.default.join(config.dataDir, "codex-home");
76941
+ const codexIsolatedHome = import_node_path85.default.join(config.dataDir, "codex-home");
76601
76942
  try {
76602
- import_node_fs65.default.mkdirSync(codexIsolatedHome, { recursive: true });
76943
+ import_node_fs66.default.mkdirSync(codexIsolatedHome, { recursive: true });
76603
76944
  for (const f2 of ["auth.json", "config.toml"]) {
76604
- const link = import_node_path84.default.join(codexIsolatedHome, f2);
76605
- const target = import_node_path84.default.join(import_node_os31.default.homedir(), ".codex", f2);
76606
- if (!import_node_fs65.default.existsSync(link) && import_node_fs65.default.existsSync(target)) import_node_fs65.default.symlinkSync(target, link);
76945
+ const link = import_node_path85.default.join(codexIsolatedHome, f2);
76946
+ const target = import_node_path85.default.join(import_node_os31.default.homedir(), ".codex", f2);
76947
+ if (!import_node_fs66.default.existsSync(link) && import_node_fs66.default.existsSync(target)) import_node_fs66.default.symlinkSync(target, link);
76607
76948
  }
76608
76949
  } catch (err) {
76609
76950
  logger.warn("codex isolated home setup failed", { err: String(err) });
@@ -76614,17 +76955,17 @@ async function startDaemon(config) {
76614
76955
  logger,
76615
76956
  historyReader: new CodexHistoryReader({
76616
76957
  roots: codexRolloutRoots(config.dataDir),
76617
- sharedHome: import_node_path84.default.join(import_node_os31.default.homedir(), ".codex"),
76958
+ sharedHome: import_node_path85.default.join(import_node_os31.default.homedir(), ".codex"),
76618
76959
  logger
76619
76960
  }),
76620
76961
  // projectPaths 每次调用现取 —— 用户新建 project 后立即生效,不用重启 daemon
76621
76962
  codexHomeFor: (cwd) => resolveCodexHome({
76622
76963
  cwd,
76623
- personaRoot: import_node_path84.default.join(config.dataDir, "personas"),
76964
+ personaRoot: import_node_path85.default.join(config.dataDir, "personas"),
76624
76965
  // 必须用 listMerged(Codex registry ∪ 叠加层):只用本地 list() 的话,用户在
76625
76966
  // Codex 里建的 project 不在表里,在它下面开的会话会被误判成隔离 → Codex 侧看不到
76626
76967
  projectPaths: projectsStore.listMerged().map((x2) => x2.path),
76627
- sharedHome: import_node_path84.default.join(import_node_os31.default.homedir(), ".codex"),
76968
+ sharedHome: import_node_path85.default.join(import_node_os31.default.homedir(), ".codex"),
76628
76969
  isolatedHome: codexIsolatedHome
76629
76970
  }),
76630
76971
  codexHomeForThread: (threadId) => locateCodexThread(codexRolloutRoots(config.dataDir), threadId)?.home,
@@ -76650,10 +76991,10 @@ async function startDaemon(config) {
76650
76991
  );
76651
76992
  registerAdapter(PI_CLOUD_TOOL_ID, new CloudPiAdapter({ client: cloudGateway, history: cloudHistorySource, logger }));
76652
76993
  const piMcpBridgeCandidates = [
76653
- import_node_path84.default.join(here, "pi-mcp-bridge", "extension.cjs"),
76654
- import_node_path84.default.join(here, "..", "dist", "pi-mcp-bridge", "extension.cjs")
76994
+ import_node_path85.default.join(here, "pi-mcp-bridge", "extension.cjs"),
76995
+ import_node_path85.default.join(here, "..", "dist", "pi-mcp-bridge", "extension.cjs")
76655
76996
  ];
76656
- const piMcpBridgePath = piMcpBridgeCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
76997
+ const piMcpBridgePath = piMcpBridgeCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76657
76998
  if (piMcpBridgePath) {
76658
76999
  logger.info("pi-mcp-bridge extension resolved", { path: piMcpBridgePath });
76659
77000
  } else {
@@ -76959,11 +77300,11 @@ async function startDaemon(config) {
76959
77300
  // 'persona/<pid>/owner',default 走 'default'。
76960
77301
  getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
76961
77302
  // guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
76962
- personaRoot: import_node_path84.default.join(config.dataDir, "personas"),
77303
+ personaRoot: import_node_path85.default.join(config.dataDir, "personas"),
76963
77304
  usersRoot
76964
77305
  },
76965
77306
  // workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
76966
- personaRoot: import_node_path84.default.join(config.dataDir, "personas"),
77307
+ personaRoot: import_node_path85.default.join(config.dataDir, "personas"),
76967
77308
  // v2 多人 persona 隔离:handler 派生 guest user-dir 放行
76968
77309
  usersRoot,
76969
77310
  // v2 Phase 6: whoami handler 装在 owner principal.displayName + persona 解析
@@ -77269,7 +77610,7 @@ async function startDaemon(config) {
77269
77610
  });
77270
77611
  shiftScheduler.start();
77271
77612
  logger.info("shift scheduler started", { shiftCount: shiftStore.list().length });
77272
- const larkBotStore = createLarkBotBindingStore(import_node_path84.default.join(config.dataDir, "personas"));
77613
+ const larkBotStore = createLarkBotBindingStore(import_node_path85.default.join(config.dataDir, "personas"));
77273
77614
  const larkBotCloud = createLarkBotCloudClient({
77274
77615
  api: config.clawosApi ?? DEFAULT_CLAWOS_API,
77275
77616
  getLoginPass: () => ownerIdentityStore.read()?.loginPass ?? null
@@ -77281,7 +77622,7 @@ async function startDaemon(config) {
77281
77622
  store: larkBotStore,
77282
77623
  fetchResource: (appId, messageId, fileKey, maxBytes, type) => larkBotCloud.fetchResource(appId, messageId, fileKey, maxBytes, type),
77283
77624
  // 图片落 guest userWorkDir 下(capId = lark-<chat_id>):CC 经 --add-dir + allowRead carve 可 Read
77284
- mediaRootFor: (chatId) => import_node_path84.default.join(deriveUserWorkDir(`lark-${chatId}`, usersRoot), "lark-media"),
77625
+ mediaRootFor: (chatId) => import_node_path85.default.join(deriveUserWorkDir(`lark-${chatId}`, usersRoot), "lark-media"),
77285
77626
  isShuttingDown: () => larkDraining,
77286
77627
  logger: {
77287
77628
  warn: (msg) => logger.warn(msg),
@@ -77594,8 +77935,8 @@ async function startDaemon(config) {
77594
77935
  const lines = [
77595
77936
  `Tunnel: ${r2.url}`,
77596
77937
  ...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
77597
- `Frpc config: ${import_node_path84.default.join(config.dataDir, "frpc.toml")}`,
77598
- `Frpc log: ${import_node_path84.default.join(logDir, "frpc.log")}`
77938
+ `Frpc config: ${import_node_path85.default.join(config.dataDir, "frpc.toml")}`,
77939
+ `Frpc log: ${import_node_path85.default.join(logDir, "frpc.log")}`
77599
77940
  ];
77600
77941
  const width2 = Math.max(...lines.map((l2) => l2.length));
77601
77942
  const bar = "\u2550".repeat(width2 + 4);
@@ -77608,8 +77949,8 @@ ${bar}
77608
77949
 
77609
77950
  `);
77610
77951
  try {
77611
- const connectPath = import_node_path84.default.join(config.dataDir, "connect.txt");
77612
- import_node_fs65.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
77952
+ const connectPath = import_node_path85.default.join(config.dataDir, "connect.txt");
77953
+ import_node_fs66.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
77613
77954
  } catch {
77614
77955
  }
77615
77956
  } catch (err) {
@@ -77708,9 +78049,9 @@ ${bar}
77708
78049
  };
77709
78050
  }
77710
78051
  function migrateDropPersonsDir(dataDir) {
77711
- const dir = import_node_path84.default.join(dataDir, "persons");
78052
+ const dir = import_node_path85.default.join(dataDir, "persons");
77712
78053
  try {
77713
- import_node_fs65.default.rmSync(dir, { recursive: true, force: true });
78054
+ import_node_fs66.default.rmSync(dir, { recursive: true, force: true });
77714
78055
  } catch {
77715
78056
  }
77716
78057
  }