@clawos-dev/clawd 0.2.617 → 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
  });
@@ -66070,13 +66366,13 @@ function mapSkillsListResponse(res) {
66070
66366
  const r2 = s2 ?? {};
66071
66367
  const name = str4(r2.name);
66072
66368
  if (!name) continue;
66073
- const path106 = str4(r2.path);
66369
+ const path107 = str4(r2.path);
66074
66370
  const description = str4(r2.description);
66075
66371
  const isPlugin = name.includes(":");
66076
66372
  out.push({
66077
66373
  name,
66078
66374
  source: isPlugin ? "plugin" : "project",
66079
- ...path106 ? { path: path106 } : {},
66375
+ ...path107 ? { path: path107 } : {},
66080
66376
  ...description ? { description } : {},
66081
66377
  ...isPlugin ? { plugin: name.split(":")[0] } : {}
66082
66378
  });
@@ -70686,7 +70982,7 @@ var ServerKeyStore = class {
70686
70982
  init_protocol();
70687
70983
 
70688
70984
  // src/handlers/index.ts
70689
- var import_node_path80 = __toESM(require("path"), 1);
70985
+ var import_node_path81 = __toESM(require("path"), 1);
70690
70986
 
70691
70987
  // src/handlers/session.ts
70692
70988
  init_protocol();
@@ -72513,45 +72809,65 @@ function buildEngineHandlers(deps, overrides = {}) {
72513
72809
  }
72514
72810
 
72515
72811
  // src/handlers/channels.ts
72812
+ var import_node_fs65 = __toESM(require("fs"), 1);
72813
+ var import_node_path72 = __toESM(require("path"), 1);
72516
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
+ }
72517
72846
  const get = async () => {
72518
72847
  return { response: deps.store.list() };
72519
72848
  };
72520
- const save = async (frame) => {
72849
+ const save = serialized(async (frame) => {
72521
72850
  const args = parseArgs2(SubscriptionChannelSaveArgsSchema, frame, "subscriptionChannel:save");
72522
- const channel = deps.store.save(args);
72523
- const state = deps.store.list();
72524
- if (state.activeChannelId === channel.id) {
72525
- applyCodexSubscriptionChannel({ codexHome: deps.codexHome, channel });
72526
- applyPiSubscriptionChannel({ agentDir: deps.agentDir, channel });
72527
- await deps.manager.getCapabilities("codex", { refresh: true });
72528
- }
72851
+ await transact(() => {
72852
+ const channel = deps.store.save(args);
72853
+ return deps.store.list().activeChannelId === channel.id ? channel : void 0;
72854
+ });
72529
72855
  return { response: deps.store.list() };
72530
- };
72531
- const del = async (frame) => {
72856
+ });
72857
+ const del = serialized(async (frame) => {
72532
72858
  const args = parseArgs2(SubscriptionChannelDeleteArgsSchema, frame, "subscriptionChannel:delete");
72533
- const wasActive = deps.store.list().activeChannelId === args.id;
72534
- deps.store.delete(args.id);
72535
- if (wasActive) {
72536
- const newActive = deps.store.getActive();
72537
- applyCodexSubscriptionChannel({ codexHome: deps.codexHome, channel: newActive });
72538
- applyPiSubscriptionChannel({ agentDir: deps.agentDir, channel: newActive });
72539
- if (newActive) {
72540
- await deps.manager.getCapabilities("codex", { refresh: true });
72541
- }
72542
- }
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
+ });
72543
72864
  return { response: { ok: true } };
72544
- };
72545
- const activate = async (frame) => {
72865
+ });
72866
+ const activate = serialized(async (frame) => {
72546
72867
  const args = parseArgs2(SubscriptionChannelActivateArgsSchema, frame, "subscriptionChannel:activate");
72547
- const channel = deps.store.setActive(args.id);
72548
- applyCodexSubscriptionChannel({ codexHome: deps.codexHome, channel });
72549
- applyPiSubscriptionChannel({ agentDir: deps.agentDir, channel });
72550
- if (channel) {
72551
- await deps.manager.getCapabilities("codex", { refresh: true });
72552
- }
72868
+ await transact(() => deps.store.setActive(args.id));
72553
72869
  return { response: { ok: true } };
72554
- };
72870
+ });
72555
72871
  return {
72556
72872
  "subscriptionChannel:get": get,
72557
72873
  "subscriptionChannel:save": save,
@@ -73520,21 +73836,21 @@ function computeMethodAccess(args) {
73520
73836
  }
73521
73837
 
73522
73838
  // src/version.ts
73523
- var version = "0.2.617".length > 0 ? "0.2.617" : "dev";
73839
+ var version = "0.2.618".length > 0 ? "0.2.618" : "dev";
73524
73840
 
73525
73841
  // src/cli-probe/probe.ts
73526
- var fs83 = __toESM(require("fs"), 1);
73527
- var path90 = __toESM(require("path"), 1);
73842
+ var fs84 = __toESM(require("fs"), 1);
73843
+ var path91 = __toESM(require("path"), 1);
73528
73844
  var PKG_NAME = "@clawos-dev/clawd";
73529
73845
  var BIN_NAME = "clawd";
73530
73846
  var MAX_PARENT_HOPS = 5;
73531
73847
  function probeGlobalCli(pathEnv) {
73532
73848
  if (!pathEnv) return null;
73533
- for (const dir of pathEnv.split(path90.delimiter)) {
73849
+ for (const dir of pathEnv.split(path91.delimiter)) {
73534
73850
  if (!dir) continue;
73535
73851
  let real;
73536
73852
  try {
73537
- real = fs83.realpathSync(path90.join(dir, BIN_NAME));
73853
+ real = fs84.realpathSync(path91.join(dir, BIN_NAME));
73538
73854
  } catch {
73539
73855
  continue;
73540
73856
  }
@@ -73544,15 +73860,15 @@ function probeGlobalCli(pathEnv) {
73544
73860
  return null;
73545
73861
  }
73546
73862
  function readOwnPackageVersion(entryPath) {
73547
- let dir = path90.dirname(entryPath);
73863
+ let dir = path91.dirname(entryPath);
73548
73864
  for (let i2 = 0; i2 < MAX_PARENT_HOPS; i2++) {
73549
73865
  try {
73550
- const raw = fs83.readFileSync(path90.join(dir, "package.json"), "utf8");
73866
+ const raw = fs84.readFileSync(path91.join(dir, "package.json"), "utf8");
73551
73867
  const pkg = JSON.parse(raw);
73552
73868
  if (pkg.name !== PKG_NAME) return null;
73553
73869
  return typeof pkg.version === "string" && pkg.version ? pkg.version : null;
73554
73870
  } catch {
73555
- const parent = path90.dirname(dir);
73871
+ const parent = path91.dirname(dir);
73556
73872
  if (parent === dir) return null;
73557
73873
  dir = parent;
73558
73874
  }
@@ -73728,7 +74044,7 @@ function buildPersonaHandlers(deps) {
73728
74044
  }
73729
74045
 
73730
74046
  // src/handlers/attachment.ts
73731
- var import_node_path72 = __toESM(require("path"), 1);
74047
+ var import_node_path73 = __toESM(require("path"), 1);
73732
74048
  init_protocol();
73733
74049
  init_protocol();
73734
74050
  function assertGuestAttachmentPath(ctx, absPath, personaRoot, method, usersRoot) {
@@ -73807,12 +74123,12 @@ function buildAttachmentHandlers(deps) {
73807
74123
  `session ${args.sessionId} scope unresolved`
73808
74124
  );
73809
74125
  }
73810
- const cwdAbs = import_node_path72.default.resolve(sessionFile.cwd);
73811
- 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);
73812
74128
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
73813
74129
  const entries = deps.groupFileStore.list(scope, args.sessionId);
73814
74130
  const entry = entries.find((e) => {
73815
- 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);
73816
74132
  return storedAbs === candidateAbs && !e.stale;
73817
74133
  });
73818
74134
  if (!entry) {
@@ -73836,7 +74152,7 @@ function buildAttachmentHandlers(deps) {
73836
74152
  if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
73837
74153
  const f2 = deps.sessionStore.read(sessionId);
73838
74154
  if (!f2) return;
73839
- 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);
73840
74156
  }
73841
74157
  const groupAdd = async (frame, _client, ctx) => {
73842
74158
  if (!deps.groupFileStore || !deps.getSessionScope) {
@@ -73851,8 +74167,8 @@ function buildAttachmentHandlers(deps) {
73851
74167
  if (!scope) {
73852
74168
  throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
73853
74169
  }
73854
- const cwdAbs = import_node_path72.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
73855
- 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);
73856
74172
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
73857
74173
  const from = args.origin === "agent" ? "agent" : ctx?.principal.kind === "owner" ? "owner" : "agent";
73858
74174
  const size = 0;
@@ -73911,19 +74227,19 @@ function buildAttachmentHandlers(deps) {
73911
74227
 
73912
74228
  // src/handlers/extension.ts
73913
74229
  var import_promises15 = __toESM(require("fs/promises"), 1);
73914
- var import_node_path77 = __toESM(require("path"), 1);
74230
+ var import_node_path78 = __toESM(require("path"), 1);
73915
74231
  init_protocol();
73916
74232
 
73917
74233
  // src/extension/bundle-zip.ts
73918
74234
  var import_promises12 = __toESM(require("fs/promises"), 1);
73919
- var import_node_path73 = __toESM(require("path"), 1);
74235
+ var import_node_path74 = __toESM(require("path"), 1);
73920
74236
  var import_node_crypto23 = __toESM(require("crypto"), 1);
73921
74237
  var import_jszip2 = __toESM(require_lib3(), 1);
73922
74238
  async function bundleExtensionDir(dir) {
73923
74239
  const entries = await listFilesSorted(dir);
73924
74240
  const zip = new import_jszip2.default();
73925
74241
  for (const rel of entries) {
73926
- const abs = import_node_path73.default.join(dir, rel);
74242
+ const abs = import_node_path74.default.join(dir, rel);
73927
74243
  const content = await import_promises12.default.readFile(abs);
73928
74244
  zip.file(rel, content, { date: FIXED_DATE });
73929
74245
  }
@@ -73944,7 +74260,7 @@ async function listFilesSorted(rootDir) {
73944
74260
  return out;
73945
74261
  }
73946
74262
  async function walk(absRoot, relPrefix, out) {
73947
- const dirAbs = import_node_path73.default.join(absRoot, relPrefix);
74263
+ const dirAbs = import_node_path74.default.join(absRoot, relPrefix);
73948
74264
  const entries = await import_promises12.default.readdir(dirAbs, { withFileTypes: true });
73949
74265
  for (const e of entries) {
73950
74266
  if (IGNORE_BASENAMES.has(e.name)) continue;
@@ -73998,25 +74314,25 @@ function computePublishCheck(args) {
73998
74314
 
73999
74315
  // src/extension/install-flow.ts
74000
74316
  var import_promises13 = __toESM(require("fs/promises"), 1);
74001
- var import_node_path75 = __toESM(require("path"), 1);
74317
+ var import_node_path76 = __toESM(require("path"), 1);
74002
74318
  var import_node_os28 = __toESM(require("os"), 1);
74003
74319
  var import_node_crypto24 = __toESM(require("crypto"), 1);
74004
74320
  var import_jszip3 = __toESM(require_lib3(), 1);
74005
74321
 
74006
74322
  // src/extension/paths.ts
74007
74323
  var import_node_os27 = __toESM(require("os"), 1);
74008
- var import_node_path74 = __toESM(require("path"), 1);
74324
+ var import_node_path75 = __toESM(require("path"), 1);
74009
74325
  function clawdHomeRoot(override) {
74010
- 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");
74011
74327
  }
74012
74328
  function extensionsRoot(override) {
74013
- return import_node_path74.default.join(clawdHomeRoot(override), "extensions");
74329
+ return import_node_path75.default.join(clawdHomeRoot(override), "extensions");
74014
74330
  }
74015
74331
  function publishedChannelsFile(override) {
74016
- return import_node_path74.default.join(clawdHomeRoot(override), "extensions-published.json");
74332
+ return import_node_path75.default.join(clawdHomeRoot(override), "extensions-published.json");
74017
74333
  }
74018
74334
  function bundleCacheRoot(override) {
74019
- return import_node_path74.default.join(clawdHomeRoot(override), "extension-bundles");
74335
+ return import_node_path75.default.join(clawdHomeRoot(override), "extension-bundles");
74020
74336
  }
74021
74337
 
74022
74338
  // src/extension/install-flow.ts
@@ -74043,7 +74359,7 @@ async function installFromChannel(args, deps) {
74043
74359
  throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
74044
74360
  }
74045
74361
  for (const name of Object.keys(zip.files)) {
74046
- if (name.includes("..") || name.startsWith("/") || import_node_path75.default.isAbsolute(name)) {
74362
+ if (name.includes("..") || name.startsWith("/") || import_node_path76.default.isAbsolute(name)) {
74047
74363
  throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
74048
74364
  }
74049
74365
  }
@@ -74075,7 +74391,7 @@ async function installFromChannel(args, deps) {
74075
74391
  );
74076
74392
  }
74077
74393
  const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
74078
- const destDir = import_node_path75.default.join(deps.extensionsRoot, localExtId);
74394
+ const destDir = import_node_path76.default.join(deps.extensionsRoot, localExtId);
74079
74395
  let destExists = false;
74080
74396
  try {
74081
74397
  await import_promises13.default.access(destDir);
@@ -74089,16 +74405,16 @@ async function installFromChannel(args, deps) {
74089
74405
  );
74090
74406
  }
74091
74407
  const stage = await import_promises13.default.mkdtemp(
74092
- 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}-`)
74093
74409
  );
74094
74410
  try {
74095
74411
  for (const [name, entry] of Object.entries(zip.files)) {
74096
- const dest = import_node_path75.default.join(stage, name);
74412
+ const dest = import_node_path76.default.join(stage, name);
74097
74413
  if (entry.dir) {
74098
74414
  await import_promises13.default.mkdir(dest, { recursive: true });
74099
74415
  continue;
74100
74416
  }
74101
- 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 });
74102
74418
  if (name === "manifest.json") {
74103
74419
  const rewritten = { ...parsed.data, id: localExtId };
74104
74420
  await import_promises13.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -74119,7 +74435,7 @@ async function installFromChannel(args, deps) {
74119
74435
 
74120
74436
  // src/extension/update-flow.ts
74121
74437
  var import_promises14 = __toESM(require("fs/promises"), 1);
74122
- var import_node_path76 = __toESM(require("path"), 1);
74438
+ var import_node_path77 = __toESM(require("path"), 1);
74123
74439
  var import_node_os29 = __toESM(require("os"), 1);
74124
74440
  var import_node_crypto25 = __toESM(require("crypto"), 1);
74125
74441
  var import_jszip4 = __toESM(require_lib3(), 1);
@@ -74136,11 +74452,11 @@ async function updateFromChannel(args, deps) {
74136
74452
  channelRef.extId,
74137
74453
  channelRef.ownerPrincipalId
74138
74454
  );
74139
- const liveDir = import_node_path76.default.join(deps.extensionsRoot, localExtId);
74455
+ const liveDir = import_node_path77.default.join(deps.extensionsRoot, localExtId);
74140
74456
  const prevDir = `${liveDir}.prev`;
74141
74457
  let existingVersion;
74142
74458
  try {
74143
- 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");
74144
74460
  const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
74145
74461
  if (!parsed2.success) {
74146
74462
  throw new UpdateError(
@@ -74173,7 +74489,7 @@ async function updateFromChannel(args, deps) {
74173
74489
  throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
74174
74490
  }
74175
74491
  for (const name of Object.keys(zip.files)) {
74176
- if (name.includes("..") || name.startsWith("/") || import_node_path76.default.isAbsolute(name)) {
74492
+ if (name.includes("..") || name.startsWith("/") || import_node_path77.default.isAbsolute(name)) {
74177
74493
  throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
74178
74494
  }
74179
74495
  }
@@ -74208,16 +74524,16 @@ async function updateFromChannel(args, deps) {
74208
74524
  await import_promises14.default.rm(prevDir, { recursive: true, force: true });
74209
74525
  await import_promises14.default.rename(liveDir, prevDir);
74210
74526
  const stage = await import_promises14.default.mkdtemp(
74211
- 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}-`)
74212
74528
  );
74213
74529
  try {
74214
74530
  for (const [name, entry] of Object.entries(zip.files)) {
74215
- const dest = import_node_path76.default.join(stage, name);
74531
+ const dest = import_node_path77.default.join(stage, name);
74216
74532
  if (entry.dir) {
74217
74533
  await import_promises14.default.mkdir(dest, { recursive: true });
74218
74534
  continue;
74219
74535
  }
74220
- 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 });
74221
74537
  if (name === "manifest.json") {
74222
74538
  const rewritten = { ...parsed.data, id: localExtId };
74223
74539
  await import_promises14.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -74284,7 +74600,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
74284
74600
  );
74285
74601
  }
74286
74602
  }
74287
- const manifestPath = import_node_path77.default.join(root, extId, "manifest.json");
74603
+ const manifestPath = import_node_path78.default.join(root, extId, "manifest.json");
74288
74604
  const manifest = await readManifest(root, extId);
74289
74605
  const next = { ...manifest, version: newVersion };
74290
74606
  const tmp = `${manifestPath}.tmp`;
@@ -74292,7 +74608,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
74292
74608
  await import_promises15.default.rename(tmp, manifestPath);
74293
74609
  }
74294
74610
  async function readManifest(root, extId) {
74295
- const file = import_node_path77.default.join(root, extId, "manifest.json");
74611
+ const file = import_node_path78.default.join(root, extId, "manifest.json");
74296
74612
  let raw;
74297
74613
  try {
74298
74614
  raw = await import_promises15.default.readFile(file, "utf8");
@@ -74376,7 +74692,7 @@ function buildExtensionHandlers(deps) {
74376
74692
  };
74377
74693
  async function buildSnapshotMeta(extId) {
74378
74694
  const manifest = await readManifest(deps.root, extId);
74379
- 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));
74380
74696
  return { manifest, contentHash: sha256, buffer };
74381
74697
  }
74382
74698
  const publish = async (frame, _client, ctx) => {
@@ -75204,7 +75520,7 @@ function buildVisitorHandlers(deps) {
75204
75520
 
75205
75521
  // src/extension/registry.ts
75206
75522
  var import_promises17 = __toESM(require("fs/promises"), 1);
75207
- var import_node_path78 = __toESM(require("path"), 1);
75523
+ var import_node_path79 = __toESM(require("path"), 1);
75208
75524
  async function loadAll(root) {
75209
75525
  let entries;
75210
75526
  try {
@@ -75217,13 +75533,13 @@ async function loadAll(root) {
75217
75533
  for (const ent of entries) {
75218
75534
  if (!ent.isDirectory()) continue;
75219
75535
  if (ent.name.startsWith(".")) continue;
75220
- 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));
75221
75537
  }
75222
75538
  records.sort((a2, b3) => a2.extId < b3.extId ? -1 : a2.extId > b3.extId ? 1 : 0);
75223
75539
  return records;
75224
75540
  }
75225
75541
  async function loadOne(dir, dirName) {
75226
- const manifestPath = import_node_path78.default.join(dir, "manifest.json");
75542
+ const manifestPath = import_node_path79.default.join(dir, "manifest.json");
75227
75543
  let raw;
75228
75544
  try {
75229
75545
  raw = await import_promises17.default.readFile(manifestPath, "utf8");
@@ -75268,7 +75584,7 @@ async function loadOne(dir, dirName) {
75268
75584
 
75269
75585
  // src/extension/uninstall.ts
75270
75586
  var import_promises18 = __toESM(require("fs/promises"), 1);
75271
- var import_node_path79 = __toESM(require("path"), 1);
75587
+ var import_node_path80 = __toESM(require("path"), 1);
75272
75588
  var UninstallError = class extends Error {
75273
75589
  constructor(code, message) {
75274
75590
  super(message);
@@ -75277,7 +75593,7 @@ var UninstallError = class extends Error {
75277
75593
  code;
75278
75594
  };
75279
75595
  async function uninstall(deps) {
75280
- const dir = import_node_path79.default.join(deps.root, deps.extId);
75596
+ const dir = import_node_path80.default.join(deps.root, deps.extId);
75281
75597
  try {
75282
75598
  await import_promises18.default.access(dir);
75283
75599
  } catch {
@@ -75495,7 +75811,7 @@ function buildMethodHandlers(deps) {
75495
75811
  broadcast: deps.broadcastToOwners
75496
75812
  }),
75497
75813
  ...buildMasterHandlers({
75498
- authorityTablePath: import_node_path80.default.join(deps.masterDataDir, "master-authority.json")
75814
+ authorityTablePath: import_node_path81.default.join(deps.masterDataDir, "master-authority.json")
75499
75815
  }),
75500
75816
  ...buildTopicHandlers({
75501
75817
  topicStore: deps.topicStore,
@@ -75638,7 +75954,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
75638
75954
 
75639
75955
  // src/extension/runtime.ts
75640
75956
  var import_node_child_process25 = require("child_process");
75641
- var import_node_path81 = __toESM(require("path"), 1);
75957
+ var import_node_path82 = __toESM(require("path"), 1);
75642
75958
  var import_promises19 = require("timers/promises");
75643
75959
 
75644
75960
  // src/extension/port-allocator.ts
@@ -75739,7 +76055,7 @@ var Runtime = class {
75739
76055
  /\$CLAWOS_EXT_PORT/g,
75740
76056
  String(port)
75741
76057
  );
75742
- const dir = import_node_path81.default.join(this.root, extId);
76058
+ const dir = import_node_path82.default.join(this.root, extId);
75743
76059
  const env = {
75744
76060
  ...process.env,
75745
76061
  CLAWOS_EXT_PORT: String(port),
@@ -75851,7 +76167,7 @@ ${handle.stderrTail}`
75851
76167
 
75852
76168
  // src/extension/published-channels.ts
75853
76169
  var import_promises20 = __toESM(require("fs/promises"), 1);
75854
- var import_node_path82 = __toESM(require("path"), 1);
76170
+ var import_node_path83 = __toESM(require("path"), 1);
75855
76171
  init_zod();
75856
76172
  var PublishedChannelsError = class extends Error {
75857
76173
  constructor(code, message) {
@@ -75950,7 +76266,7 @@ var PublishedChannelStore = class {
75950
76266
  )
75951
76267
  };
75952
76268
  const tmp = `${this.filePath}.tmp`;
75953
- 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 });
75954
76270
  await import_promises20.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
75955
76271
  await import_promises20.default.rename(tmp, this.filePath);
75956
76272
  }
@@ -75958,7 +76274,7 @@ var PublishedChannelStore = class {
75958
76274
 
75959
76275
  // src/extension/bundle-cache.ts
75960
76276
  var import_promises21 = __toESM(require("fs/promises"), 1);
75961
- var import_node_path83 = __toESM(require("path"), 1);
76277
+ var import_node_path84 = __toESM(require("path"), 1);
75962
76278
  var BundleCache = class {
75963
76279
  constructor(rootDir) {
75964
76280
  this.rootDir = rootDir;
@@ -75967,14 +76283,14 @@ var BundleCache = class {
75967
76283
  /** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
75968
76284
  async write(snapshotHash, buffer) {
75969
76285
  await import_promises21.default.mkdir(this.rootDir, { recursive: true });
75970
- const file = import_node_path83.default.join(this.rootDir, `${snapshotHash}.zip`);
76286
+ const file = import_node_path84.default.join(this.rootDir, `${snapshotHash}.zip`);
75971
76287
  const tmp = `${file}.tmp`;
75972
76288
  await import_promises21.default.writeFile(tmp, buffer, { mode: 384 });
75973
76289
  await import_promises21.default.rename(tmp, file);
75974
76290
  }
75975
76291
  /** Returns the bundle bytes, or null when the file doesn't exist. */
75976
76292
  async read(snapshotHash) {
75977
- const file = import_node_path83.default.join(this.rootDir, `${snapshotHash}.zip`);
76293
+ const file = import_node_path84.default.join(this.rootDir, `${snapshotHash}.zip`);
75978
76294
  try {
75979
76295
  return await import_promises21.default.readFile(file);
75980
76296
  } catch (e) {
@@ -75984,7 +76300,7 @@ var BundleCache = class {
75984
76300
  }
75985
76301
  /** Idempotent — missing file is not an error. */
75986
76302
  async delete(snapshotHash) {
75987
- const file = import_node_path83.default.join(this.rootDir, `${snapshotHash}.zip`);
76303
+ const file = import_node_path84.default.join(this.rootDir, `${snapshotHash}.zip`);
75988
76304
  await import_promises21.default.rm(file, { force: true });
75989
76305
  }
75990
76306
  };
@@ -76007,24 +76323,24 @@ async function startDaemon(config) {
76007
76323
  sampling: logShippingCfg.sampling,
76008
76324
  homeDir: import_node_os31.default.homedir()
76009
76325
  });
76010
- const logDir = import_node_path84.default.join(config.dataDir, "log");
76011
- 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 });
76012
76328
  const logger = createLogger({
76013
76329
  level: config.logLevel,
76014
- file: import_node_path84.default.join(logDir, "clawd.log"),
76330
+ file: import_node_path85.default.join(logDir, "clawd.log"),
76015
76331
  logClient
76016
76332
  });
76017
76333
  logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
76018
76334
  const screenIdleProbeLogger = createFileOnlyLogger({
76019
- file: import_node_path84.default.join(logDir, "screen-idle-probe.log"),
76335
+ file: import_node_path85.default.join(logDir, "screen-idle-probe.log"),
76020
76336
  level: "debug"
76021
76337
  });
76022
76338
  logger.info("screen-idle probe logger enabled", {
76023
- file: import_node_path84.default.join(logDir, "screen-idle-probe.log")
76339
+ file: import_node_path85.default.join(logDir, "screen-idle-probe.log")
76024
76340
  });
76025
76341
  const CAP_TARGETS = [
76026
- import_node_path84.default.join(logDir, "clawd.log"),
76027
- 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")
76028
76344
  ];
76029
76345
  const LOG_CAP_MAX_BYTES = 10 * 1024 * 1024;
76030
76346
  const LOG_CAP_KEEP_BYTES = 5 * 1024 * 1024;
@@ -76146,11 +76462,11 @@ async function startDaemon(config) {
76146
76462
  const agents = new AgentsScanner();
76147
76463
  const history = new ClaudeHistoryReader();
76148
76464
  let transport = null;
76149
- 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"));
76150
76466
  const subscriptionChannelStore = new SubscriptionChannelStore({ dataDir: config.dataDir });
76151
76467
  const activeSubscriptionChannel = subscriptionChannelStore.getActive();
76152
76468
  if (activeSubscriptionChannel) applyPiSubscriptionChannel({ channel: activeSubscriptionChannel });
76153
- const usersRoot = import_node_path84.default.join(config.dataDir, "users");
76469
+ const usersRoot = import_node_path85.default.join(config.dataDir, "users");
76154
76470
  const defaultsRoot = findDefaultsRoot(logger);
76155
76471
  if (defaultsRoot) {
76156
76472
  seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
@@ -76167,7 +76483,7 @@ async function startDaemon(config) {
76167
76483
  retirePersonaBuilder({ store: personaStore, logger });
76168
76484
  const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
76169
76485
  const dispatchStore = createDispatchStore({
76170
- filePath: import_node_path84.default.join(config.dataDir, "dispatch.json"),
76486
+ filePath: import_node_path85.default.join(config.dataDir, "dispatch.json"),
76171
76487
  now: () => Date.now(),
76172
76488
  onFlushError: (err) => logger.error("dispatch store flush failed", {
76173
76489
  reason: err instanceof Error ? err.message : String(err)
@@ -76176,7 +76492,7 @@ async function startDaemon(config) {
76176
76492
  await dispatchStore.load();
76177
76493
  dispatchStore.markInterruptedAsFailed((/* @__PURE__ */ new Date()).toISOString());
76178
76494
  const channelStore = createChannelStore({
76179
- filePath: import_node_path84.default.join(config.dataDir, "channels.json"),
76495
+ filePath: import_node_path85.default.join(config.dataDir, "channels.json"),
76180
76496
  now: () => Date.now(),
76181
76497
  genId: () => `ch-${(0, import_node_crypto27.randomUUID)().slice(0, 8)}`,
76182
76498
  onFlushError: (err) => logger.error("channel store flush failed", {
@@ -76185,7 +76501,7 @@ async function startDaemon(config) {
76185
76501
  });
76186
76502
  await channelStore.load();
76187
76503
  const topicStore = createTopicStore({
76188
- filePath: import_node_path84.default.join(config.dataDir, "topics.json"),
76504
+ filePath: import_node_path85.default.join(config.dataDir, "topics.json"),
76189
76505
  now: () => Date.now(),
76190
76506
  genId: () => `tp-${(0, import_node_crypto27.randomUUID)().slice(0, 8)}`,
76191
76507
  onFlushError: (err) => logger.error("topic store flush failed", {
@@ -76212,12 +76528,12 @@ async function startDaemon(config) {
76212
76528
  });
76213
76529
  }
76214
76530
  });
76215
- 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));
76216
76532
  const mcpConfigs = [];
76217
76533
  const secretsBundleRoot = findSecretsBundleRoot(logger);
76218
- 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);
76219
76535
  const readSecrets = () => readSecretTable({ bundleRoot: secretsBundleRoot, overrideDir: localSecretsDir, logger });
76220
- const githubTokenFile = import_node_path84.default.join(localSecretsDir, GITHUB_TOKEN_FILE);
76536
+ const githubTokenFile = import_node_path85.default.join(localSecretsDir, GITHUB_TOKEN_FILE);
76221
76537
  const githubIdentity = createGithubIdentity({
76222
76538
  resolve: () => resolveGithubAuth({ exec: runCommand, fileToken: () => readEnvFileVar(githubTokenFile, GITHUB_TOKEN_VAR) }),
76223
76539
  store: (token) => storeGithubAuth({
@@ -76255,22 +76571,22 @@ async function startDaemon(config) {
76255
76571
  void githubIdentity.refresh();
76256
76572
  return renderPersonaMcpSecrets({
76257
76573
  personaId: personaId2,
76258
- personaDir: import_node_path84.default.join(config.dataDir, "personas", personaId2),
76574
+ personaDir: import_node_path85.default.join(config.dataDir, "personas", personaId2),
76259
76575
  secrets,
76260
- outDir: import_node_path84.default.join(config.dataDir, "persona-mcp"),
76576
+ outDir: import_node_path85.default.join(config.dataDir, "persona-mcp"),
76261
76577
  logger
76262
76578
  });
76263
76579
  };
76264
76580
  const mcpDaemonUrl = `http://127.0.0.1:${config.port}`;
76265
76581
  const dispatchServerCandidates = [
76266
- import_node_path84.default.join(here, "dispatch", "mcp-server.cjs"),
76582
+ import_node_path85.default.join(here, "dispatch", "mcp-server.cjs"),
76267
76583
  // 生产 dist/index → dist/dispatch/mcp-server.cjs
76268
- import_node_path84.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
76584
+ import_node_path85.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
76269
76585
  // dev tsx src/index → ../dist/dispatch/mcp-server.cjs
76270
76586
  ];
76271
- const dispatchServerScriptPath = dispatchServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
76587
+ const dispatchServerScriptPath = dispatchServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76272
76588
  if (dispatchServerScriptPath) {
76273
- 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");
76274
76590
  const dispatchCfgPath = writeDispatchMcpConfig({
76275
76591
  dataDir: config.dataDir,
76276
76592
  serverScriptPath: dispatchServerScriptPath,
@@ -76290,12 +76606,12 @@ async function startDaemon(config) {
76290
76606
  });
76291
76607
  }
76292
76608
  const ticketServerCandidates = [
76293
- import_node_path84.default.join(here, "ticket", "mcp-server.cjs"),
76294
- 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")
76295
76611
  ];
76296
- const ticketServerScriptPath = ticketServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
76612
+ const ticketServerScriptPath = ticketServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76297
76613
  if (ticketServerScriptPath) {
76298
- 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");
76299
76615
  const ticketCfgPath = writeTicketMcpConfig({
76300
76616
  dataDir: config.dataDir,
76301
76617
  serverScriptPath: ticketServerScriptPath,
@@ -76317,12 +76633,12 @@ async function startDaemon(config) {
76317
76633
  });
76318
76634
  }
76319
76635
  const shiftServerCandidates = [
76320
- import_node_path84.default.join(here, "shift", "mcp-server.cjs"),
76321
- 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")
76322
76638
  ];
76323
- const shiftServerScriptPath = shiftServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
76639
+ const shiftServerScriptPath = shiftServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76324
76640
  if (shiftServerScriptPath) {
76325
- 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");
76326
76642
  const shiftCfgPath = await writeShiftMcpConfig({
76327
76643
  dataDir: config.dataDir,
76328
76644
  serverScriptPath: shiftServerScriptPath,
@@ -76343,12 +76659,12 @@ async function startDaemon(config) {
76343
76659
  );
76344
76660
  }
76345
76661
  const inboxServerCandidates = [
76346
- import_node_path84.default.join(here, "inbox", "mcp-server.cjs"),
76347
- 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")
76348
76664
  ];
76349
- const inboxServerScriptPath = inboxServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
76665
+ const inboxServerScriptPath = inboxServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76350
76666
  if (inboxServerScriptPath) {
76351
- 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");
76352
76668
  const inboxCfgPath = await writeInboxMcpConfig({
76353
76669
  dataDir: config.dataDir,
76354
76670
  serverScriptPath: inboxServerScriptPath,
@@ -76369,10 +76685,10 @@ async function startDaemon(config) {
76369
76685
  );
76370
76686
  }
76371
76687
  const peerOpsServerCandidates = [
76372
- import_node_path84.default.join(here, "peer-ops", "mcp-server.cjs"),
76373
- 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")
76374
76690
  ];
76375
- const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
76691
+ const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76376
76692
  if (peerOpsServerScriptPath) {
76377
76693
  const peerOpsCfgPath = writePeerOpsMcpConfig({
76378
76694
  dataDir: config.dataDir,
@@ -76392,12 +76708,12 @@ async function startDaemon(config) {
76392
76708
  );
76393
76709
  }
76394
76710
  const rpcToolServerCandidates = [
76395
- import_node_path84.default.join(here, "rpc-tool", "mcp-server.cjs"),
76396
- 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")
76397
76713
  ];
76398
- const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
76714
+ const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76399
76715
  if (rpcToolServerScriptPath) {
76400
- 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");
76401
76717
  const rpcToolCfgPath = writeRpcToolMcpConfig({
76402
76718
  dataDir: config.dataDir,
76403
76719
  serverScriptPath: rpcToolServerScriptPath,
@@ -76418,7 +76734,7 @@ async function startDaemon(config) {
76418
76734
  );
76419
76735
  }
76420
76736
  const shiftStore = createShiftStore({
76421
- filePath: import_node_path84.default.join(config.dataDir, "shift.json"),
76737
+ filePath: import_node_path85.default.join(config.dataDir, "shift.json"),
76422
76738
  ownerIdProvider: () => ownerPrincipalId,
76423
76739
  now: () => Date.now()
76424
76740
  });
@@ -76440,7 +76756,7 @@ async function startDaemon(config) {
76440
76756
  getAdapter,
76441
76757
  historyReader: history,
76442
76758
  dataDir: config.dataDir,
76443
- personaRoot: import_node_path84.default.join(config.dataDir, "personas"),
76759
+ personaRoot: import_node_path85.default.join(config.dataDir, "personas"),
76444
76760
  // dispatch / shift 自动化 spawn 按 persona 绑定 tool 起 B session(codex persona 用 codex)。
76445
76761
  // personaRegistry 声明在 manager 之后(同作用域 const,调用时机在启动完成后,无 TDZ 风险)。
76446
76762
  getPersonaDefaults: (personaId2) => personaRegistry.get(personaId2),
@@ -76501,10 +76817,10 @@ async function startDaemon(config) {
76501
76817
  // 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
76502
76818
  attachmentGroup: {
76503
76819
  onFileEdit: (input) => {
76504
- 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);
76505
76821
  let size = 0;
76506
76822
  try {
76507
- size = import_node_fs65.default.statSync(absPath).size;
76823
+ size = import_node_fs66.default.statSync(absPath).size;
76508
76824
  } catch (err) {
76509
76825
  logger.warn("attachment.onFileEdit stat failed", {
76510
76826
  sessionId: input.sessionId,
@@ -76545,9 +76861,9 @@ async function startDaemon(config) {
76545
76861
  logger.info("projects.seed-dropped", { dropped: droppedSeed.dropped, backup: droppedSeed.backup });
76546
76862
  }
76547
76863
  const projectsStore = new ProjectsStore({
76548
- file: import_node_path84.default.join(config.dataDir, "projects.json"),
76864
+ file: import_node_path85.default.join(config.dataDir, "projects.json"),
76549
76865
  clawdDir: config.dataDir,
76550
- 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"),
76551
76867
  logger
76552
76868
  });
76553
76869
  const observer = new SessionObserver({
@@ -76622,13 +76938,13 @@ async function startDaemon(config) {
76622
76938
  runner?.confirmCloudCancelled();
76623
76939
  });
76624
76940
  registerAdapter("claude", claudeAdapter);
76625
- const codexIsolatedHome = import_node_path84.default.join(config.dataDir, "codex-home");
76941
+ const codexIsolatedHome = import_node_path85.default.join(config.dataDir, "codex-home");
76626
76942
  try {
76627
- import_node_fs65.default.mkdirSync(codexIsolatedHome, { recursive: true });
76943
+ import_node_fs66.default.mkdirSync(codexIsolatedHome, { recursive: true });
76628
76944
  for (const f2 of ["auth.json", "config.toml"]) {
76629
- const link = import_node_path84.default.join(codexIsolatedHome, f2);
76630
- const target = import_node_path84.default.join(import_node_os31.default.homedir(), ".codex", f2);
76631
- 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);
76632
76948
  }
76633
76949
  } catch (err) {
76634
76950
  logger.warn("codex isolated home setup failed", { err: String(err) });
@@ -76639,17 +76955,17 @@ async function startDaemon(config) {
76639
76955
  logger,
76640
76956
  historyReader: new CodexHistoryReader({
76641
76957
  roots: codexRolloutRoots(config.dataDir),
76642
- 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"),
76643
76959
  logger
76644
76960
  }),
76645
76961
  // projectPaths 每次调用现取 —— 用户新建 project 后立即生效,不用重启 daemon
76646
76962
  codexHomeFor: (cwd) => resolveCodexHome({
76647
76963
  cwd,
76648
- personaRoot: import_node_path84.default.join(config.dataDir, "personas"),
76964
+ personaRoot: import_node_path85.default.join(config.dataDir, "personas"),
76649
76965
  // 必须用 listMerged(Codex registry ∪ 叠加层):只用本地 list() 的话,用户在
76650
76966
  // Codex 里建的 project 不在表里,在它下面开的会话会被误判成隔离 → Codex 侧看不到
76651
76967
  projectPaths: projectsStore.listMerged().map((x2) => x2.path),
76652
- 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"),
76653
76969
  isolatedHome: codexIsolatedHome
76654
76970
  }),
76655
76971
  codexHomeForThread: (threadId) => locateCodexThread(codexRolloutRoots(config.dataDir), threadId)?.home,
@@ -76675,10 +76991,10 @@ async function startDaemon(config) {
76675
76991
  );
76676
76992
  registerAdapter(PI_CLOUD_TOOL_ID, new CloudPiAdapter({ client: cloudGateway, history: cloudHistorySource, logger }));
76677
76993
  const piMcpBridgeCandidates = [
76678
- import_node_path84.default.join(here, "pi-mcp-bridge", "extension.cjs"),
76679
- 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")
76680
76996
  ];
76681
- const piMcpBridgePath = piMcpBridgeCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
76997
+ const piMcpBridgePath = piMcpBridgeCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76682
76998
  if (piMcpBridgePath) {
76683
76999
  logger.info("pi-mcp-bridge extension resolved", { path: piMcpBridgePath });
76684
77000
  } else {
@@ -76984,11 +77300,11 @@ async function startDaemon(config) {
76984
77300
  // 'persona/<pid>/owner',default 走 'default'。
76985
77301
  getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
76986
77302
  // guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
76987
- personaRoot: import_node_path84.default.join(config.dataDir, "personas"),
77303
+ personaRoot: import_node_path85.default.join(config.dataDir, "personas"),
76988
77304
  usersRoot
76989
77305
  },
76990
77306
  // workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
76991
- personaRoot: import_node_path84.default.join(config.dataDir, "personas"),
77307
+ personaRoot: import_node_path85.default.join(config.dataDir, "personas"),
76992
77308
  // v2 多人 persona 隔离:handler 派生 guest user-dir 放行
76993
77309
  usersRoot,
76994
77310
  // v2 Phase 6: whoami handler 装在 owner principal.displayName + persona 解析
@@ -77294,7 +77610,7 @@ async function startDaemon(config) {
77294
77610
  });
77295
77611
  shiftScheduler.start();
77296
77612
  logger.info("shift scheduler started", { shiftCount: shiftStore.list().length });
77297
- const larkBotStore = createLarkBotBindingStore(import_node_path84.default.join(config.dataDir, "personas"));
77613
+ const larkBotStore = createLarkBotBindingStore(import_node_path85.default.join(config.dataDir, "personas"));
77298
77614
  const larkBotCloud = createLarkBotCloudClient({
77299
77615
  api: config.clawosApi ?? DEFAULT_CLAWOS_API,
77300
77616
  getLoginPass: () => ownerIdentityStore.read()?.loginPass ?? null
@@ -77306,7 +77622,7 @@ async function startDaemon(config) {
77306
77622
  store: larkBotStore,
77307
77623
  fetchResource: (appId, messageId, fileKey, maxBytes, type) => larkBotCloud.fetchResource(appId, messageId, fileKey, maxBytes, type),
77308
77624
  // 图片落 guest userWorkDir 下(capId = lark-<chat_id>):CC 经 --add-dir + allowRead carve 可 Read
77309
- 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"),
77310
77626
  isShuttingDown: () => larkDraining,
77311
77627
  logger: {
77312
77628
  warn: (msg) => logger.warn(msg),
@@ -77619,8 +77935,8 @@ async function startDaemon(config) {
77619
77935
  const lines = [
77620
77936
  `Tunnel: ${r2.url}`,
77621
77937
  ...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
77622
- `Frpc config: ${import_node_path84.default.join(config.dataDir, "frpc.toml")}`,
77623
- `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")}`
77624
77940
  ];
77625
77941
  const width2 = Math.max(...lines.map((l2) => l2.length));
77626
77942
  const bar = "\u2550".repeat(width2 + 4);
@@ -77633,8 +77949,8 @@ ${bar}
77633
77949
 
77634
77950
  `);
77635
77951
  try {
77636
- const connectPath = import_node_path84.default.join(config.dataDir, "connect.txt");
77637
- 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 });
77638
77954
  } catch {
77639
77955
  }
77640
77956
  } catch (err) {
@@ -77733,9 +78049,9 @@ ${bar}
77733
78049
  };
77734
78050
  }
77735
78051
  function migrateDropPersonsDir(dataDir) {
77736
- const dir = import_node_path84.default.join(dataDir, "persons");
78052
+ const dir = import_node_path85.default.join(dataDir, "persons");
77737
78053
  try {
77738
- import_node_fs65.default.rmSync(dir, { recursive: true, force: true });
78054
+ import_node_fs66.default.rmSync(dir, { recursive: true, force: true });
77739
78055
  } catch {
77740
78056
  }
77741
78057
  }