@clawos-dev/clawd 0.2.614 → 0.2.616

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 +662 -1470
  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
@@ -46330,6 +46330,7 @@ function pushEventToBufferInPlace(next, event, deps) {
46330
46330
  const isTurnEnd = withSeq.kind === "turn_end";
46331
46331
  const isUserText = withSeq.kind === "user_text";
46332
46332
  const isBackgroundEvent = withSeq.kind === "subagent_progress";
46333
+ const isSessionInit = withSeq.kind === "session_init";
46333
46334
  if (isBackgroundEvent) {
46334
46335
  const bg = withSeq;
46335
46336
  const done = bg.status === "completed" || bg.status === "failed";
@@ -46350,7 +46351,7 @@ function pushEventToBufferInPlace(next, event, deps) {
46350
46351
  }
46351
46352
  next.turnOpen = false;
46352
46353
  next.turnStartedAt = null;
46353
- } else if (!isBackgroundEvent && !next.turnOpen) {
46354
+ } else if (!isBackgroundEvent && !(isSessionInit && next.status === "running-idle") && !next.turnOpen) {
46354
46355
  next.turnOpen = true;
46355
46356
  next.turnStartedAt = deps.now();
46356
46357
  }
@@ -46362,7 +46363,7 @@ function pushEventToBufferInPlace(next, event, deps) {
46362
46363
  }
46363
46364
  if (next.freshSpawn) next.freshSpawn = false;
46364
46365
  const effects = [emitSessionEvent(next.file.sessionId, withSeq)];
46365
- if (!isTurnEnd && !isBackgroundEvent && withSeq.kind !== "meta-text" && next.status === "running-idle" && next.procAlive) {
46366
+ if (!isTurnEnd && !isBackgroundEvent && !isSessionInit && withSeq.kind !== "meta-text" && next.status === "running-idle" && next.procAlive) {
46366
46367
  next.status = "running";
46367
46368
  effects.push({ kind: "cancel-idle-kill", sessionId: next.file.sessionId });
46368
46369
  effects.push({
@@ -46672,7 +46673,6 @@ function applyCommand(state, command, deps) {
46672
46673
  void _titleGeneratedAt;
46673
46674
  const nextFile = {
46674
46675
  ...rest,
46675
- ...command.nextCloudExecutionId ? { cloudExecutionId: command.nextCloudExecutionId } : {},
46676
46676
  ...command.nextToolSessionId ? { toolSessionId: command.nextToolSessionId } : {},
46677
46677
  updatedAt: nowIso(deps)
46678
46678
  };
@@ -46735,18 +46735,6 @@ function reduceSessionInner(state, input, deps) {
46735
46735
  case "inject-events": {
46736
46736
  return applyEventBatch(state, input.events, deps);
46737
46737
  }
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
46738
  case "cloud-command-prepared": {
46751
46739
  const pending = state.file.cloudPendingCommand;
46752
46740
  const turn = state.file.cloudPendingTurns?.find((item) => item.id === input.commandId);
@@ -47452,7 +47440,7 @@ var SessionRunner = class {
47452
47440
  applyEffect(effect) {
47453
47441
  switch (effect.kind) {
47454
47442
  case "spawn":
47455
- this.doSpawn(this.recoveringCloud && effect.ctx.cloudGatewaySessionId ? { ...effect.ctx, cloudAttachOnly: true } : effect.ctx);
47443
+ this.doSpawn(effect.ctx);
47456
47444
  break;
47457
47445
  case "kill":
47458
47446
  if (this.session) {
@@ -47601,15 +47589,6 @@ var SessionRunner = class {
47601
47589
  kind: CLOUD_HISTORY_REFRESH_KIND,
47602
47590
  synchronized
47603
47591
  }, "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
47592
  onCommandPrepared: (commandId, text, prepared) => {
47614
47593
  const pending = this.state.file.cloudPendingTurns?.find((turn) => turn.id === commandId) ?? this.state.file.cloudPendingCommand;
47615
47594
  if (!pending || pending.id !== commandId || prepared && pending.text !== text) return false;
@@ -49012,7 +48991,7 @@ var SessionManager = class {
49012
48991
  }
49013
48992
  return { response: normalized, broadcast };
49014
48993
  }
49015
- newSession(args, nextCloudExecutionId) {
48994
+ newSession(args) {
49016
48995
  const existingFile = this.getFile(args.sessionId);
49017
48996
  this.titleGenPending.get(args.sessionId)?.abort();
49018
48997
  this.titleGenPending.delete(args.sessionId);
@@ -49023,7 +49002,7 @@ var SessionManager = class {
49023
49002
  const { value, broadcast } = this.withCollector(() => {
49024
49003
  runner.input({
49025
49004
  kind: "command",
49026
- command: { kind: "new", ...nextToolSessionId ? { nextToolSessionId } : {}, ...nextCloudExecutionId ? { nextCloudExecutionId } : {} }
49005
+ command: { kind: "new", ...nextToolSessionId ? { nextToolSessionId } : {} }
49027
49006
  });
49028
49007
  return runner.getState().file;
49029
49008
  });
@@ -49059,7 +49038,6 @@ var SessionManager = class {
49059
49038
  void _titleGeneratedAt;
49060
49039
  const updated = {
49061
49040
  ...rest,
49062
- ...nextCloudExecutionId ? { cloudExecutionId: nextCloudExecutionId } : {},
49063
49041
  ...nextToolSessionId ? { toolSessionId: nextToolSessionId } : {},
49064
49042
  updatedAt: nowIso2(this.deps)
49065
49043
  };
@@ -49073,7 +49051,7 @@ var SessionManager = class {
49073
49051
  if (!this.cloudCancel) throw new Error("cloud canceller is not configured");
49074
49052
  await this.cloudCancel(file, runner);
49075
49053
  } else runner?.confirmCloudCancelled();
49076
- return this.newSession(args, file.cloudGatewaySessionId ? (0, import_node_crypto3.randomUUID)() : void 0);
49054
+ return this.newSession(args);
49077
49055
  }
49078
49056
  return this.newSession(args);
49079
49057
  }
@@ -52928,9 +52906,9 @@ var CentralClientError = class extends Error {
52928
52906
  cause;
52929
52907
  status;
52930
52908
  };
52931
- async function centralRequest(opts, path107, init) {
52909
+ async function centralRequest(opts, path106, init) {
52932
52910
  const f2 = opts.fetchImpl ?? globalThis.fetch;
52933
- const url = `${opts.api.replace(/\/+$/, "")}${path107}`;
52911
+ const url = `${opts.api.replace(/\/+$/, "")}${path106}`;
52934
52912
  const ctrl = new AbortController();
52935
52913
  const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
52936
52914
  let res;
@@ -53966,8 +53944,8 @@ function turnStartInput(text, resolveImage) {
53966
53944
  const items = [];
53967
53945
  let leftover = text;
53968
53946
  for (const m3 of text.matchAll(SKILL_RE)) {
53969
- const [marker, name, path107] = m3;
53970
- items.push({ type: "skill", name, path: path107 });
53947
+ const [marker, name, path106] = m3;
53948
+ items.push({ type: "skill", name, path: path106 });
53971
53949
  leftover = leftover.replace(marker, "");
53972
53950
  }
53973
53951
  for (const m3 of text.matchAll(ATTACHMENT_RE2)) {
@@ -61342,10 +61320,10 @@ function createGithubApi(args) {
61342
61320
  const doFetch = args.fetch ?? fetch;
61343
61321
  const seal = args.seal ?? sealWithSodium;
61344
61322
  const timeoutMs = args.timeoutMs ?? TIMEOUT_MS;
61345
- async function request(method, path107, body) {
61323
+ async function request(method, path106, body) {
61346
61324
  let res;
61347
61325
  try {
61348
- res = await doFetch(`${API}${path107}`, {
61326
+ res = await doFetch(`${API}${path106}`, {
61349
61327
  method,
61350
61328
  headers: {
61351
61329
  Authorization: `Bearer ${args.token}`,
@@ -61370,8 +61348,8 @@ function createGithubApi(args) {
61370
61348
  }
61371
61349
  return { status: res.status, json };
61372
61350
  }
61373
- async function must(method, path107, what, body) {
61374
- const r2 = await request(method, path107, body);
61351
+ async function must(method, path106, what, body) {
61352
+ const r2 = await request(method, path106, body);
61375
61353
  if (r2.status < 200 || r2.status >= 300) throw new GithubApiError(r2.status, explain(r2.status, what, r2.json));
61376
61354
  return r2.json;
61377
61355
  }
@@ -61416,9 +61394,9 @@ function createGithubApi(args) {
61416
61394
  return { env: x2.name, ...Number.isFinite(at3) ? { setAt: at3 } : {} };
61417
61395
  });
61418
61396
  },
61419
- async getJson(path107) {
61397
+ async getJson(path106) {
61420
61398
  try {
61421
- const r2 = await request("GET", path107);
61399
+ const r2 = await request("GET", path106);
61422
61400
  return r2.status >= 200 && r2.status < 300 ? r2.json : void 0;
61423
61401
  } catch {
61424
61402
  return void 0;
@@ -62970,8 +62948,8 @@ function refreshPathFromLoginShell() {
62970
62948
  timeout: 3e3,
62971
62949
  stdio: ["ignore", "pipe", "ignore"]
62972
62950
  });
62973
- const path107 = out.trim();
62974
- if (path107) process.env.PATH = path107;
62951
+ const path106 = out.trim();
62952
+ if (path106) process.env.PATH = path106;
62975
62953
  } catch {
62976
62954
  }
62977
62955
  }
@@ -63773,10 +63751,10 @@ function createCloudPersonaBotClient(opts) {
63773
63751
  const f2 = opts.fetchImpl ?? fetch;
63774
63752
  const base = opts.api.replace(/\/+$/, "");
63775
63753
  const route = (personaId2) => `/api/lark-bot/cloud/${encodeURIComponent(personaId2)}`;
63776
- async function request(method, path107, body) {
63754
+ async function request(method, path106, body) {
63777
63755
  const pass = opts.getLoginPass();
63778
63756
  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, {
63757
+ const response = await f2(base + path106, {
63780
63758
  method,
63781
63759
  headers: { authorization: `Bearer ${pass}`, "content-type": "application/json" },
63782
63760
  ...body ? { body: JSON.stringify(body) } : {},
@@ -63785,7 +63763,7 @@ function createCloudPersonaBotClient(opts) {
63785
63763
  const json = await response.json().catch(() => ({}));
63786
63764
  if (!response.ok) {
63787
63765
  const detail = typeof json.message === "string" ? json.message : `HTTP ${response.status}`;
63788
- throw new LarkBotCloudError(`cloud bot ${method} ${path107}: ${detail}`, response.status);
63766
+ throw new LarkBotCloudError(`cloud bot ${method} ${path106}: ${detail}`, response.status);
63789
63767
  }
63790
63768
  return json;
63791
63769
  }
@@ -64771,16 +64749,8 @@ async function forwardPeerExecToPeer(args) {
64771
64749
  init_protocol();
64772
64750
  init_protocol();
64773
64751
  var CLOUD_WORKSPACE_SLOT = "{{WORKSPACE}}";
64774
- var CLOUD_TURN_HEADER = "x-clawd-turn";
64775
- var CLOUD_TURN_HEADER_START = "start";
64776
64752
  var GATEWAY_ROUTES = {
64777
64753
  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
64754
  turn: (personaId2) => `/p/${encodeURIComponent(personaId2)}/v1/chat/completions`,
64785
64755
  turnCommand: (personaId2, turnId) => `/p/${encodeURIComponent(personaId2)}/turns/${encodeURIComponent(turnId)}/commands`,
64786
64756
  conversationCancel: (personaId2, conversationId) => `/p/${encodeURIComponent(personaId2)}/conversations/${encodeURIComponent(conversationId)}:cancel`,
@@ -64882,49 +64852,6 @@ var CloudGatewayClient = class {
64882
64852
  const list = await this.fetchDeployments(trimSlash(gatewayUrl));
64883
64853
  return list.find((p3) => p3.personaId === gatewayPersonaId)?.connectors ?? [];
64884
64854
  }
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
64855
  async openTurn(personaId2, opts) {
64929
64856
  const { apiKey, gatewayUrl } = await this.credentials();
64930
64857
  const health = await this.fetchImpl(gatewayUrl + GATEWAY_ROUTES.healthz());
@@ -64951,23 +64878,6 @@ var CloudGatewayClient = class {
64951
64878
  });
64952
64879
  if (!res.ok) throw new Error(`gateway conversation cancel returned ${res.status}`);
64953
64880
  }
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
64881
  /**
64972
64882
  * 看板数据(design 2026-09-23-cloud-persona-metrics §3.8):GET /metrics/<persona>?window&entry,**原样回**状态码与 body——
64973
64883
  * 形状真源在 gateway 的 cloud-persona-metrics,daemon 只是替浏览器拿本机 api key 转一跳。拿不到 key / 连不上 / 超时 → 抛(路由折成 502)。
@@ -65024,7 +64934,7 @@ var CloudGatewayClient = class {
65024
64934
  }
65025
64935
  };
65026
64936
  function openHttpTurn(opts) {
65027
- const { fetchImpl, gatewayUrl, apiKey, personaId: personaId2, conversationId, turnId, text, expectedEngine, engineSessionId, instructions, effort, personaMode, logger } = opts;
64937
+ const { fetchImpl, gatewayUrl, apiKey, personaId: personaId2, conversationId, turnId, text, expectedEngine, engineSessionId, instructions, effort, personaMode, purpose, logger } = opts;
65028
64938
  const body = JSON.stringify({
65029
64939
  messages: [{ role: "user", content: text }],
65030
64940
  stream: true,
@@ -65033,6 +64943,7 @@ function openHttpTurn(opts) {
65033
64943
  conversationId,
65034
64944
  turnId,
65035
64945
  expectedEngine,
64946
+ ...purpose ? { purpose } : {},
65036
64947
  ...engineSessionId ? { engineSessionId } : {},
65037
64948
  ...instructions ? { instructions } : {},
65038
64949
  ...effort ? { effort } : {},
@@ -65169,525 +65080,12 @@ function openHttpTurn(opts) {
65169
65080
  close: finish
65170
65081
  };
65171
65082
  }
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
65083
 
65685
65084
  // src/tools/codex-cloud.ts
65686
65085
  init_protocol();
65687
65086
 
65688
65087
  // src/tools/codex-cloud-session.ts
65689
- var import_node_fs40 = __toESM(require("fs"), 1);
65690
- var import_node_crypto14 = require("crypto");
65088
+ var import_node_fs39 = __toESM(require("fs"), 1);
65691
65089
 
65692
65090
  // src/tools/cloud-portable-input.ts
65693
65091
  async function portableCloudInput(text, resolvers) {
@@ -65746,10 +65144,11 @@ function createCloudTurnSession(args) {
65746
65144
  turnId: commandId,
65747
65145
  text: portable,
65748
65146
  expectedEngine: engine,
65749
- ...engine === "pi" ? { engineSessionId: engineSessionId ?? conversationId } : {},
65147
+ ...engine === "pi" && !ctx.titleOnly ? { engineSessionId: engineSessionId ?? conversationId } : {},
65750
65148
  ...instructions ? { instructions } : {},
65751
65149
  ...ctx.effort ? { effort: ctx.effort } : {},
65752
- ...ctx.personaMode ? { personaMode: ctx.personaMode } : {}
65150
+ ...ctx.personaMode ? { personaMode: ctx.personaMode } : {},
65151
+ ...ctx.titleOnly ? { purpose: "title" } : {}
65753
65152
  });
65754
65153
  if (closed) {
65755
65154
  stream.close();
@@ -65826,7 +65225,7 @@ function cloudImageInput(deps) {
65826
65225
  const mime = lookupMime(p3);
65827
65226
  if (!mime.startsWith("image/")) return null;
65828
65227
  try {
65829
- const bytes = (deps.readFile ?? import_node_fs40.default.readFileSync)(p3);
65228
+ const bytes = (deps.readFile ?? import_node_fs39.default.readFileSync)(p3);
65830
65229
  return { type: "image", url: `data:${mime};base64,${bytes.toString("base64")}` };
65831
65230
  } catch (e) {
65832
65231
  deps.logger?.warn("cloud image attachment unreadable", { path: p3, message: e.message });
@@ -65836,34 +65235,10 @@ function cloudImageInput(deps) {
65836
65235
  }
65837
65236
  function createCloudCodexSession(ctx, sink, deps) {
65838
65237
  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) {
65238
+ if (!personaId2 || ctx.cloudGatewaySessionId || ctx.cloudLegacyPendingCommand) {
65864
65239
  queueMicrotask(() => {
65865
- sink.onError(`cloud session is missing ${personaId2 ? "CLAWD_SESSION_ID" : "persona id"}`);
65866
- exit();
65240
+ 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");
65241
+ sink.onExit(null);
65867
65242
  });
65868
65243
  return { startTurn() {
65869
65244
  }, respondPermission() {
@@ -65871,90 +65246,15 @@ function createCloudCodexSession(ctx, sink, deps) {
65871
65246
  }, async stop() {
65872
65247
  } };
65873
65248
  }
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(() => {
65249
+ return createCloudTurnSession({
65250
+ ctx,
65251
+ sink,
65252
+ client: deps.client,
65253
+ personaId: personaId2,
65254
+ engine: "codex",
65255
+ instructions: ctx.titleOnly ? void 0 : ctx.extraSystemPrompt,
65256
+ prepare: (text) => portableCloudInput(text, { resolveCodexImage: cloudImageInput(deps) })
65916
65257
  });
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
65258
  }
65959
65259
 
65960
65260
  // src/tools/codex-cloud.ts
@@ -66025,7 +65325,7 @@ init_protocol();
66025
65325
 
66026
65326
  // src/tools/pi.ts
66027
65327
  var import_node_child_process12 = require("child_process");
66028
- var import_node_fs42 = __toESM(require("fs"), 1);
65328
+ var import_node_fs41 = __toESM(require("fs"), 1);
66029
65329
  init_protocol();
66030
65330
 
66031
65331
  // src/tools/pi-rpc-client.ts
@@ -66125,9 +65425,9 @@ var PiRpcClient = class {
66125
65425
 
66126
65426
  // src/tools/pi-session.ts
66127
65427
  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);
65428
+ var import_node_crypto14 = require("crypto");
65429
+ var import_node_fs40 = __toESM(require("fs"), 1);
65430
+ var import_node_path44 = __toESM(require("path"), 1);
66131
65431
 
66132
65432
  // src/tools/pi-events.ts
66133
65433
  init_protocol();
@@ -66398,9 +65698,9 @@ ${dirs.map((d2) => `- ${d2}`).join("\n")}`;
66398
65698
  }
66399
65699
  function createPiSession(ctx, sink, deps = {}) {
66400
65700
  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));
65701
+ const sessionId = ctx.toolSessionId ?? (0, import_node_crypto14.randomUUID)();
65702
+ const skillsDir = import_node_path44.default.join(ctx.cwd, ".claude", "skills");
65703
+ const exists = deps.skillsDirExists ?? ((d2) => import_node_fs40.default.existsSync(d2));
66404
65704
  const args = buildPiArgs(ctx, {
66405
65705
  sessionId,
66406
65706
  skillsDir: exists(skillsDir) ? skillsDir : void 0,
@@ -66462,10 +65762,10 @@ var PI_DEFAULT_MODEL_ENTRY = {
66462
65762
  };
66463
65763
  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
65764
  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 };
65765
+ if (env.PI_BIN && import_node_fs41.default.existsSync(env.PI_BIN)) return { available: true, path: env.PI_BIN };
66466
65766
  try {
66467
65767
  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 };
65768
+ if (out && import_node_fs41.default.existsSync(out)) return { available: true, path: out };
66469
65769
  } catch {
66470
65770
  }
66471
65771
  return { available: false };
@@ -66635,42 +65935,15 @@ var PiAdapter = class {
66635
65935
  };
66636
65936
 
66637
65937
  // src/tools/pi-cloud-session.ts
66638
- var import_node_crypto16 = require("crypto");
66639
65938
  function cloudPiInstructions(ctx) {
66640
65939
  return [ctx.extraSystemPrompt, workDirPrompt(CLOUD_WORKSPACE_SLOT, ctx.personaMode ?? "owner")].filter((x2) => Boolean(x2)).join("\n\n");
66641
65940
  }
66642
65941
  function createCloudPiSession(ctx, sink, deps) {
66643
65942
  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) {
65943
+ if (!personaId2 || ctx.cloudGatewaySessionId || ctx.cloudLegacyPendingCommand) {
66671
65944
  queueMicrotask(() => {
66672
- sink.onError(`cloud session is missing ${personaId2 ? "CLAWD_SESSION_ID" : "persona id"}`);
66673
- exit();
65945
+ 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");
65946
+ sink.onExit(null);
66674
65947
  });
66675
65948
  return { startTurn() {
66676
65949
  }, respondPermission() {
@@ -66678,80 +65951,16 @@ function createCloudPiSession(ctx, sink, deps) {
66678
65951
  }, async stop() {
66679
65952
  } };
66680
65953
  }
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(() => {
65954
+ return createCloudTurnSession({
65955
+ ctx,
65956
+ sink,
65957
+ client: deps.client,
65958
+ personaId: personaId2,
65959
+ engine: "pi",
65960
+ engineSessionId: ctx.toolSessionId,
65961
+ instructions: ctx.titleOnly ? void 0 : cloudPiInstructions(ctx),
65962
+ prepare: (text) => portableCloudInput(text, { fetchPiImage: deps.fetchImage ?? makeImageFetcher() })
66713
65963
  });
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
65964
  }
66756
65965
 
66757
65966
  // src/tools/pi-cloud.ts
@@ -66821,7 +66030,7 @@ var CloudPiAdapter = class {
66821
66030
  init_protocol();
66822
66031
 
66823
66032
  // src/tools/codex-skills.ts
66824
- var import_node_path46 = __toESM(require("path"), 1);
66033
+ var import_node_path45 = __toESM(require("path"), 1);
66825
66034
  function str4(v3) {
66826
66035
  return typeof v3 === "string" ? v3 : void 0;
66827
66036
  }
@@ -66836,13 +66045,13 @@ function mapSkillsListResponse(res) {
66836
66045
  const r2 = s2 ?? {};
66837
66046
  const name = str4(r2.name);
66838
66047
  if (!name) continue;
66839
- const path107 = str4(r2.path);
66048
+ const path106 = str4(r2.path);
66840
66049
  const description = str4(r2.description);
66841
66050
  const isPlugin = name.includes(":");
66842
66051
  out.push({
66843
66052
  name,
66844
66053
  source: isPlugin ? "plugin" : "project",
66845
- ...path107 ? { path: path107 } : {},
66054
+ ...path106 ? { path: path106 } : {},
66846
66055
  ...description ? { description } : {},
66847
66056
  ...isPlugin ? { plugin: name.split(":")[0] } : {}
66848
66057
  });
@@ -66858,7 +66067,7 @@ async function listCodexSkills(cwd, deps = {}) {
66858
66067
  // 先写 extraRoots 再写 list(stdio 按写入顺序处理,fire-and-forget 不 await 回包;
66859
66068
  // codex-session.ts ready 序列同款,两处保持一致)。失败不阻塞 list。
66860
66069
  beforeRequest: (client) => {
66861
- void client.request("skills/extraRoots/set", { extraRoots: [import_node_path46.default.join(cwd, ".claude", "skills")] }).catch(() => void 0);
66070
+ void client.request("skills/extraRoots/set", { extraRoots: [import_node_path45.default.join(cwd, ".claude", "skills")] }).catch(() => void 0);
66862
66071
  }
66863
66072
  });
66864
66073
  return mapSkillsListResponse(res);
@@ -66932,23 +66141,23 @@ function rec4(v3) {
66932
66141
  }
66933
66142
 
66934
66143
  // src/workspace/browser.ts
66935
- var import_node_fs43 = __toESM(require("fs"), 1);
66144
+ var import_node_fs42 = __toESM(require("fs"), 1);
66936
66145
  var import_node_os15 = __toESM(require("os"), 1);
66937
- var import_node_path47 = __toESM(require("path"), 1);
66146
+ var import_node_path46 = __toESM(require("path"), 1);
66938
66147
  init_protocol();
66939
66148
  var MAX_FILE_BYTES2 = 2 * 1024 * 1024;
66940
66149
  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)) {
66150
+ const absCwd = import_node_path46.default.resolve(cwd);
66151
+ const joined = import_node_path46.default.resolve(absCwd, subpath ?? ".");
66152
+ const rel = import_node_path46.default.relative(absCwd, joined);
66153
+ if (rel.startsWith("..") || import_node_path46.default.isAbsolute(rel)) {
66945
66154
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
66946
66155
  }
66947
66156
  return joined;
66948
66157
  }
66949
66158
  function ensureCwd(cwd) {
66950
66159
  try {
66951
- const stat = import_node_fs43.default.statSync(cwd);
66160
+ const stat = import_node_fs42.default.statSync(cwd);
66952
66161
  if (!stat.isDirectory()) {
66953
66162
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${cwd}`);
66954
66163
  }
@@ -66962,7 +66171,7 @@ var WorkspaceBrowser = class {
66962
66171
  const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os15.default.homedir();
66963
66172
  ensureCwd(cwd);
66964
66173
  const full = resolveInsideCwd(cwd, args.path);
66965
- const dirents = import_node_fs43.default.readdirSync(full, { withFileTypes: true });
66174
+ const dirents = import_node_fs42.default.readdirSync(full, { withFileTypes: true });
66966
66175
  const entries = [];
66967
66176
  for (const d2 of dirents) {
66968
66177
  if (!args.showHidden && d2.name.startsWith(".")) continue;
@@ -66972,7 +66181,7 @@ var WorkspaceBrowser = class {
66972
66181
  mtime: ""
66973
66182
  };
66974
66183
  try {
66975
- const st2 = import_node_fs43.default.statSync(import_node_path47.default.join(full, d2.name));
66184
+ const st2 = import_node_fs42.default.statSync(import_node_path46.default.join(full, d2.name));
66976
66185
  entry.mtime = new Date(st2.mtimeMs).toISOString();
66977
66186
  if (d2.isFile()) entry.size = st2.size;
66978
66187
  } catch {
@@ -66988,14 +66197,14 @@ var WorkspaceBrowser = class {
66988
66197
  read(args) {
66989
66198
  ensureCwd(args.cwd);
66990
66199
  const full = resolveInsideCwd(args.cwd, args.path);
66991
- const st2 = import_node_fs43.default.statSync(full);
66200
+ const st2 = import_node_fs42.default.statSync(full);
66992
66201
  if (!st2.isFile()) {
66993
66202
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `not a file: ${args.path}`);
66994
66203
  }
66995
66204
  if (st2.size > MAX_FILE_BYTES2) {
66996
66205
  throw new ClawdError(ERROR_CODES.FILE_TOO_LARGE, `file > ${MAX_FILE_BYTES2} bytes`);
66997
66206
  }
66998
- const buf = import_node_fs43.default.readFileSync(full);
66207
+ const buf = import_node_fs42.default.readFileSync(full);
66999
66208
  const isBinary = buf.includes(0);
67000
66209
  if (isBinary) {
67001
66210
  return {
@@ -67017,20 +66226,20 @@ var WorkspaceBrowser = class {
67017
66226
  };
67018
66227
 
67019
66228
  // src/skills/agents-scanner.ts
67020
- var import_node_fs44 = __toESM(require("fs"), 1);
66229
+ var import_node_fs43 = __toESM(require("fs"), 1);
67021
66230
  var import_node_os16 = __toESM(require("os"), 1);
67022
- var import_node_path48 = __toESM(require("path"), 1);
66231
+ var import_node_path47 = __toESM(require("path"), 1);
67023
66232
  var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
67024
66233
  function isDirLikeSync2(p3) {
67025
66234
  try {
67026
- return import_node_fs44.default.statSync(p3).isDirectory();
66235
+ return import_node_fs43.default.statSync(p3).isDirectory();
67027
66236
  } catch {
67028
66237
  return false;
67029
66238
  }
67030
66239
  }
67031
66240
  function fileExistsSync(p3) {
67032
66241
  try {
67033
- return import_node_fs44.default.statSync(p3).isFile();
66242
+ return import_node_fs43.default.statSync(p3).isFile();
67034
66243
  } catch {
67035
66244
  return false;
67036
66245
  }
@@ -67038,7 +66247,7 @@ function fileExistsSync(p3) {
67038
66247
  function parseAgentFile(filePath) {
67039
66248
  let content;
67040
66249
  try {
67041
- content = import_node_fs44.default.readFileSync(filePath, "utf8");
66250
+ content = import_node_fs43.default.readFileSync(filePath, "utf8");
67042
66251
  } catch {
67043
66252
  return {};
67044
66253
  }
@@ -67051,16 +66260,16 @@ function parseAgentFile(filePath) {
67051
66260
  function scanAgentsDir(dir, source, seen, out) {
67052
66261
  let entries;
67053
66262
  try {
67054
- entries = import_node_fs44.default.readdirSync(dir, { withFileTypes: true });
66263
+ entries = import_node_fs43.default.readdirSync(dir, { withFileTypes: true });
67055
66264
  } catch {
67056
66265
  return;
67057
66266
  }
67058
66267
  for (const ent of entries) {
67059
66268
  if (!ent.name.endsWith(".md")) continue;
67060
- if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path48.default.join(dir, ent.name)))) {
66269
+ if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path47.default.join(dir, ent.name)))) {
67061
66270
  continue;
67062
66271
  }
67063
- const filePath = import_node_path48.default.join(dir, ent.name);
66272
+ const filePath = import_node_path47.default.join(dir, ent.name);
67064
66273
  const baseName = ent.name.replace(/\.md$/, "");
67065
66274
  if (seen.has(baseName)) continue;
67066
66275
  seen.add(baseName);
@@ -67078,12 +66287,12 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
67078
66287
  function walk2(dir, namespaces) {
67079
66288
  let entries;
67080
66289
  try {
67081
- entries = import_node_fs44.default.readdirSync(dir, { withFileTypes: true });
66290
+ entries = import_node_fs43.default.readdirSync(dir, { withFileTypes: true });
67082
66291
  } catch {
67083
66292
  return;
67084
66293
  }
67085
66294
  for (const ent of entries) {
67086
- const childPath = import_node_path48.default.join(dir, ent.name);
66295
+ const childPath = import_node_path47.default.join(dir, ent.name);
67087
66296
  if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
67088
66297
  walk2(childPath, [...namespaces, ent.name]);
67089
66298
  continue;
@@ -67108,13 +66317,13 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
67108
66317
  walk2(root, []);
67109
66318
  }
67110
66319
  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");
66320
+ const pluginsDir = import_node_path47.default.join(home, ".claude", "plugins");
66321
+ const v22 = import_node_path47.default.join(pluginsDir, "installed_plugins_v2.json");
66322
+ const v1 = import_node_path47.default.join(pluginsDir, "installed_plugins.json");
67114
66323
  let raw = null;
67115
66324
  for (const candidate of [v22, v1]) {
67116
66325
  try {
67117
- raw = import_node_fs44.default.readFileSync(candidate, "utf8");
66326
+ raw = import_node_fs43.default.readFileSync(candidate, "utf8");
67118
66327
  break;
67119
66328
  } catch {
67120
66329
  }
@@ -67139,19 +66348,19 @@ function readInstalledPlugins2(home) {
67139
66348
  return out;
67140
66349
  }
67141
66350
  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;
66351
+ let cur = import_node_path47.default.resolve(startCwd);
66352
+ const fsRoot = import_node_path47.default.parse(cur).root;
67144
66353
  while (true) {
67145
- scanAgentsDir(import_node_path48.default.join(cur, ".claude", "agents"), "project", seen, out);
66354
+ scanAgentsDir(import_node_path47.default.join(cur, ".claude", "agents"), "project", seen, out);
67146
66355
  let hasGit = false;
67147
66356
  try {
67148
- hasGit = import_node_fs44.default.existsSync(import_node_path48.default.join(cur, ".git"));
66357
+ hasGit = import_node_fs43.default.existsSync(import_node_path47.default.join(cur, ".git"));
67149
66358
  } catch {
67150
66359
  }
67151
66360
  if (hasGit) return;
67152
66361
  if (cur === home) return;
67153
66362
  if (cur === fsRoot) return;
67154
- const parent = import_node_path48.default.dirname(cur);
66363
+ const parent = import_node_path47.default.dirname(cur);
67155
66364
  if (parent === cur) return;
67156
66365
  cur = parent;
67157
66366
  }
@@ -67186,7 +66395,7 @@ var AgentsScanner = class {
67186
66395
  }
67187
66396
  const fsBlock = [];
67188
66397
  scanAgentsDir(
67189
- import_node_path48.default.join(this.home, ".claude", "agents"),
66398
+ import_node_path47.default.join(this.home, ".claude", "agents"),
67190
66399
  "global",
67191
66400
  seen,
67192
66401
  fsBlock
@@ -67200,7 +66409,7 @@ var AgentsScanner = class {
67200
66409
  ...this.extraPluginRoots
67201
66410
  ];
67202
66411
  for (const { name, root } of plugins) {
67203
- const agentsRoot = import_node_path48.default.join(root, "agents");
66412
+ const agentsRoot = import_node_path47.default.join(root, "agents");
67204
66413
  scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
67205
66414
  }
67206
66415
  return [...builtinBlock, ...fsBlock];
@@ -67208,15 +66417,15 @@ var AgentsScanner = class {
67208
66417
  };
67209
66418
 
67210
66419
  // src/observer/session-observer.ts
67211
- var import_node_fs46 = __toESM(require("fs"), 1);
66420
+ var import_node_fs45 = __toESM(require("fs"), 1);
67212
66421
  var import_node_os18 = __toESM(require("os"), 1);
67213
- var import_node_path50 = __toESM(require("path"), 1);
66422
+ var import_node_path49 = __toESM(require("path"), 1);
67214
66423
  init_claude_history();
67215
66424
 
67216
66425
  // src/observer/subagent-meta-observer.ts
67217
- var import_node_fs45 = __toESM(require("fs"), 1);
66426
+ var import_node_fs44 = __toESM(require("fs"), 1);
67218
66427
  var import_node_os17 = __toESM(require("os"), 1);
67219
- var import_node_path49 = __toESM(require("path"), 1);
66428
+ var import_node_path48 = __toESM(require("path"), 1);
67220
66429
  init_claude_history();
67221
66430
  var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
67222
66431
  var SubagentMetaObserver = class {
@@ -67229,7 +66438,7 @@ var SubagentMetaObserver = class {
67229
66438
  watches = /* @__PURE__ */ new Map();
67230
66439
  // public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
67231
66440
  resolveSubagentDir(cwd, toolSessionId) {
67232
- return import_node_path49.default.join(
66441
+ return import_node_path48.default.join(
67233
66442
  this.home,
67234
66443
  ".claude",
67235
66444
  "projects",
@@ -67259,7 +66468,7 @@ var SubagentMetaObserver = class {
67259
66468
  attachWatcher(w3) {
67260
66469
  if (w3.watcher) return;
67261
66470
  try {
67262
- w3.watcher = import_node_fs45.default.watch(w3.dirPath, { persistent: false }, (_evt, name) => {
66471
+ w3.watcher = import_node_fs44.default.watch(w3.dirPath, { persistent: false }, (_evt, name) => {
67263
66472
  if (!name) return;
67264
66473
  const m3 = META_RE.exec(String(name));
67265
66474
  if (!m3) return;
@@ -67271,7 +66480,7 @@ var SubagentMetaObserver = class {
67271
66480
  scan(w3) {
67272
66481
  let entries;
67273
66482
  try {
67274
- entries = import_node_fs45.default.readdirSync(w3.dirPath);
66483
+ entries = import_node_fs44.default.readdirSync(w3.dirPath);
67275
66484
  } catch {
67276
66485
  return;
67277
66486
  }
@@ -67285,10 +66494,10 @@ var SubagentMetaObserver = class {
67285
66494
  if (!m3) return;
67286
66495
  const agentId = m3[1];
67287
66496
  if (w3.emitted.has(agentId)) return;
67288
- const file = import_node_path49.default.join(w3.dirPath, name);
66497
+ const file = import_node_path48.default.join(w3.dirPath, name);
67289
66498
  let raw;
67290
66499
  try {
67291
- raw = import_node_fs45.default.readFileSync(file, "utf8");
66500
+ raw = import_node_fs44.default.readFileSync(file, "utf8");
67292
66501
  } catch {
67293
66502
  return;
67294
66503
  }
@@ -67345,14 +66554,14 @@ var SessionObserver = class {
67345
66554
  metaObserver;
67346
66555
  resolveJsonlPath(cwd, toolSessionId, override) {
67347
66556
  if (override) return override;
67348
- return import_node_path50.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
66557
+ return import_node_path49.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
67349
66558
  }
67350
66559
  start(args) {
67351
66560
  this.stop(args.sessionId);
67352
66561
  const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
67353
66562
  let size = 0;
67354
66563
  try {
67355
- size = import_node_fs46.default.statSync(filePath).size;
66564
+ size = import_node_fs45.default.statSync(filePath).size;
67356
66565
  } catch {
67357
66566
  }
67358
66567
  const w3 = {
@@ -67365,16 +66574,16 @@ var SessionObserver = class {
67365
66574
  adapter: args.adapter,
67366
66575
  prevIsRejectSentinel: false,
67367
66576
  toolSessionId: args.toolSessionId,
67368
- sawFile: import_node_fs46.default.existsSync(filePath),
66577
+ sawFile: import_node_fs45.default.existsSync(filePath),
67369
66578
  lastRelocateScanMs: 0,
67370
66579
  pendingCwdDerive: false,
67371
66580
  lastDeriveMs: 0
67372
66581
  };
67373
66582
  try {
67374
- import_node_fs46.default.mkdirSync(import_node_path50.default.dirname(filePath), { recursive: true });
66583
+ import_node_fs45.default.mkdirSync(import_node_path49.default.dirname(filePath), { recursive: true });
67375
66584
  } catch {
67376
66585
  }
67377
- w3.watcher = import_node_fs46.default.watch(import_node_path50.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
66586
+ w3.watcher = import_node_fs45.default.watch(import_node_path49.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
67378
66587
  if (!changedName || !w3.filePath.endsWith(changedName)) return;
67379
66588
  this.poll(w3);
67380
66589
  });
@@ -67397,7 +66606,7 @@ var SessionObserver = class {
67397
66606
  // 异常静默吞,不阻塞 watcher 启动
67398
66607
  hydrateMetaTail(w3, maxLines = 200) {
67399
66608
  try {
67400
- const raw = import_node_fs46.default.readFileSync(w3.filePath, "utf8");
66609
+ const raw = import_node_fs45.default.readFileSync(w3.filePath, "utf8");
67401
66610
  if (!raw) return;
67402
66611
  const allLines = raw.split("\n").filter((l2) => l2.trim().length > 0);
67403
66612
  if (allLines.length === 0) return;
@@ -67421,7 +66630,7 @@ var SessionObserver = class {
67421
66630
  poll(w3) {
67422
66631
  let size = 0;
67423
66632
  try {
67424
- size = import_node_fs46.default.statSync(w3.filePath).size;
66633
+ size = import_node_fs45.default.statSync(w3.filePath).size;
67425
66634
  } catch {
67426
66635
  if (w3.sawFile) this.maybeRelocate(w3);
67427
66636
  return;
@@ -67432,11 +66641,11 @@ var SessionObserver = class {
67432
66641
  w3.buf = "";
67433
66642
  }
67434
66643
  if (size === w3.lastSize) return;
67435
- const fd = import_node_fs46.default.openSync(w3.filePath, "r");
66644
+ const fd = import_node_fs45.default.openSync(w3.filePath, "r");
67436
66645
  try {
67437
66646
  const len = size - w3.lastSize;
67438
66647
  const buf = Buffer.alloc(len);
67439
- import_node_fs46.default.readSync(fd, buf, 0, len, w3.lastSize);
66648
+ import_node_fs45.default.readSync(fd, buf, 0, len, w3.lastSize);
67440
66649
  w3.lastSize = size;
67441
66650
  w3.buf += buf.toString("utf8");
67442
66651
  let newlineIndex;
@@ -67459,7 +66668,7 @@ var SessionObserver = class {
67459
66668
  }
67460
66669
  }
67461
66670
  } finally {
67462
- import_node_fs46.default.closeSync(fd);
66671
+ import_node_fs45.default.closeSync(fd);
67463
66672
  }
67464
66673
  if (w3.pendingCwdDerive) this.maybeDeriveCwd(w3);
67465
66674
  }
@@ -67471,7 +66680,7 @@ var SessionObserver = class {
67471
66680
  const now = Date.now();
67472
66681
  if (now - w3.lastRelocateScanMs < 1e3) return;
67473
66682
  w3.lastRelocateScanMs = now;
67474
- const projectsRoot = import_node_path50.default.join(this.home, ".claude", "projects");
66683
+ const projectsRoot = import_node_path49.default.join(this.home, ".claude", "projects");
67475
66684
  const found = findTranscriptByToolSessionId(projectsRoot, w3.toolSessionId);
67476
66685
  if (!found || found === w3.filePath) return;
67477
66686
  try {
@@ -67480,7 +66689,7 @@ var SessionObserver = class {
67480
66689
  }
67481
66690
  w3.filePath = found;
67482
66691
  try {
67483
- w3.watcher = import_node_fs46.default.watch(import_node_path50.default.dirname(found), { persistent: false }, (_event, changedName) => {
66692
+ w3.watcher = import_node_fs45.default.watch(import_node_path49.default.dirname(found), { persistent: false }, (_event, changedName) => {
67484
66693
  if (!changedName || !w3.filePath.endsWith(changedName)) return;
67485
66694
  this.poll(w3);
67486
66695
  });
@@ -67602,9 +66811,9 @@ function listRegistered() {
67602
66811
  // src/tools/title-generator.ts
67603
66812
  var import_node_child_process13 = require("child_process");
67604
66813
  init_protocol();
67605
- var import_node_fs47 = __toESM(require("fs"), 1);
66814
+ var import_node_fs46 = __toESM(require("fs"), 1);
67606
66815
  var import_node_os19 = __toESM(require("os"), 1);
67607
- var import_node_path51 = __toESM(require("path"), 1);
66816
+ var import_node_path50 = __toESM(require("path"), 1);
67608
66817
  var TITLE_GEN_DIR_PREFIX = "clawd-title-";
67609
66818
  var TITLE_INPUT_MAX_CHARS = 400;
67610
66819
  var DEFAULT_TITLE_GEN_TIMEOUT_MS = 45e3;
@@ -67695,21 +66904,21 @@ async function generateSessionTitle(file, firstMessage, deps = {}) {
67695
66904
  }
67696
66905
  let workDir;
67697
66906
  try {
67698
- workDir = import_node_fs47.default.mkdtempSync(import_node_path51.default.join(import_node_os19.default.tmpdir(), TITLE_GEN_DIR_PREFIX));
66907
+ workDir = import_node_fs46.default.mkdtempSync(import_node_path50.default.join(import_node_os19.default.tmpdir(), TITLE_GEN_DIR_PREFIX));
67699
66908
  } catch {
67700
66909
  return null;
67701
66910
  }
67702
66911
  const cleanupWorkDir = () => {
67703
66912
  try {
67704
- import_node_fs47.default.rmSync(workDir, { recursive: true, force: true });
66913
+ import_node_fs46.default.rmSync(workDir, { recursive: true, force: true });
67705
66914
  } catch {
67706
66915
  }
67707
66916
  };
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");
66917
+ const outFile = import_node_path50.default.join(workDir, `codex-title-${process.pid}-${++outFileSeq}-${Date.now()}.txt`);
66918
+ const schemaFile = import_node_path50.default.join(workDir, "title-schema.json");
67710
66919
  if (tool === "codex") {
67711
66920
  try {
67712
- import_node_fs47.default.writeFileSync(schemaFile, CODEX_TITLE_SCHEMA);
66921
+ import_node_fs46.default.writeFileSync(schemaFile, CODEX_TITLE_SCHEMA);
67713
66922
  } catch {
67714
66923
  cleanupWorkDir();
67715
66924
  return null;
@@ -67764,7 +66973,7 @@ async function generateSessionTitle(file, firstMessage, deps = {}) {
67764
66973
  if (tool === "claude" || tool === "pi") return finish(parseTitleJson(stdout));
67765
66974
  let fileText = "";
67766
66975
  try {
67767
- fileText = import_node_fs47.default.readFileSync(outFile, "utf8");
66976
+ fileText = import_node_fs46.default.readFileSync(outFile, "utf8");
67768
66977
  } catch {
67769
66978
  return finish(null);
67770
66979
  }
@@ -67837,7 +67046,7 @@ var wrapper_default = import_websocket.default;
67837
67046
 
67838
67047
  // src/transport/local-ws-server.ts
67839
67048
  var import_node_http = __toESM(require("http"), 1);
67840
- var import_node_crypto17 = require("crypto");
67049
+ var import_node_crypto15 = require("crypto");
67841
67050
  var LocalWsServer = class {
67842
67051
  constructor(opts) {
67843
67052
  this.opts = opts;
@@ -68054,7 +67263,7 @@ var LocalWsServer = class {
68054
67263
  }
68055
67264
  }
68056
67265
  onConnection(socket, remoteAddress) {
68057
- const id = (0, import_node_crypto17.randomUUID)();
67266
+ const id = (0, import_node_crypto15.randomUUID)();
68058
67267
  const subscribedSessions = /* @__PURE__ */ new Map();
68059
67268
  const handle = {
68060
67269
  id,
@@ -68460,8 +67669,8 @@ async function authenticate(token, deps) {
68460
67669
  }
68461
67670
 
68462
67671
  // src/legacy-cleanup.ts
68463
- var fs58 = __toESM(require("fs/promises"), 1);
68464
- var path59 = __toESM(require("path"), 1);
67672
+ var fs57 = __toESM(require("fs/promises"), 1);
67673
+ var path58 = __toESM(require("path"), 1);
68465
67674
  var LEGACY_FILES = [
68466
67675
  "personal-capability.json",
68467
67676
  "received-capabilities.json",
@@ -68470,9 +67679,9 @@ var LEGACY_FILES = [
68470
67679
  async function cleanupLegacyCapabilityFiles(dataDir, logger) {
68471
67680
  const removed = [];
68472
67681
  for (const name of LEGACY_FILES) {
68473
- const p3 = path59.join(dataDir, name);
67682
+ const p3 = path58.join(dataDir, name);
68474
67683
  try {
68475
- await fs58.unlink(p3);
67684
+ await fs57.unlink(p3);
68476
67685
  removed.push(name);
68477
67686
  logger.debug("legacy capability file removed", { file: name });
68478
67687
  } catch (err) {
@@ -68484,13 +67693,13 @@ async function cleanupLegacyCapabilityFiles(dataDir, logger) {
68484
67693
  }
68485
67694
 
68486
67695
  // src/inbox/inbox-store.ts
68487
- var fs59 = __toESM(require("fs"), 1);
68488
- var path60 = __toESM(require("path"), 1);
67696
+ var fs58 = __toESM(require("fs"), 1);
67697
+ var path59 = __toESM(require("path"), 1);
68489
67698
  var INBOX_SUBDIR = "inbox";
68490
67699
  var InboxStore = class {
68491
67700
  constructor(dataDir) {
68492
67701
  this.dataDir = dataDir;
68493
- fs59.mkdirSync(this.dirPath(), { recursive: true });
67702
+ fs58.mkdirSync(this.dirPath(), { recursive: true });
68494
67703
  }
68495
67704
  dataDir;
68496
67705
  /**
@@ -68502,7 +67711,7 @@ var InboxStore = class {
68502
67711
  const file = this.filePath(peerDeviceId);
68503
67712
  let raw;
68504
67713
  try {
68505
- raw = fs59.readFileSync(file, "utf8");
67714
+ raw = fs58.readFileSync(file, "utf8");
68506
67715
  } catch (err) {
68507
67716
  if (err?.code === "ENOENT") return [];
68508
67717
  return [];
@@ -68518,7 +67727,7 @@ var InboxStore = class {
68518
67727
  const dir = this.dirPath();
68519
67728
  let entries;
68520
67729
  try {
68521
- entries = fs59.readdirSync(dir);
67730
+ entries = fs58.readdirSync(dir);
68522
67731
  } catch (err) {
68523
67732
  if (err?.code === "ENOENT") return [];
68524
67733
  return [];
@@ -68534,9 +67743,9 @@ var InboxStore = class {
68534
67743
  if (existing.some((m3) => m3.id === message.id)) return;
68535
67744
  const file = this.filePath(message.peerDeviceId);
68536
67745
  const line = JSON.stringify(message) + "\n";
68537
- fs59.appendFileSync(file, line, { mode: 384 });
67746
+ fs58.appendFileSync(file, line, { mode: 384 });
68538
67747
  try {
68539
- fs59.chmodSync(file, 384);
67748
+ fs58.chmodSync(file, 384);
68540
67749
  } catch {
68541
67750
  }
68542
67751
  }
@@ -68566,7 +67775,7 @@ var InboxStore = class {
68566
67775
  removeByPeerDeviceId(peerDeviceId) {
68567
67776
  const file = this.filePath(peerDeviceId);
68568
67777
  try {
68569
- fs59.unlinkSync(file);
67778
+ fs58.unlinkSync(file);
68570
67779
  } catch (err) {
68571
67780
  if (err?.code === "ENOENT") return;
68572
67781
  }
@@ -68575,18 +67784,18 @@ var InboxStore = class {
68575
67784
  const file = this.filePath(peerDeviceId);
68576
67785
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
68577
67786
  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);
67787
+ fs58.writeFileSync(tmp, content, { mode: 384 });
67788
+ fs58.renameSync(tmp, file);
68580
67789
  try {
68581
- fs59.chmodSync(file, 384);
67790
+ fs58.chmodSync(file, 384);
68582
67791
  } catch {
68583
67792
  }
68584
67793
  }
68585
67794
  dirPath() {
68586
- return path60.join(this.dataDir, INBOX_SUBDIR);
67795
+ return path59.join(this.dataDir, INBOX_SUBDIR);
68587
67796
  }
68588
67797
  filePath(peerDeviceId) {
68589
- return path60.join(this.dirPath(), `${peerDeviceId}.jsonl`);
67798
+ return path59.join(this.dirPath(), `${peerDeviceId}.jsonl`);
68590
67799
  }
68591
67800
  };
68592
67801
  function parseAllLines(raw) {
@@ -68674,8 +67883,8 @@ var InboxManager = class {
68674
67883
  };
68675
67884
 
68676
67885
  // src/state/contact-store.ts
68677
- var fs60 = __toESM(require("fs"), 1);
68678
- var path61 = __toESM(require("path"), 1);
67886
+ var fs59 = __toESM(require("fs"), 1);
67887
+ var path60 = __toESM(require("path"), 1);
68679
67888
  var FILE_NAME = "contacts.json";
68680
67889
  var ContactStore = class {
68681
67890
  constructor(dataDir) {
@@ -68685,10 +67894,10 @@ var ContactStore = class {
68685
67894
  contacts = /* @__PURE__ */ new Map();
68686
67895
  load() {
68687
67896
  this.contacts.clear();
68688
- const file = path61.join(this.dataDir, FILE_NAME);
67897
+ const file = path60.join(this.dataDir, FILE_NAME);
68689
67898
  let raw;
68690
67899
  try {
68691
- raw = fs60.readFileSync(file, "utf8");
67900
+ raw = fs59.readFileSync(file, "utf8");
68692
67901
  } catch (err) {
68693
67902
  if (err?.code !== "ENOENT") this.renameBak(file);
68694
67903
  return;
@@ -68769,20 +67978,20 @@ var ContactStore = class {
68769
67978
  return true;
68770
67979
  }
68771
67980
  flush() {
68772
- const file = path61.join(this.dataDir, FILE_NAME);
67981
+ const file = path60.join(this.dataDir, FILE_NAME);
68773
67982
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
68774
67983
  const content = JSON.stringify(
68775
67984
  { contacts: Array.from(this.contacts.values()) },
68776
67985
  null,
68777
67986
  2
68778
67987
  );
68779
- fs60.mkdirSync(this.dataDir, { recursive: true });
68780
- fs60.writeFileSync(tmp, content, { mode: 384 });
68781
- fs60.renameSync(tmp, file);
67988
+ fs59.mkdirSync(this.dataDir, { recursive: true });
67989
+ fs59.writeFileSync(tmp, content, { mode: 384 });
67990
+ fs59.renameSync(tmp, file);
68782
67991
  }
68783
67992
  renameBak(file) {
68784
67993
  try {
68785
- fs60.renameSync(file, `${file}.bak`);
67994
+ fs59.renameSync(file, `${file}.bak`);
68786
67995
  } catch {
68787
67996
  }
68788
67997
  }
@@ -68890,61 +68099,61 @@ async function connectRemote(args) {
68890
68099
  }
68891
68100
 
68892
68101
  // src/migrations/2026-05-20-flatten-sessions.ts
68893
- var fs61 = __toESM(require("fs"), 1);
68894
- var path62 = __toESM(require("path"), 1);
68102
+ var fs60 = __toESM(require("fs"), 1);
68103
+ var path61 = __toESM(require("path"), 1);
68895
68104
  var MIGRATION_FLAG_NAME = ".migration.v1.done";
68896
68105
  function migrateFlattenSessions(opts) {
68897
68106
  const dataDir = opts.dataDir;
68898
68107
  const now = opts.now ?? Date.now;
68899
- const sessionsDir = path62.join(dataDir, "sessions");
68900
- const flagPath = path62.join(sessionsDir, MIGRATION_FLAG_NAME);
68108
+ const sessionsDir = path61.join(dataDir, "sessions");
68109
+ const flagPath = path61.join(sessionsDir, MIGRATION_FLAG_NAME);
68901
68110
  if (existsSync3(flagPath)) {
68902
68111
  return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
68903
68112
  }
68904
68113
  let movedBare = 0;
68905
68114
  let movedVmOwner = 0;
68906
68115
  let archivedListener = 0;
68907
- const defaultDir = path62.join(sessionsDir, "default");
68116
+ const defaultDir = path61.join(sessionsDir, "default");
68908
68117
  if (existsSync3(defaultDir)) {
68909
68118
  for (const entry of readdirSafe(defaultDir)) {
68910
68119
  if (!entry.endsWith(".json")) continue;
68911
- const src = path62.join(defaultDir, entry);
68912
- const dst = path62.join(sessionsDir, entry);
68913
- fs61.renameSync(src, dst);
68120
+ const src = path61.join(defaultDir, entry);
68121
+ const dst = path61.join(sessionsDir, entry);
68122
+ fs60.renameSync(src, dst);
68914
68123
  movedBare += 1;
68915
68124
  }
68916
68125
  rmdirIfEmpty(defaultDir);
68917
68126
  }
68918
68127
  for (const pid of readdirSafe(sessionsDir)) {
68919
- const personaDir = path62.join(sessionsDir, pid);
68128
+ const personaDir = path61.join(sessionsDir, pid);
68920
68129
  if (!isDir(personaDir)) continue;
68921
68130
  if (pid === "default") continue;
68922
- const ownerSrc = path62.join(personaDir, "owner");
68131
+ const ownerSrc = path61.join(personaDir, "owner");
68923
68132
  if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
68924
- const ownerDst = path62.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
68925
- fs61.mkdirSync(ownerDst, { recursive: true });
68133
+ const ownerDst = path61.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
68134
+ fs60.mkdirSync(ownerDst, { recursive: true });
68926
68135
  for (const file of readdirSafe(ownerSrc)) {
68927
68136
  if (!file.endsWith(".json")) continue;
68928
- fs61.renameSync(path62.join(ownerSrc, file), path62.join(ownerDst, file));
68137
+ fs60.renameSync(path61.join(ownerSrc, file), path61.join(ownerDst, file));
68929
68138
  movedVmOwner += 1;
68930
68139
  }
68931
68140
  rmdirIfEmpty(ownerSrc);
68932
68141
  }
68933
- const listenerSrc = path62.join(personaDir, "listener");
68142
+ const listenerSrc = path61.join(personaDir, "listener");
68934
68143
  if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
68935
- const archiveDst = path62.join(dataDir, ".legacy", `listener-${pid}`);
68936
- fs61.mkdirSync(archiveDst, { recursive: true });
68144
+ const archiveDst = path61.join(dataDir, ".legacy", `listener-${pid}`);
68145
+ fs60.mkdirSync(archiveDst, { recursive: true });
68937
68146
  for (const file of readdirSafe(listenerSrc)) {
68938
68147
  if (!file.endsWith(".json")) continue;
68939
- fs61.renameSync(path62.join(listenerSrc, file), path62.join(archiveDst, file));
68148
+ fs60.renameSync(path61.join(listenerSrc, file), path61.join(archiveDst, file));
68940
68149
  archivedListener += 1;
68941
68150
  }
68942
68151
  rmdirIfEmpty(listenerSrc);
68943
68152
  }
68944
68153
  rmdirIfEmpty(personaDir);
68945
68154
  }
68946
- fs61.mkdirSync(sessionsDir, { recursive: true });
68947
- fs61.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
68155
+ fs60.mkdirSync(sessionsDir, { recursive: true });
68156
+ fs60.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
68948
68157
  return {
68949
68158
  skipped: false,
68950
68159
  flagWritten: true,
@@ -68955,7 +68164,7 @@ function migrateFlattenSessions(opts) {
68955
68164
  }
68956
68165
  function existsSync3(p3) {
68957
68166
  try {
68958
- fs61.statSync(p3);
68167
+ fs60.statSync(p3);
68959
68168
  return true;
68960
68169
  } catch {
68961
68170
  return false;
@@ -68963,63 +68172,63 @@ function existsSync3(p3) {
68963
68172
  }
68964
68173
  function isDir(p3) {
68965
68174
  try {
68966
- return fs61.statSync(p3).isDirectory();
68175
+ return fs60.statSync(p3).isDirectory();
68967
68176
  } catch {
68968
68177
  return false;
68969
68178
  }
68970
68179
  }
68971
68180
  function readdirSafe(p3) {
68972
68181
  try {
68973
- return fs61.readdirSync(p3);
68182
+ return fs60.readdirSync(p3);
68974
68183
  } catch {
68975
68184
  return [];
68976
68185
  }
68977
68186
  }
68978
68187
  function rmdirIfEmpty(p3) {
68979
68188
  try {
68980
- fs61.rmdirSync(p3);
68189
+ fs60.rmdirSync(p3);
68981
68190
  } catch {
68982
68191
  }
68983
68192
  }
68984
68193
 
68985
68194
  // src/migrations/2026-08-18-drop-seeded-projects.ts
68986
- var fs62 = __toESM(require("fs"), 1);
68987
- var path63 = __toESM(require("path"), 1);
68195
+ var fs61 = __toESM(require("fs"), 1);
68196
+ var path62 = __toESM(require("path"), 1);
68988
68197
  var DROP_SEEDED_PROJECTS_FLAG = ".projects-seed-dropped.v1.done";
68989
68198
  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");
68199
+ fs61.mkdirSync(opts.dataDir, { recursive: true });
68200
+ const flag = path62.join(opts.dataDir, DROP_SEEDED_PROJECTS_FLAG);
68201
+ if (fs61.existsSync(flag)) return { skipped: true, dropped: 0, backup: null };
68202
+ const file = path62.join(opts.dataDir, "projects.json");
68994
68203
  let raw = null;
68995
68204
  let dropped = 0;
68996
68205
  try {
68997
- raw = fs62.readFileSync(file, "utf8");
68206
+ raw = fs61.readFileSync(file, "utf8");
68998
68207
  dropped = JSON.parse(raw).projects?.length ?? 0;
68999
68208
  } catch {
69000
68209
  }
69001
68210
  let backup = null;
69002
68211
  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);
68212
+ const dir = path62.join(opts.dataDir, "backups");
68213
+ fs61.mkdirSync(dir, { recursive: true });
68214
+ backup = path62.join(dir, `projects.seed-dropped.${(opts.now ?? Date.now)()}.json`);
68215
+ fs61.writeFileSync(backup, raw);
69007
68216
  }
69008
68217
  if (raw != null || dropped > 0) {
69009
- fs62.writeFileSync(file, JSON.stringify({ projects: [] }, null, 2));
68218
+ fs61.writeFileSync(file, JSON.stringify({ projects: [] }, null, 2));
69010
68219
  }
69011
- fs62.writeFileSync(flag, (/* @__PURE__ */ new Date()).toISOString());
68220
+ fs61.writeFileSync(flag, (/* @__PURE__ */ new Date()).toISOString());
69012
68221
  return { skipped: false, dropped, backup };
69013
68222
  }
69014
68223
 
69015
68224
  // src/transport/http-router.ts
69016
- var import_node_fs49 = __toESM(require("fs"), 1);
69017
- var import_node_path54 = __toESM(require("path"), 1);
68225
+ var import_node_fs48 = __toESM(require("fs"), 1);
68226
+ var import_node_path53 = __toESM(require("path"), 1);
69018
68227
 
69019
68228
  // 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);
68229
+ var import_node_fs47 = __toESM(require("fs"), 1);
68230
+ var import_node_path51 = __toESM(require("path"), 1);
68231
+ var import_node_crypto16 = __toESM(require("crypto"), 1);
69023
68232
  var import_promises8 = require("stream/promises");
69024
68233
  var UploadError = class extends Error {
69025
68234
  constructor(code, message) {
@@ -69030,24 +68239,24 @@ var UploadError = class extends Error {
69030
68239
  code;
69031
68240
  };
69032
68241
  function assertValidFileName(fileName) {
69033
- if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path52.default.basename(fileName)) {
68242
+ if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path51.default.basename(fileName)) {
69034
68243
  throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
69035
68244
  }
69036
68245
  }
69037
68246
  var HASH_PREFIX_LEN = 16;
69038
68247
  async function writeUploadedAttachment(args) {
69039
68248
  assertValidFileName(args.fileName);
69040
- const attachmentsRoot = import_node_path52.default.join(args.baseDir, ".attachments");
68249
+ const attachmentsRoot = import_node_path51.default.join(args.baseDir, ".attachments");
69041
68250
  try {
69042
- import_node_fs48.default.mkdirSync(attachmentsRoot, { recursive: true });
68251
+ import_node_fs47.default.mkdirSync(attachmentsRoot, { recursive: true });
69043
68252
  } catch (err) {
69044
68253
  throw new UploadError("STORAGE_ERROR", `mkdir failed: ${err.message}`);
69045
68254
  }
69046
- const hasher = import_node_crypto18.default.createHash("sha256");
68255
+ const hasher = import_node_crypto16.default.createHash("sha256");
69047
68256
  let actualSize = 0;
69048
- const tmpPath = import_node_path52.default.join(
68257
+ const tmpPath = import_node_path51.default.join(
69049
68258
  attachmentsRoot,
69050
- `.upload-${process.pid}-${Date.now()}-${import_node_crypto18.default.randomBytes(4).toString("hex")}`
68259
+ `.upload-${process.pid}-${Date.now()}-${import_node_crypto16.default.randomBytes(4).toString("hex")}`
69051
68260
  );
69052
68261
  try {
69053
68262
  await (0, import_promises8.pipeline)(
@@ -69060,18 +68269,18 @@ async function writeUploadedAttachment(args) {
69060
68269
  yield buf;
69061
68270
  }
69062
68271
  },
69063
- import_node_fs48.default.createWriteStream(tmpPath, { mode: 384 })
68272
+ import_node_fs47.default.createWriteStream(tmpPath, { mode: 384 })
69064
68273
  );
69065
68274
  } catch (err) {
69066
68275
  try {
69067
- import_node_fs48.default.unlinkSync(tmpPath);
68276
+ import_node_fs47.default.unlinkSync(tmpPath);
69068
68277
  } catch {
69069
68278
  }
69070
68279
  throw new UploadError("STORAGE_ERROR", `write failed: ${err.message}`);
69071
68280
  }
69072
68281
  if (actualSize !== args.contentLength) {
69073
68282
  try {
69074
- import_node_fs48.default.unlinkSync(tmpPath);
68283
+ import_node_fs47.default.unlinkSync(tmpPath);
69075
68284
  } catch {
69076
68285
  }
69077
68286
  throw new UploadError(
@@ -69080,34 +68289,34 @@ async function writeUploadedAttachment(args) {
69080
68289
  );
69081
68290
  }
69082
68291
  const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
69083
- const hashDir = import_node_path52.default.join(attachmentsRoot, attachmentId);
68292
+ const hashDir = import_node_path51.default.join(attachmentsRoot, attachmentId);
69084
68293
  let finalFileName;
69085
68294
  let hashDirExists = false;
69086
68295
  try {
69087
- hashDirExists = import_node_fs48.default.statSync(hashDir).isDirectory();
68296
+ hashDirExists = import_node_fs47.default.statSync(hashDir).isDirectory();
69088
68297
  } catch {
69089
68298
  }
69090
68299
  if (hashDirExists) {
69091
- const existing = import_node_fs48.default.readdirSync(hashDir).filter((n2) => !n2.startsWith("."));
68300
+ const existing = import_node_fs47.default.readdirSync(hashDir).filter((n2) => !n2.startsWith("."));
69092
68301
  finalFileName = existing[0] ?? args.fileName;
69093
68302
  try {
69094
- import_node_fs48.default.unlinkSync(tmpPath);
68303
+ import_node_fs47.default.unlinkSync(tmpPath);
69095
68304
  } catch {
69096
68305
  }
69097
68306
  } else {
69098
68307
  try {
69099
- import_node_fs48.default.mkdirSync(hashDir, { recursive: true });
68308
+ import_node_fs47.default.mkdirSync(hashDir, { recursive: true });
69100
68309
  finalFileName = args.fileName;
69101
- import_node_fs48.default.renameSync(tmpPath, import_node_path52.default.join(hashDir, finalFileName));
68310
+ import_node_fs47.default.renameSync(tmpPath, import_node_path51.default.join(hashDir, finalFileName));
69102
68311
  } catch (err) {
69103
68312
  try {
69104
- import_node_fs48.default.unlinkSync(tmpPath);
68313
+ import_node_fs47.default.unlinkSync(tmpPath);
69105
68314
  } catch {
69106
68315
  }
69107
68316
  throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
69108
68317
  }
69109
68318
  }
69110
- const absPath = import_node_path52.default.join(hashDir, finalFileName);
68319
+ const absPath = import_node_path51.default.join(hashDir, finalFileName);
69111
68320
  const relPath = absPath;
69112
68321
  args.groupFileStore.upsert(args.scope, args.sessionId, {
69113
68322
  relPath: absPath,
@@ -69122,7 +68331,7 @@ async function writeUploadedAttachment(args) {
69122
68331
 
69123
68332
  // src/extension/import.ts
69124
68333
  var import_promises9 = __toESM(require("fs/promises"), 1);
69125
- var import_node_path53 = __toESM(require("path"), 1);
68334
+ var import_node_path52 = __toESM(require("path"), 1);
69126
68335
  var import_node_os20 = __toESM(require("os"), 1);
69127
68336
  var import_jszip = __toESM(require_lib3(), 1);
69128
68337
  var ImportError = class extends Error {
@@ -69140,7 +68349,7 @@ async function importZip(buf, root) {
69140
68349
  throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
69141
68350
  }
69142
68351
  for (const name of Object.keys(zip.files)) {
69143
- if (name.includes("..") || name.startsWith("/") || import_node_path53.default.isAbsolute(name)) {
68352
+ if (name.includes("..") || name.startsWith("/") || import_node_path52.default.isAbsolute(name)) {
69144
68353
  throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
69145
68354
  }
69146
68355
  }
@@ -69173,7 +68382,7 @@ async function importZip(buf, root) {
69173
68382
  );
69174
68383
  }
69175
68384
  }
69176
- const destDir = import_node_path53.default.join(root, manifest.id);
68385
+ const destDir = import_node_path52.default.join(root, manifest.id);
69177
68386
  let destExists = false;
69178
68387
  try {
69179
68388
  await import_promises9.default.access(destDir);
@@ -69183,15 +68392,15 @@ async function importZip(buf, root) {
69183
68392
  if (destExists) {
69184
68393
  throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
69185
68394
  }
69186
- const stage = await import_promises9.default.mkdtemp(import_node_path53.default.join(import_node_os20.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
68395
+ const stage = await import_promises9.default.mkdtemp(import_node_path52.default.join(import_node_os20.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
69187
68396
  try {
69188
68397
  for (const [name, entry] of Object.entries(zip.files)) {
69189
- const dest = import_node_path53.default.join(stage, name);
68398
+ const dest = import_node_path52.default.join(stage, name);
69190
68399
  if (entry.dir) {
69191
68400
  await import_promises9.default.mkdir(dest, { recursive: true });
69192
68401
  continue;
69193
68402
  }
69194
- await import_promises9.default.mkdir(import_node_path53.default.dirname(dest), { recursive: true });
68403
+ await import_promises9.default.mkdir(import_node_path52.default.dirname(dest), { recursive: true });
69195
68404
  const content = await entry.async("nodebuffer");
69196
68405
  await import_promises9.default.writeFile(dest, content);
69197
68406
  }
@@ -69245,7 +68454,7 @@ var SHARE_UI_ASSET_MIME = {
69245
68454
  ".wasm": "application/wasm"
69246
68455
  };
69247
68456
  function shareUiAssetMime(filePath) {
69248
- const ext = import_node_path54.default.extname(filePath).toLowerCase();
68457
+ const ext = import_node_path53.default.extname(filePath).toLowerCase();
69249
68458
  return SHARE_UI_ASSET_MIME[ext] ?? lookupMime(filePath);
69250
68459
  }
69251
68460
  var AUTHED_RPC_ROUTE_PREFIX = "/rpc/";
@@ -69344,7 +68553,7 @@ function isValidUploadFileName(fileName) {
69344
68553
  if (fileName === "." || fileName === "..") return false;
69345
68554
  if (fileName.startsWith(".")) return false;
69346
68555
  if (fileName.includes("/") || fileName.includes("\\")) return false;
69347
- return fileName === import_node_path54.default.basename(fileName);
68556
+ return fileName === import_node_path53.default.basename(fileName);
69348
68557
  }
69349
68558
  function createHttpRouter(deps) {
69350
68559
  return async (req, res) => {
@@ -69428,7 +68637,7 @@ function createHttpRouter(deps) {
69428
68637
  }
69429
68638
  let buf;
69430
68639
  try {
69431
- buf = await import_node_fs49.default.promises.readFile(abs);
68640
+ buf = await import_node_fs48.default.promises.readFile(abs);
69432
68641
  } catch {
69433
68642
  sendJson2(res, 404, { code: "NOT_FOUND", message: "asset not found" });
69434
68643
  return true;
@@ -69574,7 +68783,7 @@ function createHttpRouter(deps) {
69574
68783
  sendHtml(res, statusByCode[r2.code], loader.renderErrorHtml(r2.code, msgByCode[r2.code]));
69575
68784
  return true;
69576
68785
  }
69577
- sendHtml(res, 200, loader.renderViewerHtml(import_node_path54.default.basename(r2.absPath)));
68786
+ sendHtml(res, 200, loader.renderViewerHtml(import_node_path53.default.basename(r2.absPath)));
69578
68787
  return true;
69579
68788
  }
69580
68789
  const ctx = deps.authResolver.resolveFromHeader(
@@ -69695,7 +68904,7 @@ function createHttpRouter(deps) {
69695
68904
  return true;
69696
68905
  }
69697
68906
  let absPath;
69698
- if (import_node_path54.default.isAbsolute(pathParam)) {
68907
+ if (import_node_path53.default.isAbsolute(pathParam)) {
69699
68908
  absPath = pathParam;
69700
68909
  } else if (deps.sessionStore) {
69701
68910
  const file = deps.sessionStore.read(sid);
@@ -69703,7 +68912,7 @@ function createHttpRouter(deps) {
69703
68912
  sendJson2(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
69704
68913
  return true;
69705
68914
  }
69706
- absPath = import_node_path54.default.join(file.cwd, pathParam);
68915
+ absPath = import_node_path53.default.join(file.cwd, pathParam);
69707
68916
  } else {
69708
68917
  sendJson2(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
69709
68918
  return true;
@@ -69787,7 +68996,7 @@ function withCtx(ctx, body) {
69787
68996
  function streamFile(res, absPath, logger) {
69788
68997
  let stat;
69789
68998
  try {
69790
- stat = import_node_fs49.default.statSync(absPath);
68999
+ stat = import_node_fs48.default.statSync(absPath);
69791
69000
  } catch (err) {
69792
69001
  const code = err?.code;
69793
69002
  if (code === "ENOENT") {
@@ -69802,7 +69011,7 @@ function streamFile(res, absPath, logger) {
69802
69011
  return;
69803
69012
  }
69804
69013
  const mime = lookupMime(absPath);
69805
- const basename2 = import_node_path54.default.basename(absPath);
69014
+ const basename2 = import_node_path53.default.basename(absPath);
69806
69015
  res.writeHead(200, {
69807
69016
  "Content-Type": mime,
69808
69017
  "Content-Length": String(stat.size),
@@ -69810,7 +69019,7 @@ function streamFile(res, absPath, logger) {
69810
69019
  // 防止浏览器把任意 mime 当 html 渲染
69811
69020
  "X-Content-Type-Options": "nosniff"
69812
69021
  });
69813
- const stream = import_node_fs49.default.createReadStream(absPath);
69022
+ const stream = import_node_fs48.default.createReadStream(absPath);
69814
69023
  stream.on("error", (err) => {
69815
69024
  logger?.warn("streamFile read error", { absPath, err: err.message });
69816
69025
  res.destroy();
@@ -69819,8 +69028,8 @@ function streamFile(res, absPath, logger) {
69819
69028
  }
69820
69029
 
69821
69030
  // src/attachment/gc.ts
69822
- var import_node_fs50 = __toESM(require("fs"), 1);
69823
- var import_node_path55 = __toESM(require("path"), 1);
69031
+ var import_node_fs49 = __toESM(require("fs"), 1);
69032
+ var import_node_path54 = __toESM(require("path"), 1);
69824
69033
  var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
69825
69034
  function runAttachmentGc(args) {
69826
69035
  const now = (args.now ?? Date.now)();
@@ -69829,12 +69038,12 @@ function runAttachmentGc(args) {
69829
69038
  for (const { scope, sessionId } of args.sessionScopes) {
69830
69039
  for (const entry of args.groupFileStore.list(scope, sessionId)) {
69831
69040
  if (entry.stale) continue;
69832
- if (import_node_path55.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
69041
+ if (import_node_path54.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
69833
69042
  }
69834
69043
  }
69835
69044
  const visited = /* @__PURE__ */ new Set();
69836
69045
  for (const { scope, sessionId } of args.sessionScopes) {
69837
- const legacyDir = args.getSessionCwd?.(sessionId) ?? import_node_path55.default.join(
69046
+ const legacyDir = args.getSessionCwd?.(sessionId) ?? import_node_path54.default.join(
69838
69047
  args.dataDir,
69839
69048
  "sessions",
69840
69049
  ...scopeSubPath(scope).map(safeFileName),
@@ -69847,28 +69056,28 @@ function runAttachmentGc(args) {
69847
69056
  return true;
69848
69057
  });
69849
69058
  for (const rootDir of roots) {
69850
- const attRoot = import_node_path55.default.join(rootDir, ".attachments");
69059
+ const attRoot = import_node_path54.default.join(rootDir, ".attachments");
69851
69060
  let hashDirs;
69852
69061
  try {
69853
- hashDirs = import_node_fs50.default.readdirSync(attRoot);
69062
+ hashDirs = import_node_fs49.default.readdirSync(attRoot);
69854
69063
  } catch (err) {
69855
69064
  if (err.code === "ENOENT") continue;
69856
69065
  args.logger?.warn("attachment gc: readdir failed", { attRoot, err: err.message });
69857
69066
  continue;
69858
69067
  }
69859
69068
  for (const hashDir of hashDirs) {
69860
- const hashDirAbs = import_node_path55.default.join(attRoot, hashDir);
69069
+ const hashDirAbs = import_node_path54.default.join(attRoot, hashDir);
69861
69070
  let files;
69862
69071
  try {
69863
- files = import_node_fs50.default.readdirSync(hashDirAbs);
69072
+ files = import_node_fs49.default.readdirSync(hashDirAbs);
69864
69073
  } catch {
69865
69074
  continue;
69866
69075
  }
69867
69076
  for (const name of files) {
69868
- const file = import_node_path55.default.join(hashDirAbs, name);
69077
+ const file = import_node_path54.default.join(hashDirAbs, name);
69869
69078
  let stat;
69870
69079
  try {
69871
- stat = import_node_fs50.default.statSync(file);
69080
+ stat = import_node_fs49.default.statSync(file);
69872
69081
  } catch {
69873
69082
  continue;
69874
69083
  }
@@ -69877,18 +69086,18 @@ function runAttachmentGc(args) {
69877
69086
  if (age < ttlMs) continue;
69878
69087
  if (liveAbs.has(file)) continue;
69879
69088
  try {
69880
- import_node_fs50.default.unlinkSync(file);
69089
+ import_node_fs49.default.unlinkSync(file);
69881
69090
  } catch (err) {
69882
69091
  args.logger?.warn("attachment gc: unlink failed", { file, err: err.message });
69883
69092
  }
69884
69093
  }
69885
69094
  try {
69886
- if (import_node_fs50.default.readdirSync(hashDirAbs).length === 0) import_node_fs50.default.rmdirSync(hashDirAbs);
69095
+ if (import_node_fs49.default.readdirSync(hashDirAbs).length === 0) import_node_fs49.default.rmdirSync(hashDirAbs);
69887
69096
  } catch {
69888
69097
  }
69889
69098
  }
69890
69099
  try {
69891
- if (import_node_fs50.default.readdirSync(attRoot).length === 0) import_node_fs50.default.rmdirSync(attRoot);
69100
+ if (import_node_fs49.default.readdirSync(attRoot).length === 0) import_node_fs49.default.rmdirSync(attRoot);
69892
69101
  } catch {
69893
69102
  }
69894
69103
  }
@@ -69896,9 +69105,9 @@ function runAttachmentGc(args) {
69896
69105
  }
69897
69106
 
69898
69107
  // 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);
69108
+ var import_node_fs50 = __toESM(require("fs"), 1);
69109
+ var import_node_path55 = __toESM(require("path"), 1);
69110
+ var import_node_crypto17 = __toESM(require("crypto"), 1);
69902
69111
  init_protocol();
69903
69112
  var GroupFileStore = class {
69904
69113
  dataDir;
@@ -69909,11 +69118,11 @@ var GroupFileStore = class {
69909
69118
  this.logger = opts.logger;
69910
69119
  }
69911
69120
  rootForScope(scope) {
69912
- return import_node_path56.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
69121
+ return import_node_path55.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
69913
69122
  }
69914
69123
  /** 与 SessionStore.filePath 平级,扩展名 .group-files.json */
69915
69124
  filePath(scope, sessionId) {
69916
- return import_node_path56.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
69125
+ return import_node_path55.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
69917
69126
  }
69918
69127
  cacheKey(scope, sessionId) {
69919
69128
  return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
@@ -69922,7 +69131,7 @@ var GroupFileStore = class {
69922
69131
  readFile(scope, sessionId) {
69923
69132
  const file = this.filePath(scope, sessionId);
69924
69133
  try {
69925
- const raw = import_node_fs51.default.readFileSync(file, "utf8");
69134
+ const raw = import_node_fs50.default.readFileSync(file, "utf8");
69926
69135
  const parsed = JSON.parse(raw);
69927
69136
  if (!Array.isArray(parsed)) {
69928
69137
  this.logger?.warn("GroupFileStore.readFile: not an array; resetting session entries", {
@@ -69948,10 +69157,10 @@ var GroupFileStore = class {
69948
69157
  }
69949
69158
  writeFile(scope, sessionId, entries) {
69950
69159
  const file = this.filePath(scope, sessionId);
69951
- import_node_fs51.default.mkdirSync(import_node_path56.default.dirname(file), { recursive: true });
69160
+ import_node_fs50.default.mkdirSync(import_node_path55.default.dirname(file), { recursive: true });
69952
69161
  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);
69162
+ import_node_fs50.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
69163
+ import_node_fs50.default.renameSync(tmp, file);
69955
69164
  }
69956
69165
  /** 拉一份当前 session 的清单。读盘 → cache;之后调用复用 cache */
69957
69166
  list(scope, sessionId) {
@@ -69987,7 +69196,7 @@ var GroupFileStore = class {
69987
69196
  entries[idx] = next;
69988
69197
  } else {
69989
69198
  next = {
69990
- id: `gf-${import_node_crypto19.default.randomBytes(6).toString("base64url")}`,
69199
+ id: `gf-${import_node_crypto17.default.randomBytes(6).toString("base64url")}`,
69991
69200
  relPath: input.relPath,
69992
69201
  from: input.from,
69993
69202
  label: input.label,
@@ -70043,7 +69252,7 @@ var GroupFileStore = class {
70043
69252
  */
70044
69253
  deleteSession(scope, sessionId) {
70045
69254
  try {
70046
- import_node_fs51.default.unlinkSync(this.filePath(scope, sessionId));
69255
+ import_node_fs50.default.unlinkSync(this.filePath(scope, sessionId));
70047
69256
  } catch (err) {
70048
69257
  if (err?.code !== "ENOENT") throw err;
70049
69258
  }
@@ -70056,7 +69265,7 @@ var GroupFileStore = class {
70056
69265
  * 不在 persona 目录里(见文件头的路径约定)。没树的 persona 是 noop。
70057
69266
  */
70058
69267
  deletePersona(personaId2) {
70059
- import_node_fs51.default.rmSync(import_node_path56.default.join(this.dataDir, "sessions", safeFileName(personaId2)), { recursive: true, force: true });
69268
+ import_node_fs50.default.rmSync(import_node_path55.default.join(this.dataDir, "sessions", safeFileName(personaId2)), { recursive: true, force: true });
70060
69269
  const prefix = `persona:${personaId2}:`;
70061
69270
  for (const key of this.cache.keys()) {
70062
69271
  if (key.startsWith(prefix)) this.cache.delete(key);
@@ -70065,10 +69274,10 @@ var GroupFileStore = class {
70065
69274
  };
70066
69275
 
70067
69276
  // src/discovery/state-file.ts
70068
- var import_node_fs52 = __toESM(require("fs"), 1);
70069
- var import_node_path57 = __toESM(require("path"), 1);
69277
+ var import_node_fs51 = __toESM(require("fs"), 1);
69278
+ var import_node_path56 = __toESM(require("path"), 1);
70070
69279
  function defaultStateFilePath(dataDir) {
70071
- return import_node_path57.default.join(dataDir, "state.json");
69280
+ return import_node_path56.default.join(dataDir, "state.json");
70072
69281
  }
70073
69282
  function isPidAlive(pid) {
70074
69283
  if (!Number.isFinite(pid) || pid <= 0) return false;
@@ -70090,7 +69299,7 @@ var StateFileManager = class {
70090
69299
  }
70091
69300
  read() {
70092
69301
  try {
70093
- const raw = import_node_fs52.default.readFileSync(this.file, "utf8");
69302
+ const raw = import_node_fs51.default.readFileSync(this.file, "utf8");
70094
69303
  const parsed = JSON.parse(raw);
70095
69304
  return parsed;
70096
69305
  } catch {
@@ -70104,20 +69313,20 @@ var StateFileManager = class {
70104
69313
  return { status: "stale", existing };
70105
69314
  }
70106
69315
  write(state) {
70107
- import_node_fs52.default.mkdirSync(import_node_path57.default.dirname(this.file), { recursive: true });
69316
+ import_node_fs51.default.mkdirSync(import_node_path56.default.dirname(this.file), { recursive: true });
70108
69317
  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);
69318
+ import_node_fs51.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
69319
+ import_node_fs51.default.renameSync(tmp, this.file);
70111
69320
  if (process.platform !== "win32") {
70112
69321
  try {
70113
- import_node_fs52.default.chmodSync(this.file, 384);
69322
+ import_node_fs51.default.chmodSync(this.file, 384);
70114
69323
  } catch {
70115
69324
  }
70116
69325
  }
70117
69326
  }
70118
69327
  delete() {
70119
69328
  try {
70120
- import_node_fs52.default.unlinkSync(this.file);
69329
+ import_node_fs51.default.unlinkSync(this.file);
70121
69330
  } catch {
70122
69331
  }
70123
69332
  }
@@ -70131,14 +69340,14 @@ function readSpawnedByDesktopFromEnv(env = process.env) {
70131
69340
  }
70132
69341
 
70133
69342
  // 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);
69343
+ var import_node_fs55 = __toESM(require("fs"), 1);
69344
+ var import_node_path60 = __toESM(require("path"), 1);
69345
+ var import_node_crypto18 = __toESM(require("crypto"), 1);
70137
69346
  var import_node_child_process16 = require("child_process");
70138
69347
 
70139
69348
  // src/tunnel/tunnel-store.ts
70140
- var import_node_fs53 = __toESM(require("fs"), 1);
70141
- var import_node_path58 = __toESM(require("path"), 1);
69349
+ var import_node_fs52 = __toESM(require("fs"), 1);
69350
+ var import_node_path57 = __toESM(require("path"), 1);
70142
69351
  var TunnelStore = class {
70143
69352
  constructor(filePath) {
70144
69353
  this.filePath = filePath;
@@ -70146,7 +69355,7 @@ var TunnelStore = class {
70146
69355
  filePath;
70147
69356
  async get() {
70148
69357
  try {
70149
- const raw = await import_node_fs53.default.promises.readFile(this.filePath, "utf8");
69358
+ const raw = await import_node_fs52.default.promises.readFile(this.filePath, "utf8");
70150
69359
  const obj = JSON.parse(raw);
70151
69360
  if (!isPersistedTunnel(obj)) return null;
70152
69361
  return obj;
@@ -70157,22 +69366,22 @@ var TunnelStore = class {
70157
69366
  }
70158
69367
  }
70159
69368
  async set(v3) {
70160
- const dir = import_node_path58.default.dirname(this.filePath);
70161
- await import_node_fs53.default.promises.mkdir(dir, { recursive: true });
69369
+ const dir = import_node_path57.default.dirname(this.filePath);
69370
+ await import_node_fs52.default.promises.mkdir(dir, { recursive: true });
70162
69371
  const data = JSON.stringify(v3, null, 2);
70163
69372
  const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
70164
- await import_node_fs53.default.promises.writeFile(tmp, data, { mode: 384 });
69373
+ await import_node_fs52.default.promises.writeFile(tmp, data, { mode: 384 });
70165
69374
  if (process.platform !== "win32") {
70166
69375
  try {
70167
- await import_node_fs53.default.promises.chmod(tmp, 384);
69376
+ await import_node_fs52.default.promises.chmod(tmp, 384);
70168
69377
  } catch {
70169
69378
  }
70170
69379
  }
70171
- await import_node_fs53.default.promises.rename(tmp, this.filePath);
69380
+ await import_node_fs52.default.promises.rename(tmp, this.filePath);
70172
69381
  }
70173
69382
  async clear() {
70174
69383
  try {
70175
- await import_node_fs53.default.promises.unlink(this.filePath);
69384
+ await import_node_fs52.default.promises.unlink(this.filePath);
70176
69385
  } catch (err) {
70177
69386
  const code = err?.code;
70178
69387
  if (code !== "ENOENT") throw err;
@@ -70267,9 +69476,9 @@ function escape2(v3) {
70267
69476
  }
70268
69477
 
70269
69478
  // src/tunnel/frpc-binary.ts
70270
- var import_node_fs54 = __toESM(require("fs"), 1);
69479
+ var import_node_fs53 = __toESM(require("fs"), 1);
70271
69480
  var import_node_os21 = __toESM(require("os"), 1);
70272
- var import_node_path59 = __toESM(require("path"), 1);
69481
+ var import_node_path58 = __toESM(require("path"), 1);
70273
69482
  var import_node_child_process14 = require("child_process");
70274
69483
  var import_node_stream4 = require("stream");
70275
69484
  var import_promises10 = require("stream/promises");
@@ -70301,20 +69510,20 @@ function frpcDownloadUrl(version2, p3) {
70301
69510
  }
70302
69511
  async function ensureFrpcBinary(opts) {
70303
69512
  if (opts.override) {
70304
- if (!import_node_fs54.default.existsSync(opts.override)) {
69513
+ if (!import_node_fs53.default.existsSync(opts.override)) {
70305
69514
  throw new Error(`frpc binary not found at override path: ${opts.override}`);
70306
69515
  }
70307
69516
  return opts.override;
70308
69517
  }
70309
69518
  const version2 = opts.version ?? FRPC_VERSION;
70310
69519
  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 });
69520
+ const binDir = import_node_path58.default.join(opts.dataDir, "bin");
69521
+ import_node_fs53.default.mkdirSync(binDir, { recursive: true });
70313
69522
  cleanupStaleArtifacts(binDir);
70314
- const stableBin = import_node_path59.default.join(binDir, "frpc");
70315
- if (import_node_fs54.default.existsSync(stableBin)) return stableBin;
69523
+ const stableBin = import_node_path58.default.join(binDir, "frpc");
69524
+ if (import_node_fs53.default.existsSync(stableBin)) return stableBin;
70316
69525
  const partialBin = `${stableBin}.partial`;
70317
- const tarballPath = import_node_path59.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
69526
+ const tarballPath = import_node_path58.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
70318
69527
  try {
70319
69528
  const url = frpcDownloadUrl(version2, platform);
70320
69529
  await downloadToFile(url, tarballPath, opts.fetchImpl);
@@ -70323,8 +69532,8 @@ async function ensureFrpcBinary(opts) {
70323
69532
  } else {
70324
69533
  await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
70325
69534
  }
70326
- import_node_fs54.default.chmodSync(partialBin, 493);
70327
- import_node_fs54.default.renameSync(partialBin, stableBin);
69535
+ import_node_fs53.default.chmodSync(partialBin, 493);
69536
+ import_node_fs53.default.renameSync(partialBin, stableBin);
70328
69537
  } finally {
70329
69538
  safeUnlink(tarballPath);
70330
69539
  safeUnlink(partialBin);
@@ -70334,15 +69543,15 @@ async function ensureFrpcBinary(opts) {
70334
69543
  function cleanupStaleArtifacts(binDir) {
70335
69544
  let entries;
70336
69545
  try {
70337
- entries = import_node_fs54.default.readdirSync(binDir);
69546
+ entries = import_node_fs53.default.readdirSync(binDir);
70338
69547
  } catch {
70339
69548
  return;
70340
69549
  }
70341
69550
  for (const name of entries) {
70342
69551
  if (name.endsWith(".partial") || name.startsWith("extract-")) {
70343
- const full = import_node_path59.default.join(binDir, name);
69552
+ const full = import_node_path58.default.join(binDir, name);
70344
69553
  try {
70345
- import_node_fs54.default.rmSync(full, { recursive: true, force: true });
69554
+ import_node_fs53.default.rmSync(full, { recursive: true, force: true });
70346
69555
  } catch {
70347
69556
  }
70348
69557
  }
@@ -70350,7 +69559,7 @@ function cleanupStaleArtifacts(binDir) {
70350
69559
  }
70351
69560
  function safeUnlink(p3) {
70352
69561
  try {
70353
- import_node_fs54.default.unlinkSync(p3);
69562
+ import_node_fs53.default.unlinkSync(p3);
70354
69563
  } catch {
70355
69564
  }
70356
69565
  }
@@ -70361,13 +69570,13 @@ async function downloadToFile(url, dest, fetchImpl) {
70361
69570
  if (!res.ok || !res.body) {
70362
69571
  throw new Error(`download failed: ${res.status} ${res.statusText}`);
70363
69572
  }
70364
- const out = import_node_fs54.default.createWriteStream(dest);
69573
+ const out = import_node_fs53.default.createWriteStream(dest);
70365
69574
  const nodeStream = import_node_stream4.Readable.fromWeb(res.body);
70366
69575
  await (0, import_promises10.pipeline)(nodeStream, out);
70367
69576
  }
70368
69577
  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 });
69578
+ const work = import_node_path58.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
69579
+ import_node_fs53.default.mkdirSync(work, { recursive: true });
70371
69580
  try {
70372
69581
  await new Promise((resolve9, reject) => {
70373
69582
  const proc = (0, import_node_child_process14.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
@@ -70375,32 +69584,32 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
70375
69584
  proc.on("exit", (code) => code === 0 ? resolve9() : reject(new Error(`tar exited ${code}`)));
70376
69585
  });
70377
69586
  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)) {
69587
+ const src = import_node_path58.default.join(work, dirName, "frpc");
69588
+ if (!import_node_fs53.default.existsSync(src)) {
70380
69589
  throw new Error(`frpc not found inside tarball at ${src}`);
70381
69590
  }
70382
- import_node_fs54.default.copyFileSync(src, destBin);
69591
+ import_node_fs53.default.copyFileSync(src, destBin);
70383
69592
  } finally {
70384
- import_node_fs54.default.rmSync(work, { recursive: true, force: true });
69593
+ import_node_fs53.default.rmSync(work, { recursive: true, force: true });
70385
69594
  }
70386
69595
  }
70387
69596
 
70388
69597
  // src/tunnel/frpc-process.ts
70389
- var import_node_fs55 = __toESM(require("fs"), 1);
70390
- var import_node_path60 = __toESM(require("path"), 1);
69598
+ var import_node_fs54 = __toESM(require("fs"), 1);
69599
+ var import_node_path59 = __toESM(require("path"), 1);
70391
69600
  var import_node_child_process15 = require("child_process");
70392
69601
  function frpcPidFilePath(dataDir) {
70393
- return import_node_path60.default.join(dataDir, "frpc.pid");
69602
+ return import_node_path59.default.join(dataDir, "frpc.pid");
70394
69603
  }
70395
69604
  function writeFrpcPid(dataDir, pid) {
70396
69605
  try {
70397
- import_node_fs55.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
69606
+ import_node_fs54.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
70398
69607
  } catch {
70399
69608
  }
70400
69609
  }
70401
69610
  function clearFrpcPid(dataDir) {
70402
69611
  try {
70403
- import_node_fs55.default.unlinkSync(frpcPidFilePath(dataDir));
69612
+ import_node_fs54.default.unlinkSync(frpcPidFilePath(dataDir));
70404
69613
  } catch {
70405
69614
  }
70406
69615
  }
@@ -70416,7 +69625,7 @@ function defaultIsPidAlive(pid) {
70416
69625
  }
70417
69626
  function defaultReadPidFile(file) {
70418
69627
  try {
70419
- return import_node_fs55.default.readFileSync(file, "utf8");
69628
+ return import_node_fs54.default.readFileSync(file, "utf8");
70420
69629
  } catch {
70421
69630
  return null;
70422
69631
  }
@@ -70432,7 +69641,7 @@ function defaultSleep2(ms) {
70432
69641
  }
70433
69642
  async function killStaleFrpc(deps) {
70434
69643
  const pidFile = frpcPidFilePath(deps.dataDir);
70435
- const tomlPath = import_node_path60.default.join(deps.dataDir, "frpc.toml");
69644
+ const tomlPath = import_node_path59.default.join(deps.dataDir, "frpc.toml");
70436
69645
  const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
70437
69646
  const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
70438
69647
  const killPid = deps.killPidImpl ?? defaultKillPid;
@@ -70456,7 +69665,7 @@ async function killStaleFrpc(deps) {
70456
69665
  }
70457
69666
  if (victims.size === 0) {
70458
69667
  try {
70459
- import_node_fs55.default.unlinkSync(pidFile);
69668
+ import_node_fs54.default.unlinkSync(pidFile);
70460
69669
  } catch {
70461
69670
  }
70462
69671
  return;
@@ -70467,7 +69676,7 @@ async function killStaleFrpc(deps) {
70467
69676
  }
70468
69677
  await sleep2(deps.reapWaitMs ?? 300);
70469
69678
  try {
70470
- import_node_fs55.default.unlinkSync(pidFile);
69679
+ import_node_fs54.default.unlinkSync(pidFile);
70471
69680
  } catch {
70472
69681
  }
70473
69682
  }
@@ -70504,7 +69713,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
70504
69713
  var TunnelManager = class {
70505
69714
  constructor(deps) {
70506
69715
  this.deps = deps;
70507
- this.store = deps.store ?? new TunnelStore(import_node_path61.default.join(deps.dataDir, "tunnel.json"));
69716
+ this.store = deps.store ?? new TunnelStore(import_node_path60.default.join(deps.dataDir, "tunnel.json"));
70508
69717
  this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
70509
69718
  this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
70510
69719
  }
@@ -70631,8 +69840,8 @@ var TunnelManager = class {
70631
69840
  dataDir: this.deps.dataDir,
70632
69841
  override: this.deps.frpcBinaryOverride ?? void 0
70633
69842
  });
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")}`;
69843
+ const tomlPath = import_node_path60.default.join(this.deps.dataDir, "frpc.toml");
69844
+ const proxyName = `clawd-${t2.subdomain}-${localPort}-${import_node_crypto18.default.randomBytes(3).toString("hex")}`;
70636
69845
  const toml = buildFrpcToml({
70637
69846
  serverAddr: t2.frpsHost,
70638
69847
  serverPort: t2.frpsPort,
@@ -70642,14 +69851,14 @@ var TunnelManager = class {
70642
69851
  localPort,
70643
69852
  logLevel: "info"
70644
69853
  });
70645
- await import_node_fs56.default.promises.writeFile(tomlPath, toml, { mode: 384 });
69854
+ await import_node_fs55.default.promises.writeFile(tomlPath, toml, { mode: 384 });
70646
69855
  const proc = (this.deps.spawnImpl ?? import_node_child_process16.spawn)(frpcBin, ["-c", tomlPath], {
70647
69856
  stdio: ["ignore", "pipe", "pipe"]
70648
69857
  });
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 });
69858
+ const logDir = import_node_path60.default.join(this.deps.dataDir, "log");
69859
+ import_node_fs55.default.mkdirSync(logDir, { recursive: true });
69860
+ const logFilePath = import_node_path60.default.join(logDir, "frpc.log");
69861
+ const logStream = import_node_fs55.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
70653
69862
  logStream.on("error", () => {
70654
69863
  });
70655
69864
  const tee = (chunk) => {
@@ -70732,27 +69941,27 @@ async function waitForFrpcReady(proc, timeoutMs) {
70732
69941
 
70733
69942
  // src/tunnel/device-key.ts
70734
69943
  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);
69944
+ var import_node_path61 = __toESM(require("path"), 1);
69945
+ var import_node_crypto19 = __toESM(require("crypto"), 1);
70737
69946
  var DERIVE_SALT = "clawd-tunnel-device-v1";
70738
69947
  function deriveStableDeviceKey(opts = {}) {
70739
69948
  const hostname = opts.hostname ?? import_node_os22.default.hostname();
70740
69949
  const uid = opts.uid ?? (typeof import_node_os22.default.userInfo === "function" ? import_node_os22.default.userInfo().uid : 0);
70741
69950
  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;
69951
+ const defaultDataDir = import_node_path61.default.resolve(import_node_path61.default.join(home, ".clawd"));
69952
+ const normalizedDataDir = opts.dataDir ? import_node_path61.default.resolve(opts.dataDir) : null;
70744
69953
  const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
70745
69954
  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);
69955
+ return import_node_crypto19.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
70747
69956
  }
70748
69957
 
70749
69958
  // 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);
69959
+ var import_node_fs56 = __toESM(require("fs"), 1);
69960
+ var import_node_path62 = __toESM(require("path"), 1);
69961
+ var import_node_crypto20 = __toESM(require("crypto"), 1);
70753
69962
  var AUTH_FILE_NAME = "auth.json";
70754
69963
  function authFilePath(dataDir) {
70755
- return import_node_path63.default.join(dataDir, AUTH_FILE_NAME);
69964
+ return import_node_path62.default.join(dataDir, AUTH_FILE_NAME);
70756
69965
  }
70757
69966
  function loadOrCreateAuthFile(opts) {
70758
69967
  const file = authFilePath(opts.dataDir);
@@ -70786,14 +69995,14 @@ function loadOrCreateTunnelDeviceKey(opts) {
70786
69995
  return tunnelDeviceKey;
70787
69996
  }
70788
69997
  function defaultGenerateToken() {
70789
- return import_node_crypto22.default.randomBytes(32).toString("base64url");
69998
+ return import_node_crypto20.default.randomBytes(32).toString("base64url");
70790
69999
  }
70791
70000
  function defaultGenerateOwnerPrincipalId() {
70792
- return `owner-${import_node_crypto22.default.randomUUID()}`;
70001
+ return `owner-${import_node_crypto20.default.randomUUID()}`;
70793
70002
  }
70794
70003
  function readAuthFile(file) {
70795
70004
  try {
70796
- const raw = import_node_fs57.default.readFileSync(file, "utf8");
70005
+ const raw = import_node_fs56.default.readFileSync(file, "utf8");
70797
70006
  const parsed = JSON.parse(raw);
70798
70007
  if (typeof parsed?.token !== "string" || parsed.token.length === 0) {
70799
70008
  return null;
@@ -70814,26 +70023,26 @@ function readAuthFile(file) {
70814
70023
  }
70815
70024
  }
70816
70025
  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 });
70026
+ import_node_fs56.default.mkdirSync(import_node_path62.default.dirname(file), { recursive: true });
70027
+ import_node_fs56.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
70819
70028
  try {
70820
- import_node_fs57.default.chmodSync(file, 384);
70029
+ import_node_fs56.default.chmodSync(file, 384);
70821
70030
  } catch {
70822
70031
  }
70823
70032
  }
70824
70033
 
70825
70034
  // src/owner-profile.ts
70826
- var import_node_fs58 = __toESM(require("fs"), 1);
70035
+ var import_node_fs57 = __toESM(require("fs"), 1);
70827
70036
  var import_node_os23 = __toESM(require("os"), 1);
70828
- var import_node_path64 = __toESM(require("path"), 1);
70037
+ var import_node_path63 = __toESM(require("path"), 1);
70829
70038
  var PROFILE_FILENAME = "profile.json";
70830
70039
  function profilePath(dataDir) {
70831
- return import_node_path64.default.join(dataDir, PROFILE_FILENAME);
70040
+ return import_node_path63.default.join(dataDir, PROFILE_FILENAME);
70832
70041
  }
70833
70042
  function loadOwnerProfile(dataDir) {
70834
70043
  let raw;
70835
70044
  try {
70836
- raw = import_node_fs58.default.readFileSync(profilePath(dataDir), "utf8");
70045
+ raw = import_node_fs57.default.readFileSync(profilePath(dataDir), "utf8");
70837
70046
  } catch {
70838
70047
  return {};
70839
70048
  }
@@ -70849,7 +70058,7 @@ function loadOwnerProfile(dataDir) {
70849
70058
  }
70850
70059
  function patchOwnerProfile(dataDir, patch) {
70851
70060
  const merged = { ...loadOwnerProfile(dataDir), ...patch };
70852
- import_node_fs58.default.writeFileSync(profilePath(dataDir), JSON.stringify(merged, null, 2), { encoding: "utf8", mode: 384 });
70061
+ import_node_fs57.default.writeFileSync(profilePath(dataDir), JSON.stringify(merged, null, 2), { encoding: "utf8", mode: 384 });
70853
70062
  return merged;
70854
70063
  }
70855
70064
  function loadOwnerDisplayName(dataDir) {
@@ -70865,18 +70074,18 @@ function loadOwnerDisplayName(dataDir) {
70865
70074
  }
70866
70075
 
70867
70076
  // 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);
70077
+ var import_node_fs58 = __toESM(require("fs"), 1);
70078
+ var import_node_path64 = __toESM(require("path"), 1);
70870
70079
  var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
70871
70080
  var OwnerIdentityStore = class {
70872
70081
  file;
70873
70082
  constructor(dataDir) {
70874
- this.file = import_node_path65.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
70083
+ this.file = import_node_path64.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
70875
70084
  }
70876
70085
  read() {
70877
70086
  let raw;
70878
70087
  try {
70879
- raw = import_node_fs59.default.readFileSync(this.file, "utf8");
70088
+ raw = import_node_fs58.default.readFileSync(this.file, "utf8");
70880
70089
  } catch {
70881
70090
  return null;
70882
70091
  }
@@ -70903,16 +70112,16 @@ var OwnerIdentityStore = class {
70903
70112
  };
70904
70113
  }
70905
70114
  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 });
70115
+ import_node_fs58.default.mkdirSync(import_node_path64.default.dirname(this.file), { recursive: true });
70116
+ import_node_fs58.default.writeFileSync(this.file, JSON.stringify(record4, null, 2), { mode: 384 });
70908
70117
  try {
70909
- import_node_fs59.default.chmodSync(this.file, 384);
70118
+ import_node_fs58.default.chmodSync(this.file, 384);
70910
70119
  } catch {
70911
70120
  }
70912
70121
  }
70913
70122
  clear() {
70914
70123
  try {
70915
- import_node_fs59.default.unlinkSync(this.file);
70124
+ import_node_fs58.default.unlinkSync(this.file);
70916
70125
  } catch (err) {
70917
70126
  const code = err?.code;
70918
70127
  if (code !== "ENOENT") throw err;
@@ -70921,7 +70130,7 @@ var OwnerIdentityStore = class {
70921
70130
  };
70922
70131
 
70923
70132
  // src/feishu-auth/login-flow.ts
70924
- var import_node_crypto23 = __toESM(require("crypto"), 1);
70133
+ var import_node_crypto21 = __toESM(require("crypto"), 1);
70925
70134
  var STATE_TTL_MS = 5 * 60 * 1e3;
70926
70135
  var LoginFlow = class {
70927
70136
  constructor(deps) {
@@ -70930,7 +70139,7 @@ var LoginFlow = class {
70930
70139
  deps;
70931
70140
  pendingStates = /* @__PURE__ */ new Map();
70932
70141
  start() {
70933
- const state = import_node_crypto23.default.randomBytes(16).toString("base64url");
70142
+ const state = import_node_crypto21.default.randomBytes(16).toString("base64url");
70934
70143
  const now = (this.deps.now ?? Date.now)();
70935
70144
  this.pendingStates.set(state, now);
70936
70145
  this.gcExpired(now);
@@ -71408,8 +70617,8 @@ function verifyConnectToken(args) {
71408
70617
  }
71409
70618
 
71410
70619
  // src/feishu-auth/server-key.ts
71411
- var fs76 = __toESM(require("fs"), 1);
71412
- var path78 = __toESM(require("path"), 1);
70620
+ var fs75 = __toESM(require("fs"), 1);
70621
+ var path77 = __toESM(require("path"), 1);
71413
70622
  var FILE_NAME2 = "server-signing-key.json";
71414
70623
  var ServerKeyStore = class {
71415
70624
  constructor(dataDir) {
@@ -71417,12 +70626,12 @@ var ServerKeyStore = class {
71417
70626
  }
71418
70627
  dataDir;
71419
70628
  filePath() {
71420
- return path78.join(this.dataDir, FILE_NAME2);
70629
+ return path77.join(this.dataDir, FILE_NAME2);
71421
70630
  }
71422
70631
  /** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
71423
70632
  read() {
71424
70633
  try {
71425
- const raw = fs76.readFileSync(this.filePath(), "utf8");
70634
+ const raw = fs75.readFileSync(this.filePath(), "utf8");
71426
70635
  const parsed = JSON.parse(raw);
71427
70636
  if (typeof parsed.publicKeyPem === "string" && parsed.publicKeyPem.includes("PUBLIC KEY")) {
71428
70637
  return parsed.publicKeyPem;
@@ -71437,12 +70646,12 @@ var ServerKeyStore = class {
71437
70646
  publicKeyPem,
71438
70647
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
71439
70648
  };
71440
- fs76.mkdirSync(this.dataDir, { recursive: true });
71441
- fs76.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
70649
+ fs75.mkdirSync(this.dataDir, { recursive: true });
70650
+ fs75.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
71442
70651
  }
71443
70652
  clear() {
71444
70653
  try {
71445
- fs76.unlinkSync(this.filePath());
70654
+ fs75.unlinkSync(this.filePath());
71446
70655
  } catch {
71447
70656
  }
71448
70657
  }
@@ -71452,19 +70661,19 @@ var ServerKeyStore = class {
71452
70661
  init_protocol();
71453
70662
 
71454
70663
  // src/handlers/index.ts
71455
- var import_node_path81 = __toESM(require("path"), 1);
70664
+ var import_node_path80 = __toESM(require("path"), 1);
71456
70665
 
71457
70666
  // src/handlers/session.ts
71458
70667
  init_protocol();
71459
70668
 
71460
70669
  // src/session/fork.ts
71461
- var import_node_fs60 = __toESM(require("fs"), 1);
70670
+ var import_node_fs59 = __toESM(require("fs"), 1);
71462
70671
  var import_node_os24 = __toESM(require("os"), 1);
71463
- var import_node_path66 = __toESM(require("path"), 1);
71464
- var import_node_crypto24 = require("crypto");
70672
+ var import_node_path65 = __toESM(require("path"), 1);
70673
+ var import_node_crypto22 = require("crypto");
71465
70674
  init_claude_history();
71466
70675
  function readJsonlEntries(file) {
71467
- const raw = import_node_fs60.default.readFileSync(file, "utf8");
70676
+ const raw = import_node_fs59.default.readFileSync(file, "utf8");
71468
70677
  const out = [];
71469
70678
  for (const line of raw.split("\n")) {
71470
70679
  const t2 = line.trim();
@@ -71477,19 +70686,19 @@ function readJsonlEntries(file) {
71477
70686
  return out;
71478
70687
  }
71479
70688
  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)) {
70689
+ const baseDir = input.baseDir ?? import_node_path65.default.join(import_node_os24.default.homedir(), ".claude");
70690
+ let projectDir = import_node_path65.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
70691
+ let sourceFile = import_node_path65.default.join(projectDir, `${input.toolSessionId}.jsonl`);
70692
+ if (!import_node_fs59.default.existsSync(sourceFile)) {
71484
70693
  const found = findTranscriptByToolSessionId(
71485
- import_node_path66.default.join(baseDir, "projects"),
70694
+ import_node_path65.default.join(baseDir, "projects"),
71486
70695
  input.toolSessionId
71487
70696
  );
71488
70697
  if (!found) {
71489
70698
  throw new Error(`fork: source transcript not found: ${sourceFile}`);
71490
70699
  }
71491
70700
  sourceFile = found;
71492
- projectDir = import_node_path66.default.dirname(found);
70701
+ projectDir = import_node_path65.default.dirname(found);
71493
70702
  }
71494
70703
  const entries = readJsonlEntries(sourceFile);
71495
70704
  const mainEntries = entries.filter((e) => e.isSidechain !== true);
@@ -71498,7 +70707,7 @@ function forkSession(input) {
71498
70707
  throw new Error(`fork: messageUuid not found in transcript: ${input.messageUuid}`);
71499
70708
  }
71500
70709
  const sliced = mainEntries.slice(0, targetIdx + 1);
71501
- const forkedToolSessionId = (0, import_node_crypto24.randomUUID)();
70710
+ const forkedToolSessionId = (0, import_node_crypto22.randomUUID)();
71502
70711
  let parentUuid = null;
71503
70712
  const forkedLines = [];
71504
70713
  for (const entry of sliced) {
@@ -71518,17 +70727,17 @@ function forkSession(input) {
71518
70727
  }
71519
70728
  forkedLines.push(JSON.stringify(forked));
71520
70729
  }
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 });
70730
+ const outDir = input.targetCwd ? import_node_path65.default.join(baseDir, "projects", cwdToHashDir(input.targetCwd)) : projectDir;
70731
+ const forkedFilePath = import_node_path65.default.join(outDir, `${forkedToolSessionId}.jsonl`);
70732
+ import_node_fs59.default.mkdirSync(outDir, { recursive: true });
70733
+ import_node_fs59.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
71525
70734
  return { forkedToolSessionId, forkedFilePath };
71526
70735
  }
71527
70736
 
71528
70737
  // src/tools/codex-fork.ts
71529
70738
  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);
70739
+ var import_node_fs60 = __toESM(require("fs"), 1);
70740
+ var import_node_path66 = __toESM(require("path"), 1);
71532
70741
  function openCodexAppServer(home, cwd) {
71533
70742
  const proc = (0, import_node_child_process17.spawn)(process.env.CODEX_BIN ?? "codex", ["app-server", "--listen", "stdio://"], {
71534
70743
  cwd,
@@ -71548,7 +70757,7 @@ function openCodexAppServer(home, cwd) {
71548
70757
  async function forkCodexThread(input, deps = {}) {
71549
70758
  const source = locateCodexThread(input.roots, input.sourceThreadId);
71550
70759
  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"));
70760
+ const rollout = parseCodexRollout(import_node_fs60.default.readFileSync(source.file, "utf8"));
71552
70761
  if (rollout.meta?.threadId.toLowerCase() !== input.sourceThreadId.toLowerCase()) {
71553
70762
  throw new Error(`codex fork: source thread metadata does not match ${input.sourceThreadId}`);
71554
70763
  }
@@ -71578,7 +70787,7 @@ async function forkCodexThread(input, deps = {}) {
71578
70787
  if (typeof forkedToolSessionId !== "string" || !forkedToolSessionId) {
71579
70788
  throw new Error("codex fork: app-server returned no thread id");
71580
70789
  }
71581
- const forked = locateCodexThread([import_node_path67.default.join(source.home, "sessions")], forkedToolSessionId);
70790
+ const forked = locateCodexThread([import_node_path66.default.join(source.home, "sessions")], forkedToolSessionId);
71582
70791
  if (!forked) throw new Error(`codex fork: rollout not found for forked thread ${forkedToolSessionId}`);
71583
70792
  return { forkedToolSessionId, forkedFilePath: forked.file };
71584
70793
  })()]);
@@ -71589,19 +70798,19 @@ async function forkCodexThread(input, deps = {}) {
71589
70798
  }
71590
70799
 
71591
70800
  // src/session/external-scan.ts
71592
- var import_node_fs62 = __toESM(require("fs"), 1);
70801
+ var import_node_fs61 = __toESM(require("fs"), 1);
71593
70802
  var import_promises11 = __toESM(require("fs/promises"), 1);
71594
70803
  var import_node_os25 = __toESM(require("os"), 1);
71595
- var import_node_path68 = __toESM(require("path"), 1);
70804
+ var import_node_path67 = __toESM(require("path"), 1);
71596
70805
  var import_node_module = require("module");
71597
70806
  var import_node_child_process18 = require("child_process");
71598
70807
  var import_meta7 = {};
71599
70808
  function defaultRoots() {
71600
70809
  const home = import_node_os25.default.homedir();
71601
70810
  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")
70811
+ claudeProjectsDir: import_node_path67.default.join(home, ".claude", "projects"),
70812
+ codexDir: import_node_path67.default.join(home, ".codex"),
70813
+ clawdDir: import_node_path67.default.join(home, ".clawd")
71605
70814
  };
71606
70815
  }
71607
70816
  function width(s2) {
@@ -71652,7 +70861,7 @@ function userText(msg) {
71652
70861
  }
71653
70862
  function isDir2(p3) {
71654
70863
  try {
71655
- return import_node_fs62.default.statSync(p3).isDirectory();
70864
+ return import_node_fs61.default.statSync(p3).isDirectory();
71656
70865
  } catch {
71657
70866
  return false;
71658
70867
  }
@@ -71661,7 +70870,7 @@ async function scanClaude(roots) {
71661
70870
  const out = [];
71662
70871
  let dirs;
71663
70872
  try {
71664
- dirs = import_node_fs62.default.readdirSync(roots.claudeProjectsDir, { withFileTypes: true });
70873
+ dirs = import_node_fs61.default.readdirSync(roots.claudeProjectsDir, { withFileTypes: true });
71665
70874
  } catch {
71666
70875
  return out;
71667
70876
  }
@@ -71669,16 +70878,16 @@ async function scanClaude(roots) {
71669
70878
  if (!d2.isDirectory()) continue;
71670
70879
  let files;
71671
70880
  try {
71672
- files = import_node_fs62.default.readdirSync(import_node_path68.default.join(roots.claudeProjectsDir, d2.name));
70881
+ files = import_node_fs61.default.readdirSync(import_node_path67.default.join(roots.claudeProjectsDir, d2.name));
71673
70882
  } catch {
71674
70883
  continue;
71675
70884
  }
71676
70885
  for (const name of files) {
71677
70886
  if (!name.endsWith(".jsonl")) continue;
71678
- const file = import_node_path68.default.join(roots.claudeProjectsDir, d2.name, name);
70887
+ const file = import_node_path67.default.join(roots.claudeProjectsDir, d2.name, name);
71679
70888
  let st2;
71680
70889
  try {
71681
- st2 = import_node_fs62.default.statSync(file);
70890
+ st2 = import_node_fs61.default.statSync(file);
71682
70891
  } catch {
71683
70892
  continue;
71684
70893
  }
@@ -71731,7 +70940,7 @@ async function scanClaude(roots) {
71731
70940
  return out;
71732
70941
  }
71733
70942
  async function countCodexTurns(rolloutPath) {
71734
- if (!rolloutPath || !import_node_fs62.default.existsSync(rolloutPath)) return { turns: 0, first: "" };
70943
+ if (!rolloutPath || !import_node_fs61.default.existsSync(rolloutPath)) return { turns: 0, first: "" };
71735
70944
  let turns = 0;
71736
70945
  let first = "";
71737
70946
  for await (const rec6 of jsonLines(rolloutPath)) {
@@ -71805,7 +71014,7 @@ async function codexFromRows(rows) {
71805
71014
  async function scanCodex(roots) {
71806
71015
  let dbs = [];
71807
71016
  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));
71017
+ 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
71018
  } catch {
71810
71019
  }
71811
71020
  if (!dbs.length) return [];
@@ -71814,14 +71023,14 @@ async function scanCodex(roots) {
71814
71023
  }
71815
71024
  async function scanExternalSessions(rootsIn) {
71816
71025
  const roots = { ...defaultRoots(), ...rootsIn };
71817
- const personaRoot = import_node_path68.default.join(roots.clawdDir, "personas");
71026
+ const personaRoot = import_node_path67.default.join(roots.clawdDir, "personas");
71818
71027
  const all = [...await scanClaude(roots), ...await scanCodex(roots)];
71819
71028
  const out = [];
71820
71029
  for (const c2 of all) {
71821
71030
  if (c2.skip) continue;
71822
71031
  if (c2.turns < 1) continue;
71823
71032
  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)) {
71033
+ 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
71034
  continue;
71826
71035
  }
71827
71036
  out.push({
@@ -71838,13 +71047,13 @@ async function scanExternalSessions(rootsIn) {
71838
71047
  }
71839
71048
 
71840
71049
  // src/session/import-ledger.ts
71841
- var import_node_fs63 = __toESM(require("fs"), 1);
71842
- var import_node_path69 = __toESM(require("path"), 1);
71050
+ var import_node_fs62 = __toESM(require("fs"), 1);
71051
+ var import_node_path68 = __toESM(require("path"), 1);
71843
71052
  var LEDGER_FILENAME = "session-import-ledger.json";
71844
71053
  function readImportLedger(dataDir) {
71845
71054
  try {
71846
71055
  const parsed = JSON.parse(
71847
- import_node_fs63.default.readFileSync(import_node_path69.default.join(dataDir, LEDGER_FILENAME), "utf8")
71056
+ import_node_fs62.default.readFileSync(import_node_path68.default.join(dataDir, LEDGER_FILENAME), "utf8")
71848
71057
  );
71849
71058
  return Array.isArray(parsed) ? parsed : [];
71850
71059
  } catch {
@@ -71852,15 +71061,15 @@ function readImportLedger(dataDir) {
71852
71061
  }
71853
71062
  }
71854
71063
  function appendImportLedger(dataDir, entry) {
71855
- const file = import_node_path69.default.join(dataDir, LEDGER_FILENAME);
71064
+ const file = import_node_path68.default.join(dataDir, LEDGER_FILENAME);
71856
71065
  const entries = readImportLedger(dataDir);
71857
71066
  entries.push(entry);
71858
- import_node_fs63.default.writeFileSync(file, JSON.stringify(entries, null, 2), { encoding: "utf8", mode: 384 });
71067
+ import_node_fs62.default.writeFileSync(file, JSON.stringify(entries, null, 2), { encoding: "utf8", mode: 384 });
71859
71068
  }
71860
71069
 
71861
71070
  // src/handlers/session.ts
71862
71071
  init_protocol();
71863
- var import_node_path70 = __toESM(require("path"), 1);
71072
+ var import_node_path69 = __toESM(require("path"), 1);
71864
71073
  function canReadSearchHit(ctx, file) {
71865
71074
  if (!ctx || ctx.principal.kind === "owner") return true;
71866
71075
  return canAccessPersona(ctx.grants, file.ownerPersonaId, "read") && file.creatorPrincipalId === ctx.principal.id;
@@ -72141,7 +71350,7 @@ ${attribution}` } : args;
72141
71350
  `principal guest:${ctx.principal.id} cannot fork tool session ${args.toolSessionId}`
72142
71351
  );
72143
71352
  }
72144
- if (source?.tool === "codex" && args.targetCwd && import_node_path70.default.resolve(args.targetCwd) !== import_node_path70.default.resolve(source.cwd)) {
71353
+ if (source?.tool === "codex" && args.targetCwd && import_node_path69.default.resolve(args.targetCwd) !== import_node_path69.default.resolve(source.cwd)) {
72145
71354
  throw new ClawdError(ERROR_CODES.FORBIDDEN, "fork: guest targetCwd must match source cwd");
72146
71355
  }
72147
71356
  }
@@ -72418,7 +71627,7 @@ function buildPermissionHandlers(deps) {
72418
71627
  }
72419
71628
 
72420
71629
  // src/handlers/history.ts
72421
- var path85 = __toESM(require("path"), 1);
71630
+ var path84 = __toESM(require("path"), 1);
72422
71631
  init_protocol();
72423
71632
 
72424
71633
  // src/session/recent-dirs.ts
@@ -72436,7 +71645,7 @@ function listRecentDirs(store, limit = 50) {
72436
71645
  }
72437
71646
 
72438
71647
  // src/permission/persona-paths.ts
72439
- var path84 = __toESM(require("path"), 1);
71648
+ var path83 = __toESM(require("path"), 1);
72440
71649
  function getAllowedPersonaIds(grants, action) {
72441
71650
  const ids = /* @__PURE__ */ new Set();
72442
71651
  for (const g3 of grants) {
@@ -72449,42 +71658,42 @@ function getAllowedPersonaIds(grants, action) {
72449
71658
  return ids;
72450
71659
  }
72451
71660
  function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
72452
- const target = path84.resolve(absPath);
71661
+ const target = path83.resolve(absPath);
72453
71662
  if (userWorkDir) {
72454
- const u2 = path84.resolve(userWorkDir);
72455
- const usep = u2.endsWith(path84.sep) ? "" : path84.sep;
71663
+ const u2 = path83.resolve(userWorkDir);
71664
+ const usep = u2.endsWith(path83.sep) ? "" : path83.sep;
72456
71665
  if (target === u2 || target.startsWith(u2 + usep)) return true;
72457
71666
  }
72458
- const root = path84.resolve(personaRoot);
72459
- const sep4 = root.endsWith(path84.sep) ? "" : path84.sep;
71667
+ const root = path83.resolve(personaRoot);
71668
+ const sep4 = root.endsWith(path83.sep) ? "" : path83.sep;
72460
71669
  if (!target.startsWith(root + sep4)) return false;
72461
- const rel = path84.relative(root, target);
71670
+ const rel = path83.relative(root, target);
72462
71671
  if (!rel || rel.startsWith("..")) return false;
72463
- const personaId2 = rel.split(path84.sep)[0];
71672
+ const personaId2 = rel.split(path83.sep)[0];
72464
71673
  if (!personaId2) return false;
72465
71674
  const allowed = getAllowedPersonaIds(grants, action);
72466
71675
  if (allowed === "*") return true;
72467
71676
  return allowed.has(personaId2);
72468
71677
  }
72469
71678
  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;
71679
+ const root = path83.resolve(personaRoot);
71680
+ const target = path83.resolve(absPath);
71681
+ const sep4 = root.endsWith(path83.sep) ? "" : path83.sep;
72473
71682
  if (!target.startsWith(root + sep4)) return null;
72474
- const rel = path84.relative(root, target);
71683
+ const rel = path83.relative(root, target);
72475
71684
  if (!rel || rel.startsWith("..")) return null;
72476
- const id = rel.split(path84.sep)[0];
71685
+ const id = rel.split(path83.sep)[0];
72477
71686
  return id || null;
72478
71687
  }
72479
71688
  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;
71689
+ const d2 = path83.resolve(dir);
71690
+ const t2 = path83.resolve(absPath);
71691
+ const sep4 = d2.endsWith(path83.sep) ? "" : path83.sep;
72483
71692
  return t2 === d2 || t2.startsWith(d2 + sep4);
72484
71693
  }
72485
71694
  function isPathInGuestBoundary(personaRoot, personaId2, userWorkDir, absPath) {
72486
71695
  if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
72487
- return personaIdFromPath(path84.resolve(absPath), personaRoot) === personaId2;
71696
+ return personaIdFromPath(path83.resolve(absPath), personaRoot) === personaId2;
72488
71697
  }
72489
71698
 
72490
71699
  // src/handlers/history.ts
@@ -72538,7 +71747,7 @@ function buildHistoryHandlers(deps) {
72538
71747
  if (!pid) return false;
72539
71748
  return isGuestPathAllowed(
72540
71749
  ctx.grants,
72541
- path85.join(personaRoot, pid),
71750
+ path84.join(personaRoot, pid),
72542
71751
  personaRoot,
72543
71752
  "read",
72544
71753
  userWorkDir
@@ -72550,7 +71759,7 @@ function buildHistoryHandlers(deps) {
72550
71759
  };
72551
71760
  const list = async (frame, _client, ctx) => {
72552
71761
  const args = HistoryListArgs.parse(frame);
72553
- assertGuestPath(ctx, path85.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
71762
+ assertGuestPath(ctx, path84.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
72554
71763
  const sessions = await history.listSessions(args);
72555
71764
  return { response: { type: "history:list", sessions } };
72556
71765
  };
@@ -72625,14 +71834,14 @@ function buildHistoryHandlers(deps) {
72625
71834
  };
72626
71835
  const subagents = async (frame, _client, ctx) => {
72627
71836
  const args = HistorySubagentsArgs.parse(frame);
72628
- assertGuestPath(ctx, path85.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
71837
+ assertGuestPath(ctx, path84.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
72629
71838
  assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagents");
72630
71839
  const subs = await historyReaderForToolSession(args.toolSessionId).listSubagents(args);
72631
71840
  return { response: { type: "history:subagents", subagents: subs } };
72632
71841
  };
72633
71842
  const subagentRead = async (frame, _client, ctx) => {
72634
71843
  const args = HistorySubagentReadArgs.parse(frame);
72635
- assertGuestPath(ctx, path85.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
71844
+ assertGuestPath(ctx, path84.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
72636
71845
  assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagent-read");
72637
71846
  const res = await historyReaderForToolSession(args.toolSessionId).readSubagent(args);
72638
71847
  return { response: { type: "history:subagent-read", ...res } };
@@ -72642,7 +71851,7 @@ function buildHistoryHandlers(deps) {
72642
71851
  if (ctx?.principal.kind === "guest" && personaRoot) {
72643
71852
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
72644
71853
  const filtered = dirs.filter(
72645
- (d2) => isGuestPathAllowed(ctx.grants, path85.resolve(d2.cwd), personaRoot, "read", userWorkDir)
71854
+ (d2) => isGuestPathAllowed(ctx.grants, path84.resolve(d2.cwd), personaRoot, "read", userWorkDir)
72646
71855
  );
72647
71856
  return { response: { type: "history:recentDirs", dirs: filtered } };
72648
71857
  }
@@ -72659,17 +71868,17 @@ function buildHistoryHandlers(deps) {
72659
71868
  }
72660
71869
 
72661
71870
  // src/handlers/projects.ts
72662
- var fs81 = __toESM(require("fs"), 1);
71871
+ var fs80 = __toESM(require("fs"), 1);
72663
71872
  var os27 = __toESM(require("os"), 1);
72664
- var path86 = __toESM(require("path"), 1);
71873
+ var path85 = __toESM(require("path"), 1);
72665
71874
  var import_node_child_process19 = require("child_process");
72666
71875
  init_protocol();
72667
- var DEFAULT_PROJECTS_ROOT = path86.join(os27.homedir(), "Documents", "ChatGPT");
71876
+ var DEFAULT_PROJECTS_ROOT = path85.join(os27.homedir(), "Documents", "ChatGPT");
72668
71877
  function allocateDir(root, name) {
72669
- let candidate = path86.join(root, name);
71878
+ let candidate = path85.join(root, name);
72670
71879
  let n2 = 2;
72671
- while (fs81.existsSync(candidate)) {
72672
- candidate = path86.join(root, `${name} ${n2}`);
71880
+ while (fs80.existsSync(candidate)) {
71881
+ candidate = path85.join(root, `${name} ${n2}`);
72673
71882
  n2 += 1;
72674
71883
  }
72675
71884
  return candidate;
@@ -72697,7 +71906,7 @@ function buildProjectHandlers(deps) {
72697
71906
  throw new ClawdError(ERROR_CODES.INVALID_CWD, "project:reveal \u4EC5\u652F\u6301 macOS");
72698
71907
  }
72699
71908
  try {
72700
- if (!fs81.statSync(args.path).isDirectory()) throw new Error("not dir");
71909
+ if (!fs80.statSync(args.path).isDirectory()) throw new Error("not dir");
72701
71910
  } catch {
72702
71911
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
72703
71912
  }
@@ -72713,7 +71922,7 @@ function buildProjectHandlers(deps) {
72713
71922
  let target;
72714
71923
  if (args.path) {
72715
71924
  try {
72716
- if (!fs81.statSync(args.path).isDirectory()) throw new Error("not dir");
71925
+ if (!fs80.statSync(args.path).isDirectory()) throw new Error("not dir");
72717
71926
  } catch {
72718
71927
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
72719
71928
  }
@@ -72721,15 +71930,15 @@ function buildProjectHandlers(deps) {
72721
71930
  } else {
72722
71931
  const name = args.name;
72723
71932
  try {
72724
- fs81.mkdirSync(root, { recursive: true });
71933
+ fs80.mkdirSync(root, { recursive: true });
72725
71934
  target = allocateDir(root, name);
72726
- fs81.mkdirSync(target);
71935
+ fs80.mkdirSync(target);
72727
71936
  } catch (err) {
72728
71937
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `\u521B\u5EFA\u9879\u76EE\u76EE\u5F55\u5931\u8D25: ${String(err)}`);
72729
71938
  }
72730
71939
  const git2 = (0, import_node_child_process19.spawnSync)("git", ["init"], { cwd: target, stdio: "ignore" });
72731
71940
  if (git2.status !== 0) {
72732
- fs81.rmSync(target, { recursive: true, force: true });
71941
+ fs80.rmSync(target, { recursive: true, force: true });
72733
71942
  throw new ClawdError(
72734
71943
  ERROR_CODES.INVALID_CWD,
72735
71944
  `git init \u5931\u8D25\uFF08${git2.error ? String(git2.error) : `exit ${git2.status}`}\uFF09: ${target}`
@@ -72754,7 +71963,7 @@ function buildProjectHandlers(deps) {
72754
71963
  }
72755
71964
 
72756
71965
  // src/handlers/workspace.ts
72757
- var path87 = __toESM(require("path"), 1);
71966
+ var path86 = __toESM(require("path"), 1);
72758
71967
  init_protocol();
72759
71968
  var os28 = __toESM(require("os"), 1);
72760
71969
  init_protocol();
@@ -72797,22 +72006,22 @@ function buildWorkspaceHandlers(deps) {
72797
72006
  const args = WorkspaceListArgs.parse(frame);
72798
72007
  const isGuest = ctx?.principal.kind === "guest";
72799
72008
  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;
72009
+ const resolvedCwd = path86.resolve(args.cwd ?? fallbackCwd);
72010
+ const target = args.path ? path86.resolve(resolvedCwd, args.path) : resolvedCwd;
72802
72011
  assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
72803
72012
  const res = workspace.list({ ...args, cwd: resolvedCwd });
72804
72013
  return { response: { type: "workspace:list", ...res } };
72805
72014
  };
72806
72015
  const read = async (frame, _client, ctx) => {
72807
72016
  const args = WorkspaceReadArgs.parse(frame);
72808
- const target = path87.isAbsolute(args.path) ? path87.resolve(args.path) : path87.resolve(args.cwd, args.path);
72017
+ const target = path86.isAbsolute(args.path) ? path86.resolve(args.path) : path86.resolve(args.cwd, args.path);
72809
72018
  assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
72810
72019
  const res = workspace.read(args);
72811
72020
  return { response: { type: "workspace:read", ...res } };
72812
72021
  };
72813
72022
  const skillsList = async (frame, _client, ctx) => {
72814
72023
  const args = SkillsListArgs.parse(frame);
72815
- const cwdAbs = path87.resolve(args.cwd);
72024
+ const cwdAbs = path86.resolve(args.cwd);
72816
72025
  assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
72817
72026
  const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
72818
72027
  if (ctx?.principal.kind === "guest" && personaRoot) {
@@ -72824,7 +72033,7 @@ function buildWorkspaceHandlers(deps) {
72824
72033
  };
72825
72034
  const agentsList = async (frame, _client, ctx) => {
72826
72035
  const args = AgentsListArgs.parse(frame);
72827
- const cwdAbs = path87.resolve(args.cwd);
72036
+ const cwdAbs = path86.resolve(args.cwd);
72828
72037
  assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
72829
72038
  if (isCodexFamily(args.tool) || isPiFamily(args.tool)) {
72830
72039
  return { response: { type: "agents:list", agents: [] } };
@@ -72846,20 +72055,20 @@ function buildWorkspaceHandlers(deps) {
72846
72055
  }
72847
72056
 
72848
72057
  // src/handlers/git.ts
72849
- var path89 = __toESM(require("path"), 1);
72058
+ var path88 = __toESM(require("path"), 1);
72850
72059
  init_protocol();
72851
72060
  init_protocol();
72852
72061
 
72853
72062
  // src/workspace/git.ts
72854
72063
  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);
72064
+ var import_node_fs63 = __toESM(require("fs"), 1);
72065
+ var import_node_path70 = __toESM(require("path"), 1);
72857
72066
  var import_node_util2 = require("util");
72858
72067
  var pexec = (0, import_node_util2.promisify)(import_node_child_process20.execFile);
72859
72068
  function normalizePath(p3) {
72860
- const resolved = import_node_path71.default.resolve(p3);
72069
+ const resolved = import_node_path70.default.resolve(p3);
72861
72070
  try {
72862
- return import_node_fs64.default.realpathSync(resolved);
72071
+ return import_node_fs63.default.realpathSync(resolved);
72863
72072
  } catch {
72864
72073
  return resolved;
72865
72074
  }
@@ -72933,7 +72142,7 @@ async function listGitBranches(cwd) {
72933
72142
  function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
72934
72143
  if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
72935
72144
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
72936
- if (!isGuestPathAllowed(ctx.grants, path89.resolve(cwd), personaRoot, "read", userWorkDir)) {
72145
+ if (!isGuestPathAllowed(ctx.grants, path88.resolve(cwd), personaRoot, "read", userWorkDir)) {
72937
72146
  throw new ClawdError(
72938
72147
  ERROR_CODES.UNAUTHORIZED,
72939
72148
  `guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
@@ -73190,12 +72399,12 @@ async function queryCodexAccount(deps = {}) {
73190
72399
  }
73191
72400
 
73192
72401
  // src/tools/pi-account.ts
73193
- var import_node_fs65 = __toESM(require("fs"), 1);
73194
- var import_node_path72 = __toESM(require("path"), 1);
72402
+ var import_node_fs64 = __toESM(require("fs"), 1);
72403
+ var import_node_path71 = __toESM(require("path"), 1);
73195
72404
  function readPiCredentials(agentDir) {
73196
72405
  let raw;
73197
72406
  try {
73198
- raw = JSON.parse(import_node_fs65.default.readFileSync(import_node_path72.default.join(agentDir, "auth.json"), "utf8"));
72407
+ raw = JSON.parse(import_node_fs64.default.readFileSync(import_node_path71.default.join(agentDir, "auth.json"), "utf8"));
73199
72408
  } catch {
73200
72409
  return {};
73201
72410
  }
@@ -74286,21 +73495,21 @@ function computeMethodAccess(args) {
74286
73495
  }
74287
73496
 
74288
73497
  // src/version.ts
74289
- var version = "0.2.614".length > 0 ? "0.2.614" : "dev";
73498
+ var version = "0.2.616".length > 0 ? "0.2.616" : "dev";
74290
73499
 
74291
73500
  // src/cli-probe/probe.ts
74292
- var fs84 = __toESM(require("fs"), 1);
74293
- var path91 = __toESM(require("path"), 1);
73501
+ var fs83 = __toESM(require("fs"), 1);
73502
+ var path90 = __toESM(require("path"), 1);
74294
73503
  var PKG_NAME = "@clawos-dev/clawd";
74295
73504
  var BIN_NAME = "clawd";
74296
73505
  var MAX_PARENT_HOPS = 5;
74297
73506
  function probeGlobalCli(pathEnv) {
74298
73507
  if (!pathEnv) return null;
74299
- for (const dir of pathEnv.split(path91.delimiter)) {
73508
+ for (const dir of pathEnv.split(path90.delimiter)) {
74300
73509
  if (!dir) continue;
74301
73510
  let real;
74302
73511
  try {
74303
- real = fs84.realpathSync(path91.join(dir, BIN_NAME));
73512
+ real = fs83.realpathSync(path90.join(dir, BIN_NAME));
74304
73513
  } catch {
74305
73514
  continue;
74306
73515
  }
@@ -74310,15 +73519,15 @@ function probeGlobalCli(pathEnv) {
74310
73519
  return null;
74311
73520
  }
74312
73521
  function readOwnPackageVersion(entryPath) {
74313
- let dir = path91.dirname(entryPath);
73522
+ let dir = path90.dirname(entryPath);
74314
73523
  for (let i2 = 0; i2 < MAX_PARENT_HOPS; i2++) {
74315
73524
  try {
74316
- const raw = fs84.readFileSync(path91.join(dir, "package.json"), "utf8");
73525
+ const raw = fs83.readFileSync(path90.join(dir, "package.json"), "utf8");
74317
73526
  const pkg = JSON.parse(raw);
74318
73527
  if (pkg.name !== PKG_NAME) return null;
74319
73528
  return typeof pkg.version === "string" && pkg.version ? pkg.version : null;
74320
73529
  } catch {
74321
- const parent = path91.dirname(dir);
73530
+ const parent = path90.dirname(dir);
74322
73531
  if (parent === dir) return null;
74323
73532
  dir = parent;
74324
73533
  }
@@ -74494,7 +73703,7 @@ function buildPersonaHandlers(deps) {
74494
73703
  }
74495
73704
 
74496
73705
  // src/handlers/attachment.ts
74497
- var import_node_path73 = __toESM(require("path"), 1);
73706
+ var import_node_path72 = __toESM(require("path"), 1);
74498
73707
  init_protocol();
74499
73708
  init_protocol();
74500
73709
  function assertGuestAttachmentPath(ctx, absPath, personaRoot, method, usersRoot) {
@@ -74573,12 +73782,12 @@ function buildAttachmentHandlers(deps) {
74573
73782
  `session ${args.sessionId} scope unresolved`
74574
73783
  );
74575
73784
  }
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);
73785
+ const cwdAbs = import_node_path72.default.resolve(sessionFile.cwd);
73786
+ const candidateAbs = import_node_path72.default.isAbsolute(args.relPath) ? import_node_path72.default.resolve(args.relPath) : import_node_path72.default.resolve(cwdAbs, args.relPath);
74578
73787
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
74579
73788
  const entries = deps.groupFileStore.list(scope, args.sessionId);
74580
73789
  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);
73790
+ const storedAbs = import_node_path72.default.isAbsolute(e.relPath) ? import_node_path72.default.resolve(e.relPath) : import_node_path72.default.resolve(cwdAbs, e.relPath);
74582
73791
  return storedAbs === candidateAbs && !e.stale;
74583
73792
  });
74584
73793
  if (!entry) {
@@ -74602,7 +73811,7 @@ function buildAttachmentHandlers(deps) {
74602
73811
  if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
74603
73812
  const f2 = deps.sessionStore.read(sessionId);
74604
73813
  if (!f2) return;
74605
- assertGuestAttachmentPath(ctx, import_node_path73.default.resolve(f2.cwd), deps.personaRoot, method, deps.usersRoot);
73814
+ assertGuestAttachmentPath(ctx, import_node_path72.default.resolve(f2.cwd), deps.personaRoot, method, deps.usersRoot);
74606
73815
  }
74607
73816
  const groupAdd = async (frame, _client, ctx) => {
74608
73817
  if (!deps.groupFileStore || !deps.getSessionScope) {
@@ -74617,8 +73826,8 @@ function buildAttachmentHandlers(deps) {
74617
73826
  if (!scope) {
74618
73827
  throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
74619
73828
  }
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);
73829
+ const cwdAbs = import_node_path72.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
73830
+ const candidateAbs = import_node_path72.default.isAbsolute(args.relPath) ? import_node_path72.default.resolve(args.relPath) : import_node_path72.default.resolve(cwdAbs, args.relPath);
74622
73831
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
74623
73832
  const from = args.origin === "agent" ? "agent" : ctx?.principal.kind === "owner" ? "owner" : "agent";
74624
73833
  const size = 0;
@@ -74677,19 +73886,19 @@ function buildAttachmentHandlers(deps) {
74677
73886
 
74678
73887
  // src/handlers/extension.ts
74679
73888
  var import_promises15 = __toESM(require("fs/promises"), 1);
74680
- var import_node_path78 = __toESM(require("path"), 1);
73889
+ var import_node_path77 = __toESM(require("path"), 1);
74681
73890
  init_protocol();
74682
73891
 
74683
73892
  // src/extension/bundle-zip.ts
74684
73893
  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);
73894
+ var import_node_path73 = __toESM(require("path"), 1);
73895
+ var import_node_crypto23 = __toESM(require("crypto"), 1);
74687
73896
  var import_jszip2 = __toESM(require_lib3(), 1);
74688
73897
  async function bundleExtensionDir(dir) {
74689
73898
  const entries = await listFilesSorted(dir);
74690
73899
  const zip = new import_jszip2.default();
74691
73900
  for (const rel of entries) {
74692
- const abs = import_node_path74.default.join(dir, rel);
73901
+ const abs = import_node_path73.default.join(dir, rel);
74693
73902
  const content = await import_promises12.default.readFile(abs);
74694
73903
  zip.file(rel, content, { date: FIXED_DATE });
74695
73904
  }
@@ -74698,7 +73907,7 @@ async function bundleExtensionDir(dir) {
74698
73907
  compression: "DEFLATE",
74699
73908
  compressionOptions: { level: 6 }
74700
73909
  });
74701
- const sha256 = import_node_crypto25.default.createHash("sha256").update(buffer).digest("hex");
73910
+ const sha256 = import_node_crypto23.default.createHash("sha256").update(buffer).digest("hex");
74702
73911
  return { buffer, sha256 };
74703
73912
  }
74704
73913
  var FIXED_DATE = /* @__PURE__ */ new Date("2020-01-01T00:00:00.000Z");
@@ -74710,7 +73919,7 @@ async function listFilesSorted(rootDir) {
74710
73919
  return out;
74711
73920
  }
74712
73921
  async function walk(absRoot, relPrefix, out) {
74713
- const dirAbs = import_node_path74.default.join(absRoot, relPrefix);
73922
+ const dirAbs = import_node_path73.default.join(absRoot, relPrefix);
74714
73923
  const entries = await import_promises12.default.readdir(dirAbs, { withFileTypes: true });
74715
73924
  for (const e of entries) {
74716
73925
  if (IGNORE_BASENAMES.has(e.name)) continue;
@@ -74764,25 +73973,25 @@ function computePublishCheck(args) {
74764
73973
 
74765
73974
  // src/extension/install-flow.ts
74766
73975
  var import_promises13 = __toESM(require("fs/promises"), 1);
74767
- var import_node_path76 = __toESM(require("path"), 1);
73976
+ var import_node_path75 = __toESM(require("path"), 1);
74768
73977
  var import_node_os28 = __toESM(require("os"), 1);
74769
- var import_node_crypto26 = __toESM(require("crypto"), 1);
73978
+ var import_node_crypto24 = __toESM(require("crypto"), 1);
74770
73979
  var import_jszip3 = __toESM(require_lib3(), 1);
74771
73980
 
74772
73981
  // src/extension/paths.ts
74773
73982
  var import_node_os27 = __toESM(require("os"), 1);
74774
- var import_node_path75 = __toESM(require("path"), 1);
73983
+ var import_node_path74 = __toESM(require("path"), 1);
74775
73984
  function clawdHomeRoot(override) {
74776
- return override ?? process.env.CLAWD_HOME ?? import_node_path75.default.join(import_node_os27.default.homedir(), ".clawd");
73985
+ return override ?? process.env.CLAWD_HOME ?? import_node_path74.default.join(import_node_os27.default.homedir(), ".clawd");
74777
73986
  }
74778
73987
  function extensionsRoot(override) {
74779
- return import_node_path75.default.join(clawdHomeRoot(override), "extensions");
73988
+ return import_node_path74.default.join(clawdHomeRoot(override), "extensions");
74780
73989
  }
74781
73990
  function publishedChannelsFile(override) {
74782
- return import_node_path75.default.join(clawdHomeRoot(override), "extensions-published.json");
73991
+ return import_node_path74.default.join(clawdHomeRoot(override), "extensions-published.json");
74783
73992
  }
74784
73993
  function bundleCacheRoot(override) {
74785
- return import_node_path75.default.join(clawdHomeRoot(override), "extension-bundles");
73994
+ return import_node_path74.default.join(clawdHomeRoot(override), "extension-bundles");
74786
73995
  }
74787
73996
 
74788
73997
  // src/extension/install-flow.ts
@@ -74795,7 +74004,7 @@ var InstallError = class extends Error {
74795
74004
  };
74796
74005
  async function installFromChannel(args, deps) {
74797
74006
  const { channelRef, snapshotHash, bundleZip } = args;
74798
- const computed = import_node_crypto26.default.createHash("sha256").update(bundleZip).digest("hex");
74007
+ const computed = import_node_crypto24.default.createHash("sha256").update(bundleZip).digest("hex");
74799
74008
  if (computed !== snapshotHash) {
74800
74009
  throw new InstallError(
74801
74010
  "HASH_MISMATCH",
@@ -74809,7 +74018,7 @@ async function installFromChannel(args, deps) {
74809
74018
  throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
74810
74019
  }
74811
74020
  for (const name of Object.keys(zip.files)) {
74812
- if (name.includes("..") || name.startsWith("/") || import_node_path76.default.isAbsolute(name)) {
74021
+ if (name.includes("..") || name.startsWith("/") || import_node_path75.default.isAbsolute(name)) {
74813
74022
  throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
74814
74023
  }
74815
74024
  }
@@ -74841,7 +74050,7 @@ async function installFromChannel(args, deps) {
74841
74050
  );
74842
74051
  }
74843
74052
  const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
74844
- const destDir = import_node_path76.default.join(deps.extensionsRoot, localExtId);
74053
+ const destDir = import_node_path75.default.join(deps.extensionsRoot, localExtId);
74845
74054
  let destExists = false;
74846
74055
  try {
74847
74056
  await import_promises13.default.access(destDir);
@@ -74855,16 +74064,16 @@ async function installFromChannel(args, deps) {
74855
74064
  );
74856
74065
  }
74857
74066
  const stage = await import_promises13.default.mkdtemp(
74858
- import_node_path76.default.join(import_node_os28.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
74067
+ import_node_path75.default.join(import_node_os28.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
74859
74068
  );
74860
74069
  try {
74861
74070
  for (const [name, entry] of Object.entries(zip.files)) {
74862
- const dest = import_node_path76.default.join(stage, name);
74071
+ const dest = import_node_path75.default.join(stage, name);
74863
74072
  if (entry.dir) {
74864
74073
  await import_promises13.default.mkdir(dest, { recursive: true });
74865
74074
  continue;
74866
74075
  }
74867
- await import_promises13.default.mkdir(import_node_path76.default.dirname(dest), { recursive: true });
74076
+ await import_promises13.default.mkdir(import_node_path75.default.dirname(dest), { recursive: true });
74868
74077
  if (name === "manifest.json") {
74869
74078
  const rewritten = { ...parsed.data, id: localExtId };
74870
74079
  await import_promises13.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -74885,9 +74094,9 @@ async function installFromChannel(args, deps) {
74885
74094
 
74886
74095
  // src/extension/update-flow.ts
74887
74096
  var import_promises14 = __toESM(require("fs/promises"), 1);
74888
- var import_node_path77 = __toESM(require("path"), 1);
74097
+ var import_node_path76 = __toESM(require("path"), 1);
74889
74098
  var import_node_os29 = __toESM(require("os"), 1);
74890
- var import_node_crypto27 = __toESM(require("crypto"), 1);
74099
+ var import_node_crypto25 = __toESM(require("crypto"), 1);
74891
74100
  var import_jszip4 = __toESM(require_lib3(), 1);
74892
74101
  var UpdateError = class extends Error {
74893
74102
  constructor(code, message) {
@@ -74902,11 +74111,11 @@ async function updateFromChannel(args, deps) {
74902
74111
  channelRef.extId,
74903
74112
  channelRef.ownerPrincipalId
74904
74113
  );
74905
- const liveDir = import_node_path77.default.join(deps.extensionsRoot, localExtId);
74114
+ const liveDir = import_node_path76.default.join(deps.extensionsRoot, localExtId);
74906
74115
  const prevDir = `${liveDir}.prev`;
74907
74116
  let existingVersion;
74908
74117
  try {
74909
- const raw = await import_promises14.default.readFile(import_node_path77.default.join(liveDir, "manifest.json"), "utf8");
74118
+ const raw = await import_promises14.default.readFile(import_node_path76.default.join(liveDir, "manifest.json"), "utf8");
74910
74119
  const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
74911
74120
  if (!parsed2.success) {
74912
74121
  throw new UpdateError(
@@ -74925,7 +74134,7 @@ async function updateFromChannel(args, deps) {
74925
74134
  if (e instanceof UpdateError) throw e;
74926
74135
  throw e;
74927
74136
  }
74928
- const computed = import_node_crypto27.default.createHash("sha256").update(bundleZip).digest("hex");
74137
+ const computed = import_node_crypto25.default.createHash("sha256").update(bundleZip).digest("hex");
74929
74138
  if (computed !== snapshotHash) {
74930
74139
  throw new UpdateError(
74931
74140
  "HASH_MISMATCH",
@@ -74939,7 +74148,7 @@ async function updateFromChannel(args, deps) {
74939
74148
  throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
74940
74149
  }
74941
74150
  for (const name of Object.keys(zip.files)) {
74942
- if (name.includes("..") || name.startsWith("/") || import_node_path77.default.isAbsolute(name)) {
74151
+ if (name.includes("..") || name.startsWith("/") || import_node_path76.default.isAbsolute(name)) {
74943
74152
  throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
74944
74153
  }
74945
74154
  }
@@ -74974,16 +74183,16 @@ async function updateFromChannel(args, deps) {
74974
74183
  await import_promises14.default.rm(prevDir, { recursive: true, force: true });
74975
74184
  await import_promises14.default.rename(liveDir, prevDir);
74976
74185
  const stage = await import_promises14.default.mkdtemp(
74977
- import_node_path77.default.join(import_node_os29.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
74186
+ import_node_path76.default.join(import_node_os29.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
74978
74187
  );
74979
74188
  try {
74980
74189
  for (const [name, entry] of Object.entries(zip.files)) {
74981
- const dest = import_node_path77.default.join(stage, name);
74190
+ const dest = import_node_path76.default.join(stage, name);
74982
74191
  if (entry.dir) {
74983
74192
  await import_promises14.default.mkdir(dest, { recursive: true });
74984
74193
  continue;
74985
74194
  }
74986
- await import_promises14.default.mkdir(import_node_path77.default.dirname(dest), { recursive: true });
74195
+ await import_promises14.default.mkdir(import_node_path76.default.dirname(dest), { recursive: true });
74987
74196
  if (name === "manifest.json") {
74988
74197
  const rewritten = { ...parsed.data, id: localExtId };
74989
74198
  await import_promises14.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -75050,7 +74259,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
75050
74259
  );
75051
74260
  }
75052
74261
  }
75053
- const manifestPath = import_node_path78.default.join(root, extId, "manifest.json");
74262
+ const manifestPath = import_node_path77.default.join(root, extId, "manifest.json");
75054
74263
  const manifest = await readManifest(root, extId);
75055
74264
  const next = { ...manifest, version: newVersion };
75056
74265
  const tmp = `${manifestPath}.tmp`;
@@ -75058,7 +74267,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
75058
74267
  await import_promises15.default.rename(tmp, manifestPath);
75059
74268
  }
75060
74269
  async function readManifest(root, extId) {
75061
- const file = import_node_path78.default.join(root, extId, "manifest.json");
74270
+ const file = import_node_path77.default.join(root, extId, "manifest.json");
75062
74271
  let raw;
75063
74272
  try {
75064
74273
  raw = await import_promises15.default.readFile(file, "utf8");
@@ -75142,7 +74351,7 @@ function buildExtensionHandlers(deps) {
75142
74351
  };
75143
74352
  async function buildSnapshotMeta(extId) {
75144
74353
  const manifest = await readManifest(deps.root, extId);
75145
- const { sha256, buffer } = await bundleExtensionDir(import_node_path78.default.join(deps.root, extId));
74354
+ const { sha256, buffer } = await bundleExtensionDir(import_node_path77.default.join(deps.root, extId));
75146
74355
  return { manifest, contentHash: sha256, buffer };
75147
74356
  }
75148
74357
  const publish = async (frame, _client, ctx) => {
@@ -75970,7 +75179,7 @@ function buildVisitorHandlers(deps) {
75970
75179
 
75971
75180
  // src/extension/registry.ts
75972
75181
  var import_promises17 = __toESM(require("fs/promises"), 1);
75973
- var import_node_path79 = __toESM(require("path"), 1);
75182
+ var import_node_path78 = __toESM(require("path"), 1);
75974
75183
  async function loadAll(root) {
75975
75184
  let entries;
75976
75185
  try {
@@ -75983,13 +75192,13 @@ async function loadAll(root) {
75983
75192
  for (const ent of entries) {
75984
75193
  if (!ent.isDirectory()) continue;
75985
75194
  if (ent.name.startsWith(".")) continue;
75986
- records.push(await loadOne(import_node_path79.default.join(root, ent.name), ent.name));
75195
+ records.push(await loadOne(import_node_path78.default.join(root, ent.name), ent.name));
75987
75196
  }
75988
75197
  records.sort((a2, b3) => a2.extId < b3.extId ? -1 : a2.extId > b3.extId ? 1 : 0);
75989
75198
  return records;
75990
75199
  }
75991
75200
  async function loadOne(dir, dirName) {
75992
- const manifestPath = import_node_path79.default.join(dir, "manifest.json");
75201
+ const manifestPath = import_node_path78.default.join(dir, "manifest.json");
75993
75202
  let raw;
75994
75203
  try {
75995
75204
  raw = await import_promises17.default.readFile(manifestPath, "utf8");
@@ -76034,7 +75243,7 @@ async function loadOne(dir, dirName) {
76034
75243
 
76035
75244
  // src/extension/uninstall.ts
76036
75245
  var import_promises18 = __toESM(require("fs/promises"), 1);
76037
- var import_node_path80 = __toESM(require("path"), 1);
75246
+ var import_node_path79 = __toESM(require("path"), 1);
76038
75247
  var UninstallError = class extends Error {
76039
75248
  constructor(code, message) {
76040
75249
  super(message);
@@ -76043,7 +75252,7 @@ var UninstallError = class extends Error {
76043
75252
  code;
76044
75253
  };
76045
75254
  async function uninstall(deps) {
76046
- const dir = import_node_path80.default.join(deps.root, deps.extId);
75255
+ const dir = import_node_path79.default.join(deps.root, deps.extId);
76047
75256
  try {
76048
75257
  await import_promises18.default.access(dir);
76049
75258
  } catch {
@@ -76054,7 +75263,7 @@ async function uninstall(deps) {
76054
75263
  }
76055
75264
 
76056
75265
  // src/handlers/index.ts
76057
- var import_node_crypto28 = require("crypto");
75266
+ var import_node_crypto26 = require("crypto");
76058
75267
 
76059
75268
  // src/handlers/peer-exec.ts
76060
75269
  init_protocol();
@@ -76211,7 +75420,7 @@ function buildMethodHandlers(deps) {
76211
75420
  const c2 = deps.contactStore.get(deviceId);
76212
75421
  return c2 ? { deviceId: c2.deviceId, remoteUrl: c2.remoteUrl, connectToken: c2.connectToken } : null;
76213
75422
  },
76214
- genId: () => (0, import_node_crypto28.randomUUID)(),
75423
+ genId: () => (0, import_node_crypto26.randomUUID)(),
76215
75424
  now: () => Date.now(),
76216
75425
  forwardInboxPostToPeer,
76217
75426
  logger: deps.logger
@@ -76261,7 +75470,7 @@ function buildMethodHandlers(deps) {
76261
75470
  broadcast: deps.broadcastToOwners
76262
75471
  }),
76263
75472
  ...buildMasterHandlers({
76264
- authorityTablePath: import_node_path81.default.join(deps.masterDataDir, "master-authority.json")
75473
+ authorityTablePath: import_node_path80.default.join(deps.masterDataDir, "master-authority.json")
76265
75474
  }),
76266
75475
  ...buildTopicHandlers({
76267
75476
  topicStore: deps.topicStore,
@@ -76404,7 +75613,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
76404
75613
 
76405
75614
  // src/extension/runtime.ts
76406
75615
  var import_node_child_process25 = require("child_process");
76407
- var import_node_path82 = __toESM(require("path"), 1);
75616
+ var import_node_path81 = __toESM(require("path"), 1);
76408
75617
  var import_promises19 = require("timers/promises");
76409
75618
 
76410
75619
  // src/extension/port-allocator.ts
@@ -76505,7 +75714,7 @@ var Runtime = class {
76505
75714
  /\$CLAWOS_EXT_PORT/g,
76506
75715
  String(port)
76507
75716
  );
76508
- const dir = import_node_path82.default.join(this.root, extId);
75717
+ const dir = import_node_path81.default.join(this.root, extId);
76509
75718
  const env = {
76510
75719
  ...process.env,
76511
75720
  CLAWOS_EXT_PORT: String(port),
@@ -76617,7 +75826,7 @@ ${handle.stderrTail}`
76617
75826
 
76618
75827
  // src/extension/published-channels.ts
76619
75828
  var import_promises20 = __toESM(require("fs/promises"), 1);
76620
- var import_node_path83 = __toESM(require("path"), 1);
75829
+ var import_node_path82 = __toESM(require("path"), 1);
76621
75830
  init_zod();
76622
75831
  var PublishedChannelsError = class extends Error {
76623
75832
  constructor(code, message) {
@@ -76716,7 +75925,7 @@ var PublishedChannelStore = class {
76716
75925
  )
76717
75926
  };
76718
75927
  const tmp = `${this.filePath}.tmp`;
76719
- await import_promises20.default.mkdir(import_node_path83.default.dirname(this.filePath), { recursive: true });
75928
+ await import_promises20.default.mkdir(import_node_path82.default.dirname(this.filePath), { recursive: true });
76720
75929
  await import_promises20.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
76721
75930
  await import_promises20.default.rename(tmp, this.filePath);
76722
75931
  }
@@ -76724,7 +75933,7 @@ var PublishedChannelStore = class {
76724
75933
 
76725
75934
  // src/extension/bundle-cache.ts
76726
75935
  var import_promises21 = __toESM(require("fs/promises"), 1);
76727
- var import_node_path84 = __toESM(require("path"), 1);
75936
+ var import_node_path83 = __toESM(require("path"), 1);
76728
75937
  var BundleCache = class {
76729
75938
  constructor(rootDir) {
76730
75939
  this.rootDir = rootDir;
@@ -76733,14 +75942,14 @@ var BundleCache = class {
76733
75942
  /** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
76734
75943
  async write(snapshotHash, buffer) {
76735
75944
  await import_promises21.default.mkdir(this.rootDir, { recursive: true });
76736
- const file = import_node_path84.default.join(this.rootDir, `${snapshotHash}.zip`);
75945
+ const file = import_node_path83.default.join(this.rootDir, `${snapshotHash}.zip`);
76737
75946
  const tmp = `${file}.tmp`;
76738
75947
  await import_promises21.default.writeFile(tmp, buffer, { mode: 384 });
76739
75948
  await import_promises21.default.rename(tmp, file);
76740
75949
  }
76741
75950
  /** Returns the bundle bytes, or null when the file doesn't exist. */
76742
75951
  async read(snapshotHash) {
76743
- const file = import_node_path84.default.join(this.rootDir, `${snapshotHash}.zip`);
75952
+ const file = import_node_path83.default.join(this.rootDir, `${snapshotHash}.zip`);
76744
75953
  try {
76745
75954
  return await import_promises21.default.readFile(file);
76746
75955
  } catch (e) {
@@ -76750,7 +75959,7 @@ var BundleCache = class {
76750
75959
  }
76751
75960
  /** Idempotent — missing file is not an error. */
76752
75961
  async delete(snapshotHash) {
76753
- const file = import_node_path84.default.join(this.rootDir, `${snapshotHash}.zip`);
75962
+ const file = import_node_path83.default.join(this.rootDir, `${snapshotHash}.zip`);
76754
75963
  await import_promises21.default.rm(file, { force: true });
76755
75964
  }
76756
75965
  };
@@ -76773,24 +75982,24 @@ async function startDaemon(config) {
76773
75982
  sampling: logShippingCfg.sampling,
76774
75983
  homeDir: import_node_os31.default.homedir()
76775
75984
  });
76776
- const logDir = import_node_path85.default.join(config.dataDir, "log");
76777
- import_node_fs66.default.mkdirSync(logDir, { recursive: true });
75985
+ const logDir = import_node_path84.default.join(config.dataDir, "log");
75986
+ import_node_fs65.default.mkdirSync(logDir, { recursive: true });
76778
75987
  const logger = createLogger({
76779
75988
  level: config.logLevel,
76780
- file: import_node_path85.default.join(logDir, "clawd.log"),
75989
+ file: import_node_path84.default.join(logDir, "clawd.log"),
76781
75990
  logClient
76782
75991
  });
76783
75992
  logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
76784
75993
  const screenIdleProbeLogger = createFileOnlyLogger({
76785
- file: import_node_path85.default.join(logDir, "screen-idle-probe.log"),
75994
+ file: import_node_path84.default.join(logDir, "screen-idle-probe.log"),
76786
75995
  level: "debug"
76787
75996
  });
76788
75997
  logger.info("screen-idle probe logger enabled", {
76789
- file: import_node_path85.default.join(logDir, "screen-idle-probe.log")
75998
+ file: import_node_path84.default.join(logDir, "screen-idle-probe.log")
76790
75999
  });
76791
76000
  const CAP_TARGETS = [
76792
- import_node_path85.default.join(logDir, "clawd.log"),
76793
- import_node_path85.default.join(logDir, "screen-idle-probe.log")
76001
+ import_node_path84.default.join(logDir, "clawd.log"),
76002
+ import_node_path84.default.join(logDir, "screen-idle-probe.log")
76794
76003
  ];
76795
76004
  const LOG_CAP_MAX_BYTES = 10 * 1024 * 1024;
76796
76005
  const LOG_CAP_KEEP_BYTES = 5 * 1024 * 1024;
@@ -76912,11 +76121,11 @@ async function startDaemon(config) {
76912
76121
  const agents = new AgentsScanner();
76913
76122
  const history = new ClaudeHistoryReader();
76914
76123
  let transport = null;
76915
- const personaStore = new PersonaStore(import_node_path85.default.join(config.dataDir, "personas"));
76124
+ const personaStore = new PersonaStore(import_node_path84.default.join(config.dataDir, "personas"));
76916
76125
  const subscriptionChannelStore = new SubscriptionChannelStore({ dataDir: config.dataDir });
76917
76126
  const activeSubscriptionChannel = subscriptionChannelStore.getActive();
76918
76127
  if (activeSubscriptionChannel) applyPiSubscriptionChannel({ channel: activeSubscriptionChannel });
76919
- const usersRoot = import_node_path85.default.join(config.dataDir, "users");
76128
+ const usersRoot = import_node_path84.default.join(config.dataDir, "users");
76920
76129
  const defaultsRoot = findDefaultsRoot(logger);
76921
76130
  if (defaultsRoot) {
76922
76131
  seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
@@ -76933,7 +76142,7 @@ async function startDaemon(config) {
76933
76142
  retirePersonaBuilder({ store: personaStore, logger });
76934
76143
  const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
76935
76144
  const dispatchStore = createDispatchStore({
76936
- filePath: import_node_path85.default.join(config.dataDir, "dispatch.json"),
76145
+ filePath: import_node_path84.default.join(config.dataDir, "dispatch.json"),
76937
76146
  now: () => Date.now(),
76938
76147
  onFlushError: (err) => logger.error("dispatch store flush failed", {
76939
76148
  reason: err instanceof Error ? err.message : String(err)
@@ -76942,18 +76151,18 @@ async function startDaemon(config) {
76942
76151
  await dispatchStore.load();
76943
76152
  dispatchStore.markInterruptedAsFailed((/* @__PURE__ */ new Date()).toISOString());
76944
76153
  const channelStore = createChannelStore({
76945
- filePath: import_node_path85.default.join(config.dataDir, "channels.json"),
76154
+ filePath: import_node_path84.default.join(config.dataDir, "channels.json"),
76946
76155
  now: () => Date.now(),
76947
- genId: () => `ch-${(0, import_node_crypto29.randomUUID)().slice(0, 8)}`,
76156
+ genId: () => `ch-${(0, import_node_crypto27.randomUUID)().slice(0, 8)}`,
76948
76157
  onFlushError: (err) => logger.error("channel store flush failed", {
76949
76158
  reason: err instanceof Error ? err.message : String(err)
76950
76159
  })
76951
76160
  });
76952
76161
  await channelStore.load();
76953
76162
  const topicStore = createTopicStore({
76954
- filePath: import_node_path85.default.join(config.dataDir, "topics.json"),
76163
+ filePath: import_node_path84.default.join(config.dataDir, "topics.json"),
76955
76164
  now: () => Date.now(),
76956
- genId: () => `tp-${(0, import_node_crypto29.randomUUID)().slice(0, 8)}`,
76165
+ genId: () => `tp-${(0, import_node_crypto27.randomUUID)().slice(0, 8)}`,
76957
76166
  onFlushError: (err) => logger.error("topic store flush failed", {
76958
76167
  reason: err instanceof Error ? err.message : String(err)
76959
76168
  })
@@ -76961,7 +76170,7 @@ async function startDaemon(config) {
76961
76170
  await topicStore.load();
76962
76171
  let deliverPendingRef;
76963
76172
  const personaDispatchManager = new PersonaDispatchManager({
76964
- genId: () => (0, import_node_crypto29.randomUUID)(),
76173
+ genId: () => (0, import_node_crypto27.randomUUID)(),
76965
76174
  store: dispatchStore,
76966
76175
  now: () => Date.now(),
76967
76176
  onCompleted: (sid) => deliverPendingRef?.(sid),
@@ -76978,12 +76187,12 @@ async function startDaemon(config) {
76978
76187
  });
76979
76188
  }
76980
76189
  });
76981
- const here = typeof __dirname === "string" ? __dirname : import_node_path85.default.dirname((0, import_node_url6.fileURLToPath)(import_meta10.url));
76190
+ const here = typeof __dirname === "string" ? __dirname : import_node_path84.default.dirname((0, import_node_url6.fileURLToPath)(import_meta10.url));
76982
76191
  const mcpConfigs = [];
76983
76192
  const secretsBundleRoot = findSecretsBundleRoot(logger);
76984
- const localSecretsDir = import_node_path85.default.join(config.dataDir, LOCAL_SECRETS_DIRNAME);
76193
+ const localSecretsDir = import_node_path84.default.join(config.dataDir, LOCAL_SECRETS_DIRNAME);
76985
76194
  const readSecrets = () => readSecretTable({ bundleRoot: secretsBundleRoot, overrideDir: localSecretsDir, logger });
76986
- const githubTokenFile = import_node_path85.default.join(localSecretsDir, GITHUB_TOKEN_FILE);
76195
+ const githubTokenFile = import_node_path84.default.join(localSecretsDir, GITHUB_TOKEN_FILE);
76987
76196
  const githubIdentity = createGithubIdentity({
76988
76197
  resolve: () => resolveGithubAuth({ exec: runCommand, fileToken: () => readEnvFileVar(githubTokenFile, GITHUB_TOKEN_VAR) }),
76989
76198
  store: (token) => storeGithubAuth({
@@ -77021,22 +76230,22 @@ async function startDaemon(config) {
77021
76230
  void githubIdentity.refresh();
77022
76231
  return renderPersonaMcpSecrets({
77023
76232
  personaId: personaId2,
77024
- personaDir: import_node_path85.default.join(config.dataDir, "personas", personaId2),
76233
+ personaDir: import_node_path84.default.join(config.dataDir, "personas", personaId2),
77025
76234
  secrets,
77026
- outDir: import_node_path85.default.join(config.dataDir, "persona-mcp"),
76235
+ outDir: import_node_path84.default.join(config.dataDir, "persona-mcp"),
77027
76236
  logger
77028
76237
  });
77029
76238
  };
77030
76239
  const mcpDaemonUrl = `http://127.0.0.1:${config.port}`;
77031
76240
  const dispatchServerCandidates = [
77032
- import_node_path85.default.join(here, "dispatch", "mcp-server.cjs"),
76241
+ import_node_path84.default.join(here, "dispatch", "mcp-server.cjs"),
77033
76242
  // 生产 dist/index → dist/dispatch/mcp-server.cjs
77034
- import_node_path85.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
76243
+ import_node_path84.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
77035
76244
  // dev tsx src/index → ../dist/dispatch/mcp-server.cjs
77036
76245
  ];
77037
- const dispatchServerScriptPath = dispatchServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76246
+ const dispatchServerScriptPath = dispatchServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
77038
76247
  if (dispatchServerScriptPath) {
77039
- const dispatchLogPath = import_node_path85.default.join(logDir, "dispatch-mcp-server.log");
76248
+ const dispatchLogPath = import_node_path84.default.join(logDir, "dispatch-mcp-server.log");
77040
76249
  const dispatchCfgPath = writeDispatchMcpConfig({
77041
76250
  dataDir: config.dataDir,
77042
76251
  serverScriptPath: dispatchServerScriptPath,
@@ -77056,12 +76265,12 @@ async function startDaemon(config) {
77056
76265
  });
77057
76266
  }
77058
76267
  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")
76268
+ import_node_path84.default.join(here, "ticket", "mcp-server.cjs"),
76269
+ import_node_path84.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
77061
76270
  ];
77062
- const ticketServerScriptPath = ticketServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76271
+ const ticketServerScriptPath = ticketServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
77063
76272
  if (ticketServerScriptPath) {
77064
- const ticketLogPath = import_node_path85.default.join(logDir, "ticket-mcp-server.log");
76273
+ const ticketLogPath = import_node_path84.default.join(logDir, "ticket-mcp-server.log");
77065
76274
  const ticketCfgPath = writeTicketMcpConfig({
77066
76275
  dataDir: config.dataDir,
77067
76276
  serverScriptPath: ticketServerScriptPath,
@@ -77083,12 +76292,12 @@ async function startDaemon(config) {
77083
76292
  });
77084
76293
  }
77085
76294
  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")
76295
+ import_node_path84.default.join(here, "shift", "mcp-server.cjs"),
76296
+ import_node_path84.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
77088
76297
  ];
77089
- const shiftServerScriptPath = shiftServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76298
+ const shiftServerScriptPath = shiftServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
77090
76299
  if (shiftServerScriptPath) {
77091
- const shiftLogPath = import_node_path85.default.join(logDir, "shift-mcp-server.log");
76300
+ const shiftLogPath = import_node_path84.default.join(logDir, "shift-mcp-server.log");
77092
76301
  const shiftCfgPath = await writeShiftMcpConfig({
77093
76302
  dataDir: config.dataDir,
77094
76303
  serverScriptPath: shiftServerScriptPath,
@@ -77109,12 +76318,12 @@ async function startDaemon(config) {
77109
76318
  );
77110
76319
  }
77111
76320
  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")
76321
+ import_node_path84.default.join(here, "inbox", "mcp-server.cjs"),
76322
+ import_node_path84.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
77114
76323
  ];
77115
- const inboxServerScriptPath = inboxServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76324
+ const inboxServerScriptPath = inboxServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
77116
76325
  if (inboxServerScriptPath) {
77117
- const inboxLogPath = import_node_path85.default.join(logDir, "inbox-mcp-server.log");
76326
+ const inboxLogPath = import_node_path84.default.join(logDir, "inbox-mcp-server.log");
77118
76327
  const inboxCfgPath = await writeInboxMcpConfig({
77119
76328
  dataDir: config.dataDir,
77120
76329
  serverScriptPath: inboxServerScriptPath,
@@ -77135,10 +76344,10 @@ async function startDaemon(config) {
77135
76344
  );
77136
76345
  }
77137
76346
  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")
76347
+ import_node_path84.default.join(here, "peer-ops", "mcp-server.cjs"),
76348
+ import_node_path84.default.join(here, "..", "dist", "peer-ops", "mcp-server.cjs")
77140
76349
  ];
77141
- const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76350
+ const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
77142
76351
  if (peerOpsServerScriptPath) {
77143
76352
  const peerOpsCfgPath = writePeerOpsMcpConfig({
77144
76353
  dataDir: config.dataDir,
@@ -77158,12 +76367,12 @@ async function startDaemon(config) {
77158
76367
  );
77159
76368
  }
77160
76369
  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")
76370
+ import_node_path84.default.join(here, "rpc-tool", "mcp-server.cjs"),
76371
+ import_node_path84.default.join(here, "..", "dist", "rpc-tool", "mcp-server.cjs")
77163
76372
  ];
77164
- const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76373
+ const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
77165
76374
  if (rpcToolServerScriptPath) {
77166
- const rpcToolLogPath = import_node_path85.default.join(logDir, "rpc-tool-mcp-server.log");
76375
+ const rpcToolLogPath = import_node_path84.default.join(logDir, "rpc-tool-mcp-server.log");
77167
76376
  const rpcToolCfgPath = writeRpcToolMcpConfig({
77168
76377
  dataDir: config.dataDir,
77169
76378
  serverScriptPath: rpcToolServerScriptPath,
@@ -77184,7 +76393,7 @@ async function startDaemon(config) {
77184
76393
  );
77185
76394
  }
77186
76395
  const shiftStore = createShiftStore({
77187
- filePath: import_node_path85.default.join(config.dataDir, "shift.json"),
76396
+ filePath: import_node_path84.default.join(config.dataDir, "shift.json"),
77188
76397
  ownerIdProvider: () => ownerPrincipalId,
77189
76398
  now: () => Date.now()
77190
76399
  });
@@ -77206,7 +76415,7 @@ async function startDaemon(config) {
77206
76415
  getAdapter,
77207
76416
  historyReader: history,
77208
76417
  dataDir: config.dataDir,
77209
- personaRoot: import_node_path85.default.join(config.dataDir, "personas"),
76418
+ personaRoot: import_node_path84.default.join(config.dataDir, "personas"),
77210
76419
  // dispatch / shift 自动化 spawn 按 persona 绑定 tool 起 B session(codex persona 用 codex)。
77211
76420
  // personaRegistry 声明在 manager 之后(同作用域 const,调用时机在启动完成后,无 TDZ 风险)。
77212
76421
  getPersonaDefaults: (personaId2) => personaRegistry.get(personaId2),
@@ -77267,10 +76476,10 @@ async function startDaemon(config) {
77267
76476
  // 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
77268
76477
  attachmentGroup: {
77269
76478
  onFileEdit: (input) => {
77270
- const absPath = import_node_path85.default.isAbsolute(input.relPath) ? input.relPath : import_node_path85.default.join(input.cwd, input.relPath);
76479
+ const absPath = import_node_path84.default.isAbsolute(input.relPath) ? input.relPath : import_node_path84.default.join(input.cwd, input.relPath);
77271
76480
  let size = 0;
77272
76481
  try {
77273
- size = import_node_fs66.default.statSync(absPath).size;
76482
+ size = import_node_fs65.default.statSync(absPath).size;
77274
76483
  } catch (err) {
77275
76484
  logger.warn("attachment.onFileEdit stat failed", {
77276
76485
  sessionId: input.sessionId,
@@ -77311,9 +76520,9 @@ async function startDaemon(config) {
77311
76520
  logger.info("projects.seed-dropped", { dropped: droppedSeed.dropped, backup: droppedSeed.backup });
77312
76521
  }
77313
76522
  const projectsStore = new ProjectsStore({
77314
- file: import_node_path85.default.join(config.dataDir, "projects.json"),
76523
+ file: import_node_path84.default.join(config.dataDir, "projects.json"),
77315
76524
  clawdDir: config.dataDir,
77316
- codexStateFile: import_node_path85.default.join(import_node_os31.default.homedir(), ".codex", ".codex-global-state.json"),
76525
+ codexStateFile: import_node_path84.default.join(import_node_os31.default.homedir(), ".codex", ".codex-global-state.json"),
77317
76526
  logger
77318
76527
  });
77319
76528
  const observer = new SessionObserver({
@@ -77377,11 +76586,6 @@ async function startDaemon(config) {
77377
76586
  centralApi: config.clawosApi ?? DEFAULT_CLAWOS_API,
77378
76587
  logger
77379
76588
  });
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
76589
  manager.setCloudCanceller(async (file, runner) => {
77386
76590
  const personaId2 = personaIdFromCloudCwd(file.cwd);
77387
76591
  if (!personaId2) throw new Error(`\u4E91\u4F1A\u8BDD ${file.sessionId} \u7F3A\u5C11 gateway persona ID`);
@@ -77390,27 +76594,16 @@ async function startDaemon(config) {
77390
76594
  runner?.confirmCloudCancelled();
77391
76595
  return;
77392
76596
  }
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
- }
76597
+ runner?.confirmCloudCancelled();
77404
76598
  });
77405
- cloudCancelOutbox.start();
77406
76599
  registerAdapter("claude", claudeAdapter);
77407
- const codexIsolatedHome = import_node_path85.default.join(config.dataDir, "codex-home");
76600
+ const codexIsolatedHome = import_node_path84.default.join(config.dataDir, "codex-home");
77408
76601
  try {
77409
- import_node_fs66.default.mkdirSync(codexIsolatedHome, { recursive: true });
76602
+ import_node_fs65.default.mkdirSync(codexIsolatedHome, { recursive: true });
77410
76603
  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);
76604
+ const link = import_node_path84.default.join(codexIsolatedHome, f2);
76605
+ const target = import_node_path84.default.join(import_node_os31.default.homedir(), ".codex", f2);
76606
+ if (!import_node_fs65.default.existsSync(link) && import_node_fs65.default.existsSync(target)) import_node_fs65.default.symlinkSync(target, link);
77414
76607
  }
77415
76608
  } catch (err) {
77416
76609
  logger.warn("codex isolated home setup failed", { err: String(err) });
@@ -77421,17 +76614,17 @@ async function startDaemon(config) {
77421
76614
  logger,
77422
76615
  historyReader: new CodexHistoryReader({
77423
76616
  roots: codexRolloutRoots(config.dataDir),
77424
- sharedHome: import_node_path85.default.join(import_node_os31.default.homedir(), ".codex"),
76617
+ sharedHome: import_node_path84.default.join(import_node_os31.default.homedir(), ".codex"),
77425
76618
  logger
77426
76619
  }),
77427
76620
  // projectPaths 每次调用现取 —— 用户新建 project 后立即生效,不用重启 daemon
77428
76621
  codexHomeFor: (cwd) => resolveCodexHome({
77429
76622
  cwd,
77430
- personaRoot: import_node_path85.default.join(config.dataDir, "personas"),
76623
+ personaRoot: import_node_path84.default.join(config.dataDir, "personas"),
77431
76624
  // 必须用 listMerged(Codex registry ∪ 叠加层):只用本地 list() 的话,用户在
77432
76625
  // Codex 里建的 project 不在表里,在它下面开的会话会被误判成隔离 → Codex 侧看不到
77433
76626
  projectPaths: projectsStore.listMerged().map((x2) => x2.path),
77434
- sharedHome: import_node_path85.default.join(import_node_os31.default.homedir(), ".codex"),
76627
+ sharedHome: import_node_path84.default.join(import_node_os31.default.homedir(), ".codex"),
77435
76628
  isolatedHome: codexIsolatedHome
77436
76629
  }),
77437
76630
  codexHomeForThread: (threadId) => locateCodexThread(codexRolloutRoots(config.dataDir), threadId)?.home,
@@ -77457,10 +76650,10 @@ async function startDaemon(config) {
77457
76650
  );
77458
76651
  registerAdapter(PI_CLOUD_TOOL_ID, new CloudPiAdapter({ client: cloudGateway, history: cloudHistorySource, logger }));
77459
76652
  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")
76653
+ import_node_path84.default.join(here, "pi-mcp-bridge", "extension.cjs"),
76654
+ import_node_path84.default.join(here, "..", "dist", "pi-mcp-bridge", "extension.cjs")
77462
76655
  ];
77463
- const piMcpBridgePath = piMcpBridgeCandidates.find((p3) => import_node_fs66.default.existsSync(p3));
76656
+ const piMcpBridgePath = piMcpBridgeCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
77464
76657
  if (piMcpBridgePath) {
77465
76658
  logger.info("pi-mcp-bridge extension resolved", { path: piMcpBridgePath });
77466
76659
  } else {
@@ -77766,11 +76959,11 @@ async function startDaemon(config) {
77766
76959
  // 'persona/<pid>/owner',default 走 'default'。
77767
76960
  getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
77768
76961
  // guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
77769
- personaRoot: import_node_path85.default.join(config.dataDir, "personas"),
76962
+ personaRoot: import_node_path84.default.join(config.dataDir, "personas"),
77770
76963
  usersRoot
77771
76964
  },
77772
76965
  // workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
77773
- personaRoot: import_node_path85.default.join(config.dataDir, "personas"),
76966
+ personaRoot: import_node_path84.default.join(config.dataDir, "personas"),
77774
76967
  // v2 多人 persona 隔离:handler 派生 guest user-dir 放行
77775
76968
  usersRoot,
77776
76969
  // v2 Phase 6: whoami handler 装在 owner principal.displayName + persona 解析
@@ -78076,7 +77269,7 @@ async function startDaemon(config) {
78076
77269
  });
78077
77270
  shiftScheduler.start();
78078
77271
  logger.info("shift scheduler started", { shiftCount: shiftStore.list().length });
78079
- const larkBotStore = createLarkBotBindingStore(import_node_path85.default.join(config.dataDir, "personas"));
77272
+ const larkBotStore = createLarkBotBindingStore(import_node_path84.default.join(config.dataDir, "personas"));
78080
77273
  const larkBotCloud = createLarkBotCloudClient({
78081
77274
  api: config.clawosApi ?? DEFAULT_CLAWOS_API,
78082
77275
  getLoginPass: () => ownerIdentityStore.read()?.loginPass ?? null
@@ -78088,7 +77281,7 @@ async function startDaemon(config) {
78088
77281
  store: larkBotStore,
78089
77282
  fetchResource: (appId, messageId, fileKey, maxBytes, type) => larkBotCloud.fetchResource(appId, messageId, fileKey, maxBytes, type),
78090
77283
  // 图片落 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"),
77284
+ mediaRootFor: (chatId) => import_node_path84.default.join(deriveUserWorkDir(`lark-${chatId}`, usersRoot), "lark-media"),
78092
77285
  isShuttingDown: () => larkDraining,
78093
77286
  logger: {
78094
77287
  warn: (msg) => logger.warn(msg),
@@ -78401,8 +77594,8 @@ async function startDaemon(config) {
78401
77594
  const lines = [
78402
77595
  `Tunnel: ${r2.url}`,
78403
77596
  ...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")}`
77597
+ `Frpc config: ${import_node_path84.default.join(config.dataDir, "frpc.toml")}`,
77598
+ `Frpc log: ${import_node_path84.default.join(logDir, "frpc.log")}`
78406
77599
  ];
78407
77600
  const width2 = Math.max(...lines.map((l2) => l2.length));
78408
77601
  const bar = "\u2550".repeat(width2 + 4);
@@ -78415,8 +77608,8 @@ ${bar}
78415
77608
 
78416
77609
  `);
78417
77610
  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 });
77611
+ const connectPath = import_node_path84.default.join(config.dataDir, "connect.txt");
77612
+ import_node_fs65.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
78420
77613
  } catch {
78421
77614
  }
78422
77615
  } catch (err) {
@@ -78485,7 +77678,6 @@ ${bar}
78485
77678
  larkDraining = true;
78486
77679
  clearInterval(attachmentGcInterval);
78487
77680
  clearInterval(cloudRecoveryInterval);
78488
- cloudCancelOutbox.stop();
78489
77681
  observer.stopAll();
78490
77682
  manager.stopAll();
78491
77683
  await extensionRuntime.stopAll();
@@ -78516,9 +77708,9 @@ ${bar}
78516
77708
  };
78517
77709
  }
78518
77710
  function migrateDropPersonsDir(dataDir) {
78519
- const dir = import_node_path85.default.join(dataDir, "persons");
77711
+ const dir = import_node_path84.default.join(dataDir, "persons");
78520
77712
  try {
78521
- import_node_fs66.default.rmSync(dir, { recursive: true, force: true });
77713
+ import_node_fs65.default.rmSync(dir, { recursive: true, force: true });
78522
77714
  } catch {
78523
77715
  }
78524
77716
  }