@clawos-dev/clawd 0.2.614 → 0.2.615

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.
Files changed (2) hide show
  1. package/dist/cli.cjs +659 -1468
  2. package/package.json +1 -1
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: path107, errorMaps, issueData } = params;
454
- const fullPath = [...path107, ...issueData.path || []];
453
+ const { data, path: path106, errorMaps, issueData } = params;
454
+ const fullPath = [...path106, ...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, path107, key) {
765
+ constructor(parent, value, path106, key) {
766
766
  this._cachedPath = [];
767
767
  this.parent = parent;
768
768
  this.data = value;
769
- this._path = path107;
769
+ this._path = path106;
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 path107 = req.path;
10360
- _req.url = typeof path107 === "string" ? path107 : req.url ? req.url.path || req.url : void 0;
10359
+ const path106 = req.path;
10360
+ _req.url = typeof path106 === "string" ? path106 : 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(path107) {
10525
+ function parsePath(path106) {
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 < path107.length; i2++) {
10532
- const char = path107[i2];
10531
+ for (let i2 = 0; i2 < path106.length; i2++) {
10532
+ const char = path106[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 path107 of paths) {
10664
- const parts = parsePath(path107);
10663
+ for (const path106 of paths) {
10664
+ const parts = parsePath(path106);
10665
10665
  if (parts.includes("*")) {
10666
- redactWildcardPath(obj, parts, censor, path107, remove);
10666
+ redactWildcardPath(obj, parts, censor, path106, 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, path107) => {
10752
- const fullPath = [...pathArray.slice(0, pathLength), ...path107];
10751
+ const wrappedCensor = typeof censor === "function" ? (value, path106) => {
10752
+ const fullPath = [...pathArray.slice(0, pathLength), ...path106];
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 path107 of pathsToClone) {
10788
- const parts = parsePath(path107);
10787
+ for (const path106 of pathsToClone) {
10788
+ const parts = parsePath(path106);
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(path107) {
10841
- if (typeof path107 !== "string") {
10840
+ function validatePath(path106) {
10841
+ if (typeof path106 !== "string") {
10842
10842
  throw new Error("Paths must be (non-empty) strings");
10843
10843
  }
10844
- if (path107 === "") {
10844
+ if (path106 === "") {
10845
10845
  throw new Error("Invalid redaction path ()");
10846
10846
  }
10847
- if (path107.includes("..")) {
10848
- throw new Error(`Invalid redaction path (${path107})`);
10847
+ if (path106.includes("..")) {
10848
+ throw new Error(`Invalid redaction path (${path106})`);
10849
10849
  }
10850
- if (path107.includes(",")) {
10851
- throw new Error(`Invalid redaction path (${path107})`);
10850
+ if (path106.includes(",")) {
10851
+ throw new Error(`Invalid redaction path (${path106})`);
10852
10852
  }
10853
10853
  let bracketCount = 0;
10854
10854
  let inQuotes = false;
10855
10855
  let quoteChar = "";
10856
- for (let i2 = 0; i2 < path107.length; i2++) {
10857
- const char = path107[i2];
10856
+ for (let i2 = 0; i2 < path106.length; i2++) {
10857
+ const char = path106[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 (${path107})`);
10871
+ throw new Error(`Invalid redaction path (${path106})`);
10872
10872
  }
10873
10873
  }
10874
10874
  }
10875
10875
  if (bracketCount !== 0) {
10876
- throw new Error(`Invalid redaction path (${path107})`);
10876
+ throw new Error(`Invalid redaction path (${path106})`);
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 path107 of paths) {
10884
- validatePath(path107);
10883
+ for (const path106 of paths) {
10884
+ validatePath(path106);
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, path107) => {
11053
- return censor(value, [k3, ...path107]);
11052
+ const wrappedCensor = typeof censor === "function" ? (value, path106) => {
11053
+ return censor(value, [k3, ...path106]);
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 fs96 = require("fs");
11271
+ var fs95 = require("fs");
11272
11272
  var EventEmitter2 = require("events");
11273
11273
  var inherits = require("util").inherits;
11274
- var path107 = require("path");
11274
+ var path106 = 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) fs96.mkdirSync(path107.dirname(file), { recursive: true });
11329
- const fd = fs96.openSync(file, flags, mode);
11328
+ if (sonic.mkdir) fs95.mkdirSync(path106.dirname(file), { recursive: true });
11329
+ const fd = fs95.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
- fs96.mkdir(path107.dirname(file), { recursive: true }, (err) => {
11336
+ fs95.mkdir(path106.dirname(file), { recursive: true }, (err) => {
11337
11337
  if (err) return fileOpened(err);
11338
- fs96.open(file, flags, mode, fileOpened);
11338
+ fs95.open(file, flags, mode, fileOpened);
11339
11339
  });
11340
11340
  } else {
11341
- fs96.open(file, flags, mode, fileOpened);
11341
+ fs95.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 = () => fs96.writeSync(this.fd, this._writingBuf);
11383
- fsWrite = () => fs96.write(this.fd, this._writingBuf, this.release);
11382
+ fsWriteSync = () => fs95.writeSync(this.fd, this._writingBuf);
11383
+ fsWrite = () => fs95.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 fs96.writeSync(this.fd, this._writingBuf);
11392
+ return fs95.writeSync(this.fd, this._writingBuf);
11393
11393
  }
11394
- return fs96.writeSync(this.fd, this._writingBuf, "utf8");
11394
+ return fs95.writeSync(this.fd, this._writingBuf, "utf8");
11395
11395
  };
11396
11396
  fsWrite = () => {
11397
11397
  if (Buffer.isBuffer(this._writingBuf)) {
11398
- return fs96.write(this.fd, this._writingBuf, this.release);
11398
+ return fs95.write(this.fd, this._writingBuf, this.release);
11399
11399
  }
11400
- return fs96.write(this.fd, this._writingBuf, "utf8", this.release);
11400
+ return fs95.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
- fs96.fsyncSync(this.fd);
11457
+ fs95.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
- fs96.fsync(this.fd, (err) => {
11571
+ fs95.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
- fs96.close(fd, (err) => {
11673
+ fs95.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) ? fs96.writeSync(this.fd, buf) : fs96.writeSync(this.fd, buf, "utf8");
11722
+ const n2 = Buffer.isBuffer(buf) ? fs95.writeSync(this.fd, buf) : fs95.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
- fs96.fsyncSync(this.fd);
11738
+ fs95.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 = fs96.writeSync(this.fd, buf);
11759
+ const n2 = fs95.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) ? fs96.writeSync(this.fd, this._writingBuf) : fs96.writeSync(this.fd, this._writingBuf, "utf8");
11787
+ const written = Buffer.isBuffer(this._writingBuf) ? fs95.writeSync(this.fd, this._writingBuf) : fs95.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
- fs96.write(this.fd, this._writingBuf, release2);
11793
+ fs95.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 = fs96.writeSync(this.fd, this._writingBuf);
11802
+ const written = fs95.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
- fs96.write(this.fd, this._writingBuf, release2);
11811
+ fs95.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
- fs96.fsync(sonic.fd, closeWrapped);
11827
+ fs95.fsync(sonic.fd, closeWrapped);
11828
11828
  } catch {
11829
11829
  }
11830
11830
  function closeWrapped() {
11831
11831
  if (sonic.fd !== 1 && sonic.fd !== 2) {
11832
- fs96.close(sonic.fd, done);
11832
+ fs95.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(path107, added, removed, oldPosInc, options) {
14968
- var last = path107.lastComponent;
14967
+ addToPath: function addToPath(path106, added, removed, oldPosInc, options) {
14968
+ var last = path106.lastComponent;
14969
14969
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
14970
14970
  return {
14971
- oldPos: path107.oldPos + oldPosInc,
14971
+ oldPos: path106.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: path107.oldPos + oldPosInc,
14981
+ oldPos: path106.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 path107 = typeof rec6.path === "string" ? rec6.path : null;
15563
+ const path106 = typeof rec6.path === "string" ? rec6.path : null;
15564
15564
  const content = typeof rec6.content === "string" ? rec6.content : null;
15565
- if (!path107 || content == null) return null;
15566
- const entry = { path: path107, content };
15565
+ if (!path106 || content == null) return null;
15566
+ const entry = { path: path106, 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 path107 = typeof rec6.path === "string" ? rec6.path : null;
16432
+ const path106 = typeof rec6.path === "string" ? rec6.path : null;
16433
16433
  const content = typeof rec6.content === "string" ? rec6.content : null;
16434
- if (!path107 || content == null) return null;
16435
- const out = { path: path107, content };
16434
+ if (!path106 || content == null) return null;
16435
+ const out = { path: path106, 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(path107) {
37410
- var parts = path107.split("/");
37409
+ exports2.resolve = function(path106) {
37410
+ var parts = path106.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(path107) {
43264
- if (path107.slice(-1) === "/") {
43265
- path107 = path107.substring(0, path107.length - 1);
43263
+ var parentFolder = function(path106) {
43264
+ if (path106.slice(-1) === "/") {
43265
+ path106 = path106.substring(0, path106.length - 1);
43266
43266
  }
43267
- var lastSlash = path107.lastIndexOf("/");
43268
- return lastSlash > 0 ? path107.substring(0, lastSlash) : "";
43267
+ var lastSlash = path106.lastIndexOf("/");
43268
+ return lastSlash > 0 ? path106.substring(0, lastSlash) : "";
43269
43269
  };
43270
- var forceTrailingSlash = function(path107) {
43271
- if (path107.slice(-1) !== "/") {
43272
- path107 += "/";
43270
+ var forceTrailingSlash = function(path106) {
43271
+ if (path106.slice(-1) !== "/") {
43272
+ path106 += "/";
43273
43273
  }
43274
- return path107;
43274
+ return path106;
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_path86.default.dirname(opts.recordPath);
44276
+ const dir = import_node_path85.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_fs67.default.mkdirSync(dir, { recursive: true });
44291
- stream = import_node_fs67.default.createWriteStream(opts.recordPath, { flags: "a" });
44290
+ import_node_fs66.default.mkdirSync(dir, { recursive: true });
44291
+ stream = import_node_fs66.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_fs67, import_node_path86;
44316
+ var import_node_fs66, import_node_path85;
44317
44317
  var init_recorder = __esm({
44318
44318
  "src/run-case/recorder.ts"() {
44319
44319
  "use strict";
44320
- import_node_fs67 = __toESM(require("fs"), 1);
44321
- import_node_path86 = __toESM(require("path"), 1);
44320
+ import_node_fs66 = __toESM(require("fs"), 1);
44321
+ import_node_path85 = __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_fs68.mkdtempSync)(import_node_path87.default.join(import_node_os32.default.tmpdir(), "clawd-runcase-"));
44364
+ const cwd = opts.cwd ?? (0, import_node_fs67.mkdtempSync)(import_node_path86.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_fs68.rmSync)(cwd, { recursive: true, force: true });
44525
+ (0, import_node_fs67.rmSync)(cwd, { recursive: true, force: true });
44526
44526
  } catch {
44527
44527
  }
44528
44528
  }
44529
44529
  return exitCode ?? 0;
44530
44530
  }
44531
- var import_node_fs68, import_node_os32, import_node_path87;
44531
+ var import_node_fs67, import_node_os32, import_node_path86;
44532
44532
  var init_controller = __esm({
44533
44533
  "src/run-case/controller.ts"() {
44534
44534
  "use strict";
44535
- import_node_fs68 = require("fs");
44535
+ import_node_fs67 = require("fs");
44536
44536
  import_node_os32 = __toESM(require("os"), 1);
44537
- import_node_path87 = __toESM(require("path"), 1);
44537
+ import_node_path86 = __toESM(require("path"), 1);
44538
44538
  init_claude();
44539
44539
  init_stdout_splitter();
44540
44540
  init_permission_stdio();
@@ -44806,10 +44806,10 @@ Env (advanced):
44806
44806
  `;
44807
44807
 
44808
44808
  // src/index.ts
44809
- var import_node_path85 = __toESM(require("path"), 1);
44810
- var import_node_fs66 = __toESM(require("fs"), 1);
44809
+ var import_node_path84 = __toESM(require("path"), 1);
44810
+ var import_node_fs65 = __toESM(require("fs"), 1);
44811
44811
  var import_node_os31 = __toESM(require("os"), 1);
44812
- var import_node_crypto29 = require("crypto");
44812
+ var import_node_crypto27 = require("crypto");
44813
44813
  var import_node_url6 = require("url");
44814
44814
 
44815
44815
  // src/logger.ts
@@ -46672,7 +46672,6 @@ function applyCommand(state, command, deps) {
46672
46672
  void _titleGeneratedAt;
46673
46673
  const nextFile = {
46674
46674
  ...rest,
46675
- ...command.nextCloudExecutionId ? { cloudExecutionId: command.nextCloudExecutionId } : {},
46676
46675
  ...command.nextToolSessionId ? { toolSessionId: command.nextToolSessionId } : {},
46677
46676
  updatedAt: nowIso(deps)
46678
46677
  };
@@ -46735,18 +46734,6 @@ function reduceSessionInner(state, input, deps) {
46735
46734
  case "inject-events": {
46736
46735
  return applyEventBatch(state, input.events, deps);
46737
46736
  }
46738
- case "cloud-recovery-absent": {
46739
- if (!state.file.cloudPendingCommand) return { state, effects: [] };
46740
- const next = cloneState(state);
46741
- next.file = { ...next.file, cloudPendingCommand: void 0, cloudGatewaySessionId: void 0 };
46742
- return { state: next, effects: [{ kind: "persist-file", file: next.file }, sessionInfoFrame(next.file)] };
46743
- }
46744
- case "cloud-gateway-ready": {
46745
- if (state.file.cloudGatewaySessionId === input.gatewaySessionId) return { state, effects: [] };
46746
- const next = cloneState(state);
46747
- next.file = { ...next.file, cloudGatewaySessionId: input.gatewaySessionId };
46748
- return { state: next, effects: [{ kind: "persist-file", file: next.file }] };
46749
- }
46750
46737
  case "cloud-command-prepared": {
46751
46738
  const pending = state.file.cloudPendingCommand;
46752
46739
  const turn = state.file.cloudPendingTurns?.find((item) => item.id === input.commandId);
@@ -47452,7 +47439,7 @@ var SessionRunner = class {
47452
47439
  applyEffect(effect) {
47453
47440
  switch (effect.kind) {
47454
47441
  case "spawn":
47455
- this.doSpawn(this.recoveringCloud && effect.ctx.cloudGatewaySessionId ? { ...effect.ctx, cloudAttachOnly: true } : effect.ctx);
47442
+ this.doSpawn(effect.ctx);
47456
47443
  break;
47457
47444
  case "kill":
47458
47445
  if (this.session) {
@@ -47601,15 +47588,6 @@ var SessionRunner = class {
47601
47588
  kind: CLOUD_HISTORY_REFRESH_KIND,
47602
47589
  synchronized
47603
47590
  }, "broadcast"),
47604
- onRecoveryAbsent: () => {
47605
- this.input({ kind: "cloud-recovery-absent" });
47606
- this.hooks.broadcastFrame({ type: "session:control", sessionId: this.state.file.sessionId, kind: CLOUD_HISTORY_REFRESH_KIND, synchronized: true }, "broadcast");
47607
- },
47608
- onGatewayReady: (gatewaySessionId) => {
47609
- if (this.state.file.cloudGatewaySessionId === gatewaySessionId) return;
47610
- this.hooks.store.write({ ...this.state.file, cloudGatewaySessionId: gatewaySessionId });
47611
- this.input({ kind: "cloud-gateway-ready", gatewaySessionId });
47612
- },
47613
47591
  onCommandPrepared: (commandId, text, prepared) => {
47614
47592
  const pending = this.state.file.cloudPendingTurns?.find((turn) => turn.id === commandId) ?? this.state.file.cloudPendingCommand;
47615
47593
  if (!pending || pending.id !== commandId || prepared && pending.text !== text) return false;
@@ -49012,7 +48990,7 @@ var SessionManager = class {
49012
48990
  }
49013
48991
  return { response: normalized, broadcast };
49014
48992
  }
49015
- newSession(args, nextCloudExecutionId) {
48993
+ newSession(args) {
49016
48994
  const existingFile = this.getFile(args.sessionId);
49017
48995
  this.titleGenPending.get(args.sessionId)?.abort();
49018
48996
  this.titleGenPending.delete(args.sessionId);
@@ -49023,7 +49001,7 @@ var SessionManager = class {
49023
49001
  const { value, broadcast } = this.withCollector(() => {
49024
49002
  runner.input({
49025
49003
  kind: "command",
49026
- command: { kind: "new", ...nextToolSessionId ? { nextToolSessionId } : {}, ...nextCloudExecutionId ? { nextCloudExecutionId } : {} }
49004
+ command: { kind: "new", ...nextToolSessionId ? { nextToolSessionId } : {} }
49027
49005
  });
49028
49006
  return runner.getState().file;
49029
49007
  });
@@ -49059,7 +49037,6 @@ var SessionManager = class {
49059
49037
  void _titleGeneratedAt;
49060
49038
  const updated = {
49061
49039
  ...rest,
49062
- ...nextCloudExecutionId ? { cloudExecutionId: nextCloudExecutionId } : {},
49063
49040
  ...nextToolSessionId ? { toolSessionId: nextToolSessionId } : {},
49064
49041
  updatedAt: nowIso2(this.deps)
49065
49042
  };
@@ -49073,7 +49050,7 @@ var SessionManager = class {
49073
49050
  if (!this.cloudCancel) throw new Error("cloud canceller is not configured");
49074
49051
  await this.cloudCancel(file, runner);
49075
49052
  } else runner?.confirmCloudCancelled();
49076
- return this.newSession(args, file.cloudGatewaySessionId ? (0, import_node_crypto3.randomUUID)() : void 0);
49053
+ return this.newSession(args);
49077
49054
  }
49078
49055
  return this.newSession(args);
49079
49056
  }
@@ -52928,9 +52905,9 @@ var CentralClientError = class extends Error {
52928
52905
  cause;
52929
52906
  status;
52930
52907
  };
52931
- async function centralRequest(opts, path107, init) {
52908
+ async function centralRequest(opts, path106, init) {
52932
52909
  const f2 = opts.fetchImpl ?? globalThis.fetch;
52933
- const url = `${opts.api.replace(/\/+$/, "")}${path107}`;
52910
+ const url = `${opts.api.replace(/\/+$/, "")}${path106}`;
52934
52911
  const ctrl = new AbortController();
52935
52912
  const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
52936
52913
  let res;
@@ -53966,8 +53943,8 @@ function turnStartInput(text, resolveImage) {
53966
53943
  const items = [];
53967
53944
  let leftover = text;
53968
53945
  for (const m3 of text.matchAll(SKILL_RE)) {
53969
- const [marker, name, path107] = m3;
53970
- items.push({ type: "skill", name, path: path107 });
53946
+ const [marker, name, path106] = m3;
53947
+ items.push({ type: "skill", name, path: path106 });
53971
53948
  leftover = leftover.replace(marker, "");
53972
53949
  }
53973
53950
  for (const m3 of text.matchAll(ATTACHMENT_RE2)) {
@@ -61342,10 +61319,10 @@ function createGithubApi(args) {
61342
61319
  const doFetch = args.fetch ?? fetch;
61343
61320
  const seal = args.seal ?? sealWithSodium;
61344
61321
  const timeoutMs = args.timeoutMs ?? TIMEOUT_MS;
61345
- async function request(method, path107, body) {
61322
+ async function request(method, path106, body) {
61346
61323
  let res;
61347
61324
  try {
61348
- res = await doFetch(`${API}${path107}`, {
61325
+ res = await doFetch(`${API}${path106}`, {
61349
61326
  method,
61350
61327
  headers: {
61351
61328
  Authorization: `Bearer ${args.token}`,
@@ -61370,8 +61347,8 @@ function createGithubApi(args) {
61370
61347
  }
61371
61348
  return { status: res.status, json };
61372
61349
  }
61373
- async function must(method, path107, what, body) {
61374
- const r2 = await request(method, path107, body);
61350
+ async function must(method, path106, what, body) {
61351
+ const r2 = await request(method, path106, body);
61375
61352
  if (r2.status < 200 || r2.status >= 300) throw new GithubApiError(r2.status, explain(r2.status, what, r2.json));
61376
61353
  return r2.json;
61377
61354
  }
@@ -61416,9 +61393,9 @@ function createGithubApi(args) {
61416
61393
  return { env: x2.name, ...Number.isFinite(at3) ? { setAt: at3 } : {} };
61417
61394
  });
61418
61395
  },
61419
- async getJson(path107) {
61396
+ async getJson(path106) {
61420
61397
  try {
61421
- const r2 = await request("GET", path107);
61398
+ const r2 = await request("GET", path106);
61422
61399
  return r2.status >= 200 && r2.status < 300 ? r2.json : void 0;
61423
61400
  } catch {
61424
61401
  return void 0;
@@ -62970,8 +62947,8 @@ function refreshPathFromLoginShell() {
62970
62947
  timeout: 3e3,
62971
62948
  stdio: ["ignore", "pipe", "ignore"]
62972
62949
  });
62973
- const path107 = out.trim();
62974
- if (path107) process.env.PATH = path107;
62950
+ const path106 = out.trim();
62951
+ if (path106) process.env.PATH = path106;
62975
62952
  } catch {
62976
62953
  }
62977
62954
  }
@@ -63773,10 +63750,10 @@ function createCloudPersonaBotClient(opts) {
63773
63750
  const f2 = opts.fetchImpl ?? fetch;
63774
63751
  const base = opts.api.replace(/\/+$/, "");
63775
63752
  const route = (personaId2) => `/api/lark-bot/cloud/${encodeURIComponent(personaId2)}`;
63776
- async function request(method, path107, body) {
63753
+ async function request(method, path106, body) {
63777
63754
  const pass = opts.getLoginPass();
63778
63755
  if (!pass) throw new LarkBotCloudError("\u98DE\u4E66\u767B\u5F55\u540E\u624D\u80FD\u7BA1\u7406\u4E91 Persona \u7684 Bot", 401);
63779
- const response = await f2(base + path107, {
63756
+ const response = await f2(base + path106, {
63780
63757
  method,
63781
63758
  headers: { authorization: `Bearer ${pass}`, "content-type": "application/json" },
63782
63759
  ...body ? { body: JSON.stringify(body) } : {},
@@ -63785,7 +63762,7 @@ function createCloudPersonaBotClient(opts) {
63785
63762
  const json = await response.json().catch(() => ({}));
63786
63763
  if (!response.ok) {
63787
63764
  const detail = typeof json.message === "string" ? json.message : `HTTP ${response.status}`;
63788
- throw new LarkBotCloudError(`cloud bot ${method} ${path107}: ${detail}`, response.status);
63765
+ throw new LarkBotCloudError(`cloud bot ${method} ${path106}: ${detail}`, response.status);
63789
63766
  }
63790
63767
  return json;
63791
63768
  }
@@ -64771,16 +64748,8 @@ async function forwardPeerExecToPeer(args) {
64771
64748
  init_protocol();
64772
64749
  init_protocol();
64773
64750
  var CLOUD_WORKSPACE_SLOT = "{{WORKSPACE}}";
64774
- var CLOUD_TURN_HEADER = "x-clawd-turn";
64775
- var CLOUD_TURN_HEADER_START = "start";
64776
64751
  var GATEWAY_ROUTES = {
64777
64752
  healthz: () => "/healthz",
64778
- session: (personaId2) => `/p/${encodeURIComponent(personaId2)}/session`,
64779
- sessionSend: (personaId2, sessionId) => `/p/${encodeURIComponent(personaId2)}/session/${encodeURIComponent(sessionId)}`,
64780
- sessionMirror: (personaId2, sessionId) => `/p/${encodeURIComponent(personaId2)}/session/${encodeURIComponent(sessionId)}/mirror`,
64781
- eventSession: (personaId2) => `/p/${encodeURIComponent(personaId2)}/session/events`,
64782
- eventCancel: (personaId2) => `/p/${encodeURIComponent(personaId2)}/session/events:cancel`,
64783
- eventSend: (personaId2, sessionId) => `/p/${encodeURIComponent(personaId2)}/session/events/${encodeURIComponent(sessionId)}`,
64784
64753
  turn: (personaId2) => `/p/${encodeURIComponent(personaId2)}/v1/chat/completions`,
64785
64754
  turnCommand: (personaId2, turnId) => `/p/${encodeURIComponent(personaId2)}/turns/${encodeURIComponent(turnId)}/commands`,
64786
64755
  conversationCancel: (personaId2, conversationId) => `/p/${encodeURIComponent(personaId2)}/conversations/${encodeURIComponent(conversationId)}:cancel`,
@@ -64882,49 +64851,6 @@ var CloudGatewayClient = class {
64882
64851
  const list = await this.fetchDeployments(trimSlash(gatewayUrl));
64883
64852
  return list.find((p3) => p3.personaId === gatewayPersonaId)?.connectors ?? [];
64884
64853
  }
64885
- /**
64886
- * 会话通道。返回的行流在 Pod 就绪前就能 write:写入先攒着,收到 `ready` 控制行后按序 POST 出去——
64887
- * 编排那头一构造就发 initialize,不用知道 Pod 还在起。
64888
- * `toolSessionId`:调用方预分配的引擎会话 id(pi 的 --session-id;codex 的 thread id 是协议内的、不传),进 open 的 body `engineSessionId`
64889
- * (契约 2026-09-18 §3.2)。`instructions`:会话级指令(pi-cloud 的连接 intro,工作目录写 CLOUD_WORKSPACE_SLOT),进 body `instructions`,
64890
- * gateway 落成 Pod 里的 /run/agent/instructions.md(契约 §3.1);codex-cloud 不发(走协议内 developerInstructions)。
64891
- * `expectedEngine` 是 session 创建时的引擎;gateway 在起 Pod 前与当前发布核对。
64892
- */
64893
- async openSession(personaId2, opts = {}) {
64894
- const { apiKey, gatewayUrl } = await this.credentials();
64895
- return openHttpLineStream({
64896
- fetchImpl: this.fetchImpl,
64897
- gatewayUrl,
64898
- apiKey,
64899
- personaId: personaId2,
64900
- ...opts.toolSessionId ? { engineSessionId: opts.toolSessionId } : {},
64901
- ...opts.instructions ? { instructions: opts.instructions } : {},
64902
- ...opts.purpose ? { purpose: opts.purpose } : {},
64903
- ...opts.expectedEngine ? { expectedEngine: opts.expectedEngine } : {},
64904
- logger: this.deps.logger
64905
- });
64906
- }
64907
- async openEventSession(personaId2, opts) {
64908
- const { apiKey, gatewayUrl } = await this.credentials();
64909
- const health = await this.fetchImpl(gatewayUrl + GATEWAY_ROUTES.healthz());
64910
- if (!health.ok || (await health.json()).sessionProtocolVersion !== 2) throw new Error("\u4E91 gateway \u7684\u4F1A\u8BDD\u534F\u8BAE\u7248\u672C\u4E0D\u5339\u914D\uFF0C\u8BF7\u5148\u5347\u7EA7 gateway");
64911
- return openHttpEventSession({
64912
- fetchImpl: this.fetchImpl,
64913
- gatewayUrl,
64914
- apiKey,
64915
- personaId: personaId2,
64916
- clientSessionId: opts.clientSessionId,
64917
- gatewaySessionId: opts.gatewaySessionId,
64918
- engineSessionId: opts.toolSessionId,
64919
- instructions: opts.instructions,
64920
- purpose: opts.purpose,
64921
- expectedEngine: opts.expectedEngine,
64922
- effort: opts.effort,
64923
- personaMode: opts.personaMode,
64924
- attachOnly: opts.attachOnly,
64925
- logger: this.deps.logger
64926
- });
64927
- }
64928
64854
  async openTurn(personaId2, opts) {
64929
64855
  const { apiKey, gatewayUrl } = await this.credentials();
64930
64856
  const health = await this.fetchImpl(gatewayUrl + GATEWAY_ROUTES.healthz());
@@ -64951,23 +64877,6 @@ var CloudGatewayClient = class {
64951
64877
  });
64952
64878
  if (!res.ok) throw new Error(`gateway conversation cancel returned ${res.status}`);
64953
64879
  }
64954
- async cancelEventSession(personaId2, clientSessionId, gatewaySessionId) {
64955
- const { apiKey, gatewayUrl } = await this.credentials();
64956
- const res = await this.fetchImpl(gatewayUrl + GATEWAY_ROUTES.eventCancel(personaId2), {
64957
- method: "POST",
64958
- headers: { authorization: `Bearer ${apiKey}`, "content-type": "application/json" },
64959
- body: JSON.stringify({ protocolVersion: 2, clientSessionId, gatewaySessionId })
64960
- });
64961
- if (!res.ok) {
64962
- let message = `gateway \u56DE ${res.status}`;
64963
- try {
64964
- const body = await res.json();
64965
- if (typeof body.message === "string") message = body.message;
64966
- } catch {
64967
- }
64968
- throw new Error(message);
64969
- }
64970
- }
64971
64880
  /**
64972
64881
  * 看板数据(design 2026-09-23-cloud-persona-metrics §3.8):GET /metrics/<persona>?window&entry,**原样回**状态码与 body——
64973
64882
  * 形状真源在 gateway 的 cloud-persona-metrics,daemon 只是替浏览器拿本机 api key 转一跳。拿不到 key / 连不上 / 超时 → 抛(路由折成 502)。
@@ -65024,7 +64933,7 @@ var CloudGatewayClient = class {
65024
64933
  }
65025
64934
  };
65026
64935
  function openHttpTurn(opts) {
65027
- const { fetchImpl, gatewayUrl, apiKey, personaId: personaId2, conversationId, turnId, text, expectedEngine, engineSessionId, instructions, effort, personaMode, logger } = opts;
64936
+ const { fetchImpl, gatewayUrl, apiKey, personaId: personaId2, conversationId, turnId, text, expectedEngine, engineSessionId, instructions, effort, personaMode, purpose, logger } = opts;
65028
64937
  const body = JSON.stringify({
65029
64938
  messages: [{ role: "user", content: text }],
65030
64939
  stream: true,
@@ -65033,6 +64942,7 @@ function openHttpTurn(opts) {
65033
64942
  conversationId,
65034
64943
  turnId,
65035
64944
  expectedEngine,
64945
+ ...purpose ? { purpose } : {},
65036
64946
  ...engineSessionId ? { engineSessionId } : {},
65037
64947
  ...instructions ? { instructions } : {},
65038
64948
  ...effort ? { effort } : {},
@@ -65169,525 +65079,12 @@ function openHttpTurn(opts) {
65169
65079
  close: finish
65170
65080
  };
65171
65081
  }
65172
- function openHttpEventSession(opts) {
65173
- const { fetchImpl, gatewayUrl, apiKey, personaId: personaId2, clientSessionId, gatewaySessionId, engineSessionId, instructions, purpose, effort, personaMode, attachOnly, expectedEngine, logger } = opts;
65174
- const headers = { authorization: `Bearer ${apiKey}`, "content-type": "application/json" };
65175
- let abort = new AbortController();
65176
- const eventCbs = [];
65177
- const controlCbs = [];
65178
- const closeCbs = [];
65179
- const earlyEvents = [];
65180
- const earlyControls = [];
65181
- let closed = false;
65182
- let readyControl = null;
65183
- let errorControl = null;
65184
- let sessionId = gatewaySessionId ?? null;
65185
- let lastSeq = 0;
65186
- let everReady = false;
65187
- let connected = false;
65188
- const attachWaiters = [];
65189
- let resolveReady;
65190
- let rejectReady;
65191
- const ready = new Promise((resolve9, reject) => {
65192
- resolveReady = resolve9;
65193
- rejectReady = reject;
65194
- });
65195
- void ready.catch(() => {
65196
- });
65197
- let sendChain = Promise.resolve();
65198
- const emitControl = (control) => {
65199
- if (control.kind === "ready") readyControl = control;
65200
- if (control.kind === "error") errorControl = control;
65201
- if (!controlCbs.length) earlyControls.push(control);
65202
- for (const cb of controlCbs) cb(control);
65203
- };
65204
- const finish = (message) => {
65205
- if (closed) return;
65206
- if (message) emitControl({ kind: "error", message });
65207
- closed = true;
65208
- rejectReady(new Error(message ?? "event session closed"));
65209
- abort.abort();
65210
- for (const resolve9 of attachWaiters.splice(0)) resolve9();
65211
- for (const cb of closeCbs) cb();
65212
- };
65213
- const waitForAttach = () => connected ? Promise.resolve() : new Promise((resolve9) => {
65214
- attachWaiters.push(resolve9);
65215
- });
65216
- const retryWait = () => new Promise((resolve9) => {
65217
- const timer = setTimeout(resolve9, 250);
65218
- timer.unref?.();
65219
- abort.signal.addEventListener("abort", () => {
65220
- clearTimeout(timer);
65221
- resolve9();
65222
- }, { once: true });
65223
- });
65224
- void (async () => {
65225
- while (!closed) {
65226
- abort = new AbortController();
65227
- let fatal = false;
65228
- try {
65229
- const res = await fetchImpl(gatewayUrl + GATEWAY_ROUTES.eventSession(personaId2), {
65230
- method: "POST",
65231
- headers,
65232
- body: JSON.stringify({ protocolVersion: 2, clientSessionId, afterSeq: lastSeq, ...sessionId ? { gatewaySessionId: sessionId } : {}, expectedEngine, ...engineSessionId ? { engineSessionId } : {}, ...instructions ? { instructions } : {}, ...purpose ? { purpose } : {}, ...effort ? { effort } : {}, ...personaMode ? { personaMode } : {}, ...attachOnly ? { attachOnly: true } : {} }),
65233
- signal: abort.signal
65234
- });
65235
- if (!res.ok || !res.body) {
65236
- let message = `gateway \u56DE ${res.status}`;
65237
- let code;
65238
- try {
65239
- const body = await res.json();
65240
- if (typeof body.message === "string") message = body.message;
65241
- code = body.error;
65242
- if (body.error === "SESSION_VERSION_EXPIRED" && !message.includes("SESSION_VERSION_EXPIRED")) message = `SESSION_VERSION_EXPIRED: ${message}`;
65243
- } catch {
65244
- }
65245
- if ((attachOnly || sessionId) && res.status === 404 && code === "SESSION_NOT_FOUND") {
65246
- emitControl({ kind: "closed", reason: "not-found" });
65247
- finish();
65248
- return;
65249
- }
65250
- if (res.status === 426 || res.status === 400 || res.status === 401 || res.status === 403 || res.status === 409 || res.status === 410 || code === "CLIENT_UPGRADE_REQUIRED") {
65251
- fatal = true;
65252
- finish(message);
65253
- return;
65254
- }
65255
- throw new Error(message);
65256
- }
65257
- connected = true;
65258
- for (const resolve9 of attachWaiters.splice(0)) resolve9();
65259
- const reader = res.body.getReader();
65260
- const decoder = new TextDecoder();
65261
- let pending = "";
65262
- for (; ; ) {
65263
- const { value, done } = await reader.read();
65264
- if (done) break;
65265
- pending += decoder.decode(value, { stream: true });
65266
- const lines = pending.split("\n");
65267
- pending = lines.pop() ?? "";
65268
- for (const line of lines) {
65269
- if (!line.trim()) continue;
65270
- const data = JSON.parse(line);
65271
- if (data.clawd === "events") {
65272
- if (typeof data.seq === "number") {
65273
- if (data.seq <= lastSeq) continue;
65274
- lastSeq = data.seq;
65275
- }
65276
- const events = ParsedEventSchema.array().parse(data.events);
65277
- if (!eventCbs.length) earlyEvents.push(events);
65278
- for (const cb of eventCbs) cb(events);
65279
- continue;
65280
- }
65281
- const control = parseControlLine(line);
65282
- if (!control) throw new Error("gateway event stream contains an unknown line");
65283
- if (control.kind === "ready") {
65284
- if (!control.session) throw new Error("gateway ready line has no session id");
65285
- if (control.engine !== expectedEngine) {
65286
- finish(control.engine ? `SESSION_VERSION_EXPIRED: \u5F53\u524D Pod \u662F ${control.engine}\uFF0C\u8FD9\u6761\u4F1A\u8BDD\u9700\u8981 ${expectedEngine}` : "gateway \u7684 ready \u63A7\u5236\u884C\u6CA1\u5E26 engine\uFF0Cgateway \u592A\u8001\uFF0C\u5148\u5347 gateway");
65287
- return;
65288
- }
65289
- sessionId = control.session;
65290
- everReady = true;
65291
- resolveReady();
65292
- }
65293
- emitControl(control);
65294
- if (control.kind === "error") {
65295
- finish();
65296
- return;
65297
- }
65298
- if (control.kind === "closed") {
65299
- finish();
65300
- return;
65301
- }
65302
- }
65303
- }
65304
- connected = false;
65305
- } catch (e) {
65306
- if (!closed) {
65307
- if (e instanceof SyntaxError || e.name === "ZodError") {
65308
- finish("gateway event stream contains invalid data");
65309
- return;
65310
- }
65311
- connected = false;
65312
- logger?.warn("cloud event stream failed; reconnecting", { code: e.code, name: e.name, ready: everReady });
65313
- }
65314
- }
65315
- if (!closed && !fatal) await retryWait();
65316
- }
65317
- })();
65318
- return {
65319
- send(command) {
65320
- const next = sendChain.then(async () => {
65321
- await ready;
65322
- while (!closed) {
65323
- await waitForAttach();
65324
- if (!sessionId) continue;
65325
- let res;
65326
- try {
65327
- res = await fetchImpl(gatewayUrl + GATEWAY_ROUTES.eventSend(personaId2, sessionId), { method: "POST", headers, body: JSON.stringify(command) });
65328
- } catch {
65329
- connected = false;
65330
- abort.abort();
65331
- await retryWait();
65332
- continue;
65333
- }
65334
- if (res.ok) return;
65335
- if (res.status === 404 || res.status >= 500) {
65336
- connected = false;
65337
- abort.abort();
65338
- await retryWait();
65339
- continue;
65340
- }
65341
- let message = `gateway \u56DE ${res.status}`;
65342
- try {
65343
- const body = await res.json();
65344
- if (typeof body.message === "string") message = body.message;
65345
- } catch {
65346
- }
65347
- throw new Error(message);
65348
- }
65349
- throw new Error("event session closed");
65350
- });
65351
- sendChain = next.catch(() => {
65352
- });
65353
- return next;
65354
- },
65355
- onEvents(cb) {
65356
- const first = !eventCbs.length;
65357
- eventCbs.push(cb);
65358
- if (first) for (const events of earlyEvents.splice(0)) cb(events);
65359
- },
65360
- onControl(cb) {
65361
- const first = !controlCbs.length;
65362
- controlCbs.push(cb);
65363
- if (first) for (const control of earlyControls.splice(0)) cb(control);
65364
- else {
65365
- if (readyControl) cb(readyControl);
65366
- if (errorControl) cb(errorControl);
65367
- }
65368
- },
65369
- onClose(cb) {
65370
- closeCbs.push(cb);
65371
- if (closed) cb();
65372
- },
65373
- close() {
65374
- finish();
65375
- }
65376
- };
65377
- }
65378
- function parseControlLine(line) {
65379
- let o2;
65380
- try {
65381
- o2 = JSON.parse(line);
65382
- } catch {
65383
- return null;
65384
- }
65385
- if (!o2 || typeof o2 !== "object" || !("clawd" in o2)) return null;
65386
- const r2 = o2;
65387
- switch (r2.clawd) {
65388
- case "queued":
65389
- return { kind: "queued", running: typeof r2.running === "number" ? r2.running : 0 };
65390
- case "ready":
65391
- return {
65392
- kind: "ready",
65393
- session: typeof r2.session === "string" ? r2.session : "",
65394
- personaDir: typeof r2.personaDir === "string" ? r2.personaDir : "",
65395
- workDir: typeof r2.workDir === "string" ? r2.workDir : "",
65396
- ...typeof r2.model === "string" ? { model: r2.model } : {},
65397
- ...typeof r2.engine === "string" ? { engine: r2.engine } : {},
65398
- ...typeof r2.replayGap === "boolean" ? { replayGap: r2.replayGap } : {},
65399
- ...typeof r2.historySynchronized === "boolean" ? { historySynchronized: r2.historySynchronized } : {},
65400
- ...typeof r2.activeTurn === "boolean" ? { activeTurn: r2.activeTurn } : {}
65401
- };
65402
- case "error":
65403
- return { kind: "error", message: typeof r2.message === "string" ? r2.message : "gateway error" };
65404
- case "closed":
65405
- return { kind: "closed", reason: typeof r2.reason === "string" ? r2.reason : "unknown" };
65406
- case "history":
65407
- return { kind: "history", synchronized: r2.synchronized === true };
65408
- default:
65409
- return { kind: "ping" };
65410
- }
65411
- }
65412
- function openHttpLineStream(opts) {
65413
- const { fetchImpl, gatewayUrl, apiKey, personaId: personaId2, engineSessionId, instructions, purpose, expectedEngine, logger } = opts;
65414
- const headers = { authorization: `Bearer ${apiKey}`, "content-type": "application/json" };
65415
- const ac = new AbortController();
65416
- const lineCbs = [];
65417
- const closeCbs = [];
65418
- const controlCbs = [];
65419
- let sessionId = null;
65420
- let closed = false;
65421
- let closedWith = null;
65422
- let readyWith = null;
65423
- const pending = [];
65424
- let nextIsTurnStart = false;
65425
- let sendChain = Promise.resolve();
65426
- const finish = () => {
65427
- if (closed) return;
65428
- closed = true;
65429
- for (const cb of closeCbs) cb();
65430
- };
65431
- const emitControl = (c2) => {
65432
- if (c2.kind === "error") closedWith = c2;
65433
- if (c2.kind === "ready") readyWith = c2;
65434
- for (const cb of controlCbs) cb(c2);
65435
- };
65436
- const fail = (message) => {
65437
- if (closed) return;
65438
- emitControl({ kind: "error", message });
65439
- ac.abort();
65440
- finish();
65441
- };
65442
- const post = (line, turnStart) => {
65443
- if (closed || !sessionId) return Promise.resolve();
65444
- const url = gatewayUrl + GATEWAY_ROUTES.sessionSend(personaId2, sessionId);
65445
- return fetchImpl(url, { method: "POST", headers: turnStart ? { ...headers, [CLOUD_TURN_HEADER]: CLOUD_TURN_HEADER_START } : headers, body: line + "\n" }).then((res) => {
65446
- if (res.status === 404) {
65447
- finish();
65448
- return;
65449
- }
65450
- if (!res.ok) {
65451
- logger?.warn("cloud session send failed", { status: res.status });
65452
- fail(
65453
- res.status === 401 ? "\u8C03\u7528 key \u5DF2\u5931\u6548\uFF08\u64A4\u9500\u6216\u91CD\u65B0\u751F\u6210\u8FC7\uFF09\uFF0C\u8FD9\u6761\u4F1A\u8BDD\u65AD\u4E86\u3002\u5230\u300C\u8BBE\u7F6E \u2192 \u8D26\u53F7\u300D\u6216\u8FD9\u4E2A persona \u7684\u5361\u7247\u4E0A\u751F\u6210\u4E00\u628A\uFF0C\u518D\u5F00\u65B0\u4F1A\u8BDD" : `\u4E0A\u884C\u53D1\u4E0D\u51FA\u53BB\uFF08gateway \u56DE ${res.status}\uFF09\uFF0C\u8FD9\u6761\u4F1A\u8BDD\u65AD\u4E86`
65454
- );
65455
- }
65456
- }).catch((e) => {
65457
- if (closed) return;
65458
- logger?.warn("cloud session send error", { message: e.message });
65459
- fail(`\u4E0A\u884C\u53D1\u4E0D\u51FA\u53BB\uFF08${e.message}\uFF09\uFF0C\u8FD9\u6761\u4F1A\u8BDD\u65AD\u4E86`);
65460
- });
65461
- };
65462
- const postMirror = async (turn) => {
65463
- if (closed || !sessionId) return;
65464
- const url = gatewayUrl + GATEWAY_ROUTES.sessionMirror(personaId2, sessionId);
65465
- try {
65466
- const res = await fetchImpl(url, { method: "POST", headers, body: turn ? JSON.stringify({ turn: { outcome: turn.outcome, ...turn.afterFirstByteMs !== void 0 ? { afterFirstByteMs: turn.afterFirstByteMs } : {} } }) : "" });
65467
- if (!res.ok) logger?.warn("cloud session mirror failed", { status: res.status });
65468
- } catch (e) {
65469
- if (!closed) logger?.warn("cloud session mirror error", { message: e.message });
65470
- }
65471
- };
65472
- const flush = () => {
65473
- for (const { line, turnStart } of pending.splice(0)) sendChain = sendChain.then(() => post(line, turnStart));
65474
- };
65475
- void (async () => {
65476
- let res;
65477
- try {
65478
- res = await fetchImpl(gatewayUrl + GATEWAY_ROUTES.session(personaId2), {
65479
- method: "POST",
65480
- headers,
65481
- body: JSON.stringify({ ...engineSessionId ? { engineSessionId } : {}, ...instructions ? { instructions } : {}, ...purpose ? { purpose } : {}, ...expectedEngine ? { expectedEngine } : {} }),
65482
- signal: ac.signal
65483
- });
65484
- } catch (e) {
65485
- if (!closed) emitControl({ kind: "error", message: `\u8FDE\u4E0D\u4E0A gateway\uFF1A${e.message}` });
65486
- finish();
65487
- return;
65488
- }
65489
- if (!res.ok || !res.body) {
65490
- let message = `gateway \u56DE ${res.status}`;
65491
- try {
65492
- const body = await res.json();
65493
- if (typeof body.message === "string") message = body.message;
65494
- else if (typeof body.error === "string") message = body.error;
65495
- if (body.error === "SESSION_VERSION_EXPIRED" && !message.includes("SESSION_VERSION_EXPIRED")) message = `SESSION_VERSION_EXPIRED: ${message}`;
65496
- } catch {
65497
- }
65498
- emitControl({ kind: "error", message });
65499
- finish();
65500
- return;
65501
- }
65502
- const reader = res.body.getReader();
65503
- const decoder = new TextDecoder();
65504
- let buf = "";
65505
- let stop = false;
65506
- try {
65507
- for (; ; ) {
65508
- if (stop) break;
65509
- const { value, done } = await reader.read();
65510
- if (done) break;
65511
- buf += decoder.decode(value, { stream: true });
65512
- const lines = buf.split("\n");
65513
- buf = lines.pop() ?? "";
65514
- for (const raw of lines) {
65515
- const line = raw.trim();
65516
- if (!line) continue;
65517
- const control = parseControlLine(line);
65518
- if (control) {
65519
- if (control.kind === "ready") {
65520
- if (!control.session) {
65521
- emitControl({ kind: "error", message: "gateway \u7684 ready \u63A7\u5236\u884C\u6CA1\u5E26 session id" });
65522
- stop = true;
65523
- ac.abort();
65524
- void reader.cancel().catch(() => {
65525
- });
65526
- break;
65527
- }
65528
- if (!control.personaDir || !control.workDir) {
65529
- emitControl({ kind: "error", message: "gateway \u7684 ready \u63A7\u5236\u884C\u6CA1\u5E26 Pod \u8DEF\u5F84\uFF08personaDir / workDir\uFF09\uFF0Cgateway \u592A\u8001\uFF0C\u5148\u5347 gateway" });
65530
- stop = true;
65531
- ac.abort();
65532
- void reader.cancel().catch(() => {
65533
- });
65534
- break;
65535
- }
65536
- if (expectedEngine && control.engine !== expectedEngine) {
65537
- emitControl({ kind: "error", message: control.engine ? `SESSION_VERSION_EXPIRED: \u5F53\u524D Pod \u662F ${control.engine}\uFF0C\u8FD9\u6761\u4F1A\u8BDD\u9700\u8981 ${expectedEngine}` : "gateway \u7684 ready \u63A7\u5236\u884C\u6CA1\u5E26 engine\uFF0Cgateway \u592A\u8001\uFF0C\u5148\u5347 gateway" });
65538
- stop = true;
65539
- ac.abort();
65540
- void reader.cancel().catch(() => {
65541
- });
65542
- break;
65543
- }
65544
- sessionId = control.session;
65545
- flush();
65546
- }
65547
- emitControl(control);
65548
- if (control.kind === "error") {
65549
- stop = true;
65550
- ac.abort();
65551
- void reader.cancel().catch(() => {
65552
- });
65553
- break;
65554
- }
65555
- continue;
65556
- }
65557
- for (const cb of lineCbs) cb(line);
65558
- }
65559
- }
65560
- } catch (e) {
65561
- if (!closed && !ac.signal.aborted) logger?.warn("cloud session stream broke", { message: e.message });
65562
- }
65563
- finish();
65564
- })();
65565
- return {
65566
- write: (line) => {
65567
- if (closed) return;
65568
- pending.push({ line, turnStart: nextIsTurnStart });
65569
- nextIsTurnStart = false;
65570
- if (sessionId) flush();
65571
- },
65572
- markNextLineTurnStart: () => {
65573
- nextIsTurnStart = true;
65574
- },
65575
- onLine: (cb) => {
65576
- lineCbs.push(cb);
65577
- },
65578
- onClose: (cb) => {
65579
- closeCbs.push(cb);
65580
- if (closed) cb();
65581
- },
65582
- onControl: (cb) => {
65583
- controlCbs.push(cb);
65584
- if (readyWith) cb(readyWith);
65585
- if (closedWith) cb(closedWith);
65586
- },
65587
- close: () => {
65588
- ac.abort();
65589
- finish();
65590
- },
65591
- mirror: (turn) => {
65592
- if (closed || !sessionId) return Promise.resolve();
65593
- const p3 = sendChain.then(() => postMirror(turn));
65594
- sendChain = p3;
65595
- return p3;
65596
- }
65597
- };
65598
- }
65599
-
65600
- // src/cloud/cancel-outbox.ts
65601
- var import_node_fs39 = __toESM(require("fs"), 1);
65602
- var import_node_path44 = __toESM(require("path"), 1);
65603
- var CloudCancelOutbox = class {
65604
- constructor(dir, send2, logger) {
65605
- this.dir = dir;
65606
- this.send = send2;
65607
- this.logger = logger;
65608
- }
65609
- dir;
65610
- send;
65611
- logger;
65612
- timer = null;
65613
- inFlight = /* @__PURE__ */ new Set();
65614
- record(clientSessionId, personaId2, gatewaySessionId) {
65615
- if (!clientSessionId || !personaId2 || !gatewaySessionId) throw new Error("cloud cancel requires client, gateway and persona IDs");
65616
- import_node_fs39.default.mkdirSync(this.dir, { recursive: true, mode: 448 });
65617
- const target = this.pathFor(clientSessionId);
65618
- const temporary = `${target}.tmp-${process.pid}-${Date.now()}`;
65619
- import_node_fs39.default.writeFileSync(temporary, JSON.stringify({ clientSessionId, personaId: personaId2, gatewaySessionId }), { mode: 384 });
65620
- import_node_fs39.default.renameSync(temporary, target);
65621
- this.inFlight.add(clientSessionId);
65622
- }
65623
- confirm(clientSessionId) {
65624
- import_node_fs39.default.rmSync(this.pathFor(clientSessionId), { force: true });
65625
- this.inFlight.delete(clientSessionId);
65626
- }
65627
- release(clientSessionId) {
65628
- this.inFlight.delete(clientSessionId);
65629
- }
65630
- async request(clientSessionId, personaId2, gatewaySessionId) {
65631
- this.record(clientSessionId, personaId2, gatewaySessionId);
65632
- try {
65633
- await this.send(personaId2, clientSessionId, gatewaySessionId);
65634
- this.confirm(clientSessionId);
65635
- } catch (e) {
65636
- this.release(clientSessionId);
65637
- throw e;
65638
- }
65639
- }
65640
- async flush() {
65641
- let names;
65642
- try {
65643
- names = import_node_fs39.default.readdirSync(this.dir).filter((name) => name.endsWith(".json"));
65644
- } catch (e) {
65645
- if (e.code === "ENOENT") return;
65646
- throw e;
65647
- }
65648
- for (const name of names) {
65649
- const target = import_node_path44.default.join(this.dir, name);
65650
- let pending;
65651
- try {
65652
- pending = JSON.parse(import_node_fs39.default.readFileSync(target, "utf8"));
65653
- } catch {
65654
- continue;
65655
- }
65656
- if (!pending.clientSessionId || !pending.personaId || !pending.gatewaySessionId || this.pathFor(pending.clientSessionId) !== target) continue;
65657
- if (this.inFlight.has(pending.clientSessionId)) continue;
65658
- this.inFlight.add(pending.clientSessionId);
65659
- try {
65660
- await this.send(pending.personaId, pending.clientSessionId, pending.gatewaySessionId);
65661
- import_node_fs39.default.rmSync(target, { force: true });
65662
- } catch (e) {
65663
- this.logger?.warn("cloud cancel pending", { sessionId: pending.clientSessionId, error: e.message });
65664
- } finally {
65665
- this.inFlight.delete(pending.clientSessionId);
65666
- }
65667
- }
65668
- }
65669
- start() {
65670
- if (this.timer) return;
65671
- const retry = () => void this.flush().catch((e) => this.logger?.warn("cloud cancel outbox flush failed", { error: e.message }));
65672
- retry();
65673
- this.timer = setInterval(retry, 3e4);
65674
- this.timer.unref?.();
65675
- }
65676
- stop() {
65677
- if (this.timer) clearInterval(this.timer);
65678
- this.timer = null;
65679
- }
65680
- pathFor(clientSessionId) {
65681
- return import_node_path44.default.join(this.dir, `${safeFileName(clientSessionId)}.json`);
65682
- }
65683
- };
65684
65082
 
65685
65083
  // src/tools/codex-cloud.ts
65686
65084
  init_protocol();
65687
65085
 
65688
65086
  // src/tools/codex-cloud-session.ts
65689
- var import_node_fs40 = __toESM(require("fs"), 1);
65690
- var import_node_crypto14 = require("crypto");
65087
+ var import_node_fs39 = __toESM(require("fs"), 1);
65691
65088
 
65692
65089
  // src/tools/cloud-portable-input.ts
65693
65090
  async function portableCloudInput(text, resolvers) {
@@ -65746,10 +65143,11 @@ function createCloudTurnSession(args) {
65746
65143
  turnId: commandId,
65747
65144
  text: portable,
65748
65145
  expectedEngine: engine,
65749
- ...engine === "pi" ? { engineSessionId: engineSessionId ?? conversationId } : {},
65146
+ ...engine === "pi" && !ctx.titleOnly ? { engineSessionId: engineSessionId ?? conversationId } : {},
65750
65147
  ...instructions ? { instructions } : {},
65751
65148
  ...ctx.effort ? { effort: ctx.effort } : {},
65752
- ...ctx.personaMode ? { personaMode: ctx.personaMode } : {}
65149
+ ...ctx.personaMode ? { personaMode: ctx.personaMode } : {},
65150
+ ...ctx.titleOnly ? { purpose: "title" } : {}
65753
65151
  });
65754
65152
  if (closed) {
65755
65153
  stream.close();
@@ -65826,7 +65224,7 @@ function cloudImageInput(deps) {
65826
65224
  const mime = lookupMime(p3);
65827
65225
  if (!mime.startsWith("image/")) return null;
65828
65226
  try {
65829
- const bytes = (deps.readFile ?? import_node_fs40.default.readFileSync)(p3);
65227
+ const bytes = (deps.readFile ?? import_node_fs39.default.readFileSync)(p3);
65830
65228
  return { type: "image", url: `data:${mime};base64,${bytes.toString("base64")}` };
65831
65229
  } catch (e) {
65832
65230
  deps.logger?.warn("cloud image attachment unreadable", { path: p3, message: e.message });
@@ -65836,34 +65234,10 @@ function cloudImageInput(deps) {
65836
65234
  }
65837
65235
  function createCloudCodexSession(ctx, sink, deps) {
65838
65236
  const personaId2 = personaIdFromCloudCwd(ctx.cwd);
65839
- if (personaId2 && !ctx.titleOnly && !ctx.cloudGatewaySessionId && !ctx.cloudLegacyPendingCommand && deps.client.openTurn && deps.client.commandTurn && deps.client.cancelConversation) {
65840
- return createCloudTurnSession({
65841
- ctx,
65842
- sink,
65843
- client: deps.client,
65844
- personaId: personaId2,
65845
- engine: "codex",
65846
- instructions: ctx.extraSystemPrompt,
65847
- prepare: (text) => portableCloudInput(text, { resolveCodexImage: cloudImageInput(deps) })
65848
- });
65849
- }
65850
- const clientSessionId = ctx.titleOnly ? (0, import_node_crypto14.randomUUID)() : ctx.cloudExecutionId ?? ctx.env?.CLAWD_SESSION_ID;
65851
- let channel = null;
65852
- let closed = false;
65853
- let detached = false;
65854
- let stopping = null;
65855
- let exited = false;
65856
- let ready = false;
65857
- const exit = () => {
65858
- if (!exited) {
65859
- exited = true;
65860
- sink.onExit(null);
65861
- }
65862
- };
65863
- if (!personaId2 || !clientSessionId) {
65237
+ if (!personaId2 || ctx.cloudGatewaySessionId || ctx.cloudLegacyPendingCommand) {
65864
65238
  queueMicrotask(() => {
65865
- sink.onError(`cloud session is missing ${personaId2 ? "CLAWD_SESSION_ID" : "persona id"}`);
65866
- exit();
65239
+ sink.onError(personaId2 ? "\u65E7\u4E91\u4F1A\u8BDD\u534F\u8BAE\u5DF2\u505C\u7528\uFF0C\u8BF7\u5347\u7EA7\u5BA2\u6237\u7AEF\u5E76\u65B0\u5F00\u4F1A\u8BDD" : "cloud session is missing persona id");
65240
+ sink.onExit(null);
65867
65241
  });
65868
65242
  return { startTurn() {
65869
65243
  }, respondPermission() {
@@ -65871,90 +65245,15 @@ function createCloudCodexSession(ctx, sink, deps) {
65871
65245
  }, async stop() {
65872
65246
  } };
65873
65247
  }
65874
- const opened = deps.client.openEventSession(personaId2, {
65875
- expectedEngine: "codex",
65876
- clientSessionId,
65877
- ...ctx.cloudGatewaySessionId ? { gatewaySessionId: ctx.cloudGatewaySessionId } : {},
65878
- ...ctx.toolSessionId ? { toolSessionId: ctx.toolSessionId } : {},
65879
- ...ctx.extraSystemPrompt ? { instructions: ctx.extraSystemPrompt } : {},
65880
- ...ctx.effort ? { effort: ctx.effort } : {},
65881
- ...ctx.personaMode ? { personaMode: ctx.personaMode } : {},
65882
- ...ctx.titleOnly ? { purpose: "title" } : {},
65883
- ...ctx.cloudAttachOnly ? { attachOnly: true } : {}
65884
- }).then(
65885
- (opened2) => {
65886
- channel = opened2;
65887
- channel.onEvents((events) => sink.pushEvents(events));
65888
- channel.onControl((c2) => {
65889
- if (c2.kind === "ready") {
65890
- ready = true;
65891
- sink.onGatewayReady?.(c2.session);
65892
- if (c2.replayGap || c2.historySynchronized === false) sink.onHistoryGap?.(c2.historySynchronized === true);
65893
- } else if (c2.kind === "queued") {
65894
- sink.pushEvents([{ kind: "meta-text", text: `\u4E91\u4E0A\u673A\u5668\u6709 ${c2.running} \u4E2A\u4EFB\u52A1\u5728\u8DD1\uFF0C\u7B49\u4E00\u4E2A\u7ED3\u675F\u5C31\u8F6E\u5230\u4F60` }]);
65895
- } else if (c2.kind === "history") {
65896
- sink.onHistoryGap?.(c2.synchronized);
65897
- } else if (c2.kind === "error") {
65898
- sink.onError(`${ready ? "\u4E91\u4E0A\u6267\u884C\u5931\u8D25" : "\u4E91\u4E0A persona \u8D77\u4E0D\u6765"}\uFF1A${c2.message}`);
65899
- } else if (c2.kind === "closed" && c2.reason === "not-found") {
65900
- sink.onRecoveryAbsent?.();
65901
- }
65902
- });
65903
- channel.onClose(() => {
65904
- if (!detached) exit();
65905
- });
65906
- if (closed) channel.close();
65907
- return channel;
65908
- },
65909
- (e) => {
65910
- sink.onError(e instanceof CloudApiKeyRequiredError ? e.message : `\u8FDE\u4E0D\u4E0A\u4E91 gateway\uFF1A${e.message}`);
65911
- exit();
65912
- throw e;
65913
- }
65914
- );
65915
- void opened.catch(() => {
65248
+ return createCloudTurnSession({
65249
+ ctx,
65250
+ sink,
65251
+ client: deps.client,
65252
+ personaId: personaId2,
65253
+ engine: "codex",
65254
+ instructions: ctx.titleOnly ? void 0 : ctx.extraSystemPrompt,
65255
+ prepare: (text) => portableCloudInput(text, { resolveCodexImage: cloudImageInput(deps) })
65916
65256
  });
65917
- let sendChain = Promise.resolve();
65918
- const send2 = (command) => {
65919
- sendChain = sendChain.then(command).catch((e) => {
65920
- if (!closed && !exited) sink.onError(`\u4E91\u4E0A\u4F1A\u8BDD\u4E0A\u884C\u5931\u8D25\uFF1A${e.message}`);
65921
- });
65922
- };
65923
- return {
65924
- startTurn(text, commandId = (0, import_node_crypto14.randomUUID)(), prepared = false) {
65925
- send2(async () => {
65926
- const ch = await opened;
65927
- if (closed) return;
65928
- const portable = prepared ? text : await portableCloudInput(text, { resolveCodexImage: cloudImageInput(deps) });
65929
- if (sink.onCommandPrepared?.(commandId, portable, prepared) === false) return;
65930
- await ch.send({ command: "turn", text: portable, commandId });
65931
- });
65932
- },
65933
- respondPermission(requestId, allow) {
65934
- send2(async () => (await opened).send({ command: "permission", requestId, allow }));
65935
- },
65936
- interrupt() {
65937
- send2(async () => (await opened).send({ command: "interrupt" }));
65938
- },
65939
- detach() {
65940
- detached = true;
65941
- closed = true;
65942
- channel?.close();
65943
- },
65944
- stop() {
65945
- if (stopping) return stopping;
65946
- closed = true;
65947
- stopping = (async () => {
65948
- const ch = await opened.catch(() => null);
65949
- if (ch) {
65950
- await ch.send({ command: "cancel" });
65951
- ch.close();
65952
- }
65953
- exit();
65954
- })();
65955
- return stopping;
65956
- }
65957
- };
65958
65257
  }
65959
65258
 
65960
65259
  // src/tools/codex-cloud.ts
@@ -66025,7 +65324,7 @@ init_protocol();
66025
65324
 
66026
65325
  // src/tools/pi.ts
66027
65326
  var import_node_child_process12 = require("child_process");
66028
- var import_node_fs42 = __toESM(require("fs"), 1);
65327
+ var import_node_fs41 = __toESM(require("fs"), 1);
66029
65328
  init_protocol();
66030
65329
 
66031
65330
  // src/tools/pi-rpc-client.ts
@@ -66125,9 +65424,9 @@ var PiRpcClient = class {
66125
65424
 
66126
65425
  // src/tools/pi-session.ts
66127
65426
  var import_node_child_process11 = require("child_process");
66128
- var import_node_crypto15 = require("crypto");
66129
- var import_node_fs41 = __toESM(require("fs"), 1);
66130
- var import_node_path45 = __toESM(require("path"), 1);
65427
+ var import_node_crypto14 = require("crypto");
65428
+ var import_node_fs40 = __toESM(require("fs"), 1);
65429
+ var import_node_path44 = __toESM(require("path"), 1);
66131
65430
 
66132
65431
  // src/tools/pi-events.ts
66133
65432
  init_protocol();
@@ -66398,9 +65697,9 @@ ${dirs.map((d2) => `- ${d2}`).join("\n")}`;
66398
65697
  }
66399
65698
  function createPiSession(ctx, sink, deps = {}) {
66400
65699
  const cmd = process.env.PI_BIN ?? "pi";
66401
- const sessionId = ctx.toolSessionId ?? (0, import_node_crypto15.randomUUID)();
66402
- const skillsDir = import_node_path45.default.join(ctx.cwd, ".claude", "skills");
66403
- const exists = deps.skillsDirExists ?? ((d2) => import_node_fs41.default.existsSync(d2));
65700
+ const sessionId = ctx.toolSessionId ?? (0, import_node_crypto14.randomUUID)();
65701
+ const skillsDir = import_node_path44.default.join(ctx.cwd, ".claude", "skills");
65702
+ const exists = deps.skillsDirExists ?? ((d2) => import_node_fs40.default.existsSync(d2));
66404
65703
  const args = buildPiArgs(ctx, {
66405
65704
  sessionId,
66406
65705
  skillsDir: exists(skillsDir) ? skillsDir : void 0,
@@ -66462,10 +65761,10 @@ var PI_DEFAULT_MODEL_ENTRY = {
66462
65761
  };
66463
65762
  var PI_FULL_ACCESS = { id: "never", label: "Full Access", description: "pi \u65E0\u5BA1\u6279\uFF1A\u4ECE\u4E0D\u8BE2\u95EE\uFF0C\u81EA\u4E3B\u6267\u884C" };
66464
65763
  async function probePi(env = process.env) {
66465
- if (env.PI_BIN && import_node_fs42.default.existsSync(env.PI_BIN)) return { available: true, path: env.PI_BIN };
65764
+ if (env.PI_BIN && import_node_fs41.default.existsSync(env.PI_BIN)) return { available: true, path: env.PI_BIN };
66466
65765
  try {
66467
65766
  const out = (0, import_node_child_process12.execFileSync)("which", ["pi"], { encoding: "utf8" }).trim();
66468
- if (out && import_node_fs42.default.existsSync(out)) return { available: true, path: out };
65767
+ if (out && import_node_fs41.default.existsSync(out)) return { available: true, path: out };
66469
65768
  } catch {
66470
65769
  }
66471
65770
  return { available: false };
@@ -66635,42 +65934,15 @@ var PiAdapter = class {
66635
65934
  };
66636
65935
 
66637
65936
  // src/tools/pi-cloud-session.ts
66638
- var import_node_crypto16 = require("crypto");
66639
65937
  function cloudPiInstructions(ctx) {
66640
65938
  return [ctx.extraSystemPrompt, workDirPrompt(CLOUD_WORKSPACE_SLOT, ctx.personaMode ?? "owner")].filter((x2) => Boolean(x2)).join("\n\n");
66641
65939
  }
66642
65940
  function createCloudPiSession(ctx, sink, deps) {
66643
65941
  const personaId2 = personaIdFromCloudCwd(ctx.cwd);
66644
- if (personaId2 && !ctx.titleOnly && !ctx.cloudGatewaySessionId && !ctx.cloudLegacyPendingCommand && deps.client.openTurn && deps.client.commandTurn && deps.client.cancelConversation) {
66645
- return createCloudTurnSession({
66646
- ctx,
66647
- sink,
66648
- client: deps.client,
66649
- personaId: personaId2,
66650
- engine: "pi",
66651
- engineSessionId: ctx.toolSessionId,
66652
- instructions: cloudPiInstructions(ctx),
66653
- prepare: (text) => portableCloudInput(text, { fetchPiImage: deps.fetchImage ?? makeImageFetcher() })
66654
- });
66655
- }
66656
- const clientSessionId = ctx.titleOnly ? (0, import_node_crypto16.randomUUID)() : ctx.cloudExecutionId ?? ctx.env?.CLAWD_SESSION_ID;
66657
- const sessionId = ctx.toolSessionId ?? (0, import_node_crypto16.randomUUID)();
66658
- let channel = null;
66659
- let closed = false;
66660
- let detached = false;
66661
- let stopping = null;
66662
- let exited = false;
66663
- let ready = false;
66664
- const exit = () => {
66665
- if (!exited) {
66666
- exited = true;
66667
- sink.onExit(null);
66668
- }
66669
- };
66670
- if (!personaId2 || !clientSessionId) {
65942
+ if (!personaId2 || ctx.cloudGatewaySessionId || ctx.cloudLegacyPendingCommand) {
66671
65943
  queueMicrotask(() => {
66672
- sink.onError(`cloud session is missing ${personaId2 ? "CLAWD_SESSION_ID" : "persona id"}`);
66673
- exit();
65944
+ sink.onError(personaId2 ? "\u65E7\u4E91\u4F1A\u8BDD\u534F\u8BAE\u5DF2\u505C\u7528\uFF0C\u8BF7\u5347\u7EA7\u5BA2\u6237\u7AEF\u5E76\u65B0\u5F00\u4F1A\u8BDD" : "cloud session is missing persona id");
65945
+ sink.onExit(null);
66674
65946
  });
66675
65947
  return { startTurn() {
66676
65948
  }, respondPermission() {
@@ -66678,80 +65950,16 @@ function createCloudPiSession(ctx, sink, deps) {
66678
65950
  }, async stop() {
66679
65951
  } };
66680
65952
  }
66681
- const opened = deps.client.openEventSession(personaId2, { expectedEngine: "pi", clientSessionId, ...ctx.cloudGatewaySessionId ? { gatewaySessionId: ctx.cloudGatewaySessionId } : {}, toolSessionId: sessionId, instructions: ctx.titleOnly ? "" : cloudPiInstructions(ctx), ...ctx.titleOnly ? { purpose: "title" } : {}, ...ctx.cloudAttachOnly ? { attachOnly: true } : {} }).then(
66682
- (opened2) => {
66683
- channel = opened2;
66684
- channel.onEvents((events) => sink.pushEvents(events));
66685
- channel.onControl((c2) => {
66686
- if (c2.kind === "ready") {
66687
- ready = true;
66688
- sink.onGatewayReady?.(c2.session);
66689
- if (c2.replayGap || c2.historySynchronized === false) sink.onHistoryGap?.(c2.historySynchronized === true);
66690
- } else if (c2.kind === "queued") {
66691
- sink.pushEvents([{ kind: "meta-text", text: `\u4E91\u4E0A\u673A\u5668\u6709 ${c2.running} \u4E2A\u4EFB\u52A1\u5728\u8DD1\uFF0C\u7B49\u4E00\u4E2A\u7ED3\u675F\u5C31\u8F6E\u5230\u4F60` }]);
66692
- } else if (c2.kind === "history") {
66693
- sink.onHistoryGap?.(c2.synchronized);
66694
- } else if (c2.kind === "error") {
66695
- sink.onError(`${ready ? "\u4E91\u4E0A\u6267\u884C\u5931\u8D25" : "\u4E91\u4E0A persona \u8D77\u4E0D\u6765"}\uFF1A${c2.message}`);
66696
- } else if (c2.kind === "closed" && c2.reason === "not-found") {
66697
- sink.onRecoveryAbsent?.();
66698
- }
66699
- });
66700
- channel.onClose(() => {
66701
- if (!detached) exit();
66702
- });
66703
- if (closed) channel.close();
66704
- return channel;
66705
- },
66706
- (e) => {
66707
- sink.onError(e instanceof CloudApiKeyRequiredError ? e.message : `\u8FDE\u4E0D\u4E0A\u4E91 gateway\uFF1A${e.message}`);
66708
- exit();
66709
- throw e;
66710
- }
66711
- );
66712
- void opened.catch(() => {
65953
+ return createCloudTurnSession({
65954
+ ctx,
65955
+ sink,
65956
+ client: deps.client,
65957
+ personaId: personaId2,
65958
+ engine: "pi",
65959
+ engineSessionId: ctx.toolSessionId,
65960
+ instructions: ctx.titleOnly ? void 0 : cloudPiInstructions(ctx),
65961
+ prepare: (text) => portableCloudInput(text, { fetchPiImage: deps.fetchImage ?? makeImageFetcher() })
66713
65962
  });
66714
- let sendChain = Promise.resolve();
66715
- const send2 = (command) => {
66716
- sendChain = sendChain.then(command).catch((e) => {
66717
- if (!closed && !exited) sink.onError(`\u4E91\u4E0A\u4F1A\u8BDD\u4E0A\u884C\u5931\u8D25\uFF1A${e.message}`);
66718
- });
66719
- };
66720
- return {
66721
- startTurn(text, commandId = (0, import_node_crypto16.randomUUID)(), prepared = false) {
66722
- send2(async () => {
66723
- const ch = await opened;
66724
- if (closed) return;
66725
- const portable = prepared ? text : await portableCloudInput(text, { fetchPiImage: deps.fetchImage ?? makeImageFetcher() });
66726
- if (sink.onCommandPrepared?.(commandId, portable, prepared) === false) return;
66727
- await ch.send({ command: "turn", text: portable, commandId });
66728
- });
66729
- },
66730
- respondPermission(requestId, allow) {
66731
- send2(async () => (await opened).send({ command: "permission", requestId, allow }));
66732
- },
66733
- interrupt() {
66734
- send2(async () => (await opened).send({ command: "interrupt" }));
66735
- },
66736
- detach() {
66737
- detached = true;
66738
- closed = true;
66739
- channel?.close();
66740
- },
66741
- stop() {
66742
- if (stopping) return stopping;
66743
- closed = true;
66744
- stopping = (async () => {
66745
- const ch = await opened.catch(() => null);
66746
- if (ch) {
66747
- await ch.send({ command: "cancel" });
66748
- ch.close();
66749
- }
66750
- exit();
66751
- })();
66752
- return stopping;
66753
- }
66754
- };
66755
65963
  }
66756
65964
 
66757
65965
  // src/tools/pi-cloud.ts
@@ -66821,7 +66029,7 @@ var CloudPiAdapter = class {
66821
66029
  init_protocol();
66822
66030
 
66823
66031
  // src/tools/codex-skills.ts
66824
- var import_node_path46 = __toESM(require("path"), 1);
66032
+ var import_node_path45 = __toESM(require("path"), 1);
66825
66033
  function str4(v3) {
66826
66034
  return typeof v3 === "string" ? v3 : void 0;
66827
66035
  }
@@ -66836,13 +66044,13 @@ function mapSkillsListResponse(res) {
66836
66044
  const r2 = s2 ?? {};
66837
66045
  const name = str4(r2.name);
66838
66046
  if (!name) continue;
66839
- const path107 = str4(r2.path);
66047
+ const path106 = str4(r2.path);
66840
66048
  const description = str4(r2.description);
66841
66049
  const isPlugin = name.includes(":");
66842
66050
  out.push({
66843
66051
  name,
66844
66052
  source: isPlugin ? "plugin" : "project",
66845
- ...path107 ? { path: path107 } : {},
66053
+ ...path106 ? { path: path106 } : {},
66846
66054
  ...description ? { description } : {},
66847
66055
  ...isPlugin ? { plugin: name.split(":")[0] } : {}
66848
66056
  });
@@ -66858,7 +66066,7 @@ async function listCodexSkills(cwd, deps = {}) {
66858
66066
  // 先写 extraRoots 再写 list(stdio 按写入顺序处理,fire-and-forget 不 await 回包;
66859
66067
  // codex-session.ts ready 序列同款,两处保持一致)。失败不阻塞 list。
66860
66068
  beforeRequest: (client) => {
66861
- void client.request("skills/extraRoots/set", { extraRoots: [import_node_path46.default.join(cwd, ".claude", "skills")] }).catch(() => void 0);
66069
+ void client.request("skills/extraRoots/set", { extraRoots: [import_node_path45.default.join(cwd, ".claude", "skills")] }).catch(() => void 0);
66862
66070
  }
66863
66071
  });
66864
66072
  return mapSkillsListResponse(res);
@@ -66932,23 +66140,23 @@ function rec4(v3) {
66932
66140
  }
66933
66141
 
66934
66142
  // src/workspace/browser.ts
66935
- var import_node_fs43 = __toESM(require("fs"), 1);
66143
+ var import_node_fs42 = __toESM(require("fs"), 1);
66936
66144
  var import_node_os15 = __toESM(require("os"), 1);
66937
- var import_node_path47 = __toESM(require("path"), 1);
66145
+ var import_node_path46 = __toESM(require("path"), 1);
66938
66146
  init_protocol();
66939
66147
  var MAX_FILE_BYTES2 = 2 * 1024 * 1024;
66940
66148
  function resolveInsideCwd(cwd, subpath) {
66941
- const absCwd = import_node_path47.default.resolve(cwd);
66942
- const joined = import_node_path47.default.resolve(absCwd, subpath ?? ".");
66943
- const rel = import_node_path47.default.relative(absCwd, joined);
66944
- if (rel.startsWith("..") || import_node_path47.default.isAbsolute(rel)) {
66149
+ const absCwd = import_node_path46.default.resolve(cwd);
66150
+ const joined = import_node_path46.default.resolve(absCwd, subpath ?? ".");
66151
+ const rel = import_node_path46.default.relative(absCwd, joined);
66152
+ if (rel.startsWith("..") || import_node_path46.default.isAbsolute(rel)) {
66945
66153
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
66946
66154
  }
66947
66155
  return joined;
66948
66156
  }
66949
66157
  function ensureCwd(cwd) {
66950
66158
  try {
66951
- const stat = import_node_fs43.default.statSync(cwd);
66159
+ const stat = import_node_fs42.default.statSync(cwd);
66952
66160
  if (!stat.isDirectory()) {
66953
66161
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${cwd}`);
66954
66162
  }
@@ -66962,7 +66170,7 @@ var WorkspaceBrowser = class {
66962
66170
  const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os15.default.homedir();
66963
66171
  ensureCwd(cwd);
66964
66172
  const full = resolveInsideCwd(cwd, args.path);
66965
- const dirents = import_node_fs43.default.readdirSync(full, { withFileTypes: true });
66173
+ const dirents = import_node_fs42.default.readdirSync(full, { withFileTypes: true });
66966
66174
  const entries = [];
66967
66175
  for (const d2 of dirents) {
66968
66176
  if (!args.showHidden && d2.name.startsWith(".")) continue;
@@ -66972,7 +66180,7 @@ var WorkspaceBrowser = class {
66972
66180
  mtime: ""
66973
66181
  };
66974
66182
  try {
66975
- const st2 = import_node_fs43.default.statSync(import_node_path47.default.join(full, d2.name));
66183
+ const st2 = import_node_fs42.default.statSync(import_node_path46.default.join(full, d2.name));
66976
66184
  entry.mtime = new Date(st2.mtimeMs).toISOString();
66977
66185
  if (d2.isFile()) entry.size = st2.size;
66978
66186
  } catch {
@@ -66988,14 +66196,14 @@ var WorkspaceBrowser = class {
66988
66196
  read(args) {
66989
66197
  ensureCwd(args.cwd);
66990
66198
  const full = resolveInsideCwd(args.cwd, args.path);
66991
- const st2 = import_node_fs43.default.statSync(full);
66199
+ const st2 = import_node_fs42.default.statSync(full);
66992
66200
  if (!st2.isFile()) {
66993
66201
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `not a file: ${args.path}`);
66994
66202
  }
66995
66203
  if (st2.size > MAX_FILE_BYTES2) {
66996
66204
  throw new ClawdError(ERROR_CODES.FILE_TOO_LARGE, `file > ${MAX_FILE_BYTES2} bytes`);
66997
66205
  }
66998
- const buf = import_node_fs43.default.readFileSync(full);
66206
+ const buf = import_node_fs42.default.readFileSync(full);
66999
66207
  const isBinary = buf.includes(0);
67000
66208
  if (isBinary) {
67001
66209
  return {
@@ -67017,20 +66225,20 @@ var WorkspaceBrowser = class {
67017
66225
  };
67018
66226
 
67019
66227
  // src/skills/agents-scanner.ts
67020
- var import_node_fs44 = __toESM(require("fs"), 1);
66228
+ var import_node_fs43 = __toESM(require("fs"), 1);
67021
66229
  var import_node_os16 = __toESM(require("os"), 1);
67022
- var import_node_path48 = __toESM(require("path"), 1);
66230
+ var import_node_path47 = __toESM(require("path"), 1);
67023
66231
  var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
67024
66232
  function isDirLikeSync2(p3) {
67025
66233
  try {
67026
- return import_node_fs44.default.statSync(p3).isDirectory();
66234
+ return import_node_fs43.default.statSync(p3).isDirectory();
67027
66235
  } catch {
67028
66236
  return false;
67029
66237
  }
67030
66238
  }
67031
66239
  function fileExistsSync(p3) {
67032
66240
  try {
67033
- return import_node_fs44.default.statSync(p3).isFile();
66241
+ return import_node_fs43.default.statSync(p3).isFile();
67034
66242
  } catch {
67035
66243
  return false;
67036
66244
  }
@@ -67038,7 +66246,7 @@ function fileExistsSync(p3) {
67038
66246
  function parseAgentFile(filePath) {
67039
66247
  let content;
67040
66248
  try {
67041
- content = import_node_fs44.default.readFileSync(filePath, "utf8");
66249
+ content = import_node_fs43.default.readFileSync(filePath, "utf8");
67042
66250
  } catch {
67043
66251
  return {};
67044
66252
  }
@@ -67051,16 +66259,16 @@ function parseAgentFile(filePath) {
67051
66259
  function scanAgentsDir(dir, source, seen, out) {
67052
66260
  let entries;
67053
66261
  try {
67054
- entries = import_node_fs44.default.readdirSync(dir, { withFileTypes: true });
66262
+ entries = import_node_fs43.default.readdirSync(dir, { withFileTypes: true });
67055
66263
  } catch {
67056
66264
  return;
67057
66265
  }
67058
66266
  for (const ent of entries) {
67059
66267
  if (!ent.name.endsWith(".md")) continue;
67060
- if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path48.default.join(dir, ent.name)))) {
66268
+ if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path47.default.join(dir, ent.name)))) {
67061
66269
  continue;
67062
66270
  }
67063
- const filePath = import_node_path48.default.join(dir, ent.name);
66271
+ const filePath = import_node_path47.default.join(dir, ent.name);
67064
66272
  const baseName = ent.name.replace(/\.md$/, "");
67065
66273
  if (seen.has(baseName)) continue;
67066
66274
  seen.add(baseName);
@@ -67078,12 +66286,12 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
67078
66286
  function walk2(dir, namespaces) {
67079
66287
  let entries;
67080
66288
  try {
67081
- entries = import_node_fs44.default.readdirSync(dir, { withFileTypes: true });
66289
+ entries = import_node_fs43.default.readdirSync(dir, { withFileTypes: true });
67082
66290
  } catch {
67083
66291
  return;
67084
66292
  }
67085
66293
  for (const ent of entries) {
67086
- const childPath = import_node_path48.default.join(dir, ent.name);
66294
+ const childPath = import_node_path47.default.join(dir, ent.name);
67087
66295
  if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
67088
66296
  walk2(childPath, [...namespaces, ent.name]);
67089
66297
  continue;
@@ -67108,13 +66316,13 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
67108
66316
  walk2(root, []);
67109
66317
  }
67110
66318
  function readInstalledPlugins2(home) {
67111
- const pluginsDir = import_node_path48.default.join(home, ".claude", "plugins");
67112
- const v22 = import_node_path48.default.join(pluginsDir, "installed_plugins_v2.json");
67113
- const v1 = import_node_path48.default.join(pluginsDir, "installed_plugins.json");
66319
+ const pluginsDir = import_node_path47.default.join(home, ".claude", "plugins");
66320
+ const v22 = import_node_path47.default.join(pluginsDir, "installed_plugins_v2.json");
66321
+ const v1 = import_node_path47.default.join(pluginsDir, "installed_plugins.json");
67114
66322
  let raw = null;
67115
66323
  for (const candidate of [v22, v1]) {
67116
66324
  try {
67117
- raw = import_node_fs44.default.readFileSync(candidate, "utf8");
66325
+ raw = import_node_fs43.default.readFileSync(candidate, "utf8");
67118
66326
  break;
67119
66327
  } catch {
67120
66328
  }
@@ -67139,19 +66347,19 @@ function readInstalledPlugins2(home) {
67139
66347
  return out;
67140
66348
  }
67141
66349
  function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
67142
- let cur = import_node_path48.default.resolve(startCwd);
67143
- const fsRoot = import_node_path48.default.parse(cur).root;
66350
+ let cur = import_node_path47.default.resolve(startCwd);
66351
+ const fsRoot = import_node_path47.default.parse(cur).root;
67144
66352
  while (true) {
67145
- scanAgentsDir(import_node_path48.default.join(cur, ".claude", "agents"), "project", seen, out);
66353
+ scanAgentsDir(import_node_path47.default.join(cur, ".claude", "agents"), "project", seen, out);
67146
66354
  let hasGit = false;
67147
66355
  try {
67148
- hasGit = import_node_fs44.default.existsSync(import_node_path48.default.join(cur, ".git"));
66356
+ hasGit = import_node_fs43.default.existsSync(import_node_path47.default.join(cur, ".git"));
67149
66357
  } catch {
67150
66358
  }
67151
66359
  if (hasGit) return;
67152
66360
  if (cur === home) return;
67153
66361
  if (cur === fsRoot) return;
67154
- const parent = import_node_path48.default.dirname(cur);
66362
+ const parent = import_node_path47.default.dirname(cur);
67155
66363
  if (parent === cur) return;
67156
66364
  cur = parent;
67157
66365
  }
@@ -67186,7 +66394,7 @@ var AgentsScanner = class {
67186
66394
  }
67187
66395
  const fsBlock = [];
67188
66396
  scanAgentsDir(
67189
- import_node_path48.default.join(this.home, ".claude", "agents"),
66397
+ import_node_path47.default.join(this.home, ".claude", "agents"),
67190
66398
  "global",
67191
66399
  seen,
67192
66400
  fsBlock
@@ -67200,7 +66408,7 @@ var AgentsScanner = class {
67200
66408
  ...this.extraPluginRoots
67201
66409
  ];
67202
66410
  for (const { name, root } of plugins) {
67203
- const agentsRoot = import_node_path48.default.join(root, "agents");
66411
+ const agentsRoot = import_node_path47.default.join(root, "agents");
67204
66412
  scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
67205
66413
  }
67206
66414
  return [...builtinBlock, ...fsBlock];
@@ -67208,15 +66416,15 @@ var AgentsScanner = class {
67208
66416
  };
67209
66417
 
67210
66418
  // src/observer/session-observer.ts
67211
- var import_node_fs46 = __toESM(require("fs"), 1);
66419
+ var import_node_fs45 = __toESM(require("fs"), 1);
67212
66420
  var import_node_os18 = __toESM(require("os"), 1);
67213
- var import_node_path50 = __toESM(require("path"), 1);
66421
+ var import_node_path49 = __toESM(require("path"), 1);
67214
66422
  init_claude_history();
67215
66423
 
67216
66424
  // src/observer/subagent-meta-observer.ts
67217
- var import_node_fs45 = __toESM(require("fs"), 1);
66425
+ var import_node_fs44 = __toESM(require("fs"), 1);
67218
66426
  var import_node_os17 = __toESM(require("os"), 1);
67219
- var import_node_path49 = __toESM(require("path"), 1);
66427
+ var import_node_path48 = __toESM(require("path"), 1);
67220
66428
  init_claude_history();
67221
66429
  var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
67222
66430
  var SubagentMetaObserver = class {
@@ -67229,7 +66437,7 @@ var SubagentMetaObserver = class {
67229
66437
  watches = /* @__PURE__ */ new Map();
67230
66438
  // public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
67231
66439
  resolveSubagentDir(cwd, toolSessionId) {
67232
- return import_node_path49.default.join(
66440
+ return import_node_path48.default.join(
67233
66441
  this.home,
67234
66442
  ".claude",
67235
66443
  "projects",
@@ -67259,7 +66467,7 @@ var SubagentMetaObserver = class {
67259
66467
  attachWatcher(w3) {
67260
66468
  if (w3.watcher) return;
67261
66469
  try {
67262
- w3.watcher = import_node_fs45.default.watch(w3.dirPath, { persistent: false }, (_evt, name) => {
66470
+ w3.watcher = import_node_fs44.default.watch(w3.dirPath, { persistent: false }, (_evt, name) => {
67263
66471
  if (!name) return;
67264
66472
  const m3 = META_RE.exec(String(name));
67265
66473
  if (!m3) return;
@@ -67271,7 +66479,7 @@ var SubagentMetaObserver = class {
67271
66479
  scan(w3) {
67272
66480
  let entries;
67273
66481
  try {
67274
- entries = import_node_fs45.default.readdirSync(w3.dirPath);
66482
+ entries = import_node_fs44.default.readdirSync(w3.dirPath);
67275
66483
  } catch {
67276
66484
  return;
67277
66485
  }
@@ -67285,10 +66493,10 @@ var SubagentMetaObserver = class {
67285
66493
  if (!m3) return;
67286
66494
  const agentId = m3[1];
67287
66495
  if (w3.emitted.has(agentId)) return;
67288
- const file = import_node_path49.default.join(w3.dirPath, name);
66496
+ const file = import_node_path48.default.join(w3.dirPath, name);
67289
66497
  let raw;
67290
66498
  try {
67291
- raw = import_node_fs45.default.readFileSync(file, "utf8");
66499
+ raw = import_node_fs44.default.readFileSync(file, "utf8");
67292
66500
  } catch {
67293
66501
  return;
67294
66502
  }
@@ -67345,14 +66553,14 @@ var SessionObserver = class {
67345
66553
  metaObserver;
67346
66554
  resolveJsonlPath(cwd, toolSessionId, override) {
67347
66555
  if (override) return override;
67348
- return import_node_path50.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
66556
+ return import_node_path49.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
67349
66557
  }
67350
66558
  start(args) {
67351
66559
  this.stop(args.sessionId);
67352
66560
  const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
67353
66561
  let size = 0;
67354
66562
  try {
67355
- size = import_node_fs46.default.statSync(filePath).size;
66563
+ size = import_node_fs45.default.statSync(filePath).size;
67356
66564
  } catch {
67357
66565
  }
67358
66566
  const w3 = {
@@ -67365,16 +66573,16 @@ var SessionObserver = class {
67365
66573
  adapter: args.adapter,
67366
66574
  prevIsRejectSentinel: false,
67367
66575
  toolSessionId: args.toolSessionId,
67368
- sawFile: import_node_fs46.default.existsSync(filePath),
66576
+ sawFile: import_node_fs45.default.existsSync(filePath),
67369
66577
  lastRelocateScanMs: 0,
67370
66578
  pendingCwdDerive: false,
67371
66579
  lastDeriveMs: 0
67372
66580
  };
67373
66581
  try {
67374
- import_node_fs46.default.mkdirSync(import_node_path50.default.dirname(filePath), { recursive: true });
66582
+ import_node_fs45.default.mkdirSync(import_node_path49.default.dirname(filePath), { recursive: true });
67375
66583
  } catch {
67376
66584
  }
67377
- w3.watcher = import_node_fs46.default.watch(import_node_path50.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
66585
+ w3.watcher = import_node_fs45.default.watch(import_node_path49.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
67378
66586
  if (!changedName || !w3.filePath.endsWith(changedName)) return;
67379
66587
  this.poll(w3);
67380
66588
  });
@@ -67397,7 +66605,7 @@ var SessionObserver = class {
67397
66605
  // 异常静默吞,不阻塞 watcher 启动
67398
66606
  hydrateMetaTail(w3, maxLines = 200) {
67399
66607
  try {
67400
- const raw = import_node_fs46.default.readFileSync(w3.filePath, "utf8");
66608
+ const raw = import_node_fs45.default.readFileSync(w3.filePath, "utf8");
67401
66609
  if (!raw) return;
67402
66610
  const allLines = raw.split("\n").filter((l2) => l2.trim().length > 0);
67403
66611
  if (allLines.length === 0) return;
@@ -67421,7 +66629,7 @@ var SessionObserver = class {
67421
66629
  poll(w3) {
67422
66630
  let size = 0;
67423
66631
  try {
67424
- size = import_node_fs46.default.statSync(w3.filePath).size;
66632
+ size = import_node_fs45.default.statSync(w3.filePath).size;
67425
66633
  } catch {
67426
66634
  if (w3.sawFile) this.maybeRelocate(w3);
67427
66635
  return;
@@ -67432,11 +66640,11 @@ var SessionObserver = class {
67432
66640
  w3.buf = "";
67433
66641
  }
67434
66642
  if (size === w3.lastSize) return;
67435
- const fd = import_node_fs46.default.openSync(w3.filePath, "r");
66643
+ const fd = import_node_fs45.default.openSync(w3.filePath, "r");
67436
66644
  try {
67437
66645
  const len = size - w3.lastSize;
67438
66646
  const buf = Buffer.alloc(len);
67439
- import_node_fs46.default.readSync(fd, buf, 0, len, w3.lastSize);
66647
+ import_node_fs45.default.readSync(fd, buf, 0, len, w3.lastSize);
67440
66648
  w3.lastSize = size;
67441
66649
  w3.buf += buf.toString("utf8");
67442
66650
  let newlineIndex;
@@ -67459,7 +66667,7 @@ var SessionObserver = class {
67459
66667
  }
67460
66668
  }
67461
66669
  } finally {
67462
- import_node_fs46.default.closeSync(fd);
66670
+ import_node_fs45.default.closeSync(fd);
67463
66671
  }
67464
66672
  if (w3.pendingCwdDerive) this.maybeDeriveCwd(w3);
67465
66673
  }
@@ -67471,7 +66679,7 @@ var SessionObserver = class {
67471
66679
  const now = Date.now();
67472
66680
  if (now - w3.lastRelocateScanMs < 1e3) return;
67473
66681
  w3.lastRelocateScanMs = now;
67474
- const projectsRoot = import_node_path50.default.join(this.home, ".claude", "projects");
66682
+ const projectsRoot = import_node_path49.default.join(this.home, ".claude", "projects");
67475
66683
  const found = findTranscriptByToolSessionId(projectsRoot, w3.toolSessionId);
67476
66684
  if (!found || found === w3.filePath) return;
67477
66685
  try {
@@ -67480,7 +66688,7 @@ var SessionObserver = class {
67480
66688
  }
67481
66689
  w3.filePath = found;
67482
66690
  try {
67483
- w3.watcher = import_node_fs46.default.watch(import_node_path50.default.dirname(found), { persistent: false }, (_event, changedName) => {
66691
+ w3.watcher = import_node_fs45.default.watch(import_node_path49.default.dirname(found), { persistent: false }, (_event, changedName) => {
67484
66692
  if (!changedName || !w3.filePath.endsWith(changedName)) return;
67485
66693
  this.poll(w3);
67486
66694
  });
@@ -67602,9 +66810,9 @@ function listRegistered() {
67602
66810
  // src/tools/title-generator.ts
67603
66811
  var import_node_child_process13 = require("child_process");
67604
66812
  init_protocol();
67605
- var import_node_fs47 = __toESM(require("fs"), 1);
66813
+ var import_node_fs46 = __toESM(require("fs"), 1);
67606
66814
  var import_node_os19 = __toESM(require("os"), 1);
67607
- var import_node_path51 = __toESM(require("path"), 1);
66815
+ var import_node_path50 = __toESM(require("path"), 1);
67608
66816
  var TITLE_GEN_DIR_PREFIX = "clawd-title-";
67609
66817
  var TITLE_INPUT_MAX_CHARS = 400;
67610
66818
  var DEFAULT_TITLE_GEN_TIMEOUT_MS = 45e3;
@@ -67695,21 +66903,21 @@ async function generateSessionTitle(file, firstMessage, deps = {}) {
67695
66903
  }
67696
66904
  let workDir;
67697
66905
  try {
67698
- workDir = import_node_fs47.default.mkdtempSync(import_node_path51.default.join(import_node_os19.default.tmpdir(), TITLE_GEN_DIR_PREFIX));
66906
+ workDir = import_node_fs46.default.mkdtempSync(import_node_path50.default.join(import_node_os19.default.tmpdir(), TITLE_GEN_DIR_PREFIX));
67699
66907
  } catch {
67700
66908
  return null;
67701
66909
  }
67702
66910
  const cleanupWorkDir = () => {
67703
66911
  try {
67704
- import_node_fs47.default.rmSync(workDir, { recursive: true, force: true });
66912
+ import_node_fs46.default.rmSync(workDir, { recursive: true, force: true });
67705
66913
  } catch {
67706
66914
  }
67707
66915
  };
67708
- const outFile = import_node_path51.default.join(workDir, `codex-title-${process.pid}-${++outFileSeq}-${Date.now()}.txt`);
67709
- const schemaFile = import_node_path51.default.join(workDir, "title-schema.json");
66916
+ const outFile = import_node_path50.default.join(workDir, `codex-title-${process.pid}-${++outFileSeq}-${Date.now()}.txt`);
66917
+ const schemaFile = import_node_path50.default.join(workDir, "title-schema.json");
67710
66918
  if (tool === "codex") {
67711
66919
  try {
67712
- import_node_fs47.default.writeFileSync(schemaFile, CODEX_TITLE_SCHEMA);
66920
+ import_node_fs46.default.writeFileSync(schemaFile, CODEX_TITLE_SCHEMA);
67713
66921
  } catch {
67714
66922
  cleanupWorkDir();
67715
66923
  return null;
@@ -67764,7 +66972,7 @@ async function generateSessionTitle(file, firstMessage, deps = {}) {
67764
66972
  if (tool === "claude" || tool === "pi") return finish(parseTitleJson(stdout));
67765
66973
  let fileText = "";
67766
66974
  try {
67767
- fileText = import_node_fs47.default.readFileSync(outFile, "utf8");
66975
+ fileText = import_node_fs46.default.readFileSync(outFile, "utf8");
67768
66976
  } catch {
67769
66977
  return finish(null);
67770
66978
  }
@@ -67837,7 +67045,7 @@ var wrapper_default = import_websocket.default;
67837
67045
 
67838
67046
  // src/transport/local-ws-server.ts
67839
67047
  var import_node_http = __toESM(require("http"), 1);
67840
- var import_node_crypto17 = require("crypto");
67048
+ var import_node_crypto15 = require("crypto");
67841
67049
  var LocalWsServer = class {
67842
67050
  constructor(opts) {
67843
67051
  this.opts = opts;
@@ -68054,7 +67262,7 @@ var LocalWsServer = class {
68054
67262
  }
68055
67263
  }
68056
67264
  onConnection(socket, remoteAddress) {
68057
- const id = (0, import_node_crypto17.randomUUID)();
67265
+ const id = (0, import_node_crypto15.randomUUID)();
68058
67266
  const subscribedSessions = /* @__PURE__ */ new Map();
68059
67267
  const handle = {
68060
67268
  id,
@@ -68460,8 +67668,8 @@ async function authenticate(token, deps) {
68460
67668
  }
68461
67669
 
68462
67670
  // src/legacy-cleanup.ts
68463
- var fs58 = __toESM(require("fs/promises"), 1);
68464
- var path59 = __toESM(require("path"), 1);
67671
+ var fs57 = __toESM(require("fs/promises"), 1);
67672
+ var path58 = __toESM(require("path"), 1);
68465
67673
  var LEGACY_FILES = [
68466
67674
  "personal-capability.json",
68467
67675
  "received-capabilities.json",
@@ -68470,9 +67678,9 @@ var LEGACY_FILES = [
68470
67678
  async function cleanupLegacyCapabilityFiles(dataDir, logger) {
68471
67679
  const removed = [];
68472
67680
  for (const name of LEGACY_FILES) {
68473
- const p3 = path59.join(dataDir, name);
67681
+ const p3 = path58.join(dataDir, name);
68474
67682
  try {
68475
- await fs58.unlink(p3);
67683
+ await fs57.unlink(p3);
68476
67684
  removed.push(name);
68477
67685
  logger.debug("legacy capability file removed", { file: name });
68478
67686
  } catch (err) {
@@ -68484,13 +67692,13 @@ async function cleanupLegacyCapabilityFiles(dataDir, logger) {
68484
67692
  }
68485
67693
 
68486
67694
  // src/inbox/inbox-store.ts
68487
- var fs59 = __toESM(require("fs"), 1);
68488
- var path60 = __toESM(require("path"), 1);
67695
+ var fs58 = __toESM(require("fs"), 1);
67696
+ var path59 = __toESM(require("path"), 1);
68489
67697
  var INBOX_SUBDIR = "inbox";
68490
67698
  var InboxStore = class {
68491
67699
  constructor(dataDir) {
68492
67700
  this.dataDir = dataDir;
68493
- fs59.mkdirSync(this.dirPath(), { recursive: true });
67701
+ fs58.mkdirSync(this.dirPath(), { recursive: true });
68494
67702
  }
68495
67703
  dataDir;
68496
67704
  /**
@@ -68502,7 +67710,7 @@ var InboxStore = class {
68502
67710
  const file = this.filePath(peerDeviceId);
68503
67711
  let raw;
68504
67712
  try {
68505
- raw = fs59.readFileSync(file, "utf8");
67713
+ raw = fs58.readFileSync(file, "utf8");
68506
67714
  } catch (err) {
68507
67715
  if (err?.code === "ENOENT") return [];
68508
67716
  return [];
@@ -68518,7 +67726,7 @@ var InboxStore = class {
68518
67726
  const dir = this.dirPath();
68519
67727
  let entries;
68520
67728
  try {
68521
- entries = fs59.readdirSync(dir);
67729
+ entries = fs58.readdirSync(dir);
68522
67730
  } catch (err) {
68523
67731
  if (err?.code === "ENOENT") return [];
68524
67732
  return [];
@@ -68534,9 +67742,9 @@ var InboxStore = class {
68534
67742
  if (existing.some((m3) => m3.id === message.id)) return;
68535
67743
  const file = this.filePath(message.peerDeviceId);
68536
67744
  const line = JSON.stringify(message) + "\n";
68537
- fs59.appendFileSync(file, line, { mode: 384 });
67745
+ fs58.appendFileSync(file, line, { mode: 384 });
68538
67746
  try {
68539
- fs59.chmodSync(file, 384);
67747
+ fs58.chmodSync(file, 384);
68540
67748
  } catch {
68541
67749
  }
68542
67750
  }
@@ -68566,7 +67774,7 @@ var InboxStore = class {
68566
67774
  removeByPeerDeviceId(peerDeviceId) {
68567
67775
  const file = this.filePath(peerDeviceId);
68568
67776
  try {
68569
- fs59.unlinkSync(file);
67777
+ fs58.unlinkSync(file);
68570
67778
  } catch (err) {
68571
67779
  if (err?.code === "ENOENT") return;
68572
67780
  }
@@ -68575,18 +67783,18 @@ var InboxStore = class {
68575
67783
  const file = this.filePath(peerDeviceId);
68576
67784
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
68577
67785
  const content = messages.map((m3) => JSON.stringify(m3)).join("\n") + (messages.length > 0 ? "\n" : "");
68578
- fs59.writeFileSync(tmp, content, { mode: 384 });
68579
- fs59.renameSync(tmp, file);
67786
+ fs58.writeFileSync(tmp, content, { mode: 384 });
67787
+ fs58.renameSync(tmp, file);
68580
67788
  try {
68581
- fs59.chmodSync(file, 384);
67789
+ fs58.chmodSync(file, 384);
68582
67790
  } catch {
68583
67791
  }
68584
67792
  }
68585
67793
  dirPath() {
68586
- return path60.join(this.dataDir, INBOX_SUBDIR);
67794
+ return path59.join(this.dataDir, INBOX_SUBDIR);
68587
67795
  }
68588
67796
  filePath(peerDeviceId) {
68589
- return path60.join(this.dirPath(), `${peerDeviceId}.jsonl`);
67797
+ return path59.join(this.dirPath(), `${peerDeviceId}.jsonl`);
68590
67798
  }
68591
67799
  };
68592
67800
  function parseAllLines(raw) {
@@ -68674,8 +67882,8 @@ var InboxManager = class {
68674
67882
  };
68675
67883
 
68676
67884
  // src/state/contact-store.ts
68677
- var fs60 = __toESM(require("fs"), 1);
68678
- var path61 = __toESM(require("path"), 1);
67885
+ var fs59 = __toESM(require("fs"), 1);
67886
+ var path60 = __toESM(require("path"), 1);
68679
67887
  var FILE_NAME = "contacts.json";
68680
67888
  var ContactStore = class {
68681
67889
  constructor(dataDir) {
@@ -68685,10 +67893,10 @@ var ContactStore = class {
68685
67893
  contacts = /* @__PURE__ */ new Map();
68686
67894
  load() {
68687
67895
  this.contacts.clear();
68688
- const file = path61.join(this.dataDir, FILE_NAME);
67896
+ const file = path60.join(this.dataDir, FILE_NAME);
68689
67897
  let raw;
68690
67898
  try {
68691
- raw = fs60.readFileSync(file, "utf8");
67899
+ raw = fs59.readFileSync(file, "utf8");
68692
67900
  } catch (err) {
68693
67901
  if (err?.code !== "ENOENT") this.renameBak(file);
68694
67902
  return;
@@ -68769,20 +67977,20 @@ var ContactStore = class {
68769
67977
  return true;
68770
67978
  }
68771
67979
  flush() {
68772
- const file = path61.join(this.dataDir, FILE_NAME);
67980
+ const file = path60.join(this.dataDir, FILE_NAME);
68773
67981
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
68774
67982
  const content = JSON.stringify(
68775
67983
  { contacts: Array.from(this.contacts.values()) },
68776
67984
  null,
68777
67985
  2
68778
67986
  );
68779
- fs60.mkdirSync(this.dataDir, { recursive: true });
68780
- fs60.writeFileSync(tmp, content, { mode: 384 });
68781
- fs60.renameSync(tmp, file);
67987
+ fs59.mkdirSync(this.dataDir, { recursive: true });
67988
+ fs59.writeFileSync(tmp, content, { mode: 384 });
67989
+ fs59.renameSync(tmp, file);
68782
67990
  }
68783
67991
  renameBak(file) {
68784
67992
  try {
68785
- fs60.renameSync(file, `${file}.bak`);
67993
+ fs59.renameSync(file, `${file}.bak`);
68786
67994
  } catch {
68787
67995
  }
68788
67996
  }
@@ -68890,61 +68098,61 @@ async function connectRemote(args) {
68890
68098
  }
68891
68099
 
68892
68100
  // src/migrations/2026-05-20-flatten-sessions.ts
68893
- var fs61 = __toESM(require("fs"), 1);
68894
- var path62 = __toESM(require("path"), 1);
68101
+ var fs60 = __toESM(require("fs"), 1);
68102
+ var path61 = __toESM(require("path"), 1);
68895
68103
  var MIGRATION_FLAG_NAME = ".migration.v1.done";
68896
68104
  function migrateFlattenSessions(opts) {
68897
68105
  const dataDir = opts.dataDir;
68898
68106
  const now = opts.now ?? Date.now;
68899
- const sessionsDir = path62.join(dataDir, "sessions");
68900
- const flagPath = path62.join(sessionsDir, MIGRATION_FLAG_NAME);
68107
+ const sessionsDir = path61.join(dataDir, "sessions");
68108
+ const flagPath = path61.join(sessionsDir, MIGRATION_FLAG_NAME);
68901
68109
  if (existsSync3(flagPath)) {
68902
68110
  return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
68903
68111
  }
68904
68112
  let movedBare = 0;
68905
68113
  let movedVmOwner = 0;
68906
68114
  let archivedListener = 0;
68907
- const defaultDir = path62.join(sessionsDir, "default");
68115
+ const defaultDir = path61.join(sessionsDir, "default");
68908
68116
  if (existsSync3(defaultDir)) {
68909
68117
  for (const entry of readdirSafe(defaultDir)) {
68910
68118
  if (!entry.endsWith(".json")) continue;
68911
- const src = path62.join(defaultDir, entry);
68912
- const dst = path62.join(sessionsDir, entry);
68913
- fs61.renameSync(src, dst);
68119
+ const src = path61.join(defaultDir, entry);
68120
+ const dst = path61.join(sessionsDir, entry);
68121
+ fs60.renameSync(src, dst);
68914
68122
  movedBare += 1;
68915
68123
  }
68916
68124
  rmdirIfEmpty(defaultDir);
68917
68125
  }
68918
68126
  for (const pid of readdirSafe(sessionsDir)) {
68919
- const personaDir = path62.join(sessionsDir, pid);
68127
+ const personaDir = path61.join(sessionsDir, pid);
68920
68128
  if (!isDir(personaDir)) continue;
68921
68129
  if (pid === "default") continue;
68922
- const ownerSrc = path62.join(personaDir, "owner");
68130
+ const ownerSrc = path61.join(personaDir, "owner");
68923
68131
  if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
68924
- const ownerDst = path62.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
68925
- fs61.mkdirSync(ownerDst, { recursive: true });
68132
+ const ownerDst = path61.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
68133
+ fs60.mkdirSync(ownerDst, { recursive: true });
68926
68134
  for (const file of readdirSafe(ownerSrc)) {
68927
68135
  if (!file.endsWith(".json")) continue;
68928
- fs61.renameSync(path62.join(ownerSrc, file), path62.join(ownerDst, file));
68136
+ fs60.renameSync(path61.join(ownerSrc, file), path61.join(ownerDst, file));
68929
68137
  movedVmOwner += 1;
68930
68138
  }
68931
68139
  rmdirIfEmpty(ownerSrc);
68932
68140
  }
68933
- const listenerSrc = path62.join(personaDir, "listener");
68141
+ const listenerSrc = path61.join(personaDir, "listener");
68934
68142
  if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
68935
- const archiveDst = path62.join(dataDir, ".legacy", `listener-${pid}`);
68936
- fs61.mkdirSync(archiveDst, { recursive: true });
68143
+ const archiveDst = path61.join(dataDir, ".legacy", `listener-${pid}`);
68144
+ fs60.mkdirSync(archiveDst, { recursive: true });
68937
68145
  for (const file of readdirSafe(listenerSrc)) {
68938
68146
  if (!file.endsWith(".json")) continue;
68939
- fs61.renameSync(path62.join(listenerSrc, file), path62.join(archiveDst, file));
68147
+ fs60.renameSync(path61.join(listenerSrc, file), path61.join(archiveDst, file));
68940
68148
  archivedListener += 1;
68941
68149
  }
68942
68150
  rmdirIfEmpty(listenerSrc);
68943
68151
  }
68944
68152
  rmdirIfEmpty(personaDir);
68945
68153
  }
68946
- fs61.mkdirSync(sessionsDir, { recursive: true });
68947
- fs61.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
68154
+ fs60.mkdirSync(sessionsDir, { recursive: true });
68155
+ fs60.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
68948
68156
  return {
68949
68157
  skipped: false,
68950
68158
  flagWritten: true,
@@ -68955,7 +68163,7 @@ function migrateFlattenSessions(opts) {
68955
68163
  }
68956
68164
  function existsSync3(p3) {
68957
68165
  try {
68958
- fs61.statSync(p3);
68166
+ fs60.statSync(p3);
68959
68167
  return true;
68960
68168
  } catch {
68961
68169
  return false;
@@ -68963,63 +68171,63 @@ function existsSync3(p3) {
68963
68171
  }
68964
68172
  function isDir(p3) {
68965
68173
  try {
68966
- return fs61.statSync(p3).isDirectory();
68174
+ return fs60.statSync(p3).isDirectory();
68967
68175
  } catch {
68968
68176
  return false;
68969
68177
  }
68970
68178
  }
68971
68179
  function readdirSafe(p3) {
68972
68180
  try {
68973
- return fs61.readdirSync(p3);
68181
+ return fs60.readdirSync(p3);
68974
68182
  } catch {
68975
68183
  return [];
68976
68184
  }
68977
68185
  }
68978
68186
  function rmdirIfEmpty(p3) {
68979
68187
  try {
68980
- fs61.rmdirSync(p3);
68188
+ fs60.rmdirSync(p3);
68981
68189
  } catch {
68982
68190
  }
68983
68191
  }
68984
68192
 
68985
68193
  // src/migrations/2026-08-18-drop-seeded-projects.ts
68986
- var fs62 = __toESM(require("fs"), 1);
68987
- var path63 = __toESM(require("path"), 1);
68194
+ var fs61 = __toESM(require("fs"), 1);
68195
+ var path62 = __toESM(require("path"), 1);
68988
68196
  var DROP_SEEDED_PROJECTS_FLAG = ".projects-seed-dropped.v1.done";
68989
68197
  function dropSeededProjects(opts) {
68990
- fs62.mkdirSync(opts.dataDir, { recursive: true });
68991
- const flag = path63.join(opts.dataDir, DROP_SEEDED_PROJECTS_FLAG);
68992
- if (fs62.existsSync(flag)) return { skipped: true, dropped: 0, backup: null };
68993
- const file = path63.join(opts.dataDir, "projects.json");
68198
+ fs61.mkdirSync(opts.dataDir, { recursive: true });
68199
+ const flag = path62.join(opts.dataDir, DROP_SEEDED_PROJECTS_FLAG);
68200
+ if (fs61.existsSync(flag)) return { skipped: true, dropped: 0, backup: null };
68201
+ const file = path62.join(opts.dataDir, "projects.json");
68994
68202
  let raw = null;
68995
68203
  let dropped = 0;
68996
68204
  try {
68997
- raw = fs62.readFileSync(file, "utf8");
68205
+ raw = fs61.readFileSync(file, "utf8");
68998
68206
  dropped = JSON.parse(raw).projects?.length ?? 0;
68999
68207
  } catch {
69000
68208
  }
69001
68209
  let backup = null;
69002
68210
  if (raw != null && dropped > 0) {
69003
- const dir = path63.join(opts.dataDir, "backups");
69004
- fs62.mkdirSync(dir, { recursive: true });
69005
- backup = path63.join(dir, `projects.seed-dropped.${(opts.now ?? Date.now)()}.json`);
69006
- fs62.writeFileSync(backup, raw);
68211
+ const dir = path62.join(opts.dataDir, "backups");
68212
+ fs61.mkdirSync(dir, { recursive: true });
68213
+ backup = path62.join(dir, `projects.seed-dropped.${(opts.now ?? Date.now)()}.json`);
68214
+ fs61.writeFileSync(backup, raw);
69007
68215
  }
69008
68216
  if (raw != null || dropped > 0) {
69009
- fs62.writeFileSync(file, JSON.stringify({ projects: [] }, null, 2));
68217
+ fs61.writeFileSync(file, JSON.stringify({ projects: [] }, null, 2));
69010
68218
  }
69011
- fs62.writeFileSync(flag, (/* @__PURE__ */ new Date()).toISOString());
68219
+ fs61.writeFileSync(flag, (/* @__PURE__ */ new Date()).toISOString());
69012
68220
  return { skipped: false, dropped, backup };
69013
68221
  }
69014
68222
 
69015
68223
  // src/transport/http-router.ts
69016
- var import_node_fs49 = __toESM(require("fs"), 1);
69017
- var import_node_path54 = __toESM(require("path"), 1);
68224
+ var import_node_fs48 = __toESM(require("fs"), 1);
68225
+ var import_node_path53 = __toESM(require("path"), 1);
69018
68226
 
69019
68227
  // src/attachment/upload.ts
69020
- var import_node_fs48 = __toESM(require("fs"), 1);
69021
- var import_node_path52 = __toESM(require("path"), 1);
69022
- var import_node_crypto18 = __toESM(require("crypto"), 1);
68228
+ var import_node_fs47 = __toESM(require("fs"), 1);
68229
+ var import_node_path51 = __toESM(require("path"), 1);
68230
+ var import_node_crypto16 = __toESM(require("crypto"), 1);
69023
68231
  var import_promises8 = require("stream/promises");
69024
68232
  var UploadError = class extends Error {
69025
68233
  constructor(code, message) {
@@ -69030,24 +68238,24 @@ var UploadError = class extends Error {
69030
68238
  code;
69031
68239
  };
69032
68240
  function assertValidFileName(fileName) {
69033
- if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path52.default.basename(fileName)) {
68241
+ if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path51.default.basename(fileName)) {
69034
68242
  throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
69035
68243
  }
69036
68244
  }
69037
68245
  var HASH_PREFIX_LEN = 16;
69038
68246
  async function writeUploadedAttachment(args) {
69039
68247
  assertValidFileName(args.fileName);
69040
- const attachmentsRoot = import_node_path52.default.join(args.baseDir, ".attachments");
68248
+ const attachmentsRoot = import_node_path51.default.join(args.baseDir, ".attachments");
69041
68249
  try {
69042
- import_node_fs48.default.mkdirSync(attachmentsRoot, { recursive: true });
68250
+ import_node_fs47.default.mkdirSync(attachmentsRoot, { recursive: true });
69043
68251
  } catch (err) {
69044
68252
  throw new UploadError("STORAGE_ERROR", `mkdir failed: ${err.message}`);
69045
68253
  }
69046
- const hasher = import_node_crypto18.default.createHash("sha256");
68254
+ const hasher = import_node_crypto16.default.createHash("sha256");
69047
68255
  let actualSize = 0;
69048
- const tmpPath = import_node_path52.default.join(
68256
+ const tmpPath = import_node_path51.default.join(
69049
68257
  attachmentsRoot,
69050
- `.upload-${process.pid}-${Date.now()}-${import_node_crypto18.default.randomBytes(4).toString("hex")}`
68258
+ `.upload-${process.pid}-${Date.now()}-${import_node_crypto16.default.randomBytes(4).toString("hex")}`
69051
68259
  );
69052
68260
  try {
69053
68261
  await (0, import_promises8.pipeline)(
@@ -69060,18 +68268,18 @@ async function writeUploadedAttachment(args) {
69060
68268
  yield buf;
69061
68269
  }
69062
68270
  },
69063
- import_node_fs48.default.createWriteStream(tmpPath, { mode: 384 })
68271
+ import_node_fs47.default.createWriteStream(tmpPath, { mode: 384 })
69064
68272
  );
69065
68273
  } catch (err) {
69066
68274
  try {
69067
- import_node_fs48.default.unlinkSync(tmpPath);
68275
+ import_node_fs47.default.unlinkSync(tmpPath);
69068
68276
  } catch {
69069
68277
  }
69070
68278
  throw new UploadError("STORAGE_ERROR", `write failed: ${err.message}`);
69071
68279
  }
69072
68280
  if (actualSize !== args.contentLength) {
69073
68281
  try {
69074
- import_node_fs48.default.unlinkSync(tmpPath);
68282
+ import_node_fs47.default.unlinkSync(tmpPath);
69075
68283
  } catch {
69076
68284
  }
69077
68285
  throw new UploadError(
@@ -69080,34 +68288,34 @@ async function writeUploadedAttachment(args) {
69080
68288
  );
69081
68289
  }
69082
68290
  const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
69083
- const hashDir = import_node_path52.default.join(attachmentsRoot, attachmentId);
68291
+ const hashDir = import_node_path51.default.join(attachmentsRoot, attachmentId);
69084
68292
  let finalFileName;
69085
68293
  let hashDirExists = false;
69086
68294
  try {
69087
- hashDirExists = import_node_fs48.default.statSync(hashDir).isDirectory();
68295
+ hashDirExists = import_node_fs47.default.statSync(hashDir).isDirectory();
69088
68296
  } catch {
69089
68297
  }
69090
68298
  if (hashDirExists) {
69091
- const existing = import_node_fs48.default.readdirSync(hashDir).filter((n2) => !n2.startsWith("."));
68299
+ const existing = import_node_fs47.default.readdirSync(hashDir).filter((n2) => !n2.startsWith("."));
69092
68300
  finalFileName = existing[0] ?? args.fileName;
69093
68301
  try {
69094
- import_node_fs48.default.unlinkSync(tmpPath);
68302
+ import_node_fs47.default.unlinkSync(tmpPath);
69095
68303
  } catch {
69096
68304
  }
69097
68305
  } else {
69098
68306
  try {
69099
- import_node_fs48.default.mkdirSync(hashDir, { recursive: true });
68307
+ import_node_fs47.default.mkdirSync(hashDir, { recursive: true });
69100
68308
  finalFileName = args.fileName;
69101
- import_node_fs48.default.renameSync(tmpPath, import_node_path52.default.join(hashDir, finalFileName));
68309
+ import_node_fs47.default.renameSync(tmpPath, import_node_path51.default.join(hashDir, finalFileName));
69102
68310
  } catch (err) {
69103
68311
  try {
69104
- import_node_fs48.default.unlinkSync(tmpPath);
68312
+ import_node_fs47.default.unlinkSync(tmpPath);
69105
68313
  } catch {
69106
68314
  }
69107
68315
  throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
69108
68316
  }
69109
68317
  }
69110
- const absPath = import_node_path52.default.join(hashDir, finalFileName);
68318
+ const absPath = import_node_path51.default.join(hashDir, finalFileName);
69111
68319
  const relPath = absPath;
69112
68320
  args.groupFileStore.upsert(args.scope, args.sessionId, {
69113
68321
  relPath: absPath,
@@ -69122,7 +68330,7 @@ async function writeUploadedAttachment(args) {
69122
68330
 
69123
68331
  // src/extension/import.ts
69124
68332
  var import_promises9 = __toESM(require("fs/promises"), 1);
69125
- var import_node_path53 = __toESM(require("path"), 1);
68333
+ var import_node_path52 = __toESM(require("path"), 1);
69126
68334
  var import_node_os20 = __toESM(require("os"), 1);
69127
68335
  var import_jszip = __toESM(require_lib3(), 1);
69128
68336
  var ImportError = class extends Error {
@@ -69140,7 +68348,7 @@ async function importZip(buf, root) {
69140
68348
  throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
69141
68349
  }
69142
68350
  for (const name of Object.keys(zip.files)) {
69143
- if (name.includes("..") || name.startsWith("/") || import_node_path53.default.isAbsolute(name)) {
68351
+ if (name.includes("..") || name.startsWith("/") || import_node_path52.default.isAbsolute(name)) {
69144
68352
  throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
69145
68353
  }
69146
68354
  }
@@ -69173,7 +68381,7 @@ async function importZip(buf, root) {
69173
68381
  );
69174
68382
  }
69175
68383
  }
69176
- const destDir = import_node_path53.default.join(root, manifest.id);
68384
+ const destDir = import_node_path52.default.join(root, manifest.id);
69177
68385
  let destExists = false;
69178
68386
  try {
69179
68387
  await import_promises9.default.access(destDir);
@@ -69183,15 +68391,15 @@ async function importZip(buf, root) {
69183
68391
  if (destExists) {
69184
68392
  throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
69185
68393
  }
69186
- const stage = await import_promises9.default.mkdtemp(import_node_path53.default.join(import_node_os20.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
68394
+ const stage = await import_promises9.default.mkdtemp(import_node_path52.default.join(import_node_os20.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
69187
68395
  try {
69188
68396
  for (const [name, entry] of Object.entries(zip.files)) {
69189
- const dest = import_node_path53.default.join(stage, name);
68397
+ const dest = import_node_path52.default.join(stage, name);
69190
68398
  if (entry.dir) {
69191
68399
  await import_promises9.default.mkdir(dest, { recursive: true });
69192
68400
  continue;
69193
68401
  }
69194
- await import_promises9.default.mkdir(import_node_path53.default.dirname(dest), { recursive: true });
68402
+ await import_promises9.default.mkdir(import_node_path52.default.dirname(dest), { recursive: true });
69195
68403
  const content = await entry.async("nodebuffer");
69196
68404
  await import_promises9.default.writeFile(dest, content);
69197
68405
  }
@@ -69245,7 +68453,7 @@ var SHARE_UI_ASSET_MIME = {
69245
68453
  ".wasm": "application/wasm"
69246
68454
  };
69247
68455
  function shareUiAssetMime(filePath) {
69248
- const ext = import_node_path54.default.extname(filePath).toLowerCase();
68456
+ const ext = import_node_path53.default.extname(filePath).toLowerCase();
69249
68457
  return SHARE_UI_ASSET_MIME[ext] ?? lookupMime(filePath);
69250
68458
  }
69251
68459
  var AUTHED_RPC_ROUTE_PREFIX = "/rpc/";
@@ -69344,7 +68552,7 @@ function isValidUploadFileName(fileName) {
69344
68552
  if (fileName === "." || fileName === "..") return false;
69345
68553
  if (fileName.startsWith(".")) return false;
69346
68554
  if (fileName.includes("/") || fileName.includes("\\")) return false;
69347
- return fileName === import_node_path54.default.basename(fileName);
68555
+ return fileName === import_node_path53.default.basename(fileName);
69348
68556
  }
69349
68557
  function createHttpRouter(deps) {
69350
68558
  return async (req, res) => {
@@ -69428,7 +68636,7 @@ function createHttpRouter(deps) {
69428
68636
  }
69429
68637
  let buf;
69430
68638
  try {
69431
- buf = await import_node_fs49.default.promises.readFile(abs);
68639
+ buf = await import_node_fs48.default.promises.readFile(abs);
69432
68640
  } catch {
69433
68641
  sendJson2(res, 404, { code: "NOT_FOUND", message: "asset not found" });
69434
68642
  return true;
@@ -69574,7 +68782,7 @@ function createHttpRouter(deps) {
69574
68782
  sendHtml(res, statusByCode[r2.code], loader.renderErrorHtml(r2.code, msgByCode[r2.code]));
69575
68783
  return true;
69576
68784
  }
69577
- sendHtml(res, 200, loader.renderViewerHtml(import_node_path54.default.basename(r2.absPath)));
68785
+ sendHtml(res, 200, loader.renderViewerHtml(import_node_path53.default.basename(r2.absPath)));
69578
68786
  return true;
69579
68787
  }
69580
68788
  const ctx = deps.authResolver.resolveFromHeader(
@@ -69695,7 +68903,7 @@ function createHttpRouter(deps) {
69695
68903
  return true;
69696
68904
  }
69697
68905
  let absPath;
69698
- if (import_node_path54.default.isAbsolute(pathParam)) {
68906
+ if (import_node_path53.default.isAbsolute(pathParam)) {
69699
68907
  absPath = pathParam;
69700
68908
  } else if (deps.sessionStore) {
69701
68909
  const file = deps.sessionStore.read(sid);
@@ -69703,7 +68911,7 @@ function createHttpRouter(deps) {
69703
68911
  sendJson2(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
69704
68912
  return true;
69705
68913
  }
69706
- absPath = import_node_path54.default.join(file.cwd, pathParam);
68914
+ absPath = import_node_path53.default.join(file.cwd, pathParam);
69707
68915
  } else {
69708
68916
  sendJson2(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
69709
68917
  return true;
@@ -69787,7 +68995,7 @@ function withCtx(ctx, body) {
69787
68995
  function streamFile(res, absPath, logger) {
69788
68996
  let stat;
69789
68997
  try {
69790
- stat = import_node_fs49.default.statSync(absPath);
68998
+ stat = import_node_fs48.default.statSync(absPath);
69791
68999
  } catch (err) {
69792
69000
  const code = err?.code;
69793
69001
  if (code === "ENOENT") {
@@ -69802,7 +69010,7 @@ function streamFile(res, absPath, logger) {
69802
69010
  return;
69803
69011
  }
69804
69012
  const mime = lookupMime(absPath);
69805
- const basename2 = import_node_path54.default.basename(absPath);
69013
+ const basename2 = import_node_path53.default.basename(absPath);
69806
69014
  res.writeHead(200, {
69807
69015
  "Content-Type": mime,
69808
69016
  "Content-Length": String(stat.size),
@@ -69810,7 +69018,7 @@ function streamFile(res, absPath, logger) {
69810
69018
  // 防止浏览器把任意 mime 当 html 渲染
69811
69019
  "X-Content-Type-Options": "nosniff"
69812
69020
  });
69813
- const stream = import_node_fs49.default.createReadStream(absPath);
69021
+ const stream = import_node_fs48.default.createReadStream(absPath);
69814
69022
  stream.on("error", (err) => {
69815
69023
  logger?.warn("streamFile read error", { absPath, err: err.message });
69816
69024
  res.destroy();
@@ -69819,8 +69027,8 @@ function streamFile(res, absPath, logger) {
69819
69027
  }
69820
69028
 
69821
69029
  // src/attachment/gc.ts
69822
- var import_node_fs50 = __toESM(require("fs"), 1);
69823
- var import_node_path55 = __toESM(require("path"), 1);
69030
+ var import_node_fs49 = __toESM(require("fs"), 1);
69031
+ var import_node_path54 = __toESM(require("path"), 1);
69824
69032
  var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
69825
69033
  function runAttachmentGc(args) {
69826
69034
  const now = (args.now ?? Date.now)();
@@ -69829,12 +69037,12 @@ function runAttachmentGc(args) {
69829
69037
  for (const { scope, sessionId } of args.sessionScopes) {
69830
69038
  for (const entry of args.groupFileStore.list(scope, sessionId)) {
69831
69039
  if (entry.stale) continue;
69832
- if (import_node_path55.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
69040
+ if (import_node_path54.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
69833
69041
  }
69834
69042
  }
69835
69043
  const visited = /* @__PURE__ */ new Set();
69836
69044
  for (const { scope, sessionId } of args.sessionScopes) {
69837
- const legacyDir = args.getSessionCwd?.(sessionId) ?? import_node_path55.default.join(
69045
+ const legacyDir = args.getSessionCwd?.(sessionId) ?? import_node_path54.default.join(
69838
69046
  args.dataDir,
69839
69047
  "sessions",
69840
69048
  ...scopeSubPath(scope).map(safeFileName),
@@ -69847,28 +69055,28 @@ function runAttachmentGc(args) {
69847
69055
  return true;
69848
69056
  });
69849
69057
  for (const rootDir of roots) {
69850
- const attRoot = import_node_path55.default.join(rootDir, ".attachments");
69058
+ const attRoot = import_node_path54.default.join(rootDir, ".attachments");
69851
69059
  let hashDirs;
69852
69060
  try {
69853
- hashDirs = import_node_fs50.default.readdirSync(attRoot);
69061
+ hashDirs = import_node_fs49.default.readdirSync(attRoot);
69854
69062
  } catch (err) {
69855
69063
  if (err.code === "ENOENT") continue;
69856
69064
  args.logger?.warn("attachment gc: readdir failed", { attRoot, err: err.message });
69857
69065
  continue;
69858
69066
  }
69859
69067
  for (const hashDir of hashDirs) {
69860
- const hashDirAbs = import_node_path55.default.join(attRoot, hashDir);
69068
+ const hashDirAbs = import_node_path54.default.join(attRoot, hashDir);
69861
69069
  let files;
69862
69070
  try {
69863
- files = import_node_fs50.default.readdirSync(hashDirAbs);
69071
+ files = import_node_fs49.default.readdirSync(hashDirAbs);
69864
69072
  } catch {
69865
69073
  continue;
69866
69074
  }
69867
69075
  for (const name of files) {
69868
- const file = import_node_path55.default.join(hashDirAbs, name);
69076
+ const file = import_node_path54.default.join(hashDirAbs, name);
69869
69077
  let stat;
69870
69078
  try {
69871
- stat = import_node_fs50.default.statSync(file);
69079
+ stat = import_node_fs49.default.statSync(file);
69872
69080
  } catch {
69873
69081
  continue;
69874
69082
  }
@@ -69877,18 +69085,18 @@ function runAttachmentGc(args) {
69877
69085
  if (age < ttlMs) continue;
69878
69086
  if (liveAbs.has(file)) continue;
69879
69087
  try {
69880
- import_node_fs50.default.unlinkSync(file);
69088
+ import_node_fs49.default.unlinkSync(file);
69881
69089
  } catch (err) {
69882
69090
  args.logger?.warn("attachment gc: unlink failed", { file, err: err.message });
69883
69091
  }
69884
69092
  }
69885
69093
  try {
69886
- if (import_node_fs50.default.readdirSync(hashDirAbs).length === 0) import_node_fs50.default.rmdirSync(hashDirAbs);
69094
+ if (import_node_fs49.default.readdirSync(hashDirAbs).length === 0) import_node_fs49.default.rmdirSync(hashDirAbs);
69887
69095
  } catch {
69888
69096
  }
69889
69097
  }
69890
69098
  try {
69891
- if (import_node_fs50.default.readdirSync(attRoot).length === 0) import_node_fs50.default.rmdirSync(attRoot);
69099
+ if (import_node_fs49.default.readdirSync(attRoot).length === 0) import_node_fs49.default.rmdirSync(attRoot);
69892
69100
  } catch {
69893
69101
  }
69894
69102
  }
@@ -69896,9 +69104,9 @@ function runAttachmentGc(args) {
69896
69104
  }
69897
69105
 
69898
69106
  // src/attachment/group.ts
69899
- var import_node_fs51 = __toESM(require("fs"), 1);
69900
- var import_node_path56 = __toESM(require("path"), 1);
69901
- var import_node_crypto19 = __toESM(require("crypto"), 1);
69107
+ var import_node_fs50 = __toESM(require("fs"), 1);
69108
+ var import_node_path55 = __toESM(require("path"), 1);
69109
+ var import_node_crypto17 = __toESM(require("crypto"), 1);
69902
69110
  init_protocol();
69903
69111
  var GroupFileStore = class {
69904
69112
  dataDir;
@@ -69909,11 +69117,11 @@ var GroupFileStore = class {
69909
69117
  this.logger = opts.logger;
69910
69118
  }
69911
69119
  rootForScope(scope) {
69912
- return import_node_path56.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
69120
+ return import_node_path55.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
69913
69121
  }
69914
69122
  /** 与 SessionStore.filePath 平级,扩展名 .group-files.json */
69915
69123
  filePath(scope, sessionId) {
69916
- return import_node_path56.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
69124
+ return import_node_path55.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
69917
69125
  }
69918
69126
  cacheKey(scope, sessionId) {
69919
69127
  return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
@@ -69922,7 +69130,7 @@ var GroupFileStore = class {
69922
69130
  readFile(scope, sessionId) {
69923
69131
  const file = this.filePath(scope, sessionId);
69924
69132
  try {
69925
- const raw = import_node_fs51.default.readFileSync(file, "utf8");
69133
+ const raw = import_node_fs50.default.readFileSync(file, "utf8");
69926
69134
  const parsed = JSON.parse(raw);
69927
69135
  if (!Array.isArray(parsed)) {
69928
69136
  this.logger?.warn("GroupFileStore.readFile: not an array; resetting session entries", {
@@ -69948,10 +69156,10 @@ var GroupFileStore = class {
69948
69156
  }
69949
69157
  writeFile(scope, sessionId, entries) {
69950
69158
  const file = this.filePath(scope, sessionId);
69951
- import_node_fs51.default.mkdirSync(import_node_path56.default.dirname(file), { recursive: true });
69159
+ import_node_fs50.default.mkdirSync(import_node_path55.default.dirname(file), { recursive: true });
69952
69160
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
69953
- import_node_fs51.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
69954
- import_node_fs51.default.renameSync(tmp, file);
69161
+ import_node_fs50.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
69162
+ import_node_fs50.default.renameSync(tmp, file);
69955
69163
  }
69956
69164
  /** 拉一份当前 session 的清单。读盘 → cache;之后调用复用 cache */
69957
69165
  list(scope, sessionId) {
@@ -69987,7 +69195,7 @@ var GroupFileStore = class {
69987
69195
  entries[idx] = next;
69988
69196
  } else {
69989
69197
  next = {
69990
- id: `gf-${import_node_crypto19.default.randomBytes(6).toString("base64url")}`,
69198
+ id: `gf-${import_node_crypto17.default.randomBytes(6).toString("base64url")}`,
69991
69199
  relPath: input.relPath,
69992
69200
  from: input.from,
69993
69201
  label: input.label,
@@ -70043,7 +69251,7 @@ var GroupFileStore = class {
70043
69251
  */
70044
69252
  deleteSession(scope, sessionId) {
70045
69253
  try {
70046
- import_node_fs51.default.unlinkSync(this.filePath(scope, sessionId));
69254
+ import_node_fs50.default.unlinkSync(this.filePath(scope, sessionId));
70047
69255
  } catch (err) {
70048
69256
  if (err?.code !== "ENOENT") throw err;
70049
69257
  }
@@ -70056,7 +69264,7 @@ var GroupFileStore = class {
70056
69264
  * 不在 persona 目录里(见文件头的路径约定)。没树的 persona 是 noop。
70057
69265
  */
70058
69266
  deletePersona(personaId2) {
70059
- import_node_fs51.default.rmSync(import_node_path56.default.join(this.dataDir, "sessions", safeFileName(personaId2)), { recursive: true, force: true });
69267
+ import_node_fs50.default.rmSync(import_node_path55.default.join(this.dataDir, "sessions", safeFileName(personaId2)), { recursive: true, force: true });
70060
69268
  const prefix = `persona:${personaId2}:`;
70061
69269
  for (const key of this.cache.keys()) {
70062
69270
  if (key.startsWith(prefix)) this.cache.delete(key);
@@ -70065,10 +69273,10 @@ var GroupFileStore = class {
70065
69273
  };
70066
69274
 
70067
69275
  // src/discovery/state-file.ts
70068
- var import_node_fs52 = __toESM(require("fs"), 1);
70069
- var import_node_path57 = __toESM(require("path"), 1);
69276
+ var import_node_fs51 = __toESM(require("fs"), 1);
69277
+ var import_node_path56 = __toESM(require("path"), 1);
70070
69278
  function defaultStateFilePath(dataDir) {
70071
- return import_node_path57.default.join(dataDir, "state.json");
69279
+ return import_node_path56.default.join(dataDir, "state.json");
70072
69280
  }
70073
69281
  function isPidAlive(pid) {
70074
69282
  if (!Number.isFinite(pid) || pid <= 0) return false;
@@ -70090,7 +69298,7 @@ var StateFileManager = class {
70090
69298
  }
70091
69299
  read() {
70092
69300
  try {
70093
- const raw = import_node_fs52.default.readFileSync(this.file, "utf8");
69301
+ const raw = import_node_fs51.default.readFileSync(this.file, "utf8");
70094
69302
  const parsed = JSON.parse(raw);
70095
69303
  return parsed;
70096
69304
  } catch {
@@ -70104,20 +69312,20 @@ var StateFileManager = class {
70104
69312
  return { status: "stale", existing };
70105
69313
  }
70106
69314
  write(state) {
70107
- import_node_fs52.default.mkdirSync(import_node_path57.default.dirname(this.file), { recursive: true });
69315
+ import_node_fs51.default.mkdirSync(import_node_path56.default.dirname(this.file), { recursive: true });
70108
69316
  const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
70109
- import_node_fs52.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
70110
- import_node_fs52.default.renameSync(tmp, this.file);
69317
+ import_node_fs51.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
69318
+ import_node_fs51.default.renameSync(tmp, this.file);
70111
69319
  if (process.platform !== "win32") {
70112
69320
  try {
70113
- import_node_fs52.default.chmodSync(this.file, 384);
69321
+ import_node_fs51.default.chmodSync(this.file, 384);
70114
69322
  } catch {
70115
69323
  }
70116
69324
  }
70117
69325
  }
70118
69326
  delete() {
70119
69327
  try {
70120
- import_node_fs52.default.unlinkSync(this.file);
69328
+ import_node_fs51.default.unlinkSync(this.file);
70121
69329
  } catch {
70122
69330
  }
70123
69331
  }
@@ -70131,14 +69339,14 @@ function readSpawnedByDesktopFromEnv(env = process.env) {
70131
69339
  }
70132
69340
 
70133
69341
  // src/tunnel/tunnel-manager.ts
70134
- var import_node_fs56 = __toESM(require("fs"), 1);
70135
- var import_node_path61 = __toESM(require("path"), 1);
70136
- var import_node_crypto20 = __toESM(require("crypto"), 1);
69342
+ var import_node_fs55 = __toESM(require("fs"), 1);
69343
+ var import_node_path60 = __toESM(require("path"), 1);
69344
+ var import_node_crypto18 = __toESM(require("crypto"), 1);
70137
69345
  var import_node_child_process16 = require("child_process");
70138
69346
 
70139
69347
  // src/tunnel/tunnel-store.ts
70140
- var import_node_fs53 = __toESM(require("fs"), 1);
70141
- var import_node_path58 = __toESM(require("path"), 1);
69348
+ var import_node_fs52 = __toESM(require("fs"), 1);
69349
+ var import_node_path57 = __toESM(require("path"), 1);
70142
69350
  var TunnelStore = class {
70143
69351
  constructor(filePath) {
70144
69352
  this.filePath = filePath;
@@ -70146,7 +69354,7 @@ var TunnelStore = class {
70146
69354
  filePath;
70147
69355
  async get() {
70148
69356
  try {
70149
- const raw = await import_node_fs53.default.promises.readFile(this.filePath, "utf8");
69357
+ const raw = await import_node_fs52.default.promises.readFile(this.filePath, "utf8");
70150
69358
  const obj = JSON.parse(raw);
70151
69359
  if (!isPersistedTunnel(obj)) return null;
70152
69360
  return obj;
@@ -70157,22 +69365,22 @@ var TunnelStore = class {
70157
69365
  }
70158
69366
  }
70159
69367
  async set(v3) {
70160
- const dir = import_node_path58.default.dirname(this.filePath);
70161
- await import_node_fs53.default.promises.mkdir(dir, { recursive: true });
69368
+ const dir = import_node_path57.default.dirname(this.filePath);
69369
+ await import_node_fs52.default.promises.mkdir(dir, { recursive: true });
70162
69370
  const data = JSON.stringify(v3, null, 2);
70163
69371
  const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
70164
- await import_node_fs53.default.promises.writeFile(tmp, data, { mode: 384 });
69372
+ await import_node_fs52.default.promises.writeFile(tmp, data, { mode: 384 });
70165
69373
  if (process.platform !== "win32") {
70166
69374
  try {
70167
- await import_node_fs53.default.promises.chmod(tmp, 384);
69375
+ await import_node_fs52.default.promises.chmod(tmp, 384);
70168
69376
  } catch {
70169
69377
  }
70170
69378
  }
70171
- await import_node_fs53.default.promises.rename(tmp, this.filePath);
69379
+ await import_node_fs52.default.promises.rename(tmp, this.filePath);
70172
69380
  }
70173
69381
  async clear() {
70174
69382
  try {
70175
- await import_node_fs53.default.promises.unlink(this.filePath);
69383
+ await import_node_fs52.default.promises.unlink(this.filePath);
70176
69384
  } catch (err) {
70177
69385
  const code = err?.code;
70178
69386
  if (code !== "ENOENT") throw err;
@@ -70267,9 +69475,9 @@ function escape2(v3) {
70267
69475
  }
70268
69476
 
70269
69477
  // src/tunnel/frpc-binary.ts
70270
- var import_node_fs54 = __toESM(require("fs"), 1);
69478
+ var import_node_fs53 = __toESM(require("fs"), 1);
70271
69479
  var import_node_os21 = __toESM(require("os"), 1);
70272
- var import_node_path59 = __toESM(require("path"), 1);
69480
+ var import_node_path58 = __toESM(require("path"), 1);
70273
69481
  var import_node_child_process14 = require("child_process");
70274
69482
  var import_node_stream4 = require("stream");
70275
69483
  var import_promises10 = require("stream/promises");
@@ -70301,20 +69509,20 @@ function frpcDownloadUrl(version2, p3) {
70301
69509
  }
70302
69510
  async function ensureFrpcBinary(opts) {
70303
69511
  if (opts.override) {
70304
- if (!import_node_fs54.default.existsSync(opts.override)) {
69512
+ if (!import_node_fs53.default.existsSync(opts.override)) {
70305
69513
  throw new Error(`frpc binary not found at override path: ${opts.override}`);
70306
69514
  }
70307
69515
  return opts.override;
70308
69516
  }
70309
69517
  const version2 = opts.version ?? FRPC_VERSION;
70310
69518
  const platform = opts.platform ?? detectPlatform();
70311
- const binDir = import_node_path59.default.join(opts.dataDir, "bin");
70312
- import_node_fs54.default.mkdirSync(binDir, { recursive: true });
69519
+ const binDir = import_node_path58.default.join(opts.dataDir, "bin");
69520
+ import_node_fs53.default.mkdirSync(binDir, { recursive: true });
70313
69521
  cleanupStaleArtifacts(binDir);
70314
- const stableBin = import_node_path59.default.join(binDir, "frpc");
70315
- if (import_node_fs54.default.existsSync(stableBin)) return stableBin;
69522
+ const stableBin = import_node_path58.default.join(binDir, "frpc");
69523
+ if (import_node_fs53.default.existsSync(stableBin)) return stableBin;
70316
69524
  const partialBin = `${stableBin}.partial`;
70317
- const tarballPath = import_node_path59.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
69525
+ const tarballPath = import_node_path58.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
70318
69526
  try {
70319
69527
  const url = frpcDownloadUrl(version2, platform);
70320
69528
  await downloadToFile(url, tarballPath, opts.fetchImpl);
@@ -70323,8 +69531,8 @@ async function ensureFrpcBinary(opts) {
70323
69531
  } else {
70324
69532
  await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
70325
69533
  }
70326
- import_node_fs54.default.chmodSync(partialBin, 493);
70327
- import_node_fs54.default.renameSync(partialBin, stableBin);
69534
+ import_node_fs53.default.chmodSync(partialBin, 493);
69535
+ import_node_fs53.default.renameSync(partialBin, stableBin);
70328
69536
  } finally {
70329
69537
  safeUnlink(tarballPath);
70330
69538
  safeUnlink(partialBin);
@@ -70334,15 +69542,15 @@ async function ensureFrpcBinary(opts) {
70334
69542
  function cleanupStaleArtifacts(binDir) {
70335
69543
  let entries;
70336
69544
  try {
70337
- entries = import_node_fs54.default.readdirSync(binDir);
69545
+ entries = import_node_fs53.default.readdirSync(binDir);
70338
69546
  } catch {
70339
69547
  return;
70340
69548
  }
70341
69549
  for (const name of entries) {
70342
69550
  if (name.endsWith(".partial") || name.startsWith("extract-")) {
70343
- const full = import_node_path59.default.join(binDir, name);
69551
+ const full = import_node_path58.default.join(binDir, name);
70344
69552
  try {
70345
- import_node_fs54.default.rmSync(full, { recursive: true, force: true });
69553
+ import_node_fs53.default.rmSync(full, { recursive: true, force: true });
70346
69554
  } catch {
70347
69555
  }
70348
69556
  }
@@ -70350,7 +69558,7 @@ function cleanupStaleArtifacts(binDir) {
70350
69558
  }
70351
69559
  function safeUnlink(p3) {
70352
69560
  try {
70353
- import_node_fs54.default.unlinkSync(p3);
69561
+ import_node_fs53.default.unlinkSync(p3);
70354
69562
  } catch {
70355
69563
  }
70356
69564
  }
@@ -70361,13 +69569,13 @@ async function downloadToFile(url, dest, fetchImpl) {
70361
69569
  if (!res.ok || !res.body) {
70362
69570
  throw new Error(`download failed: ${res.status} ${res.statusText}`);
70363
69571
  }
70364
- const out = import_node_fs54.default.createWriteStream(dest);
69572
+ const out = import_node_fs53.default.createWriteStream(dest);
70365
69573
  const nodeStream = import_node_stream4.Readable.fromWeb(res.body);
70366
69574
  await (0, import_promises10.pipeline)(nodeStream, out);
70367
69575
  }
70368
69576
  async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
70369
- const work = import_node_path59.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
70370
- import_node_fs54.default.mkdirSync(work, { recursive: true });
69577
+ const work = import_node_path58.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
69578
+ import_node_fs53.default.mkdirSync(work, { recursive: true });
70371
69579
  try {
70372
69580
  await new Promise((resolve9, reject) => {
70373
69581
  const proc = (0, import_node_child_process14.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
@@ -70375,32 +69583,32 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
70375
69583
  proc.on("exit", (code) => code === 0 ? resolve9() : reject(new Error(`tar exited ${code}`)));
70376
69584
  });
70377
69585
  const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
70378
- const src = import_node_path59.default.join(work, dirName, "frpc");
70379
- if (!import_node_fs54.default.existsSync(src)) {
69586
+ const src = import_node_path58.default.join(work, dirName, "frpc");
69587
+ if (!import_node_fs53.default.existsSync(src)) {
70380
69588
  throw new Error(`frpc not found inside tarball at ${src}`);
70381
69589
  }
70382
- import_node_fs54.default.copyFileSync(src, destBin);
69590
+ import_node_fs53.default.copyFileSync(src, destBin);
70383
69591
  } finally {
70384
- import_node_fs54.default.rmSync(work, { recursive: true, force: true });
69592
+ import_node_fs53.default.rmSync(work, { recursive: true, force: true });
70385
69593
  }
70386
69594
  }
70387
69595
 
70388
69596
  // src/tunnel/frpc-process.ts
70389
- var import_node_fs55 = __toESM(require("fs"), 1);
70390
- var import_node_path60 = __toESM(require("path"), 1);
69597
+ var import_node_fs54 = __toESM(require("fs"), 1);
69598
+ var import_node_path59 = __toESM(require("path"), 1);
70391
69599
  var import_node_child_process15 = require("child_process");
70392
69600
  function frpcPidFilePath(dataDir) {
70393
- return import_node_path60.default.join(dataDir, "frpc.pid");
69601
+ return import_node_path59.default.join(dataDir, "frpc.pid");
70394
69602
  }
70395
69603
  function writeFrpcPid(dataDir, pid) {
70396
69604
  try {
70397
- import_node_fs55.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
69605
+ import_node_fs54.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
70398
69606
  } catch {
70399
69607
  }
70400
69608
  }
70401
69609
  function clearFrpcPid(dataDir) {
70402
69610
  try {
70403
- import_node_fs55.default.unlinkSync(frpcPidFilePath(dataDir));
69611
+ import_node_fs54.default.unlinkSync(frpcPidFilePath(dataDir));
70404
69612
  } catch {
70405
69613
  }
70406
69614
  }
@@ -70416,7 +69624,7 @@ function defaultIsPidAlive(pid) {
70416
69624
  }
70417
69625
  function defaultReadPidFile(file) {
70418
69626
  try {
70419
- return import_node_fs55.default.readFileSync(file, "utf8");
69627
+ return import_node_fs54.default.readFileSync(file, "utf8");
70420
69628
  } catch {
70421
69629
  return null;
70422
69630
  }
@@ -70432,7 +69640,7 @@ function defaultSleep2(ms) {
70432
69640
  }
70433
69641
  async function killStaleFrpc(deps) {
70434
69642
  const pidFile = frpcPidFilePath(deps.dataDir);
70435
- const tomlPath = import_node_path60.default.join(deps.dataDir, "frpc.toml");
69643
+ const tomlPath = import_node_path59.default.join(deps.dataDir, "frpc.toml");
70436
69644
  const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
70437
69645
  const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
70438
69646
  const killPid = deps.killPidImpl ?? defaultKillPid;
@@ -70456,7 +69664,7 @@ async function killStaleFrpc(deps) {
70456
69664
  }
70457
69665
  if (victims.size === 0) {
70458
69666
  try {
70459
- import_node_fs55.default.unlinkSync(pidFile);
69667
+ import_node_fs54.default.unlinkSync(pidFile);
70460
69668
  } catch {
70461
69669
  }
70462
69670
  return;
@@ -70467,7 +69675,7 @@ async function killStaleFrpc(deps) {
70467
69675
  }
70468
69676
  await sleep2(deps.reapWaitMs ?? 300);
70469
69677
  try {
70470
- import_node_fs55.default.unlinkSync(pidFile);
69678
+ import_node_fs54.default.unlinkSync(pidFile);
70471
69679
  } catch {
70472
69680
  }
70473
69681
  }
@@ -70504,7 +69712,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
70504
69712
  var TunnelManager = class {
70505
69713
  constructor(deps) {
70506
69714
  this.deps = deps;
70507
- this.store = deps.store ?? new TunnelStore(import_node_path61.default.join(deps.dataDir, "tunnel.json"));
69715
+ this.store = deps.store ?? new TunnelStore(import_node_path60.default.join(deps.dataDir, "tunnel.json"));
70508
69716
  this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
70509
69717
  this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
70510
69718
  }
@@ -70631,8 +69839,8 @@ var TunnelManager = class {
70631
69839
  dataDir: this.deps.dataDir,
70632
69840
  override: this.deps.frpcBinaryOverride ?? void 0
70633
69841
  });
70634
- const tomlPath = import_node_path61.default.join(this.deps.dataDir, "frpc.toml");
70635
- const proxyName = `clawd-${t2.subdomain}-${localPort}-${import_node_crypto20.default.randomBytes(3).toString("hex")}`;
69842
+ const tomlPath = import_node_path60.default.join(this.deps.dataDir, "frpc.toml");
69843
+ const proxyName = `clawd-${t2.subdomain}-${localPort}-${import_node_crypto18.default.randomBytes(3).toString("hex")}`;
70636
69844
  const toml = buildFrpcToml({
70637
69845
  serverAddr: t2.frpsHost,
70638
69846
  serverPort: t2.frpsPort,
@@ -70642,14 +69850,14 @@ var TunnelManager = class {
70642
69850
  localPort,
70643
69851
  logLevel: "info"
70644
69852
  });
70645
- await import_node_fs56.default.promises.writeFile(tomlPath, toml, { mode: 384 });
69853
+ await import_node_fs55.default.promises.writeFile(tomlPath, toml, { mode: 384 });
70646
69854
  const proc = (this.deps.spawnImpl ?? import_node_child_process16.spawn)(frpcBin, ["-c", tomlPath], {
70647
69855
  stdio: ["ignore", "pipe", "pipe"]
70648
69856
  });
70649
- const logDir = import_node_path61.default.join(this.deps.dataDir, "log");
70650
- import_node_fs56.default.mkdirSync(logDir, { recursive: true });
70651
- const logFilePath = import_node_path61.default.join(logDir, "frpc.log");
70652
- const logStream = import_node_fs56.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
69857
+ const logDir = import_node_path60.default.join(this.deps.dataDir, "log");
69858
+ import_node_fs55.default.mkdirSync(logDir, { recursive: true });
69859
+ const logFilePath = import_node_path60.default.join(logDir, "frpc.log");
69860
+ const logStream = import_node_fs55.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
70653
69861
  logStream.on("error", () => {
70654
69862
  });
70655
69863
  const tee = (chunk) => {
@@ -70732,27 +69940,27 @@ async function waitForFrpcReady(proc, timeoutMs) {
70732
69940
 
70733
69941
  // src/tunnel/device-key.ts
70734
69942
  var import_node_os22 = __toESM(require("os"), 1);
70735
- var import_node_path62 = __toESM(require("path"), 1);
70736
- var import_node_crypto21 = __toESM(require("crypto"), 1);
69943
+ var import_node_path61 = __toESM(require("path"), 1);
69944
+ var import_node_crypto19 = __toESM(require("crypto"), 1);
70737
69945
  var DERIVE_SALT = "clawd-tunnel-device-v1";
70738
69946
  function deriveStableDeviceKey(opts = {}) {
70739
69947
  const hostname = opts.hostname ?? import_node_os22.default.hostname();
70740
69948
  const uid = opts.uid ?? (typeof import_node_os22.default.userInfo === "function" ? import_node_os22.default.userInfo().uid : 0);
70741
69949
  const home = opts.home ?? import_node_os22.default.homedir();
70742
- const defaultDataDir = import_node_path62.default.resolve(import_node_path62.default.join(home, ".clawd"));
70743
- const normalizedDataDir = opts.dataDir ? import_node_path62.default.resolve(opts.dataDir) : null;
69950
+ const defaultDataDir = import_node_path61.default.resolve(import_node_path61.default.join(home, ".clawd"));
69951
+ const normalizedDataDir = opts.dataDir ? import_node_path61.default.resolve(opts.dataDir) : null;
70744
69952
  const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
70745
69953
  const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
70746
- return import_node_crypto21.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
69954
+ return import_node_crypto19.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
70747
69955
  }
70748
69956
 
70749
69957
  // src/auth-store.ts
70750
- var import_node_fs57 = __toESM(require("fs"), 1);
70751
- var import_node_path63 = __toESM(require("path"), 1);
70752
- var import_node_crypto22 = __toESM(require("crypto"), 1);
69958
+ var import_node_fs56 = __toESM(require("fs"), 1);
69959
+ var import_node_path62 = __toESM(require("path"), 1);
69960
+ var import_node_crypto20 = __toESM(require("crypto"), 1);
70753
69961
  var AUTH_FILE_NAME = "auth.json";
70754
69962
  function authFilePath(dataDir) {
70755
- return import_node_path63.default.join(dataDir, AUTH_FILE_NAME);
69963
+ return import_node_path62.default.join(dataDir, AUTH_FILE_NAME);
70756
69964
  }
70757
69965
  function loadOrCreateAuthFile(opts) {
70758
69966
  const file = authFilePath(opts.dataDir);
@@ -70786,14 +69994,14 @@ function loadOrCreateTunnelDeviceKey(opts) {
70786
69994
  return tunnelDeviceKey;
70787
69995
  }
70788
69996
  function defaultGenerateToken() {
70789
- return import_node_crypto22.default.randomBytes(32).toString("base64url");
69997
+ return import_node_crypto20.default.randomBytes(32).toString("base64url");
70790
69998
  }
70791
69999
  function defaultGenerateOwnerPrincipalId() {
70792
- return `owner-${import_node_crypto22.default.randomUUID()}`;
70000
+ return `owner-${import_node_crypto20.default.randomUUID()}`;
70793
70001
  }
70794
70002
  function readAuthFile(file) {
70795
70003
  try {
70796
- const raw = import_node_fs57.default.readFileSync(file, "utf8");
70004
+ const raw = import_node_fs56.default.readFileSync(file, "utf8");
70797
70005
  const parsed = JSON.parse(raw);
70798
70006
  if (typeof parsed?.token !== "string" || parsed.token.length === 0) {
70799
70007
  return null;
@@ -70814,26 +70022,26 @@ function readAuthFile(file) {
70814
70022
  }
70815
70023
  }
70816
70024
  function writeAuthFile(file, content) {
70817
- import_node_fs57.default.mkdirSync(import_node_path63.default.dirname(file), { recursive: true });
70818
- import_node_fs57.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
70025
+ import_node_fs56.default.mkdirSync(import_node_path62.default.dirname(file), { recursive: true });
70026
+ import_node_fs56.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
70819
70027
  try {
70820
- import_node_fs57.default.chmodSync(file, 384);
70028
+ import_node_fs56.default.chmodSync(file, 384);
70821
70029
  } catch {
70822
70030
  }
70823
70031
  }
70824
70032
 
70825
70033
  // src/owner-profile.ts
70826
- var import_node_fs58 = __toESM(require("fs"), 1);
70034
+ var import_node_fs57 = __toESM(require("fs"), 1);
70827
70035
  var import_node_os23 = __toESM(require("os"), 1);
70828
- var import_node_path64 = __toESM(require("path"), 1);
70036
+ var import_node_path63 = __toESM(require("path"), 1);
70829
70037
  var PROFILE_FILENAME = "profile.json";
70830
70038
  function profilePath(dataDir) {
70831
- return import_node_path64.default.join(dataDir, PROFILE_FILENAME);
70039
+ return import_node_path63.default.join(dataDir, PROFILE_FILENAME);
70832
70040
  }
70833
70041
  function loadOwnerProfile(dataDir) {
70834
70042
  let raw;
70835
70043
  try {
70836
- raw = import_node_fs58.default.readFileSync(profilePath(dataDir), "utf8");
70044
+ raw = import_node_fs57.default.readFileSync(profilePath(dataDir), "utf8");
70837
70045
  } catch {
70838
70046
  return {};
70839
70047
  }
@@ -70849,7 +70057,7 @@ function loadOwnerProfile(dataDir) {
70849
70057
  }
70850
70058
  function patchOwnerProfile(dataDir, patch) {
70851
70059
  const merged = { ...loadOwnerProfile(dataDir), ...patch };
70852
- import_node_fs58.default.writeFileSync(profilePath(dataDir), JSON.stringify(merged, null, 2), { encoding: "utf8", mode: 384 });
70060
+ import_node_fs57.default.writeFileSync(profilePath(dataDir), JSON.stringify(merged, null, 2), { encoding: "utf8", mode: 384 });
70853
70061
  return merged;
70854
70062
  }
70855
70063
  function loadOwnerDisplayName(dataDir) {
@@ -70865,18 +70073,18 @@ function loadOwnerDisplayName(dataDir) {
70865
70073
  }
70866
70074
 
70867
70075
  // src/feishu-auth/owner-identity-store.ts
70868
- var import_node_fs59 = __toESM(require("fs"), 1);
70869
- var import_node_path65 = __toESM(require("path"), 1);
70076
+ var import_node_fs58 = __toESM(require("fs"), 1);
70077
+ var import_node_path64 = __toESM(require("path"), 1);
70870
70078
  var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
70871
70079
  var OwnerIdentityStore = class {
70872
70080
  file;
70873
70081
  constructor(dataDir) {
70874
- this.file = import_node_path65.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
70082
+ this.file = import_node_path64.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
70875
70083
  }
70876
70084
  read() {
70877
70085
  let raw;
70878
70086
  try {
70879
- raw = import_node_fs59.default.readFileSync(this.file, "utf8");
70087
+ raw = import_node_fs58.default.readFileSync(this.file, "utf8");
70880
70088
  } catch {
70881
70089
  return null;
70882
70090
  }
@@ -70903,16 +70111,16 @@ var OwnerIdentityStore = class {
70903
70111
  };
70904
70112
  }
70905
70113
  write(record4) {
70906
- import_node_fs59.default.mkdirSync(import_node_path65.default.dirname(this.file), { recursive: true });
70907
- import_node_fs59.default.writeFileSync(this.file, JSON.stringify(record4, null, 2), { mode: 384 });
70114
+ import_node_fs58.default.mkdirSync(import_node_path64.default.dirname(this.file), { recursive: true });
70115
+ import_node_fs58.default.writeFileSync(this.file, JSON.stringify(record4, null, 2), { mode: 384 });
70908
70116
  try {
70909
- import_node_fs59.default.chmodSync(this.file, 384);
70117
+ import_node_fs58.default.chmodSync(this.file, 384);
70910
70118
  } catch {
70911
70119
  }
70912
70120
  }
70913
70121
  clear() {
70914
70122
  try {
70915
- import_node_fs59.default.unlinkSync(this.file);
70123
+ import_node_fs58.default.unlinkSync(this.file);
70916
70124
  } catch (err) {
70917
70125
  const code = err?.code;
70918
70126
  if (code !== "ENOENT") throw err;
@@ -70921,7 +70129,7 @@ var OwnerIdentityStore = class {
70921
70129
  };
70922
70130
 
70923
70131
  // src/feishu-auth/login-flow.ts
70924
- var import_node_crypto23 = __toESM(require("crypto"), 1);
70132
+ var import_node_crypto21 = __toESM(require("crypto"), 1);
70925
70133
  var STATE_TTL_MS = 5 * 60 * 1e3;
70926
70134
  var LoginFlow = class {
70927
70135
  constructor(deps) {
@@ -70930,7 +70138,7 @@ var LoginFlow = class {
70930
70138
  deps;
70931
70139
  pendingStates = /* @__PURE__ */ new Map();
70932
70140
  start() {
70933
- const state = import_node_crypto23.default.randomBytes(16).toString("base64url");
70141
+ const state = import_node_crypto21.default.randomBytes(16).toString("base64url");
70934
70142
  const now = (this.deps.now ?? Date.now)();
70935
70143
  this.pendingStates.set(state, now);
70936
70144
  this.gcExpired(now);
@@ -71408,8 +70616,8 @@ function verifyConnectToken(args) {
71408
70616
  }
71409
70617
 
71410
70618
  // src/feishu-auth/server-key.ts
71411
- var fs76 = __toESM(require("fs"), 1);
71412
- var path78 = __toESM(require("path"), 1);
70619
+ var fs75 = __toESM(require("fs"), 1);
70620
+ var path77 = __toESM(require("path"), 1);
71413
70621
  var FILE_NAME2 = "server-signing-key.json";
71414
70622
  var ServerKeyStore = class {
71415
70623
  constructor(dataDir) {
@@ -71417,12 +70625,12 @@ var ServerKeyStore = class {
71417
70625
  }
71418
70626
  dataDir;
71419
70627
  filePath() {
71420
- return path78.join(this.dataDir, FILE_NAME2);
70628
+ return path77.join(this.dataDir, FILE_NAME2);
71421
70629
  }
71422
70630
  /** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
71423
70631
  read() {
71424
70632
  try {
71425
- const raw = fs76.readFileSync(this.filePath(), "utf8");
70633
+ const raw = fs75.readFileSync(this.filePath(), "utf8");
71426
70634
  const parsed = JSON.parse(raw);
71427
70635
  if (typeof parsed.publicKeyPem === "string" && parsed.publicKeyPem.includes("PUBLIC KEY")) {
71428
70636
  return parsed.publicKeyPem;
@@ -71437,12 +70645,12 @@ var ServerKeyStore = class {
71437
70645
  publicKeyPem,
71438
70646
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
71439
70647
  };
71440
- fs76.mkdirSync(this.dataDir, { recursive: true });
71441
- fs76.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
70648
+ fs75.mkdirSync(this.dataDir, { recursive: true });
70649
+ fs75.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
71442
70650
  }
71443
70651
  clear() {
71444
70652
  try {
71445
- fs76.unlinkSync(this.filePath());
70653
+ fs75.unlinkSync(this.filePath());
71446
70654
  } catch {
71447
70655
  }
71448
70656
  }
@@ -71452,19 +70660,19 @@ var ServerKeyStore = class {
71452
70660
  init_protocol();
71453
70661
 
71454
70662
  // src/handlers/index.ts
71455
- var import_node_path81 = __toESM(require("path"), 1);
70663
+ var import_node_path80 = __toESM(require("path"), 1);
71456
70664
 
71457
70665
  // src/handlers/session.ts
71458
70666
  init_protocol();
71459
70667
 
71460
70668
  // src/session/fork.ts
71461
- var import_node_fs60 = __toESM(require("fs"), 1);
70669
+ var import_node_fs59 = __toESM(require("fs"), 1);
71462
70670
  var import_node_os24 = __toESM(require("os"), 1);
71463
- var import_node_path66 = __toESM(require("path"), 1);
71464
- var import_node_crypto24 = require("crypto");
70671
+ var import_node_path65 = __toESM(require("path"), 1);
70672
+ var import_node_crypto22 = require("crypto");
71465
70673
  init_claude_history();
71466
70674
  function readJsonlEntries(file) {
71467
- const raw = import_node_fs60.default.readFileSync(file, "utf8");
70675
+ const raw = import_node_fs59.default.readFileSync(file, "utf8");
71468
70676
  const out = [];
71469
70677
  for (const line of raw.split("\n")) {
71470
70678
  const t2 = line.trim();
@@ -71477,19 +70685,19 @@ function readJsonlEntries(file) {
71477
70685
  return out;
71478
70686
  }
71479
70687
  function forkSession(input) {
71480
- const baseDir = input.baseDir ?? import_node_path66.default.join(import_node_os24.default.homedir(), ".claude");
71481
- let projectDir = import_node_path66.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
71482
- let sourceFile = import_node_path66.default.join(projectDir, `${input.toolSessionId}.jsonl`);
71483
- if (!import_node_fs60.default.existsSync(sourceFile)) {
70688
+ const baseDir = input.baseDir ?? import_node_path65.default.join(import_node_os24.default.homedir(), ".claude");
70689
+ let projectDir = import_node_path65.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
70690
+ let sourceFile = import_node_path65.default.join(projectDir, `${input.toolSessionId}.jsonl`);
70691
+ if (!import_node_fs59.default.existsSync(sourceFile)) {
71484
70692
  const found = findTranscriptByToolSessionId(
71485
- import_node_path66.default.join(baseDir, "projects"),
70693
+ import_node_path65.default.join(baseDir, "projects"),
71486
70694
  input.toolSessionId
71487
70695
  );
71488
70696
  if (!found) {
71489
70697
  throw new Error(`fork: source transcript not found: ${sourceFile}`);
71490
70698
  }
71491
70699
  sourceFile = found;
71492
- projectDir = import_node_path66.default.dirname(found);
70700
+ projectDir = import_node_path65.default.dirname(found);
71493
70701
  }
71494
70702
  const entries = readJsonlEntries(sourceFile);
71495
70703
  const mainEntries = entries.filter((e) => e.isSidechain !== true);
@@ -71498,7 +70706,7 @@ function forkSession(input) {
71498
70706
  throw new Error(`fork: messageUuid not found in transcript: ${input.messageUuid}`);
71499
70707
  }
71500
70708
  const sliced = mainEntries.slice(0, targetIdx + 1);
71501
- const forkedToolSessionId = (0, import_node_crypto24.randomUUID)();
70709
+ const forkedToolSessionId = (0, import_node_crypto22.randomUUID)();
71502
70710
  let parentUuid = null;
71503
70711
  const forkedLines = [];
71504
70712
  for (const entry of sliced) {
@@ -71518,17 +70726,17 @@ function forkSession(input) {
71518
70726
  }
71519
70727
  forkedLines.push(JSON.stringify(forked));
71520
70728
  }
71521
- const outDir = input.targetCwd ? import_node_path66.default.join(baseDir, "projects", cwdToHashDir(input.targetCwd)) : projectDir;
71522
- const forkedFilePath = import_node_path66.default.join(outDir, `${forkedToolSessionId}.jsonl`);
71523
- import_node_fs60.default.mkdirSync(outDir, { recursive: true });
71524
- import_node_fs60.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
70729
+ const outDir = input.targetCwd ? import_node_path65.default.join(baseDir, "projects", cwdToHashDir(input.targetCwd)) : projectDir;
70730
+ const forkedFilePath = import_node_path65.default.join(outDir, `${forkedToolSessionId}.jsonl`);
70731
+ import_node_fs59.default.mkdirSync(outDir, { recursive: true });
70732
+ import_node_fs59.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
71525
70733
  return { forkedToolSessionId, forkedFilePath };
71526
70734
  }
71527
70735
 
71528
70736
  // src/tools/codex-fork.ts
71529
70737
  var import_node_child_process17 = require("child_process");
71530
- var import_node_fs61 = __toESM(require("fs"), 1);
71531
- var import_node_path67 = __toESM(require("path"), 1);
70738
+ var import_node_fs60 = __toESM(require("fs"), 1);
70739
+ var import_node_path66 = __toESM(require("path"), 1);
71532
70740
  function openCodexAppServer(home, cwd) {
71533
70741
  const proc = (0, import_node_child_process17.spawn)(process.env.CODEX_BIN ?? "codex", ["app-server", "--listen", "stdio://"], {
71534
70742
  cwd,
@@ -71548,7 +70756,7 @@ function openCodexAppServer(home, cwd) {
71548
70756
  async function forkCodexThread(input, deps = {}) {
71549
70757
  const source = locateCodexThread(input.roots, input.sourceThreadId);
71550
70758
  if (!source) throw new Error(`codex fork: source thread not found: ${input.sourceThreadId}`);
71551
- const rollout = parseCodexRollout(import_node_fs61.default.readFileSync(source.file, "utf8"));
70759
+ const rollout = parseCodexRollout(import_node_fs60.default.readFileSync(source.file, "utf8"));
71552
70760
  if (rollout.meta?.threadId.toLowerCase() !== input.sourceThreadId.toLowerCase()) {
71553
70761
  throw new Error(`codex fork: source thread metadata does not match ${input.sourceThreadId}`);
71554
70762
  }
@@ -71578,7 +70786,7 @@ async function forkCodexThread(input, deps = {}) {
71578
70786
  if (typeof forkedToolSessionId !== "string" || !forkedToolSessionId) {
71579
70787
  throw new Error("codex fork: app-server returned no thread id");
71580
70788
  }
71581
- const forked = locateCodexThread([import_node_path67.default.join(source.home, "sessions")], forkedToolSessionId);
70789
+ const forked = locateCodexThread([import_node_path66.default.join(source.home, "sessions")], forkedToolSessionId);
71582
70790
  if (!forked) throw new Error(`codex fork: rollout not found for forked thread ${forkedToolSessionId}`);
71583
70791
  return { forkedToolSessionId, forkedFilePath: forked.file };
71584
70792
  })()]);
@@ -71589,19 +70797,19 @@ async function forkCodexThread(input, deps = {}) {
71589
70797
  }
71590
70798
 
71591
70799
  // src/session/external-scan.ts
71592
- var import_node_fs62 = __toESM(require("fs"), 1);
70800
+ var import_node_fs61 = __toESM(require("fs"), 1);
71593
70801
  var import_promises11 = __toESM(require("fs/promises"), 1);
71594
70802
  var import_node_os25 = __toESM(require("os"), 1);
71595
- var import_node_path68 = __toESM(require("path"), 1);
70803
+ var import_node_path67 = __toESM(require("path"), 1);
71596
70804
  var import_node_module = require("module");
71597
70805
  var import_node_child_process18 = require("child_process");
71598
70806
  var import_meta7 = {};
71599
70807
  function defaultRoots() {
71600
70808
  const home = import_node_os25.default.homedir();
71601
70809
  return {
71602
- claudeProjectsDir: import_node_path68.default.join(home, ".claude", "projects"),
71603
- codexDir: import_node_path68.default.join(home, ".codex"),
71604
- clawdDir: import_node_path68.default.join(home, ".clawd")
70810
+ claudeProjectsDir: import_node_path67.default.join(home, ".claude", "projects"),
70811
+ codexDir: import_node_path67.default.join(home, ".codex"),
70812
+ clawdDir: import_node_path67.default.join(home, ".clawd")
71605
70813
  };
71606
70814
  }
71607
70815
  function width(s2) {
@@ -71652,7 +70860,7 @@ function userText(msg) {
71652
70860
  }
71653
70861
  function isDir2(p3) {
71654
70862
  try {
71655
- return import_node_fs62.default.statSync(p3).isDirectory();
70863
+ return import_node_fs61.default.statSync(p3).isDirectory();
71656
70864
  } catch {
71657
70865
  return false;
71658
70866
  }
@@ -71661,7 +70869,7 @@ async function scanClaude(roots) {
71661
70869
  const out = [];
71662
70870
  let dirs;
71663
70871
  try {
71664
- dirs = import_node_fs62.default.readdirSync(roots.claudeProjectsDir, { withFileTypes: true });
70872
+ dirs = import_node_fs61.default.readdirSync(roots.claudeProjectsDir, { withFileTypes: true });
71665
70873
  } catch {
71666
70874
  return out;
71667
70875
  }
@@ -71669,16 +70877,16 @@ async function scanClaude(roots) {
71669
70877
  if (!d2.isDirectory()) continue;
71670
70878
  let files;
71671
70879
  try {
71672
- files = import_node_fs62.default.readdirSync(import_node_path68.default.join(roots.claudeProjectsDir, d2.name));
70880
+ files = import_node_fs61.default.readdirSync(import_node_path67.default.join(roots.claudeProjectsDir, d2.name));
71673
70881
  } catch {
71674
70882
  continue;
71675
70883
  }
71676
70884
  for (const name of files) {
71677
70885
  if (!name.endsWith(".jsonl")) continue;
71678
- const file = import_node_path68.default.join(roots.claudeProjectsDir, d2.name, name);
70886
+ const file = import_node_path67.default.join(roots.claudeProjectsDir, d2.name, name);
71679
70887
  let st2;
71680
70888
  try {
71681
- st2 = import_node_fs62.default.statSync(file);
70889
+ st2 = import_node_fs61.default.statSync(file);
71682
70890
  } catch {
71683
70891
  continue;
71684
70892
  }
@@ -71731,7 +70939,7 @@ async function scanClaude(roots) {
71731
70939
  return out;
71732
70940
  }
71733
70941
  async function countCodexTurns(rolloutPath) {
71734
- if (!rolloutPath || !import_node_fs62.default.existsSync(rolloutPath)) return { turns: 0, first: "" };
70942
+ if (!rolloutPath || !import_node_fs61.default.existsSync(rolloutPath)) return { turns: 0, first: "" };
71735
70943
  let turns = 0;
71736
70944
  let first = "";
71737
70945
  for await (const rec6 of jsonLines(rolloutPath)) {
@@ -71805,7 +71013,7 @@ async function codexFromRows(rows) {
71805
71013
  async function scanCodex(roots) {
71806
71014
  let dbs = [];
71807
71015
  try {
71808
- dbs = import_node_fs62.default.readdirSync(roots.codexDir).filter((n2) => /^state_.*\.sqlite$/.test(n2)).sort().map((n2) => import_node_path68.default.join(roots.codexDir, n2));
71016
+ dbs = import_node_fs61.default.readdirSync(roots.codexDir).filter((n2) => /^state_.*\.sqlite$/.test(n2)).sort().map((n2) => import_node_path67.default.join(roots.codexDir, n2));
71809
71017
  } catch {
71810
71018
  }
71811
71019
  if (!dbs.length) return [];
@@ -71814,14 +71022,14 @@ async function scanCodex(roots) {
71814
71022
  }
71815
71023
  async function scanExternalSessions(rootsIn) {
71816
71024
  const roots = { ...defaultRoots(), ...rootsIn };
71817
- const personaRoot = import_node_path68.default.join(roots.clawdDir, "personas");
71025
+ const personaRoot = import_node_path67.default.join(roots.clawdDir, "personas");
71818
71026
  const all = [...await scanClaude(roots), ...await scanCodex(roots)];
71819
71027
  const out = [];
71820
71028
  for (const c2 of all) {
71821
71029
  if (c2.skip) continue;
71822
71030
  if (c2.turns < 1) continue;
71823
71031
  if (!c2.cwd || !isDir2(c2.cwd)) continue;
71824
- if (c2.cwd === roots.clawdDir || c2.cwd === personaRoot || c2.cwd.startsWith(personaRoot + import_node_path68.default.sep) || c2.cwd.startsWith(roots.clawdDir + import_node_path68.default.sep)) {
71032
+ if (c2.cwd === roots.clawdDir || c2.cwd === personaRoot || c2.cwd.startsWith(personaRoot + import_node_path67.default.sep) || c2.cwd.startsWith(roots.clawdDir + import_node_path67.default.sep)) {
71825
71033
  continue;
71826
71034
  }
71827
71035
  out.push({
@@ -71838,13 +71046,13 @@ async function scanExternalSessions(rootsIn) {
71838
71046
  }
71839
71047
 
71840
71048
  // src/session/import-ledger.ts
71841
- var import_node_fs63 = __toESM(require("fs"), 1);
71842
- var import_node_path69 = __toESM(require("path"), 1);
71049
+ var import_node_fs62 = __toESM(require("fs"), 1);
71050
+ var import_node_path68 = __toESM(require("path"), 1);
71843
71051
  var LEDGER_FILENAME = "session-import-ledger.json";
71844
71052
  function readImportLedger(dataDir) {
71845
71053
  try {
71846
71054
  const parsed = JSON.parse(
71847
- import_node_fs63.default.readFileSync(import_node_path69.default.join(dataDir, LEDGER_FILENAME), "utf8")
71055
+ import_node_fs62.default.readFileSync(import_node_path68.default.join(dataDir, LEDGER_FILENAME), "utf8")
71848
71056
  );
71849
71057
  return Array.isArray(parsed) ? parsed : [];
71850
71058
  } catch {
@@ -71852,15 +71060,15 @@ function readImportLedger(dataDir) {
71852
71060
  }
71853
71061
  }
71854
71062
  function appendImportLedger(dataDir, entry) {
71855
- const file = import_node_path69.default.join(dataDir, LEDGER_FILENAME);
71063
+ const file = import_node_path68.default.join(dataDir, LEDGER_FILENAME);
71856
71064
  const entries = readImportLedger(dataDir);
71857
71065
  entries.push(entry);
71858
- import_node_fs63.default.writeFileSync(file, JSON.stringify(entries, null, 2), { encoding: "utf8", mode: 384 });
71066
+ import_node_fs62.default.writeFileSync(file, JSON.stringify(entries, null, 2), { encoding: "utf8", mode: 384 });
71859
71067
  }
71860
71068
 
71861
71069
  // src/handlers/session.ts
71862
71070
  init_protocol();
71863
- var import_node_path70 = __toESM(require("path"), 1);
71071
+ var import_node_path69 = __toESM(require("path"), 1);
71864
71072
  function canReadSearchHit(ctx, file) {
71865
71073
  if (!ctx || ctx.principal.kind === "owner") return true;
71866
71074
  return canAccessPersona(ctx.grants, file.ownerPersonaId, "read") && file.creatorPrincipalId === ctx.principal.id;
@@ -72141,7 +71349,7 @@ ${attribution}` } : args;
72141
71349
  `principal guest:${ctx.principal.id} cannot fork tool session ${args.toolSessionId}`
72142
71350
  );
72143
71351
  }
72144
- if (source?.tool === "codex" && args.targetCwd && import_node_path70.default.resolve(args.targetCwd) !== import_node_path70.default.resolve(source.cwd)) {
71352
+ if (source?.tool === "codex" && args.targetCwd && import_node_path69.default.resolve(args.targetCwd) !== import_node_path69.default.resolve(source.cwd)) {
72145
71353
  throw new ClawdError(ERROR_CODES.FORBIDDEN, "fork: guest targetCwd must match source cwd");
72146
71354
  }
72147
71355
  }
@@ -72418,7 +71626,7 @@ function buildPermissionHandlers(deps) {
72418
71626
  }
72419
71627
 
72420
71628
  // src/handlers/history.ts
72421
- var path85 = __toESM(require("path"), 1);
71629
+ var path84 = __toESM(require("path"), 1);
72422
71630
  init_protocol();
72423
71631
 
72424
71632
  // src/session/recent-dirs.ts
@@ -72436,7 +71644,7 @@ function listRecentDirs(store, limit = 50) {
72436
71644
  }
72437
71645
 
72438
71646
  // src/permission/persona-paths.ts
72439
- var path84 = __toESM(require("path"), 1);
71647
+ var path83 = __toESM(require("path"), 1);
72440
71648
  function getAllowedPersonaIds(grants, action) {
72441
71649
  const ids = /* @__PURE__ */ new Set();
72442
71650
  for (const g3 of grants) {
@@ -72449,42 +71657,42 @@ function getAllowedPersonaIds(grants, action) {
72449
71657
  return ids;
72450
71658
  }
72451
71659
  function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
72452
- const target = path84.resolve(absPath);
71660
+ const target = path83.resolve(absPath);
72453
71661
  if (userWorkDir) {
72454
- const u2 = path84.resolve(userWorkDir);
72455
- const usep = u2.endsWith(path84.sep) ? "" : path84.sep;
71662
+ const u2 = path83.resolve(userWorkDir);
71663
+ const usep = u2.endsWith(path83.sep) ? "" : path83.sep;
72456
71664
  if (target === u2 || target.startsWith(u2 + usep)) return true;
72457
71665
  }
72458
- const root = path84.resolve(personaRoot);
72459
- const sep4 = root.endsWith(path84.sep) ? "" : path84.sep;
71666
+ const root = path83.resolve(personaRoot);
71667
+ const sep4 = root.endsWith(path83.sep) ? "" : path83.sep;
72460
71668
  if (!target.startsWith(root + sep4)) return false;
72461
- const rel = path84.relative(root, target);
71669
+ const rel = path83.relative(root, target);
72462
71670
  if (!rel || rel.startsWith("..")) return false;
72463
- const personaId2 = rel.split(path84.sep)[0];
71671
+ const personaId2 = rel.split(path83.sep)[0];
72464
71672
  if (!personaId2) return false;
72465
71673
  const allowed = getAllowedPersonaIds(grants, action);
72466
71674
  if (allowed === "*") return true;
72467
71675
  return allowed.has(personaId2);
72468
71676
  }
72469
71677
  function personaIdFromPath(absPath, personaRoot) {
72470
- const root = path84.resolve(personaRoot);
72471
- const target = path84.resolve(absPath);
72472
- const sep4 = root.endsWith(path84.sep) ? "" : path84.sep;
71678
+ const root = path83.resolve(personaRoot);
71679
+ const target = path83.resolve(absPath);
71680
+ const sep4 = root.endsWith(path83.sep) ? "" : path83.sep;
72473
71681
  if (!target.startsWith(root + sep4)) return null;
72474
- const rel = path84.relative(root, target);
71682
+ const rel = path83.relative(root, target);
72475
71683
  if (!rel || rel.startsWith("..")) return null;
72476
- const id = rel.split(path84.sep)[0];
71684
+ const id = rel.split(path83.sep)[0];
72477
71685
  return id || null;
72478
71686
  }
72479
71687
  function isPathWithin(dir, absPath) {
72480
- const d2 = path84.resolve(dir);
72481
- const t2 = path84.resolve(absPath);
72482
- const sep4 = d2.endsWith(path84.sep) ? "" : path84.sep;
71688
+ const d2 = path83.resolve(dir);
71689
+ const t2 = path83.resolve(absPath);
71690
+ const sep4 = d2.endsWith(path83.sep) ? "" : path83.sep;
72483
71691
  return t2 === d2 || t2.startsWith(d2 + sep4);
72484
71692
  }
72485
71693
  function isPathInGuestBoundary(personaRoot, personaId2, userWorkDir, absPath) {
72486
71694
  if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
72487
- return personaIdFromPath(path84.resolve(absPath), personaRoot) === personaId2;
71695
+ return personaIdFromPath(path83.resolve(absPath), personaRoot) === personaId2;
72488
71696
  }
72489
71697
 
72490
71698
  // src/handlers/history.ts
@@ -72538,7 +71746,7 @@ function buildHistoryHandlers(deps) {
72538
71746
  if (!pid) return false;
72539
71747
  return isGuestPathAllowed(
72540
71748
  ctx.grants,
72541
- path85.join(personaRoot, pid),
71749
+ path84.join(personaRoot, pid),
72542
71750
  personaRoot,
72543
71751
  "read",
72544
71752
  userWorkDir
@@ -72550,7 +71758,7 @@ function buildHistoryHandlers(deps) {
72550
71758
  };
72551
71759
  const list = async (frame, _client, ctx) => {
72552
71760
  const args = HistoryListArgs.parse(frame);
72553
- assertGuestPath(ctx, path85.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
71761
+ assertGuestPath(ctx, path84.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
72554
71762
  const sessions = await history.listSessions(args);
72555
71763
  return { response: { type: "history:list", sessions } };
72556
71764
  };
@@ -72625,14 +71833,14 @@ function buildHistoryHandlers(deps) {
72625
71833
  };
72626
71834
  const subagents = async (frame, _client, ctx) => {
72627
71835
  const args = HistorySubagentsArgs.parse(frame);
72628
- assertGuestPath(ctx, path85.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
71836
+ assertGuestPath(ctx, path84.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
72629
71837
  assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagents");
72630
71838
  const subs = await historyReaderForToolSession(args.toolSessionId).listSubagents(args);
72631
71839
  return { response: { type: "history:subagents", subagents: subs } };
72632
71840
  };
72633
71841
  const subagentRead = async (frame, _client, ctx) => {
72634
71842
  const args = HistorySubagentReadArgs.parse(frame);
72635
- assertGuestPath(ctx, path85.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
71843
+ assertGuestPath(ctx, path84.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
72636
71844
  assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagent-read");
72637
71845
  const res = await historyReaderForToolSession(args.toolSessionId).readSubagent(args);
72638
71846
  return { response: { type: "history:subagent-read", ...res } };
@@ -72642,7 +71850,7 @@ function buildHistoryHandlers(deps) {
72642
71850
  if (ctx?.principal.kind === "guest" && personaRoot) {
72643
71851
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
72644
71852
  const filtered = dirs.filter(
72645
- (d2) => isGuestPathAllowed(ctx.grants, path85.resolve(d2.cwd), personaRoot, "read", userWorkDir)
71853
+ (d2) => isGuestPathAllowed(ctx.grants, path84.resolve(d2.cwd), personaRoot, "read", userWorkDir)
72646
71854
  );
72647
71855
  return { response: { type: "history:recentDirs", dirs: filtered } };
72648
71856
  }
@@ -72659,17 +71867,17 @@ function buildHistoryHandlers(deps) {
72659
71867
  }
72660
71868
 
72661
71869
  // src/handlers/projects.ts
72662
- var fs81 = __toESM(require("fs"), 1);
71870
+ var fs80 = __toESM(require("fs"), 1);
72663
71871
  var os27 = __toESM(require("os"), 1);
72664
- var path86 = __toESM(require("path"), 1);
71872
+ var path85 = __toESM(require("path"), 1);
72665
71873
  var import_node_child_process19 = require("child_process");
72666
71874
  init_protocol();
72667
- var DEFAULT_PROJECTS_ROOT = path86.join(os27.homedir(), "Documents", "ChatGPT");
71875
+ var DEFAULT_PROJECTS_ROOT = path85.join(os27.homedir(), "Documents", "ChatGPT");
72668
71876
  function allocateDir(root, name) {
72669
- let candidate = path86.join(root, name);
71877
+ let candidate = path85.join(root, name);
72670
71878
  let n2 = 2;
72671
- while (fs81.existsSync(candidate)) {
72672
- candidate = path86.join(root, `${name} ${n2}`);
71879
+ while (fs80.existsSync(candidate)) {
71880
+ candidate = path85.join(root, `${name} ${n2}`);
72673
71881
  n2 += 1;
72674
71882
  }
72675
71883
  return candidate;
@@ -72697,7 +71905,7 @@ function buildProjectHandlers(deps) {
72697
71905
  throw new ClawdError(ERROR_CODES.INVALID_CWD, "project:reveal \u4EC5\u652F\u6301 macOS");
72698
71906
  }
72699
71907
  try {
72700
- if (!fs81.statSync(args.path).isDirectory()) throw new Error("not dir");
71908
+ if (!fs80.statSync(args.path).isDirectory()) throw new Error("not dir");
72701
71909
  } catch {
72702
71910
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
72703
71911
  }
@@ -72713,7 +71921,7 @@ function buildProjectHandlers(deps) {
72713
71921
  let target;
72714
71922
  if (args.path) {
72715
71923
  try {
72716
- if (!fs81.statSync(args.path).isDirectory()) throw new Error("not dir");
71924
+ if (!fs80.statSync(args.path).isDirectory()) throw new Error("not dir");
72717
71925
  } catch {
72718
71926
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
72719
71927
  }
@@ -72721,15 +71929,15 @@ function buildProjectHandlers(deps) {
72721
71929
  } else {
72722
71930
  const name = args.name;
72723
71931
  try {
72724
- fs81.mkdirSync(root, { recursive: true });
71932
+ fs80.mkdirSync(root, { recursive: true });
72725
71933
  target = allocateDir(root, name);
72726
- fs81.mkdirSync(target);
71934
+ fs80.mkdirSync(target);
72727
71935
  } catch (err) {
72728
71936
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `\u521B\u5EFA\u9879\u76EE\u76EE\u5F55\u5931\u8D25: ${String(err)}`);
72729
71937
  }
72730
71938
  const git2 = (0, import_node_child_process19.spawnSync)("git", ["init"], { cwd: target, stdio: "ignore" });
72731
71939
  if (git2.status !== 0) {
72732
- fs81.rmSync(target, { recursive: true, force: true });
71940
+ fs80.rmSync(target, { recursive: true, force: true });
72733
71941
  throw new ClawdError(
72734
71942
  ERROR_CODES.INVALID_CWD,
72735
71943
  `git init \u5931\u8D25\uFF08${git2.error ? String(git2.error) : `exit ${git2.status}`}\uFF09: ${target}`
@@ -72754,7 +71962,7 @@ function buildProjectHandlers(deps) {
72754
71962
  }
72755
71963
 
72756
71964
  // src/handlers/workspace.ts
72757
- var path87 = __toESM(require("path"), 1);
71965
+ var path86 = __toESM(require("path"), 1);
72758
71966
  init_protocol();
72759
71967
  var os28 = __toESM(require("os"), 1);
72760
71968
  init_protocol();
@@ -72797,22 +72005,22 @@ function buildWorkspaceHandlers(deps) {
72797
72005
  const args = WorkspaceListArgs.parse(frame);
72798
72006
  const isGuest = ctx?.principal.kind === "guest";
72799
72007
  const fallbackCwd = isGuest && personaRoot ? personaRoot : os28.homedir();
72800
- const resolvedCwd = path87.resolve(args.cwd ?? fallbackCwd);
72801
- const target = args.path ? path87.resolve(resolvedCwd, args.path) : resolvedCwd;
72008
+ const resolvedCwd = path86.resolve(args.cwd ?? fallbackCwd);
72009
+ const target = args.path ? path86.resolve(resolvedCwd, args.path) : resolvedCwd;
72802
72010
  assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
72803
72011
  const res = workspace.list({ ...args, cwd: resolvedCwd });
72804
72012
  return { response: { type: "workspace:list", ...res } };
72805
72013
  };
72806
72014
  const read = async (frame, _client, ctx) => {
72807
72015
  const args = WorkspaceReadArgs.parse(frame);
72808
- const target = path87.isAbsolute(args.path) ? path87.resolve(args.path) : path87.resolve(args.cwd, args.path);
72016
+ const target = path86.isAbsolute(args.path) ? path86.resolve(args.path) : path86.resolve(args.cwd, args.path);
72809
72017
  assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
72810
72018
  const res = workspace.read(args);
72811
72019
  return { response: { type: "workspace:read", ...res } };
72812
72020
  };
72813
72021
  const skillsList = async (frame, _client, ctx) => {
72814
72022
  const args = SkillsListArgs.parse(frame);
72815
- const cwdAbs = path87.resolve(args.cwd);
72023
+ const cwdAbs = path86.resolve(args.cwd);
72816
72024
  assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
72817
72025
  const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
72818
72026
  if (ctx?.principal.kind === "guest" && personaRoot) {
@@ -72824,7 +72032,7 @@ function buildWorkspaceHandlers(deps) {
72824
72032
  };
72825
72033
  const agentsList = async (frame, _client, ctx) => {
72826
72034
  const args = AgentsListArgs.parse(frame);
72827
- const cwdAbs = path87.resolve(args.cwd);
72035
+ const cwdAbs = path86.resolve(args.cwd);
72828
72036
  assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
72829
72037
  if (isCodexFamily(args.tool) || isPiFamily(args.tool)) {
72830
72038
  return { response: { type: "agents:list", agents: [] } };
@@ -72846,20 +72054,20 @@ function buildWorkspaceHandlers(deps) {
72846
72054
  }
72847
72055
 
72848
72056
  // src/handlers/git.ts
72849
- var path89 = __toESM(require("path"), 1);
72057
+ var path88 = __toESM(require("path"), 1);
72850
72058
  init_protocol();
72851
72059
  init_protocol();
72852
72060
 
72853
72061
  // src/workspace/git.ts
72854
72062
  var import_node_child_process20 = require("child_process");
72855
- var import_node_fs64 = __toESM(require("fs"), 1);
72856
- var import_node_path71 = __toESM(require("path"), 1);
72063
+ var import_node_fs63 = __toESM(require("fs"), 1);
72064
+ var import_node_path70 = __toESM(require("path"), 1);
72857
72065
  var import_node_util2 = require("util");
72858
72066
  var pexec = (0, import_node_util2.promisify)(import_node_child_process20.execFile);
72859
72067
  function normalizePath(p3) {
72860
- const resolved = import_node_path71.default.resolve(p3);
72068
+ const resolved = import_node_path70.default.resolve(p3);
72861
72069
  try {
72862
- return import_node_fs64.default.realpathSync(resolved);
72070
+ return import_node_fs63.default.realpathSync(resolved);
72863
72071
  } catch {
72864
72072
  return resolved;
72865
72073
  }
@@ -72933,7 +72141,7 @@ async function listGitBranches(cwd) {
72933
72141
  function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
72934
72142
  if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
72935
72143
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
72936
- if (!isGuestPathAllowed(ctx.grants, path89.resolve(cwd), personaRoot, "read", userWorkDir)) {
72144
+ if (!isGuestPathAllowed(ctx.grants, path88.resolve(cwd), personaRoot, "read", userWorkDir)) {
72937
72145
  throw new ClawdError(
72938
72146
  ERROR_CODES.UNAUTHORIZED,
72939
72147
  `guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
@@ -73190,12 +72398,12 @@ async function queryCodexAccount(deps = {}) {
73190
72398
  }
73191
72399
 
73192
72400
  // src/tools/pi-account.ts
73193
- var import_node_fs65 = __toESM(require("fs"), 1);
73194
- var import_node_path72 = __toESM(require("path"), 1);
72401
+ var import_node_fs64 = __toESM(require("fs"), 1);
72402
+ var import_node_path71 = __toESM(require("path"), 1);
73195
72403
  function readPiCredentials(agentDir) {
73196
72404
  let raw;
73197
72405
  try {
73198
- raw = JSON.parse(import_node_fs65.default.readFileSync(import_node_path72.default.join(agentDir, "auth.json"), "utf8"));
72406
+ raw = JSON.parse(import_node_fs64.default.readFileSync(import_node_path71.default.join(agentDir, "auth.json"), "utf8"));
73199
72407
  } catch {
73200
72408
  return {};
73201
72409
  }
@@ -74286,21 +73494,21 @@ function computeMethodAccess(args) {
74286
73494
  }
74287
73495
 
74288
73496
  // src/version.ts
74289
- var version = "0.2.614".length > 0 ? "0.2.614" : "dev";
73497
+ var version = "0.2.615".length > 0 ? "0.2.615" : "dev";
74290
73498
 
74291
73499
  // src/cli-probe/probe.ts
74292
- var fs84 = __toESM(require("fs"), 1);
74293
- var path91 = __toESM(require("path"), 1);
73500
+ var fs83 = __toESM(require("fs"), 1);
73501
+ var path90 = __toESM(require("path"), 1);
74294
73502
  var PKG_NAME = "@clawos-dev/clawd";
74295
73503
  var BIN_NAME = "clawd";
74296
73504
  var MAX_PARENT_HOPS = 5;
74297
73505
  function probeGlobalCli(pathEnv) {
74298
73506
  if (!pathEnv) return null;
74299
- for (const dir of pathEnv.split(path91.delimiter)) {
73507
+ for (const dir of pathEnv.split(path90.delimiter)) {
74300
73508
  if (!dir) continue;
74301
73509
  let real;
74302
73510
  try {
74303
- real = fs84.realpathSync(path91.join(dir, BIN_NAME));
73511
+ real = fs83.realpathSync(path90.join(dir, BIN_NAME));
74304
73512
  } catch {
74305
73513
  continue;
74306
73514
  }
@@ -74310,15 +73518,15 @@ function probeGlobalCli(pathEnv) {
74310
73518
  return null;
74311
73519
  }
74312
73520
  function readOwnPackageVersion(entryPath) {
74313
- let dir = path91.dirname(entryPath);
73521
+ let dir = path90.dirname(entryPath);
74314
73522
  for (let i2 = 0; i2 < MAX_PARENT_HOPS; i2++) {
74315
73523
  try {
74316
- const raw = fs84.readFileSync(path91.join(dir, "package.json"), "utf8");
73524
+ const raw = fs83.readFileSync(path90.join(dir, "package.json"), "utf8");
74317
73525
  const pkg = JSON.parse(raw);
74318
73526
  if (pkg.name !== PKG_NAME) return null;
74319
73527
  return typeof pkg.version === "string" && pkg.version ? pkg.version : null;
74320
73528
  } catch {
74321
- const parent = path91.dirname(dir);
73529
+ const parent = path90.dirname(dir);
74322
73530
  if (parent === dir) return null;
74323
73531
  dir = parent;
74324
73532
  }
@@ -74494,7 +73702,7 @@ function buildPersonaHandlers(deps) {
74494
73702
  }
74495
73703
 
74496
73704
  // src/handlers/attachment.ts
74497
- var import_node_path73 = __toESM(require("path"), 1);
73705
+ var import_node_path72 = __toESM(require("path"), 1);
74498
73706
  init_protocol();
74499
73707
  init_protocol();
74500
73708
  function assertGuestAttachmentPath(ctx, absPath, personaRoot, method, usersRoot) {
@@ -74573,12 +73781,12 @@ function buildAttachmentHandlers(deps) {
74573
73781
  `session ${args.sessionId} scope unresolved`
74574
73782
  );
74575
73783
  }
74576
- const cwdAbs = import_node_path73.default.resolve(sessionFile.cwd);
74577
- const candidateAbs = import_node_path73.default.isAbsolute(args.relPath) ? import_node_path73.default.resolve(args.relPath) : import_node_path73.default.resolve(cwdAbs, args.relPath);
73784
+ const cwdAbs = import_node_path72.default.resolve(sessionFile.cwd);
73785
+ const candidateAbs = import_node_path72.default.isAbsolute(args.relPath) ? import_node_path72.default.resolve(args.relPath) : import_node_path72.default.resolve(cwdAbs, args.relPath);
74578
73786
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
74579
73787
  const entries = deps.groupFileStore.list(scope, args.sessionId);
74580
73788
  const entry = entries.find((e) => {
74581
- const storedAbs = import_node_path73.default.isAbsolute(e.relPath) ? import_node_path73.default.resolve(e.relPath) : import_node_path73.default.resolve(cwdAbs, e.relPath);
73789
+ const storedAbs = import_node_path72.default.isAbsolute(e.relPath) ? import_node_path72.default.resolve(e.relPath) : import_node_path72.default.resolve(cwdAbs, e.relPath);
74582
73790
  return storedAbs === candidateAbs && !e.stale;
74583
73791
  });
74584
73792
  if (!entry) {
@@ -74602,7 +73810,7 @@ function buildAttachmentHandlers(deps) {
74602
73810
  if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
74603
73811
  const f2 = deps.sessionStore.read(sessionId);
74604
73812
  if (!f2) return;
74605
- assertGuestAttachmentPath(ctx, import_node_path73.default.resolve(f2.cwd), deps.personaRoot, method, deps.usersRoot);
73813
+ assertGuestAttachmentPath(ctx, import_node_path72.default.resolve(f2.cwd), deps.personaRoot, method, deps.usersRoot);
74606
73814
  }
74607
73815
  const groupAdd = async (frame, _client, ctx) => {
74608
73816
  if (!deps.groupFileStore || !deps.getSessionScope) {
@@ -74617,8 +73825,8 @@ function buildAttachmentHandlers(deps) {
74617
73825
  if (!scope) {
74618
73826
  throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
74619
73827
  }
74620
- const cwdAbs = import_node_path73.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
74621
- const candidateAbs = import_node_path73.default.isAbsolute(args.relPath) ? import_node_path73.default.resolve(args.relPath) : import_node_path73.default.resolve(cwdAbs, args.relPath);
73828
+ const cwdAbs = import_node_path72.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
73829
+ const candidateAbs = import_node_path72.default.isAbsolute(args.relPath) ? import_node_path72.default.resolve(args.relPath) : import_node_path72.default.resolve(cwdAbs, args.relPath);
74622
73830
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
74623
73831
  const from = args.origin === "agent" ? "agent" : ctx?.principal.kind === "owner" ? "owner" : "agent";
74624
73832
  const size = 0;
@@ -74677,19 +73885,19 @@ function buildAttachmentHandlers(deps) {
74677
73885
 
74678
73886
  // src/handlers/extension.ts
74679
73887
  var import_promises15 = __toESM(require("fs/promises"), 1);
74680
- var import_node_path78 = __toESM(require("path"), 1);
73888
+ var import_node_path77 = __toESM(require("path"), 1);
74681
73889
  init_protocol();
74682
73890
 
74683
73891
  // src/extension/bundle-zip.ts
74684
73892
  var import_promises12 = __toESM(require("fs/promises"), 1);
74685
- var import_node_path74 = __toESM(require("path"), 1);
74686
- var import_node_crypto25 = __toESM(require("crypto"), 1);
73893
+ var import_node_path73 = __toESM(require("path"), 1);
73894
+ var import_node_crypto23 = __toESM(require("crypto"), 1);
74687
73895
  var import_jszip2 = __toESM(require_lib3(), 1);
74688
73896
  async function bundleExtensionDir(dir) {
74689
73897
  const entries = await listFilesSorted(dir);
74690
73898
  const zip = new import_jszip2.default();
74691
73899
  for (const rel of entries) {
74692
- const abs = import_node_path74.default.join(dir, rel);
73900
+ const abs = import_node_path73.default.join(dir, rel);
74693
73901
  const content = await import_promises12.default.readFile(abs);
74694
73902
  zip.file(rel, content, { date: FIXED_DATE });
74695
73903
  }
@@ -74698,7 +73906,7 @@ async function bundleExtensionDir(dir) {
74698
73906
  compression: "DEFLATE",
74699
73907
  compressionOptions: { level: 6 }
74700
73908
  });
74701
- const sha256 = import_node_crypto25.default.createHash("sha256").update(buffer).digest("hex");
73909
+ const sha256 = import_node_crypto23.default.createHash("sha256").update(buffer).digest("hex");
74702
73910
  return { buffer, sha256 };
74703
73911
  }
74704
73912
  var FIXED_DATE = /* @__PURE__ */ new Date("2020-01-01T00:00:00.000Z");
@@ -74710,7 +73918,7 @@ async function listFilesSorted(rootDir) {
74710
73918
  return out;
74711
73919
  }
74712
73920
  async function walk(absRoot, relPrefix, out) {
74713
- const dirAbs = import_node_path74.default.join(absRoot, relPrefix);
73921
+ const dirAbs = import_node_path73.default.join(absRoot, relPrefix);
74714
73922
  const entries = await import_promises12.default.readdir(dirAbs, { withFileTypes: true });
74715
73923
  for (const e of entries) {
74716
73924
  if (IGNORE_BASENAMES.has(e.name)) continue;
@@ -74764,25 +73972,25 @@ function computePublishCheck(args) {
74764
73972
 
74765
73973
  // src/extension/install-flow.ts
74766
73974
  var import_promises13 = __toESM(require("fs/promises"), 1);
74767
- var import_node_path76 = __toESM(require("path"), 1);
73975
+ var import_node_path75 = __toESM(require("path"), 1);
74768
73976
  var import_node_os28 = __toESM(require("os"), 1);
74769
- var import_node_crypto26 = __toESM(require("crypto"), 1);
73977
+ var import_node_crypto24 = __toESM(require("crypto"), 1);
74770
73978
  var import_jszip3 = __toESM(require_lib3(), 1);
74771
73979
 
74772
73980
  // src/extension/paths.ts
74773
73981
  var import_node_os27 = __toESM(require("os"), 1);
74774
- var import_node_path75 = __toESM(require("path"), 1);
73982
+ var import_node_path74 = __toESM(require("path"), 1);
74775
73983
  function clawdHomeRoot(override) {
74776
- return override ?? process.env.CLAWD_HOME ?? import_node_path75.default.join(import_node_os27.default.homedir(), ".clawd");
73984
+ return override ?? process.env.CLAWD_HOME ?? import_node_path74.default.join(import_node_os27.default.homedir(), ".clawd");
74777
73985
  }
74778
73986
  function extensionsRoot(override) {
74779
- return import_node_path75.default.join(clawdHomeRoot(override), "extensions");
73987
+ return import_node_path74.default.join(clawdHomeRoot(override), "extensions");
74780
73988
  }
74781
73989
  function publishedChannelsFile(override) {
74782
- return import_node_path75.default.join(clawdHomeRoot(override), "extensions-published.json");
73990
+ return import_node_path74.default.join(clawdHomeRoot(override), "extensions-published.json");
74783
73991
  }
74784
73992
  function bundleCacheRoot(override) {
74785
- return import_node_path75.default.join(clawdHomeRoot(override), "extension-bundles");
73993
+ return import_node_path74.default.join(clawdHomeRoot(override), "extension-bundles");
74786
73994
  }
74787
73995
 
74788
73996
  // src/extension/install-flow.ts
@@ -74795,7 +74003,7 @@ var InstallError = class extends Error {
74795
74003
  };
74796
74004
  async function installFromChannel(args, deps) {
74797
74005
  const { channelRef, snapshotHash, bundleZip } = args;
74798
- const computed = import_node_crypto26.default.createHash("sha256").update(bundleZip).digest("hex");
74006
+ const computed = import_node_crypto24.default.createHash("sha256").update(bundleZip).digest("hex");
74799
74007
  if (computed !== snapshotHash) {
74800
74008
  throw new InstallError(
74801
74009
  "HASH_MISMATCH",
@@ -74809,7 +74017,7 @@ async function installFromChannel(args, deps) {
74809
74017
  throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
74810
74018
  }
74811
74019
  for (const name of Object.keys(zip.files)) {
74812
- if (name.includes("..") || name.startsWith("/") || import_node_path76.default.isAbsolute(name)) {
74020
+ if (name.includes("..") || name.startsWith("/") || import_node_path75.default.isAbsolute(name)) {
74813
74021
  throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
74814
74022
  }
74815
74023
  }
@@ -74841,7 +74049,7 @@ async function installFromChannel(args, deps) {
74841
74049
  );
74842
74050
  }
74843
74051
  const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
74844
- const destDir = import_node_path76.default.join(deps.extensionsRoot, localExtId);
74052
+ const destDir = import_node_path75.default.join(deps.extensionsRoot, localExtId);
74845
74053
  let destExists = false;
74846
74054
  try {
74847
74055
  await import_promises13.default.access(destDir);
@@ -74855,16 +74063,16 @@ async function installFromChannel(args, deps) {
74855
74063
  );
74856
74064
  }
74857
74065
  const stage = await import_promises13.default.mkdtemp(
74858
- import_node_path76.default.join(import_node_os28.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
74066
+ import_node_path75.default.join(import_node_os28.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
74859
74067
  );
74860
74068
  try {
74861
74069
  for (const [name, entry] of Object.entries(zip.files)) {
74862
- const dest = import_node_path76.default.join(stage, name);
74070
+ const dest = import_node_path75.default.join(stage, name);
74863
74071
  if (entry.dir) {
74864
74072
  await import_promises13.default.mkdir(dest, { recursive: true });
74865
74073
  continue;
74866
74074
  }
74867
- await import_promises13.default.mkdir(import_node_path76.default.dirname(dest), { recursive: true });
74075
+ await import_promises13.default.mkdir(import_node_path75.default.dirname(dest), { recursive: true });
74868
74076
  if (name === "manifest.json") {
74869
74077
  const rewritten = { ...parsed.data, id: localExtId };
74870
74078
  await import_promises13.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -74885,9 +74093,9 @@ async function installFromChannel(args, deps) {
74885
74093
 
74886
74094
  // src/extension/update-flow.ts
74887
74095
  var import_promises14 = __toESM(require("fs/promises"), 1);
74888
- var import_node_path77 = __toESM(require("path"), 1);
74096
+ var import_node_path76 = __toESM(require("path"), 1);
74889
74097
  var import_node_os29 = __toESM(require("os"), 1);
74890
- var import_node_crypto27 = __toESM(require("crypto"), 1);
74098
+ var import_node_crypto25 = __toESM(require("crypto"), 1);
74891
74099
  var import_jszip4 = __toESM(require_lib3(), 1);
74892
74100
  var UpdateError = class extends Error {
74893
74101
  constructor(code, message) {
@@ -74902,11 +74110,11 @@ async function updateFromChannel(args, deps) {
74902
74110
  channelRef.extId,
74903
74111
  channelRef.ownerPrincipalId
74904
74112
  );
74905
- const liveDir = import_node_path77.default.join(deps.extensionsRoot, localExtId);
74113
+ const liveDir = import_node_path76.default.join(deps.extensionsRoot, localExtId);
74906
74114
  const prevDir = `${liveDir}.prev`;
74907
74115
  let existingVersion;
74908
74116
  try {
74909
- const raw = await import_promises14.default.readFile(import_node_path77.default.join(liveDir, "manifest.json"), "utf8");
74117
+ const raw = await import_promises14.default.readFile(import_node_path76.default.join(liveDir, "manifest.json"), "utf8");
74910
74118
  const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
74911
74119
  if (!parsed2.success) {
74912
74120
  throw new UpdateError(
@@ -74925,7 +74133,7 @@ async function updateFromChannel(args, deps) {
74925
74133
  if (e instanceof UpdateError) throw e;
74926
74134
  throw e;
74927
74135
  }
74928
- const computed = import_node_crypto27.default.createHash("sha256").update(bundleZip).digest("hex");
74136
+ const computed = import_node_crypto25.default.createHash("sha256").update(bundleZip).digest("hex");
74929
74137
  if (computed !== snapshotHash) {
74930
74138
  throw new UpdateError(
74931
74139
  "HASH_MISMATCH",
@@ -74939,7 +74147,7 @@ async function updateFromChannel(args, deps) {
74939
74147
  throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
74940
74148
  }
74941
74149
  for (const name of Object.keys(zip.files)) {
74942
- if (name.includes("..") || name.startsWith("/") || import_node_path77.default.isAbsolute(name)) {
74150
+ if (name.includes("..") || name.startsWith("/") || import_node_path76.default.isAbsolute(name)) {
74943
74151
  throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
74944
74152
  }
74945
74153
  }
@@ -74974,16 +74182,16 @@ async function updateFromChannel(args, deps) {
74974
74182
  await import_promises14.default.rm(prevDir, { recursive: true, force: true });
74975
74183
  await import_promises14.default.rename(liveDir, prevDir);
74976
74184
  const stage = await import_promises14.default.mkdtemp(
74977
- import_node_path77.default.join(import_node_os29.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
74185
+ import_node_path76.default.join(import_node_os29.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
74978
74186
  );
74979
74187
  try {
74980
74188
  for (const [name, entry] of Object.entries(zip.files)) {
74981
- const dest = import_node_path77.default.join(stage, name);
74189
+ const dest = import_node_path76.default.join(stage, name);
74982
74190
  if (entry.dir) {
74983
74191
  await import_promises14.default.mkdir(dest, { recursive: true });
74984
74192
  continue;
74985
74193
  }
74986
- await import_promises14.default.mkdir(import_node_path77.default.dirname(dest), { recursive: true });
74194
+ await import_promises14.default.mkdir(import_node_path76.default.dirname(dest), { recursive: true });
74987
74195
  if (name === "manifest.json") {
74988
74196
  const rewritten = { ...parsed.data, id: localExtId };
74989
74197
  await import_promises14.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -75050,7 +74258,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
75050
74258
  );
75051
74259
  }
75052
74260
  }
75053
- const manifestPath = import_node_path78.default.join(root, extId, "manifest.json");
74261
+ const manifestPath = import_node_path77.default.join(root, extId, "manifest.json");
75054
74262
  const manifest = await readManifest(root, extId);
75055
74263
  const next = { ...manifest, version: newVersion };
75056
74264
  const tmp = `${manifestPath}.tmp`;
@@ -75058,7 +74266,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
75058
74266
  await import_promises15.default.rename(tmp, manifestPath);
75059
74267
  }
75060
74268
  async function readManifest(root, extId) {
75061
- const file = import_node_path78.default.join(root, extId, "manifest.json");
74269
+ const file = import_node_path77.default.join(root, extId, "manifest.json");
75062
74270
  let raw;
75063
74271
  try {
75064
74272
  raw = await import_promises15.default.readFile(file, "utf8");
@@ -75142,7 +74350,7 @@ function buildExtensionHandlers(deps) {
75142
74350
  };
75143
74351
  async function buildSnapshotMeta(extId) {
75144
74352
  const manifest = await readManifest(deps.root, extId);
75145
- const { sha256, buffer } = await bundleExtensionDir(import_node_path78.default.join(deps.root, extId));
74353
+ const { sha256, buffer } = await bundleExtensionDir(import_node_path77.default.join(deps.root, extId));
75146
74354
  return { manifest, contentHash: sha256, buffer };
75147
74355
  }
75148
74356
  const publish = async (frame, _client, ctx) => {
@@ -75970,7 +75178,7 @@ function buildVisitorHandlers(deps) {
75970
75178
 
75971
75179
  // src/extension/registry.ts
75972
75180
  var import_promises17 = __toESM(require("fs/promises"), 1);
75973
- var import_node_path79 = __toESM(require("path"), 1);
75181
+ var import_node_path78 = __toESM(require("path"), 1);
75974
75182
  async function loadAll(root) {
75975
75183
  let entries;
75976
75184
  try {
@@ -75983,13 +75191,13 @@ async function loadAll(root) {
75983
75191
  for (const ent of entries) {
75984
75192
  if (!ent.isDirectory()) continue;
75985
75193
  if (ent.name.startsWith(".")) continue;
75986
- records.push(await loadOne(import_node_path79.default.join(root, ent.name), ent.name));
75194
+ records.push(await loadOne(import_node_path78.default.join(root, ent.name), ent.name));
75987
75195
  }
75988
75196
  records.sort((a2, b3) => a2.extId < b3.extId ? -1 : a2.extId > b3.extId ? 1 : 0);
75989
75197
  return records;
75990
75198
  }
75991
75199
  async function loadOne(dir, dirName) {
75992
- const manifestPath = import_node_path79.default.join(dir, "manifest.json");
75200
+ const manifestPath = import_node_path78.default.join(dir, "manifest.json");
75993
75201
  let raw;
75994
75202
  try {
75995
75203
  raw = await import_promises17.default.readFile(manifestPath, "utf8");
@@ -76034,7 +75242,7 @@ async function loadOne(dir, dirName) {
76034
75242
 
76035
75243
  // src/extension/uninstall.ts
76036
75244
  var import_promises18 = __toESM(require("fs/promises"), 1);
76037
- var import_node_path80 = __toESM(require("path"), 1);
75245
+ var import_node_path79 = __toESM(require("path"), 1);
76038
75246
  var UninstallError = class extends Error {
76039
75247
  constructor(code, message) {
76040
75248
  super(message);
@@ -76043,7 +75251,7 @@ var UninstallError = class extends Error {
76043
75251
  code;
76044
75252
  };
76045
75253
  async function uninstall(deps) {
76046
- const dir = import_node_path80.default.join(deps.root, deps.extId);
75254
+ const dir = import_node_path79.default.join(deps.root, deps.extId);
76047
75255
  try {
76048
75256
  await import_promises18.default.access(dir);
76049
75257
  } catch {
@@ -76054,7 +75262,7 @@ async function uninstall(deps) {
76054
75262
  }
76055
75263
 
76056
75264
  // src/handlers/index.ts
76057
- var import_node_crypto28 = require("crypto");
75265
+ var import_node_crypto26 = require("crypto");
76058
75266
 
76059
75267
  // src/handlers/peer-exec.ts
76060
75268
  init_protocol();
@@ -76211,7 +75419,7 @@ function buildMethodHandlers(deps) {
76211
75419
  const c2 = deps.contactStore.get(deviceId);
76212
75420
  return c2 ? { deviceId: c2.deviceId, remoteUrl: c2.remoteUrl, connectToken: c2.connectToken } : null;
76213
75421
  },
76214
- genId: () => (0, import_node_crypto28.randomUUID)(),
75422
+ genId: () => (0, import_node_crypto26.randomUUID)(),
76215
75423
  now: () => Date.now(),
76216
75424
  forwardInboxPostToPeer,
76217
75425
  logger: deps.logger
@@ -76261,7 +75469,7 @@ function buildMethodHandlers(deps) {
76261
75469
  broadcast: deps.broadcastToOwners
76262
75470
  }),
76263
75471
  ...buildMasterHandlers({
76264
- authorityTablePath: import_node_path81.default.join(deps.masterDataDir, "master-authority.json")
75472
+ authorityTablePath: import_node_path80.default.join(deps.masterDataDir, "master-authority.json")
76265
75473
  }),
76266
75474
  ...buildTopicHandlers({
76267
75475
  topicStore: deps.topicStore,
@@ -76404,7 +75612,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
76404
75612
 
76405
75613
  // src/extension/runtime.ts
76406
75614
  var import_node_child_process25 = require("child_process");
76407
- var import_node_path82 = __toESM(require("path"), 1);
75615
+ var import_node_path81 = __toESM(require("path"), 1);
76408
75616
  var import_promises19 = require("timers/promises");
76409
75617
 
76410
75618
  // src/extension/port-allocator.ts
@@ -76505,7 +75713,7 @@ var Runtime = class {
76505
75713
  /\$CLAWOS_EXT_PORT/g,
76506
75714
  String(port)
76507
75715
  );
76508
- const dir = import_node_path82.default.join(this.root, extId);
75716
+ const dir = import_node_path81.default.join(this.root, extId);
76509
75717
  const env = {
76510
75718
  ...process.env,
76511
75719
  CLAWOS_EXT_PORT: String(port),
@@ -76617,7 +75825,7 @@ ${handle.stderrTail}`
76617
75825
 
76618
75826
  // src/extension/published-channels.ts
76619
75827
  var import_promises20 = __toESM(require("fs/promises"), 1);
76620
- var import_node_path83 = __toESM(require("path"), 1);
75828
+ var import_node_path82 = __toESM(require("path"), 1);
76621
75829
  init_zod();
76622
75830
  var PublishedChannelsError = class extends Error {
76623
75831
  constructor(code, message) {
@@ -76716,7 +75924,7 @@ var PublishedChannelStore = class {
76716
75924
  )
76717
75925
  };
76718
75926
  const tmp = `${this.filePath}.tmp`;
76719
- await import_promises20.default.mkdir(import_node_path83.default.dirname(this.filePath), { recursive: true });
75927
+ await import_promises20.default.mkdir(import_node_path82.default.dirname(this.filePath), { recursive: true });
76720
75928
  await import_promises20.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
76721
75929
  await import_promises20.default.rename(tmp, this.filePath);
76722
75930
  }
@@ -76724,7 +75932,7 @@ var PublishedChannelStore = class {
76724
75932
 
76725
75933
  // src/extension/bundle-cache.ts
76726
75934
  var import_promises21 = __toESM(require("fs/promises"), 1);
76727
- var import_node_path84 = __toESM(require("path"), 1);
75935
+ var import_node_path83 = __toESM(require("path"), 1);
76728
75936
  var BundleCache = class {
76729
75937
  constructor(rootDir) {
76730
75938
  this.rootDir = rootDir;
@@ -76733,14 +75941,14 @@ var BundleCache = class {
76733
75941
  /** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
76734
75942
  async write(snapshotHash, buffer) {
76735
75943
  await import_promises21.default.mkdir(this.rootDir, { recursive: true });
76736
- const file = import_node_path84.default.join(this.rootDir, `${snapshotHash}.zip`);
75944
+ const file = import_node_path83.default.join(this.rootDir, `${snapshotHash}.zip`);
76737
75945
  const tmp = `${file}.tmp`;
76738
75946
  await import_promises21.default.writeFile(tmp, buffer, { mode: 384 });
76739
75947
  await import_promises21.default.rename(tmp, file);
76740
75948
  }
76741
75949
  /** Returns the bundle bytes, or null when the file doesn't exist. */
76742
75950
  async read(snapshotHash) {
76743
- const file = import_node_path84.default.join(this.rootDir, `${snapshotHash}.zip`);
75951
+ const file = import_node_path83.default.join(this.rootDir, `${snapshotHash}.zip`);
76744
75952
  try {
76745
75953
  return await import_promises21.default.readFile(file);
76746
75954
  } catch (e) {
@@ -76750,7 +75958,7 @@ var BundleCache = class {
76750
75958
  }
76751
75959
  /** Idempotent — missing file is not an error. */
76752
75960
  async delete(snapshotHash) {
76753
- const file = import_node_path84.default.join(this.rootDir, `${snapshotHash}.zip`);
75961
+ const file = import_node_path83.default.join(this.rootDir, `${snapshotHash}.zip`);
76754
75962
  await import_promises21.default.rm(file, { force: true });
76755
75963
  }
76756
75964
  };
@@ -76773,24 +75981,24 @@ async function startDaemon(config) {
76773
75981
  sampling: logShippingCfg.sampling,
76774
75982
  homeDir: import_node_os31.default.homedir()
76775
75983
  });
76776
- const logDir = import_node_path85.default.join(config.dataDir, "log");
76777
- import_node_fs66.default.mkdirSync(logDir, { recursive: true });
75984
+ const logDir = import_node_path84.default.join(config.dataDir, "log");
75985
+ import_node_fs65.default.mkdirSync(logDir, { recursive: true });
76778
75986
  const logger = createLogger({
76779
75987
  level: config.logLevel,
76780
- file: import_node_path85.default.join(logDir, "clawd.log"),
75988
+ file: import_node_path84.default.join(logDir, "clawd.log"),
76781
75989
  logClient
76782
75990
  });
76783
75991
  logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
76784
75992
  const screenIdleProbeLogger = createFileOnlyLogger({
76785
- file: import_node_path85.default.join(logDir, "screen-idle-probe.log"),
75993
+ file: import_node_path84.default.join(logDir, "screen-idle-probe.log"),
76786
75994
  level: "debug"
76787
75995
  });
76788
75996
  logger.info("screen-idle probe logger enabled", {
76789
- file: import_node_path85.default.join(logDir, "screen-idle-probe.log")
75997
+ file: import_node_path84.default.join(logDir, "screen-idle-probe.log")
76790
75998
  });
76791
75999
  const CAP_TARGETS = [
76792
- import_node_path85.default.join(logDir, "clawd.log"),
76793
- import_node_path85.default.join(logDir, "screen-idle-probe.log")
76000
+ import_node_path84.default.join(logDir, "clawd.log"),
76001
+ import_node_path84.default.join(logDir, "screen-idle-probe.log")
76794
76002
  ];
76795
76003
  const LOG_CAP_MAX_BYTES = 10 * 1024 * 1024;
76796
76004
  const LOG_CAP_KEEP_BYTES = 5 * 1024 * 1024;
@@ -76912,11 +76120,11 @@ async function startDaemon(config) {
76912
76120
  const agents = new AgentsScanner();
76913
76121
  const history = new ClaudeHistoryReader();
76914
76122
  let transport = null;
76915
- const personaStore = new PersonaStore(import_node_path85.default.join(config.dataDir, "personas"));
76123
+ const personaStore = new PersonaStore(import_node_path84.default.join(config.dataDir, "personas"));
76916
76124
  const subscriptionChannelStore = new SubscriptionChannelStore({ dataDir: config.dataDir });
76917
76125
  const activeSubscriptionChannel = subscriptionChannelStore.getActive();
76918
76126
  if (activeSubscriptionChannel) applyPiSubscriptionChannel({ channel: activeSubscriptionChannel });
76919
- const usersRoot = import_node_path85.default.join(config.dataDir, "users");
76127
+ const usersRoot = import_node_path84.default.join(config.dataDir, "users");
76920
76128
  const defaultsRoot = findDefaultsRoot(logger);
76921
76129
  if (defaultsRoot) {
76922
76130
  seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
@@ -76933,7 +76141,7 @@ async function startDaemon(config) {
76933
76141
  retirePersonaBuilder({ store: personaStore, logger });
76934
76142
  const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
76935
76143
  const dispatchStore = createDispatchStore({
76936
- filePath: import_node_path85.default.join(config.dataDir, "dispatch.json"),
76144
+ filePath: import_node_path84.default.join(config.dataDir, "dispatch.json"),
76937
76145
  now: () => Date.now(),
76938
76146
  onFlushError: (err) => logger.error("dispatch store flush failed", {
76939
76147
  reason: err instanceof Error ? err.message : String(err)
@@ -76942,18 +76150,18 @@ async function startDaemon(config) {
76942
76150
  await dispatchStore.load();
76943
76151
  dispatchStore.markInterruptedAsFailed((/* @__PURE__ */ new Date()).toISOString());
76944
76152
  const channelStore = createChannelStore({
76945
- filePath: import_node_path85.default.join(config.dataDir, "channels.json"),
76153
+ filePath: import_node_path84.default.join(config.dataDir, "channels.json"),
76946
76154
  now: () => Date.now(),
76947
- genId: () => `ch-${(0, import_node_crypto29.randomUUID)().slice(0, 8)}`,
76155
+ genId: () => `ch-${(0, import_node_crypto27.randomUUID)().slice(0, 8)}`,
76948
76156
  onFlushError: (err) => logger.error("channel store flush failed", {
76949
76157
  reason: err instanceof Error ? err.message : String(err)
76950
76158
  })
76951
76159
  });
76952
76160
  await channelStore.load();
76953
76161
  const topicStore = createTopicStore({
76954
- filePath: import_node_path85.default.join(config.dataDir, "topics.json"),
76162
+ filePath: import_node_path84.default.join(config.dataDir, "topics.json"),
76955
76163
  now: () => Date.now(),
76956
- genId: () => `tp-${(0, import_node_crypto29.randomUUID)().slice(0, 8)}`,
76164
+ genId: () => `tp-${(0, import_node_crypto27.randomUUID)().slice(0, 8)}`,
76957
76165
  onFlushError: (err) => logger.error("topic store flush failed", {
76958
76166
  reason: err instanceof Error ? err.message : String(err)
76959
76167
  })
@@ -76961,7 +76169,7 @@ async function startDaemon(config) {
76961
76169
  await topicStore.load();
76962
76170
  let deliverPendingRef;
76963
76171
  const personaDispatchManager = new PersonaDispatchManager({
76964
- genId: () => (0, import_node_crypto29.randomUUID)(),
76172
+ genId: () => (0, import_node_crypto27.randomUUID)(),
76965
76173
  store: dispatchStore,
76966
76174
  now: () => Date.now(),
76967
76175
  onCompleted: (sid) => deliverPendingRef?.(sid),
@@ -76978,12 +76186,12 @@ async function startDaemon(config) {
76978
76186
  });
76979
76187
  }
76980
76188
  });
76981
- const here = typeof __dirname === "string" ? __dirname : import_node_path85.default.dirname((0, import_node_url6.fileURLToPath)(import_meta10.url));
76189
+ const here = typeof __dirname === "string" ? __dirname : import_node_path84.default.dirname((0, import_node_url6.fileURLToPath)(import_meta10.url));
76982
76190
  const mcpConfigs = [];
76983
76191
  const secretsBundleRoot = findSecretsBundleRoot(logger);
76984
- const localSecretsDir = import_node_path85.default.join(config.dataDir, LOCAL_SECRETS_DIRNAME);
76192
+ const localSecretsDir = import_node_path84.default.join(config.dataDir, LOCAL_SECRETS_DIRNAME);
76985
76193
  const readSecrets = () => readSecretTable({ bundleRoot: secretsBundleRoot, overrideDir: localSecretsDir, logger });
76986
- const githubTokenFile = import_node_path85.default.join(localSecretsDir, GITHUB_TOKEN_FILE);
76194
+ const githubTokenFile = import_node_path84.default.join(localSecretsDir, GITHUB_TOKEN_FILE);
76987
76195
  const githubIdentity = createGithubIdentity({
76988
76196
  resolve: () => resolveGithubAuth({ exec: runCommand, fileToken: () => readEnvFileVar(githubTokenFile, GITHUB_TOKEN_VAR) }),
76989
76197
  store: (token) => storeGithubAuth({
@@ -77021,22 +76229,22 @@ async function startDaemon(config) {
77021
76229
  void githubIdentity.refresh();
77022
76230
  return renderPersonaMcpSecrets({
77023
76231
  personaId: personaId2,
77024
- personaDir: import_node_path85.default.join(config.dataDir, "personas", personaId2),
76232
+ personaDir: import_node_path84.default.join(config.dataDir, "personas", personaId2),
77025
76233
  secrets,
77026
- outDir: import_node_path85.default.join(config.dataDir, "persona-mcp"),
76234
+ outDir: import_node_path84.default.join(config.dataDir, "persona-mcp"),
77027
76235
  logger
77028
76236
  });
77029
76237
  };
77030
76238
  const mcpDaemonUrl = `http://127.0.0.1:${config.port}`;
77031
76239
  const dispatchServerCandidates = [
77032
- import_node_path85.default.join(here, "dispatch", "mcp-server.cjs"),
76240
+ import_node_path84.default.join(here, "dispatch", "mcp-server.cjs"),
77033
76241
  // 生产 dist/index → dist/dispatch/mcp-server.cjs
77034
- import_node_path85.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
76242
+ import_node_path84.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
77035
76243
  // dev tsx src/index → ../dist/dispatch/mcp-server.cjs
77036
76244
  ];
77037
- const dispatchServerScriptPath = dispatchServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76245
+ const dispatchServerScriptPath = dispatchServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
77038
76246
  if (dispatchServerScriptPath) {
77039
- const dispatchLogPath = import_node_path85.default.join(logDir, "dispatch-mcp-server.log");
76247
+ const dispatchLogPath = import_node_path84.default.join(logDir, "dispatch-mcp-server.log");
77040
76248
  const dispatchCfgPath = writeDispatchMcpConfig({
77041
76249
  dataDir: config.dataDir,
77042
76250
  serverScriptPath: dispatchServerScriptPath,
@@ -77056,12 +76264,12 @@ async function startDaemon(config) {
77056
76264
  });
77057
76265
  }
77058
76266
  const ticketServerCandidates = [
77059
- import_node_path85.default.join(here, "ticket", "mcp-server.cjs"),
77060
- import_node_path85.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
76267
+ import_node_path84.default.join(here, "ticket", "mcp-server.cjs"),
76268
+ import_node_path84.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
77061
76269
  ];
77062
- const ticketServerScriptPath = ticketServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76270
+ const ticketServerScriptPath = ticketServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
77063
76271
  if (ticketServerScriptPath) {
77064
- const ticketLogPath = import_node_path85.default.join(logDir, "ticket-mcp-server.log");
76272
+ const ticketLogPath = import_node_path84.default.join(logDir, "ticket-mcp-server.log");
77065
76273
  const ticketCfgPath = writeTicketMcpConfig({
77066
76274
  dataDir: config.dataDir,
77067
76275
  serverScriptPath: ticketServerScriptPath,
@@ -77083,12 +76291,12 @@ async function startDaemon(config) {
77083
76291
  });
77084
76292
  }
77085
76293
  const shiftServerCandidates = [
77086
- import_node_path85.default.join(here, "shift", "mcp-server.cjs"),
77087
- import_node_path85.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
76294
+ import_node_path84.default.join(here, "shift", "mcp-server.cjs"),
76295
+ import_node_path84.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
77088
76296
  ];
77089
- const shiftServerScriptPath = shiftServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76297
+ const shiftServerScriptPath = shiftServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
77090
76298
  if (shiftServerScriptPath) {
77091
- const shiftLogPath = import_node_path85.default.join(logDir, "shift-mcp-server.log");
76299
+ const shiftLogPath = import_node_path84.default.join(logDir, "shift-mcp-server.log");
77092
76300
  const shiftCfgPath = await writeShiftMcpConfig({
77093
76301
  dataDir: config.dataDir,
77094
76302
  serverScriptPath: shiftServerScriptPath,
@@ -77109,12 +76317,12 @@ async function startDaemon(config) {
77109
76317
  );
77110
76318
  }
77111
76319
  const inboxServerCandidates = [
77112
- import_node_path85.default.join(here, "inbox", "mcp-server.cjs"),
77113
- import_node_path85.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
76320
+ import_node_path84.default.join(here, "inbox", "mcp-server.cjs"),
76321
+ import_node_path84.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
77114
76322
  ];
77115
- const inboxServerScriptPath = inboxServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76323
+ const inboxServerScriptPath = inboxServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
77116
76324
  if (inboxServerScriptPath) {
77117
- const inboxLogPath = import_node_path85.default.join(logDir, "inbox-mcp-server.log");
76325
+ const inboxLogPath = import_node_path84.default.join(logDir, "inbox-mcp-server.log");
77118
76326
  const inboxCfgPath = await writeInboxMcpConfig({
77119
76327
  dataDir: config.dataDir,
77120
76328
  serverScriptPath: inboxServerScriptPath,
@@ -77135,10 +76343,10 @@ async function startDaemon(config) {
77135
76343
  );
77136
76344
  }
77137
76345
  const peerOpsServerCandidates = [
77138
- import_node_path85.default.join(here, "peer-ops", "mcp-server.cjs"),
77139
- import_node_path85.default.join(here, "..", "dist", "peer-ops", "mcp-server.cjs")
76346
+ import_node_path84.default.join(here, "peer-ops", "mcp-server.cjs"),
76347
+ import_node_path84.default.join(here, "..", "dist", "peer-ops", "mcp-server.cjs")
77140
76348
  ];
77141
- const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76349
+ const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
77142
76350
  if (peerOpsServerScriptPath) {
77143
76351
  const peerOpsCfgPath = writePeerOpsMcpConfig({
77144
76352
  dataDir: config.dataDir,
@@ -77158,12 +76366,12 @@ async function startDaemon(config) {
77158
76366
  );
77159
76367
  }
77160
76368
  const rpcToolServerCandidates = [
77161
- import_node_path85.default.join(here, "rpc-tool", "mcp-server.cjs"),
77162
- import_node_path85.default.join(here, "..", "dist", "rpc-tool", "mcp-server.cjs")
76369
+ import_node_path84.default.join(here, "rpc-tool", "mcp-server.cjs"),
76370
+ import_node_path84.default.join(here, "..", "dist", "rpc-tool", "mcp-server.cjs")
77163
76371
  ];
77164
- const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76372
+ const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
77165
76373
  if (rpcToolServerScriptPath) {
77166
- const rpcToolLogPath = import_node_path85.default.join(logDir, "rpc-tool-mcp-server.log");
76374
+ const rpcToolLogPath = import_node_path84.default.join(logDir, "rpc-tool-mcp-server.log");
77167
76375
  const rpcToolCfgPath = writeRpcToolMcpConfig({
77168
76376
  dataDir: config.dataDir,
77169
76377
  serverScriptPath: rpcToolServerScriptPath,
@@ -77184,7 +76392,7 @@ async function startDaemon(config) {
77184
76392
  );
77185
76393
  }
77186
76394
  const shiftStore = createShiftStore({
77187
- filePath: import_node_path85.default.join(config.dataDir, "shift.json"),
76395
+ filePath: import_node_path84.default.join(config.dataDir, "shift.json"),
77188
76396
  ownerIdProvider: () => ownerPrincipalId,
77189
76397
  now: () => Date.now()
77190
76398
  });
@@ -77206,7 +76414,7 @@ async function startDaemon(config) {
77206
76414
  getAdapter,
77207
76415
  historyReader: history,
77208
76416
  dataDir: config.dataDir,
77209
- personaRoot: import_node_path85.default.join(config.dataDir, "personas"),
76417
+ personaRoot: import_node_path84.default.join(config.dataDir, "personas"),
77210
76418
  // dispatch / shift 自动化 spawn 按 persona 绑定 tool 起 B session(codex persona 用 codex)。
77211
76419
  // personaRegistry 声明在 manager 之后(同作用域 const,调用时机在启动完成后,无 TDZ 风险)。
77212
76420
  getPersonaDefaults: (personaId2) => personaRegistry.get(personaId2),
@@ -77267,10 +76475,10 @@ async function startDaemon(config) {
77267
76475
  // 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
77268
76476
  attachmentGroup: {
77269
76477
  onFileEdit: (input) => {
77270
- const absPath = import_node_path85.default.isAbsolute(input.relPath) ? input.relPath : import_node_path85.default.join(input.cwd, input.relPath);
76478
+ const absPath = import_node_path84.default.isAbsolute(input.relPath) ? input.relPath : import_node_path84.default.join(input.cwd, input.relPath);
77271
76479
  let size = 0;
77272
76480
  try {
77273
- size = import_node_fs66.default.statSync(absPath).size;
76481
+ size = import_node_fs65.default.statSync(absPath).size;
77274
76482
  } catch (err) {
77275
76483
  logger.warn("attachment.onFileEdit stat failed", {
77276
76484
  sessionId: input.sessionId,
@@ -77311,9 +76519,9 @@ async function startDaemon(config) {
77311
76519
  logger.info("projects.seed-dropped", { dropped: droppedSeed.dropped, backup: droppedSeed.backup });
77312
76520
  }
77313
76521
  const projectsStore = new ProjectsStore({
77314
- file: import_node_path85.default.join(config.dataDir, "projects.json"),
76522
+ file: import_node_path84.default.join(config.dataDir, "projects.json"),
77315
76523
  clawdDir: config.dataDir,
77316
- codexStateFile: import_node_path85.default.join(import_node_os31.default.homedir(), ".codex", ".codex-global-state.json"),
76524
+ codexStateFile: import_node_path84.default.join(import_node_os31.default.homedir(), ".codex", ".codex-global-state.json"),
77317
76525
  logger
77318
76526
  });
77319
76527
  const observer = new SessionObserver({
@@ -77377,11 +76585,6 @@ async function startDaemon(config) {
77377
76585
  centralApi: config.clawosApi ?? DEFAULT_CLAWOS_API,
77378
76586
  logger
77379
76587
  });
77380
- const cloudCancelOutbox = new CloudCancelOutbox(
77381
- import_node_path85.default.join(config.dataDir, "cloud-cancel-outbox"),
77382
- (personaId2, clientSessionId, gatewaySessionId) => cloudGateway.cancelEventSession(personaId2, clientSessionId, gatewaySessionId),
77383
- logger
77384
- );
77385
76588
  manager.setCloudCanceller(async (file, runner) => {
77386
76589
  const personaId2 = personaIdFromCloudCwd(file.cwd);
77387
76590
  if (!personaId2) throw new Error(`\u4E91\u4F1A\u8BDD ${file.sessionId} \u7F3A\u5C11 gateway persona ID`);
@@ -77390,27 +76593,16 @@ async function startDaemon(config) {
77390
76593
  runner?.confirmCloudCancelled();
77391
76594
  return;
77392
76595
  }
77393
- const executionId = file.cloudExecutionId ?? file.sessionId;
77394
- if (!file.cloudGatewaySessionId) throw new Error(`\u4E91\u4F1A\u8BDD ${file.sessionId} \u5C1A\u672A\u6536\u5230 gateway ready`);
77395
- cloudCancelOutbox.record(executionId, personaId2, file.cloudGatewaySessionId);
77396
- try {
77397
- await cloudGateway.cancelEventSession(personaId2, executionId, file.cloudGatewaySessionId);
77398
- cloudCancelOutbox.confirm(executionId);
77399
- runner?.confirmCloudCancelled();
77400
- } catch (e) {
77401
- cloudCancelOutbox.release(executionId);
77402
- throw e;
77403
- }
76596
+ runner?.confirmCloudCancelled();
77404
76597
  });
77405
- cloudCancelOutbox.start();
77406
76598
  registerAdapter("claude", claudeAdapter);
77407
- const codexIsolatedHome = import_node_path85.default.join(config.dataDir, "codex-home");
76599
+ const codexIsolatedHome = import_node_path84.default.join(config.dataDir, "codex-home");
77408
76600
  try {
77409
- import_node_fs66.default.mkdirSync(codexIsolatedHome, { recursive: true });
76601
+ import_node_fs65.default.mkdirSync(codexIsolatedHome, { recursive: true });
77410
76602
  for (const f2 of ["auth.json", "config.toml"]) {
77411
- const link = import_node_path85.default.join(codexIsolatedHome, f2);
77412
- const target = import_node_path85.default.join(import_node_os31.default.homedir(), ".codex", f2);
77413
- if (!import_node_fs66.default.existsSync(link) && import_node_fs66.default.existsSync(target)) import_node_fs66.default.symlinkSync(target, link);
76603
+ const link = import_node_path84.default.join(codexIsolatedHome, f2);
76604
+ const target = import_node_path84.default.join(import_node_os31.default.homedir(), ".codex", f2);
76605
+ if (!import_node_fs65.default.existsSync(link) && import_node_fs65.default.existsSync(target)) import_node_fs65.default.symlinkSync(target, link);
77414
76606
  }
77415
76607
  } catch (err) {
77416
76608
  logger.warn("codex isolated home setup failed", { err: String(err) });
@@ -77421,17 +76613,17 @@ async function startDaemon(config) {
77421
76613
  logger,
77422
76614
  historyReader: new CodexHistoryReader({
77423
76615
  roots: codexRolloutRoots(config.dataDir),
77424
- sharedHome: import_node_path85.default.join(import_node_os31.default.homedir(), ".codex"),
76616
+ sharedHome: import_node_path84.default.join(import_node_os31.default.homedir(), ".codex"),
77425
76617
  logger
77426
76618
  }),
77427
76619
  // projectPaths 每次调用现取 —— 用户新建 project 后立即生效,不用重启 daemon
77428
76620
  codexHomeFor: (cwd) => resolveCodexHome({
77429
76621
  cwd,
77430
- personaRoot: import_node_path85.default.join(config.dataDir, "personas"),
76622
+ personaRoot: import_node_path84.default.join(config.dataDir, "personas"),
77431
76623
  // 必须用 listMerged(Codex registry ∪ 叠加层):只用本地 list() 的话,用户在
77432
76624
  // Codex 里建的 project 不在表里,在它下面开的会话会被误判成隔离 → Codex 侧看不到
77433
76625
  projectPaths: projectsStore.listMerged().map((x2) => x2.path),
77434
- sharedHome: import_node_path85.default.join(import_node_os31.default.homedir(), ".codex"),
76626
+ sharedHome: import_node_path84.default.join(import_node_os31.default.homedir(), ".codex"),
77435
76627
  isolatedHome: codexIsolatedHome
77436
76628
  }),
77437
76629
  codexHomeForThread: (threadId) => locateCodexThread(codexRolloutRoots(config.dataDir), threadId)?.home,
@@ -77457,10 +76649,10 @@ async function startDaemon(config) {
77457
76649
  );
77458
76650
  registerAdapter(PI_CLOUD_TOOL_ID, new CloudPiAdapter({ client: cloudGateway, history: cloudHistorySource, logger }));
77459
76651
  const piMcpBridgeCandidates = [
77460
- import_node_path85.default.join(here, "pi-mcp-bridge", "extension.cjs"),
77461
- import_node_path85.default.join(here, "..", "dist", "pi-mcp-bridge", "extension.cjs")
76652
+ import_node_path84.default.join(here, "pi-mcp-bridge", "extension.cjs"),
76653
+ import_node_path84.default.join(here, "..", "dist", "pi-mcp-bridge", "extension.cjs")
77462
76654
  ];
77463
- const piMcpBridgePath = piMcpBridgeCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76655
+ const piMcpBridgePath = piMcpBridgeCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
77464
76656
  if (piMcpBridgePath) {
77465
76657
  logger.info("pi-mcp-bridge extension resolved", { path: piMcpBridgePath });
77466
76658
  } else {
@@ -77766,11 +76958,11 @@ async function startDaemon(config) {
77766
76958
  // 'persona/<pid>/owner',default 走 'default'。
77767
76959
  getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
77768
76960
  // guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
77769
- personaRoot: import_node_path85.default.join(config.dataDir, "personas"),
76961
+ personaRoot: import_node_path84.default.join(config.dataDir, "personas"),
77770
76962
  usersRoot
77771
76963
  },
77772
76964
  // workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
77773
- personaRoot: import_node_path85.default.join(config.dataDir, "personas"),
76965
+ personaRoot: import_node_path84.default.join(config.dataDir, "personas"),
77774
76966
  // v2 多人 persona 隔离:handler 派生 guest user-dir 放行
77775
76967
  usersRoot,
77776
76968
  // v2 Phase 6: whoami handler 装在 owner principal.displayName + persona 解析
@@ -78076,7 +77268,7 @@ async function startDaemon(config) {
78076
77268
  });
78077
77269
  shiftScheduler.start();
78078
77270
  logger.info("shift scheduler started", { shiftCount: shiftStore.list().length });
78079
- const larkBotStore = createLarkBotBindingStore(import_node_path85.default.join(config.dataDir, "personas"));
77271
+ const larkBotStore = createLarkBotBindingStore(import_node_path84.default.join(config.dataDir, "personas"));
78080
77272
  const larkBotCloud = createLarkBotCloudClient({
78081
77273
  api: config.clawosApi ?? DEFAULT_CLAWOS_API,
78082
77274
  getLoginPass: () => ownerIdentityStore.read()?.loginPass ?? null
@@ -78088,7 +77280,7 @@ async function startDaemon(config) {
78088
77280
  store: larkBotStore,
78089
77281
  fetchResource: (appId, messageId, fileKey, maxBytes, type) => larkBotCloud.fetchResource(appId, messageId, fileKey, maxBytes, type),
78090
77282
  // 图片落 guest userWorkDir 下(capId = lark-<chat_id>):CC 经 --add-dir + allowRead carve 可 Read
78091
- mediaRootFor: (chatId) => import_node_path85.default.join(deriveUserWorkDir(`lark-${chatId}`, usersRoot), "lark-media"),
77283
+ mediaRootFor: (chatId) => import_node_path84.default.join(deriveUserWorkDir(`lark-${chatId}`, usersRoot), "lark-media"),
78092
77284
  isShuttingDown: () => larkDraining,
78093
77285
  logger: {
78094
77286
  warn: (msg) => logger.warn(msg),
@@ -78401,8 +77593,8 @@ async function startDaemon(config) {
78401
77593
  const lines = [
78402
77594
  `Tunnel: ${r2.url}`,
78403
77595
  ...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
78404
- `Frpc config: ${import_node_path85.default.join(config.dataDir, "frpc.toml")}`,
78405
- `Frpc log: ${import_node_path85.default.join(logDir, "frpc.log")}`
77596
+ `Frpc config: ${import_node_path84.default.join(config.dataDir, "frpc.toml")}`,
77597
+ `Frpc log: ${import_node_path84.default.join(logDir, "frpc.log")}`
78406
77598
  ];
78407
77599
  const width2 = Math.max(...lines.map((l2) => l2.length));
78408
77600
  const bar = "\u2550".repeat(width2 + 4);
@@ -78415,8 +77607,8 @@ ${bar}
78415
77607
 
78416
77608
  `);
78417
77609
  try {
78418
- const connectPath = import_node_path85.default.join(config.dataDir, "connect.txt");
78419
- import_node_fs66.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
77610
+ const connectPath = import_node_path84.default.join(config.dataDir, "connect.txt");
77611
+ import_node_fs65.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
78420
77612
  } catch {
78421
77613
  }
78422
77614
  } catch (err) {
@@ -78485,7 +77677,6 @@ ${bar}
78485
77677
  larkDraining = true;
78486
77678
  clearInterval(attachmentGcInterval);
78487
77679
  clearInterval(cloudRecoveryInterval);
78488
- cloudCancelOutbox.stop();
78489
77680
  observer.stopAll();
78490
77681
  manager.stopAll();
78491
77682
  await extensionRuntime.stopAll();
@@ -78516,9 +77707,9 @@ ${bar}
78516
77707
  };
78517
77708
  }
78518
77709
  function migrateDropPersonsDir(dataDir) {
78519
- const dir = import_node_path85.default.join(dataDir, "persons");
77710
+ const dir = import_node_path84.default.join(dataDir, "persons");
78520
77711
  try {
78521
- import_node_fs66.default.rmSync(dir, { recursive: true, force: true });
77712
+ import_node_fs65.default.rmSync(dir, { recursive: true, force: true });
78522
77713
  } catch {
78523
77714
  }
78524
77715
  }