@clawos-dev/clawd 0.2.208 → 0.2.209-beta.415.57f6599

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs CHANGED
@@ -742,8 +742,8 @@ var init_parseUtil = __esm({
742
742
  init_errors2();
743
743
  init_en();
744
744
  makeIssue = (params) => {
745
- const { data, path: path78, errorMaps, issueData } = params;
746
- const fullPath = [...path78, ...issueData.path || []];
745
+ const { data, path: path77, errorMaps, issueData } = params;
746
+ const fullPath = [...path77, ...issueData.path || []];
747
747
  const fullIssue = {
748
748
  ...issueData,
749
749
  path: fullPath
@@ -1054,11 +1054,11 @@ var init_types = __esm({
1054
1054
  init_parseUtil();
1055
1055
  init_util();
1056
1056
  ParseInputLazyPath = class {
1057
- constructor(parent, value, path78, key) {
1057
+ constructor(parent, value, path77, key) {
1058
1058
  this._cachedPath = [];
1059
1059
  this.parent = parent;
1060
1060
  this.data = value;
1061
- this._path = path78;
1061
+ this._path = path77;
1062
1062
  this._key = key;
1063
1063
  }
1064
1064
  get path() {
@@ -6449,8 +6449,8 @@ var require_req = __commonJS({
6449
6449
  if (req.originalUrl) {
6450
6450
  _req.url = req.originalUrl;
6451
6451
  } else {
6452
- const path78 = req.path;
6453
- _req.url = typeof path78 === "string" ? path78 : req.url ? req.url.path || req.url : void 0;
6452
+ const path77 = req.path;
6453
+ _req.url = typeof path77 === "string" ? path77 : req.url ? req.url.path || req.url : void 0;
6454
6454
  }
6455
6455
  if (req.query) {
6456
6456
  _req.query = req.query;
@@ -6615,14 +6615,14 @@ var require_redact = __commonJS({
6615
6615
  }
6616
6616
  return obj;
6617
6617
  }
6618
- function parsePath(path78) {
6618
+ function parsePath(path77) {
6619
6619
  const parts = [];
6620
6620
  let current = "";
6621
6621
  let inBrackets = false;
6622
6622
  let inQuotes = false;
6623
6623
  let quoteChar = "";
6624
- for (let i = 0; i < path78.length; i++) {
6625
- const char = path78[i];
6624
+ for (let i = 0; i < path77.length; i++) {
6625
+ const char = path77[i];
6626
6626
  if (!inBrackets && char === ".") {
6627
6627
  if (current) {
6628
6628
  parts.push(current);
@@ -6753,10 +6753,10 @@ var require_redact = __commonJS({
6753
6753
  return current;
6754
6754
  }
6755
6755
  function redactPaths(obj, paths, censor, remove = false) {
6756
- for (const path78 of paths) {
6757
- const parts = parsePath(path78);
6756
+ for (const path77 of paths) {
6757
+ const parts = parsePath(path77);
6758
6758
  if (parts.includes("*")) {
6759
- redactWildcardPath(obj, parts, censor, path78, remove);
6759
+ redactWildcardPath(obj, parts, censor, path77, remove);
6760
6760
  } else {
6761
6761
  if (remove) {
6762
6762
  removeKey(obj, parts);
@@ -6841,8 +6841,8 @@ var require_redact = __commonJS({
6841
6841
  }
6842
6842
  } else {
6843
6843
  if (afterWildcard.includes("*")) {
6844
- const wrappedCensor = typeof censor === "function" ? (value, path78) => {
6845
- const fullPath = [...pathArray.slice(0, pathLength), ...path78];
6844
+ const wrappedCensor = typeof censor === "function" ? (value, path77) => {
6845
+ const fullPath = [...pathArray.slice(0, pathLength), ...path77];
6846
6846
  return censor(value, fullPath);
6847
6847
  } : censor;
6848
6848
  redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
@@ -6877,8 +6877,8 @@ var require_redact = __commonJS({
6877
6877
  return null;
6878
6878
  }
6879
6879
  const pathStructure = /* @__PURE__ */ new Map();
6880
- for (const path78 of pathsToClone) {
6881
- const parts = parsePath(path78);
6880
+ for (const path77 of pathsToClone) {
6881
+ const parts = parsePath(path77);
6882
6882
  let current = pathStructure;
6883
6883
  for (let i = 0; i < parts.length; i++) {
6884
6884
  const part = parts[i];
@@ -6930,24 +6930,24 @@ var require_redact = __commonJS({
6930
6930
  }
6931
6931
  return cloneSelectively(obj, pathStructure);
6932
6932
  }
6933
- function validatePath(path78) {
6934
- if (typeof path78 !== "string") {
6933
+ function validatePath(path77) {
6934
+ if (typeof path77 !== "string") {
6935
6935
  throw new Error("Paths must be (non-empty) strings");
6936
6936
  }
6937
- if (path78 === "") {
6937
+ if (path77 === "") {
6938
6938
  throw new Error("Invalid redaction path ()");
6939
6939
  }
6940
- if (path78.includes("..")) {
6941
- throw new Error(`Invalid redaction path (${path78})`);
6940
+ if (path77.includes("..")) {
6941
+ throw new Error(`Invalid redaction path (${path77})`);
6942
6942
  }
6943
- if (path78.includes(",")) {
6944
- throw new Error(`Invalid redaction path (${path78})`);
6943
+ if (path77.includes(",")) {
6944
+ throw new Error(`Invalid redaction path (${path77})`);
6945
6945
  }
6946
6946
  let bracketCount = 0;
6947
6947
  let inQuotes = false;
6948
6948
  let quoteChar = "";
6949
- for (let i = 0; i < path78.length; i++) {
6950
- const char = path78[i];
6949
+ for (let i = 0; i < path77.length; i++) {
6950
+ const char = path77[i];
6951
6951
  if ((char === '"' || char === "'") && bracketCount > 0) {
6952
6952
  if (!inQuotes) {
6953
6953
  inQuotes = true;
@@ -6961,20 +6961,20 @@ var require_redact = __commonJS({
6961
6961
  } else if (char === "]" && !inQuotes) {
6962
6962
  bracketCount--;
6963
6963
  if (bracketCount < 0) {
6964
- throw new Error(`Invalid redaction path (${path78})`);
6964
+ throw new Error(`Invalid redaction path (${path77})`);
6965
6965
  }
6966
6966
  }
6967
6967
  }
6968
6968
  if (bracketCount !== 0) {
6969
- throw new Error(`Invalid redaction path (${path78})`);
6969
+ throw new Error(`Invalid redaction path (${path77})`);
6970
6970
  }
6971
6971
  }
6972
6972
  function validatePaths(paths) {
6973
6973
  if (!Array.isArray(paths)) {
6974
6974
  throw new TypeError("paths must be an array");
6975
6975
  }
6976
- for (const path78 of paths) {
6977
- validatePath(path78);
6976
+ for (const path77 of paths) {
6977
+ validatePath(path77);
6978
6978
  }
6979
6979
  }
6980
6980
  function slowRedact(options = {}) {
@@ -7142,8 +7142,8 @@ var require_redaction = __commonJS({
7142
7142
  if (shape[k2] === null) {
7143
7143
  o[k2] = (value) => topCensor(value, [k2]);
7144
7144
  } else {
7145
- const wrappedCensor = typeof censor === "function" ? (value, path78) => {
7146
- return censor(value, [k2, ...path78]);
7145
+ const wrappedCensor = typeof censor === "function" ? (value, path77) => {
7146
+ return censor(value, [k2, ...path77]);
7147
7147
  } : censor;
7148
7148
  o[k2] = Redact({
7149
7149
  paths: shape[k2],
@@ -7361,10 +7361,10 @@ var require_atomic_sleep = __commonJS({
7361
7361
  var require_sonic_boom = __commonJS({
7362
7362
  "../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
7363
7363
  "use strict";
7364
- var fs71 = require("fs");
7364
+ var fs70 = require("fs");
7365
7365
  var EventEmitter3 = require("events");
7366
7366
  var inherits = require("util").inherits;
7367
- var path78 = require("path");
7367
+ var path77 = require("path");
7368
7368
  var sleep2 = require_atomic_sleep();
7369
7369
  var assert = require("assert");
7370
7370
  var BUSY_WRITE_TIMEOUT = 100;
@@ -7418,20 +7418,20 @@ var require_sonic_boom = __commonJS({
7418
7418
  const mode = sonic.mode;
7419
7419
  if (sonic.sync) {
7420
7420
  try {
7421
- if (sonic.mkdir) fs71.mkdirSync(path78.dirname(file), { recursive: true });
7422
- const fd = fs71.openSync(file, flags, mode);
7421
+ if (sonic.mkdir) fs70.mkdirSync(path77.dirname(file), { recursive: true });
7422
+ const fd = fs70.openSync(file, flags, mode);
7423
7423
  fileOpened(null, fd);
7424
7424
  } catch (err) {
7425
7425
  fileOpened(err);
7426
7426
  throw err;
7427
7427
  }
7428
7428
  } else if (sonic.mkdir) {
7429
- fs71.mkdir(path78.dirname(file), { recursive: true }, (err) => {
7429
+ fs70.mkdir(path77.dirname(file), { recursive: true }, (err) => {
7430
7430
  if (err) return fileOpened(err);
7431
- fs71.open(file, flags, mode, fileOpened);
7431
+ fs70.open(file, flags, mode, fileOpened);
7432
7432
  });
7433
7433
  } else {
7434
- fs71.open(file, flags, mode, fileOpened);
7434
+ fs70.open(file, flags, mode, fileOpened);
7435
7435
  }
7436
7436
  }
7437
7437
  function SonicBoom(opts) {
@@ -7472,8 +7472,8 @@ var require_sonic_boom = __commonJS({
7472
7472
  this.flush = flushBuffer;
7473
7473
  this.flushSync = flushBufferSync;
7474
7474
  this._actualWrite = actualWriteBuffer;
7475
- fsWriteSync = () => fs71.writeSync(this.fd, this._writingBuf);
7476
- fsWrite = () => fs71.write(this.fd, this._writingBuf, this.release);
7475
+ fsWriteSync = () => fs70.writeSync(this.fd, this._writingBuf);
7476
+ fsWrite = () => fs70.write(this.fd, this._writingBuf, this.release);
7477
7477
  } else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
7478
7478
  this._writingBuf = "";
7479
7479
  this.write = write;
@@ -7482,15 +7482,15 @@ var require_sonic_boom = __commonJS({
7482
7482
  this._actualWrite = actualWrite;
7483
7483
  fsWriteSync = () => {
7484
7484
  if (Buffer.isBuffer(this._writingBuf)) {
7485
- return fs71.writeSync(this.fd, this._writingBuf);
7485
+ return fs70.writeSync(this.fd, this._writingBuf);
7486
7486
  }
7487
- return fs71.writeSync(this.fd, this._writingBuf, "utf8");
7487
+ return fs70.writeSync(this.fd, this._writingBuf, "utf8");
7488
7488
  };
7489
7489
  fsWrite = () => {
7490
7490
  if (Buffer.isBuffer(this._writingBuf)) {
7491
- return fs71.write(this.fd, this._writingBuf, this.release);
7491
+ return fs70.write(this.fd, this._writingBuf, this.release);
7492
7492
  }
7493
- return fs71.write(this.fd, this._writingBuf, "utf8", this.release);
7493
+ return fs70.write(this.fd, this._writingBuf, "utf8", this.release);
7494
7494
  };
7495
7495
  } else {
7496
7496
  throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
@@ -7547,7 +7547,7 @@ var require_sonic_boom = __commonJS({
7547
7547
  }
7548
7548
  }
7549
7549
  if (this._fsync) {
7550
- fs71.fsyncSync(this.fd);
7550
+ fs70.fsyncSync(this.fd);
7551
7551
  }
7552
7552
  const len = this._len;
7553
7553
  if (this._reopening) {
@@ -7661,7 +7661,7 @@ var require_sonic_boom = __commonJS({
7661
7661
  const onDrain = () => {
7662
7662
  if (!this._fsync) {
7663
7663
  try {
7664
- fs71.fsync(this.fd, (err) => {
7664
+ fs70.fsync(this.fd, (err) => {
7665
7665
  this._flushPending = false;
7666
7666
  cb(err);
7667
7667
  });
@@ -7763,7 +7763,7 @@ var require_sonic_boom = __commonJS({
7763
7763
  const fd = this.fd;
7764
7764
  this.once("ready", () => {
7765
7765
  if (fd !== this.fd) {
7766
- fs71.close(fd, (err) => {
7766
+ fs70.close(fd, (err) => {
7767
7767
  if (err) {
7768
7768
  return this.emit("error", err);
7769
7769
  }
@@ -7812,7 +7812,7 @@ var require_sonic_boom = __commonJS({
7812
7812
  buf = this._bufs[0];
7813
7813
  }
7814
7814
  try {
7815
- const n = Buffer.isBuffer(buf) ? fs71.writeSync(this.fd, buf) : fs71.writeSync(this.fd, buf, "utf8");
7815
+ const n = Buffer.isBuffer(buf) ? fs70.writeSync(this.fd, buf) : fs70.writeSync(this.fd, buf, "utf8");
7816
7816
  const releasedBufObj = releaseWritingBuf(buf, this._len, n);
7817
7817
  buf = releasedBufObj.writingBuf;
7818
7818
  this._len = releasedBufObj.len;
@@ -7828,7 +7828,7 @@ var require_sonic_boom = __commonJS({
7828
7828
  }
7829
7829
  }
7830
7830
  try {
7831
- fs71.fsyncSync(this.fd);
7831
+ fs70.fsyncSync(this.fd);
7832
7832
  } catch {
7833
7833
  }
7834
7834
  }
@@ -7849,7 +7849,7 @@ var require_sonic_boom = __commonJS({
7849
7849
  buf = mergeBuf(this._bufs[0], this._lens[0]);
7850
7850
  }
7851
7851
  try {
7852
- const n = fs71.writeSync(this.fd, buf);
7852
+ const n = fs70.writeSync(this.fd, buf);
7853
7853
  buf = buf.subarray(n);
7854
7854
  this._len = Math.max(this._len - n, 0);
7855
7855
  if (buf.length <= 0) {
@@ -7877,13 +7877,13 @@ var require_sonic_boom = __commonJS({
7877
7877
  this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
7878
7878
  if (this.sync) {
7879
7879
  try {
7880
- const written = Buffer.isBuffer(this._writingBuf) ? fs71.writeSync(this.fd, this._writingBuf) : fs71.writeSync(this.fd, this._writingBuf, "utf8");
7880
+ const written = Buffer.isBuffer(this._writingBuf) ? fs70.writeSync(this.fd, this._writingBuf) : fs70.writeSync(this.fd, this._writingBuf, "utf8");
7881
7881
  release(null, written);
7882
7882
  } catch (err) {
7883
7883
  release(err);
7884
7884
  }
7885
7885
  } else {
7886
- fs71.write(this.fd, this._writingBuf, release);
7886
+ fs70.write(this.fd, this._writingBuf, release);
7887
7887
  }
7888
7888
  }
7889
7889
  function actualWriteBuffer() {
@@ -7892,7 +7892,7 @@ var require_sonic_boom = __commonJS({
7892
7892
  this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
7893
7893
  if (this.sync) {
7894
7894
  try {
7895
- const written = fs71.writeSync(this.fd, this._writingBuf);
7895
+ const written = fs70.writeSync(this.fd, this._writingBuf);
7896
7896
  release(null, written);
7897
7897
  } catch (err) {
7898
7898
  release(err);
@@ -7901,7 +7901,7 @@ var require_sonic_boom = __commonJS({
7901
7901
  if (kCopyBuffer) {
7902
7902
  this._writingBuf = Buffer.from(this._writingBuf);
7903
7903
  }
7904
- fs71.write(this.fd, this._writingBuf, release);
7904
+ fs70.write(this.fd, this._writingBuf, release);
7905
7905
  }
7906
7906
  }
7907
7907
  function actualClose(sonic) {
@@ -7917,12 +7917,12 @@ var require_sonic_boom = __commonJS({
7917
7917
  sonic._lens = [];
7918
7918
  assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
7919
7919
  try {
7920
- fs71.fsync(sonic.fd, closeWrapped);
7920
+ fs70.fsync(sonic.fd, closeWrapped);
7921
7921
  } catch {
7922
7922
  }
7923
7923
  function closeWrapped() {
7924
7924
  if (sonic.fd !== 1 && sonic.fd !== 2) {
7925
- fs71.close(sonic.fd, done);
7925
+ fs70.close(sonic.fd, done);
7926
7926
  } else {
7927
7927
  done();
7928
7928
  }
@@ -11057,11 +11057,11 @@ var init_lib = __esm({
11057
11057
  }
11058
11058
  }
11059
11059
  },
11060
- addToPath: function addToPath(path78, added, removed, oldPosInc, options) {
11061
- var last = path78.lastComponent;
11060
+ addToPath: function addToPath(path77, added, removed, oldPosInc, options) {
11061
+ var last = path77.lastComponent;
11062
11062
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
11063
11063
  return {
11064
- oldPos: path78.oldPos + oldPosInc,
11064
+ oldPos: path77.oldPos + oldPosInc,
11065
11065
  lastComponent: {
11066
11066
  count: last.count + 1,
11067
11067
  added,
@@ -11071,7 +11071,7 @@ var init_lib = __esm({
11071
11071
  };
11072
11072
  } else {
11073
11073
  return {
11074
- oldPos: path78.oldPos + oldPosInc,
11074
+ oldPos: path77.oldPos + oldPosInc,
11075
11075
  lastComponent: {
11076
11076
  count: 1,
11077
11077
  added,
@@ -11312,10 +11312,10 @@ function cwdToHashDir(cwd) {
11312
11312
  return cwd.replace(/[^a-zA-Z0-9]/g, "-");
11313
11313
  }
11314
11314
  function newestSubagentMtimeMs(projectsRoot, cwd, toolSessionId) {
11315
- const dir = import_node_path5.default.join(projectsRoot, cwdToHashDir(cwd), toolSessionId, "subagents");
11315
+ const dir = import_node_path4.default.join(projectsRoot, cwdToHashDir(cwd), toolSessionId, "subagents");
11316
11316
  let entries;
11317
11317
  try {
11318
- entries = import_node_fs5.default.readdirSync(dir, { withFileTypes: true });
11318
+ entries = import_node_fs4.default.readdirSync(dir, { withFileTypes: true });
11319
11319
  } catch {
11320
11320
  return null;
11321
11321
  }
@@ -11324,7 +11324,7 @@ function newestSubagentMtimeMs(projectsRoot, cwd, toolSessionId) {
11324
11324
  if (!e.isFile()) continue;
11325
11325
  if (!e.name.startsWith("agent-") || !e.name.endsWith(".jsonl")) continue;
11326
11326
  try {
11327
- const m2 = import_node_fs5.default.statSync(import_node_path5.default.join(dir, e.name)).mtimeMs;
11327
+ const m2 = import_node_fs4.default.statSync(import_node_path4.default.join(dir, e.name)).mtimeMs;
11328
11328
  if (newest === null || m2 > newest) newest = m2;
11329
11329
  } catch {
11330
11330
  }
@@ -11337,7 +11337,7 @@ function hashDirToCwd(hash) {
11337
11337
  }
11338
11338
  function safeStatMtime(p2) {
11339
11339
  try {
11340
- return import_node_fs5.default.statSync(p2).mtimeMs;
11340
+ return import_node_fs4.default.statSync(p2).mtimeMs;
11341
11341
  } catch {
11342
11342
  return 0;
11343
11343
  }
@@ -11345,7 +11345,7 @@ function safeStatMtime(p2) {
11345
11345
  function readJsonlLines(file) {
11346
11346
  let raw;
11347
11347
  try {
11348
- raw = import_node_fs5.default.readFileSync(file, "utf8");
11348
+ raw = import_node_fs4.default.readFileSync(file, "utf8");
11349
11349
  } catch (err) {
11350
11350
  if (err.code === "ENOENT") return [];
11351
11351
  throw err;
@@ -11537,10 +11537,10 @@ function attachmentToHistoryMessage(o, ts) {
11537
11537
  const memories = raw.map((m2) => {
11538
11538
  if (!m2 || typeof m2 !== "object") return null;
11539
11539
  const rec3 = m2;
11540
- const path78 = typeof rec3.path === "string" ? rec3.path : null;
11540
+ const path77 = typeof rec3.path === "string" ? rec3.path : null;
11541
11541
  const content = typeof rec3.content === "string" ? rec3.content : null;
11542
- if (!path78 || content == null) return null;
11543
- const entry = { path: path78, content };
11542
+ if (!path77 || content == null) return null;
11543
+ const entry = { path: path77, content };
11544
11544
  if (typeof rec3.mtimeMs === "number") entry.mtimeMs = rec3.mtimeMs;
11545
11545
  return entry;
11546
11546
  }).filter((m2) => m2 !== null);
@@ -11576,8 +11576,8 @@ function attachmentDeferredToolsText(a) {
11576
11576
  function readBackupContent(fileHistoryRoot, toolSessionId, backupFileName) {
11577
11577
  if (backupFileName === null) return null;
11578
11578
  try {
11579
- return import_node_fs5.default.readFileSync(
11580
- import_node_path5.default.join(fileHistoryRoot, toolSessionId, backupFileName),
11579
+ return import_node_fs4.default.readFileSync(
11580
+ import_node_path4.default.join(fileHistoryRoot, toolSessionId, backupFileName),
11581
11581
  "utf8"
11582
11582
  );
11583
11583
  } catch {
@@ -11586,19 +11586,19 @@ function readBackupContent(fileHistoryRoot, toolSessionId, backupFileName) {
11586
11586
  }
11587
11587
  function readCurrentContent(filePath) {
11588
11588
  try {
11589
- return import_node_fs5.default.readFileSync(filePath, "utf8");
11589
+ return import_node_fs4.default.readFileSync(filePath, "utf8");
11590
11590
  } catch (err) {
11591
11591
  if (err.code === "ENOENT") return null;
11592
11592
  return null;
11593
11593
  }
11594
11594
  }
11595
- var import_node_fs5, import_node_os3, import_node_path5, TASK_NOTIFICATION_RE, TASK_ID_RE, TOOL_USE_ID_RE, SLASH_COMMAND_RE, LOCAL_COMMAND_RE, SYSTEM_REMINDER_RE, OPENSPEC_BLOCK_RE, SKILL_HINT_RE, ATTACHMENT_SILENT_SUBTYPES, ClaudeHistoryReader;
11595
+ var import_node_fs4, import_node_os3, import_node_path4, TASK_NOTIFICATION_RE, TASK_ID_RE, TOOL_USE_ID_RE, SLASH_COMMAND_RE, LOCAL_COMMAND_RE, SYSTEM_REMINDER_RE, OPENSPEC_BLOCK_RE, SKILL_HINT_RE, ATTACHMENT_SILENT_SUBTYPES, ClaudeHistoryReader;
11596
11596
  var init_claude_history = __esm({
11597
11597
  "src/tools/claude-history.ts"() {
11598
11598
  "use strict";
11599
- import_node_fs5 = __toESM(require("fs"), 1);
11599
+ import_node_fs4 = __toESM(require("fs"), 1);
11600
11600
  import_node_os3 = __toESM(require("os"), 1);
11601
- import_node_path5 = __toESM(require("path"), 1);
11601
+ import_node_path4 = __toESM(require("path"), 1);
11602
11602
  init_lib();
11603
11603
  init_tool_result_extra();
11604
11604
  TASK_NOTIFICATION_RE = /<task-notification\b[\s\S]*?<\/task-notification>/i;
@@ -11622,14 +11622,14 @@ var init_claude_history = __esm({
11622
11622
  // 每次 user 提交前 trackEdit 拷一份,作为 rewind 回退目标
11623
11623
  fileHistoryRoot;
11624
11624
  constructor(opts = {}) {
11625
- const base = opts.baseDir ?? import_node_path5.default.join(import_node_os3.default.homedir(), ".claude");
11626
- this.projectsRoot = import_node_path5.default.join(base, "projects");
11627
- this.fileHistoryRoot = import_node_path5.default.join(base, "file-history");
11625
+ const base = opts.baseDir ?? import_node_path4.default.join(import_node_os3.default.homedir(), ".claude");
11626
+ this.projectsRoot = import_node_path4.default.join(base, "projects");
11627
+ this.fileHistoryRoot = import_node_path4.default.join(base, "file-history");
11628
11628
  }
11629
11629
  async listProjects() {
11630
11630
  let entries;
11631
11631
  try {
11632
- entries = import_node_fs5.default.readdirSync(this.projectsRoot, { withFileTypes: true });
11632
+ entries = import_node_fs4.default.readdirSync(this.projectsRoot, { withFileTypes: true });
11633
11633
  } catch (err) {
11634
11634
  if (err.code === "ENOENT") return [];
11635
11635
  throw err;
@@ -11637,9 +11637,9 @@ var init_claude_history = __esm({
11637
11637
  const out = [];
11638
11638
  for (const ent of entries) {
11639
11639
  if (!ent.isDirectory()) continue;
11640
- const dir = import_node_path5.default.join(this.projectsRoot, ent.name);
11641
- const files = import_node_fs5.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
11642
- const updatedAtMs = files.reduce((m2, f) => Math.max(m2, safeStatMtime(import_node_path5.default.join(dir, f))), 0);
11640
+ const dir = import_node_path4.default.join(this.projectsRoot, ent.name);
11641
+ const files = import_node_fs4.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
11642
+ const updatedAtMs = files.reduce((m2, f) => Math.max(m2, safeStatMtime(import_node_path4.default.join(dir, f))), 0);
11643
11643
  out.push({
11644
11644
  projectPath: hashDirToCwd(ent.name),
11645
11645
  hashDir: ent.name,
@@ -11651,17 +11651,17 @@ var init_claude_history = __esm({
11651
11651
  return out;
11652
11652
  }
11653
11653
  async listSessions(args) {
11654
- const dir = import_node_path5.default.join(this.projectsRoot, cwdToHashDir(args.projectPath));
11654
+ const dir = import_node_path4.default.join(this.projectsRoot, cwdToHashDir(args.projectPath));
11655
11655
  let files;
11656
11656
  try {
11657
- files = import_node_fs5.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
11657
+ files = import_node_fs4.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
11658
11658
  } catch (err) {
11659
11659
  if (err.code === "ENOENT") return [];
11660
11660
  throw err;
11661
11661
  }
11662
11662
  const out = [];
11663
11663
  for (const f of files) {
11664
- const full = import_node_path5.default.join(dir, f);
11664
+ const full = import_node_path4.default.join(dir, f);
11665
11665
  const toolSessionId = f.slice(0, -".jsonl".length);
11666
11666
  const lines = readJsonlLines(full);
11667
11667
  let summary = "";
@@ -11716,7 +11716,7 @@ var init_claude_history = __esm({
11716
11716
  return out;
11717
11717
  }
11718
11718
  async read(args) {
11719
- const file = import_node_path5.default.join(
11719
+ const file = import_node_path4.default.join(
11720
11720
  this.projectsRoot,
11721
11721
  cwdToHashDir(args.cwd),
11722
11722
  `${args.toolSessionId}.jsonl`
@@ -11753,7 +11753,7 @@ var init_claude_history = __esm({
11753
11753
  // 独立目录路径:<projectsRoot>/<cwdHash>/<toolSessionId>/subagents/*.jsonl
11754
11754
  // 返回 null 表示目录不存在(调用方回退旧实现);返回空数组表示目录存在但无 jsonl
11755
11755
  listSubagentsFromDirectory(cwd, toolSessionId) {
11756
- const dir = import_node_path5.default.join(
11756
+ const dir = import_node_path4.default.join(
11757
11757
  this.projectsRoot,
11758
11758
  cwdToHashDir(cwd),
11759
11759
  toolSessionId,
@@ -11761,7 +11761,7 @@ var init_claude_history = __esm({
11761
11761
  );
11762
11762
  let entries;
11763
11763
  try {
11764
- entries = import_node_fs5.default.readdirSync(dir, { withFileTypes: true });
11764
+ entries = import_node_fs4.default.readdirSync(dir, { withFileTypes: true });
11765
11765
  } catch (err) {
11766
11766
  if (err.code === "ENOENT") return null;
11767
11767
  return null;
@@ -11771,7 +11771,7 @@ var init_claude_history = __esm({
11771
11771
  if (!e.isFile()) continue;
11772
11772
  if (!e.name.startsWith("agent-") || !e.name.endsWith(".jsonl")) continue;
11773
11773
  const subagentId = e.name.slice("agent-".length, -".jsonl".length);
11774
- const filePath = import_node_path5.default.join(dir, e.name);
11774
+ const filePath = import_node_path4.default.join(dir, e.name);
11775
11775
  const lines = readJsonlLines(filePath);
11776
11776
  let firstText = "";
11777
11777
  let messageCount = 0;
@@ -11788,7 +11788,7 @@ var init_claude_history = __esm({
11788
11788
  return out;
11789
11789
  }
11790
11790
  listSubagentsFromMainJsonl(cwd, toolSessionId) {
11791
- const file = import_node_path5.default.join(
11791
+ const file = import_node_path4.default.join(
11792
11792
  this.projectsRoot,
11793
11793
  cwdToHashDir(cwd),
11794
11794
  `${toolSessionId}.jsonl`
@@ -11823,7 +11823,7 @@ var init_claude_history = __esm({
11823
11823
  }
11824
11824
  // 独立文件路径:agent-<subagentId>.jsonl;文件不存在返回 null 让调用方回退旧实现
11825
11825
  readSubagentFromFile(cwd, toolSessionId, subagentId) {
11826
- const file = import_node_path5.default.join(
11826
+ const file = import_node_path4.default.join(
11827
11827
  this.projectsRoot,
11828
11828
  cwdToHashDir(cwd),
11829
11829
  toolSessionId,
@@ -11832,7 +11832,7 @@ var init_claude_history = __esm({
11832
11832
  );
11833
11833
  let exists = false;
11834
11834
  try {
11835
- exists = import_node_fs5.default.statSync(file).isFile();
11835
+ exists = import_node_fs4.default.statSync(file).isFile();
11836
11836
  } catch {
11837
11837
  return null;
11838
11838
  }
@@ -11851,7 +11851,7 @@ var init_claude_history = __esm({
11851
11851
  * "那一刻每个 tracked 文件对应的 backup 文件名"
11852
11852
  */
11853
11853
  readFileHistorySnapshots(args) {
11854
- const file = import_node_path5.default.join(
11854
+ const file = import_node_path4.default.join(
11855
11855
  this.projectsRoot,
11856
11856
  cwdToHashDir(args.cwd),
11857
11857
  `${args.toolSessionId}.jsonl`
@@ -11896,7 +11896,7 @@ var init_claude_history = __esm({
11896
11896
  for (const [anchorId, target] of snapshots) {
11897
11897
  let hasAny = false;
11898
11898
  for (const [rawPath, backup] of Object.entries(target)) {
11899
- const absPath = import_node_path5.default.isAbsolute(rawPath) ? rawPath : import_node_path5.default.join(args.cwd, rawPath);
11899
+ const absPath = import_node_path4.default.isAbsolute(rawPath) ? rawPath : import_node_path4.default.join(args.cwd, rawPath);
11900
11900
  const backupContent = readBackupContent(
11901
11901
  this.fileHistoryRoot,
11902
11902
  args.toolSessionId,
@@ -11936,7 +11936,7 @@ var init_claude_history = __esm({
11936
11936
  let totalInsertions = 0;
11937
11937
  let totalDeletions = 0;
11938
11938
  for (const [rawPath, backup] of Object.entries(target)) {
11939
- const absPath = import_node_path5.default.isAbsolute(rawPath) ? rawPath : import_node_path5.default.join(args.cwd, rawPath);
11939
+ const absPath = import_node_path4.default.isAbsolute(rawPath) ? rawPath : import_node_path4.default.join(args.cwd, rawPath);
11940
11940
  const backupContent = readBackupContent(
11941
11941
  this.fileHistoryRoot,
11942
11942
  args.toolSessionId,
@@ -11983,7 +11983,7 @@ var init_claude_history = __esm({
11983
11983
  };
11984
11984
  }
11985
11985
  readSubagentFromMainJsonl(cwd, toolSessionId, subagentId) {
11986
- const file = import_node_path5.default.join(
11986
+ const file = import_node_path4.default.join(
11987
11987
  this.projectsRoot,
11988
11988
  cwdToHashDir(cwd),
11989
11989
  `${toolSessionId}.jsonl`
@@ -12016,13 +12016,13 @@ var init_src = __esm({
12016
12016
  function probeViaWhich() {
12017
12017
  try {
12018
12018
  const out = (0, import_node_child_process2.execFileSync)("which", ["claude"], { encoding: "utf8" }).trim();
12019
- if (out && import_node_fs15.default.existsSync(out)) return out;
12019
+ if (out && import_node_fs14.default.existsSync(out)) return out;
12020
12020
  } catch {
12021
12021
  }
12022
12022
  return null;
12023
12023
  }
12024
12024
  async function probeClaude(env = process.env) {
12025
- if (env.CLAUDE_BIN && import_node_fs15.default.existsSync(env.CLAUDE_BIN)) {
12025
+ if (env.CLAUDE_BIN && import_node_fs14.default.existsSync(env.CLAUDE_BIN)) {
12026
12026
  return { available: true, path: env.CLAUDE_BIN };
12027
12027
  }
12028
12028
  const w2 = probeViaWhich();
@@ -12360,10 +12360,10 @@ function parseAttachment(obj) {
12360
12360
  const memories = raw.map((m2) => {
12361
12361
  if (!m2 || typeof m2 !== "object") return null;
12362
12362
  const rec3 = m2;
12363
- const path78 = typeof rec3.path === "string" ? rec3.path : null;
12363
+ const path77 = typeof rec3.path === "string" ? rec3.path : null;
12364
12364
  const content = typeof rec3.content === "string" ? rec3.content : null;
12365
- if (!path78 || content == null) return null;
12366
- const out = { path: path78, content };
12365
+ if (!path77 || content == null) return null;
12366
+ const out = { path: path77, content };
12367
12367
  if (typeof rec3.mtimeMs === "number") out.mtimeMs = rec3.mtimeMs;
12368
12368
  return out;
12369
12369
  }).filter((m2) => m2 !== null);
@@ -12467,13 +12467,13 @@ function encodeClaudeStdin(text) {
12467
12467
  };
12468
12468
  return JSON.stringify(frame) + "\n";
12469
12469
  }
12470
- var import_node_child_process, import_node_child_process2, import_node_fs15, ATTACHMENT_SILENT_SUBTYPES2, unknownTypeHandler, ATTACHMENT_RE, IMAGE_EXT_MIME, CLAUDE_MODELS, CLAUDE_PERMISSION_MODES, CLAUDE_CAPABILITIES, ClaudeAdapter;
12470
+ var import_node_child_process, import_node_child_process2, import_node_fs14, ATTACHMENT_SILENT_SUBTYPES2, unknownTypeHandler, ATTACHMENT_RE, IMAGE_EXT_MIME, CLAUDE_MODELS, CLAUDE_PERMISSION_MODES, CLAUDE_CAPABILITIES, ClaudeAdapter;
12471
12471
  var init_claude = __esm({
12472
12472
  "src/tools/claude.ts"() {
12473
12473
  "use strict";
12474
12474
  import_node_child_process = require("child_process");
12475
12475
  import_node_child_process2 = require("child_process");
12476
- import_node_fs15 = __toESM(require("fs"), 1);
12476
+ import_node_fs14 = __toESM(require("fs"), 1);
12477
12477
  init_protocol();
12478
12478
  init_claude_history();
12479
12479
  init_tool_result_extra();
@@ -33460,8 +33460,8 @@ var require_utils = __commonJS({
33460
33460
  var result = transform[inputType][outputType](input);
33461
33461
  return result;
33462
33462
  };
33463
- exports2.resolve = function(path78) {
33464
- var parts = path78.split("/");
33463
+ exports2.resolve = function(path77) {
33464
+ var parts = path77.split("/");
33465
33465
  var result = [];
33466
33466
  for (var index = 0; index < parts.length; index++) {
33467
33467
  var part = parts[index];
@@ -39314,18 +39314,18 @@ var require_object = __commonJS({
39314
39314
  var object = new ZipObject(name, zipObjectContent, o);
39315
39315
  this.files[name] = object;
39316
39316
  };
39317
- var parentFolder = function(path78) {
39318
- if (path78.slice(-1) === "/") {
39319
- path78 = path78.substring(0, path78.length - 1);
39317
+ var parentFolder = function(path77) {
39318
+ if (path77.slice(-1) === "/") {
39319
+ path77 = path77.substring(0, path77.length - 1);
39320
39320
  }
39321
- var lastSlash = path78.lastIndexOf("/");
39322
- return lastSlash > 0 ? path78.substring(0, lastSlash) : "";
39321
+ var lastSlash = path77.lastIndexOf("/");
39322
+ return lastSlash > 0 ? path77.substring(0, lastSlash) : "";
39323
39323
  };
39324
- var forceTrailingSlash = function(path78) {
39325
- if (path78.slice(-1) !== "/") {
39326
- path78 += "/";
39324
+ var forceTrailingSlash = function(path77) {
39325
+ if (path77.slice(-1) !== "/") {
39326
+ path77 += "/";
39327
39327
  }
39328
- return path78;
39328
+ return path77;
39329
39329
  };
39330
39330
  var folderAdd = function(name, createFolders) {
39331
39331
  createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
@@ -40326,7 +40326,7 @@ var require_lib3 = __commonJS({
40326
40326
 
40327
40327
  // src/sshd/contact-ssh-log.ts
40328
40328
  function createContactSshLog(dataDir) {
40329
- const file = import_node_path41.default.join(dataDir, "contact-ssh.log");
40329
+ const file = import_node_path40.default.join(dataDir, "contact-ssh.log");
40330
40330
  function append(level, tag, message, meta) {
40331
40331
  const time = (/* @__PURE__ */ new Date()).toISOString();
40332
40332
  let line = `[${time}] [${level}] [${tag}] ${message}`;
@@ -40339,8 +40339,8 @@ function createContactSshLog(dataDir) {
40339
40339
  }
40340
40340
  line += "\n";
40341
40341
  try {
40342
- import_node_fs40.default.mkdirSync(import_node_path41.default.dirname(file), { recursive: true });
40343
- import_node_fs40.default.appendFileSync(file, line, { mode: 384 });
40342
+ import_node_fs39.default.mkdirSync(import_node_path40.default.dirname(file), { recursive: true });
40343
+ import_node_fs39.default.appendFileSync(file, line, { mode: 384 });
40344
40344
  } catch {
40345
40345
  }
40346
40346
  }
@@ -40350,12 +40350,12 @@ function createContactSshLog(dataDir) {
40350
40350
  error: (tag, message, meta) => append("ERROR", tag, message, meta)
40351
40351
  };
40352
40352
  }
40353
- var import_node_fs40, import_node_path41, nullContactSshLog;
40353
+ var import_node_fs39, import_node_path40, nullContactSshLog;
40354
40354
  var init_contact_ssh_log = __esm({
40355
40355
  "src/sshd/contact-ssh-log.ts"() {
40356
40356
  "use strict";
40357
- import_node_fs40 = __toESM(require("fs"), 1);
40358
- import_node_path41 = __toESM(require("path"), 1);
40357
+ import_node_fs39 = __toESM(require("fs"), 1);
40358
+ import_node_path40 = __toESM(require("path"), 1);
40359
40359
  nullContactSshLog = {
40360
40360
  info: () => {
40361
40361
  },
@@ -40370,7 +40370,7 @@ var init_contact_ssh_log = __esm({
40370
40370
  // src/run-case/recorder.ts
40371
40371
  function startRunCaseRecorder(opts) {
40372
40372
  const now = opts.now ?? Date.now;
40373
- const dir = import_node_path65.default.dirname(opts.recordPath);
40373
+ const dir = import_node_path64.default.dirname(opts.recordPath);
40374
40374
  let stream = null;
40375
40375
  let closing = false;
40376
40376
  let closedSettled = false;
@@ -40384,8 +40384,8 @@ function startRunCaseRecorder(opts) {
40384
40384
  });
40385
40385
  const ensureStream = () => {
40386
40386
  if (stream) return stream;
40387
- import_node_fs52.default.mkdirSync(dir, { recursive: true });
40388
- stream = import_node_fs52.default.createWriteStream(opts.recordPath, { flags: "a" });
40387
+ import_node_fs51.default.mkdirSync(dir, { recursive: true });
40388
+ stream = import_node_fs51.default.createWriteStream(opts.recordPath, { flags: "a" });
40389
40389
  stream.on("close", () => closedResolve());
40390
40390
  return stream;
40391
40391
  };
@@ -40410,12 +40410,12 @@ function startRunCaseRecorder(opts) {
40410
40410
  };
40411
40411
  return { tap, close, closed };
40412
40412
  }
40413
- var import_node_fs52, import_node_path65;
40413
+ var import_node_fs51, import_node_path64;
40414
40414
  var init_recorder = __esm({
40415
40415
  "src/run-case/recorder.ts"() {
40416
40416
  "use strict";
40417
- import_node_fs52 = __toESM(require("fs"), 1);
40418
- import_node_path65 = __toESM(require("path"), 1);
40417
+ import_node_fs51 = __toESM(require("fs"), 1);
40418
+ import_node_path64 = __toESM(require("path"), 1);
40419
40419
  }
40420
40420
  });
40421
40421
 
@@ -40458,7 +40458,7 @@ var init_wire = __esm({
40458
40458
  // src/run-case/controller.ts
40459
40459
  async function runController(opts) {
40460
40460
  const now = opts.now ?? Date.now;
40461
- const cwd = opts.cwd ?? (0, import_node_fs53.mkdtempSync)(import_node_path66.default.join(import_node_os22.default.tmpdir(), "clawd-runcase-"));
40461
+ const cwd = opts.cwd ?? (0, import_node_fs52.mkdtempSync)(import_node_path65.default.join(import_node_os22.default.tmpdir(), "clawd-runcase-"));
40462
40462
  const ownsCwd = opts.cwd === void 0;
40463
40463
  const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
40464
40464
  const spawnCtx = { cwd };
@@ -40619,19 +40619,19 @@ async function runController(opts) {
40619
40619
  if (sigintHandler) process.off("SIGINT", sigintHandler);
40620
40620
  if (ownsCwd) {
40621
40621
  try {
40622
- (0, import_node_fs53.rmSync)(cwd, { recursive: true, force: true });
40622
+ (0, import_node_fs52.rmSync)(cwd, { recursive: true, force: true });
40623
40623
  } catch {
40624
40624
  }
40625
40625
  }
40626
40626
  return exitCode ?? 0;
40627
40627
  }
40628
- var import_node_fs53, import_node_os22, import_node_path66;
40628
+ var import_node_fs52, import_node_os22, import_node_path65;
40629
40629
  var init_controller = __esm({
40630
40630
  "src/run-case/controller.ts"() {
40631
40631
  "use strict";
40632
- import_node_fs53 = require("fs");
40632
+ import_node_fs52 = require("fs");
40633
40633
  import_node_os22 = __toESM(require("os"), 1);
40634
- import_node_path66 = __toESM(require("path"), 1);
40634
+ import_node_path65 = __toESM(require("path"), 1);
40635
40635
  init_claude();
40636
40636
  init_stdout_splitter();
40637
40637
  init_permission_stdio();
@@ -40742,13 +40742,13 @@ async function sshRelay(argv) {
40742
40742
  process.stderr.write("clawd ssh-relay: missing <peer-device-id>\n" + SSH_RELAY_HELP);
40743
40743
  return 2;
40744
40744
  }
40745
- const dataDir = args.dataDir ?? import_node_path67.default.join(import_node_os23.default.homedir(), ".clawd");
40745
+ const dataDir = args.dataDir ?? import_node_path66.default.join(import_node_os23.default.homedir(), ".clawd");
40746
40746
  const sshLog = createContactSshLog(dataDir);
40747
40747
  const contact = findContact(dataDir, args.peerDeviceId);
40748
40748
  if (!contact) {
40749
40749
  sshLog.error("relay.contact-not-found", "ssh-relay \u627E\u4E0D\u5230 peer contact", {
40750
40750
  peerDeviceId: args.peerDeviceId,
40751
- contactsPath: import_node_path67.default.join(dataDir, "contacts.json")
40751
+ contactsPath: import_node_path66.default.join(dataDir, "contacts.json")
40752
40752
  });
40753
40753
  process.stderr.write(`clawd ssh-relay: contact ${args.peerDeviceId} not found in ${dataDir}/contacts.json
40754
40754
  `);
@@ -40869,10 +40869,10 @@ function parseSshRelayArgs(argv) {
40869
40869
  return out;
40870
40870
  }
40871
40871
  function findContact(dataDir, deviceId) {
40872
- const file = import_node_path67.default.join(dataDir, "contacts.json");
40872
+ const file = import_node_path66.default.join(dataDir, "contacts.json");
40873
40873
  let raw;
40874
40874
  try {
40875
- raw = import_node_fs54.default.readFileSync(file, "utf8");
40875
+ raw = import_node_fs53.default.readFileSync(file, "utf8");
40876
40876
  } catch {
40877
40877
  return null;
40878
40878
  }
@@ -40890,13 +40890,13 @@ function findContact(dataDir, deviceId) {
40890
40890
  }
40891
40891
  return null;
40892
40892
  }
40893
- var import_node_fs54, import_node_os23, import_node_path67, SSH_RELAY_HELP;
40893
+ var import_node_fs53, import_node_os23, import_node_path66, SSH_RELAY_HELP;
40894
40894
  var init_sshd_cli_relay = __esm({
40895
40895
  "src/sshd/sshd-cli-relay.ts"() {
40896
40896
  "use strict";
40897
- import_node_fs54 = __toESM(require("fs"), 1);
40897
+ import_node_fs53 = __toESM(require("fs"), 1);
40898
40898
  import_node_os23 = __toESM(require("os"), 1);
40899
- import_node_path67 = __toESM(require("path"), 1);
40899
+ import_node_path66 = __toESM(require("path"), 1);
40900
40900
  init_wrapper();
40901
40901
  init_src();
40902
40902
  init_peer_forward();
@@ -41100,8 +41100,8 @@ Env (advanced):
41100
41100
  `;
41101
41101
 
41102
41102
  // src/index.ts
41103
- var import_node_path64 = __toESM(require("path"), 1);
41104
- var import_node_fs51 = __toESM(require("fs"), 1);
41103
+ var import_node_path63 = __toESM(require("path"), 1);
41104
+ var import_node_fs50 = __toESM(require("fs"), 1);
41105
41105
  var import_node_os21 = __toESM(require("os"), 1);
41106
41106
 
41107
41107
  // ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/stringify.js
@@ -41731,8 +41731,8 @@ var SessionStoreFactory = class {
41731
41731
  };
41732
41732
 
41733
41733
  // src/session/manager.ts
41734
- var import_node_fs8 = __toESM(require("fs"), 1);
41735
- var import_node_path9 = __toESM(require("path"), 1);
41734
+ var import_node_fs7 = __toESM(require("fs"), 1);
41735
+ var import_node_path8 = __toESM(require("path"), 1);
41736
41736
  var import_node_os5 = __toESM(require("os"), 1);
41737
41737
  init_protocol();
41738
41738
 
@@ -41820,63 +41820,11 @@ function composeGuestSandbox(base, userWorkDir, spawnCwd) {
41820
41820
  "~/.clawd/config.json",
41821
41821
  "~/.clawd/auth.json"
41822
41822
  ]);
41823
+ const netv = s.sandbox.network ?? (s.sandbox.network = {});
41824
+ netv.allowedDomains = unionArr(netv.allowedDomains, ["*.tunnel.clawos.chat"]);
41823
41825
  return s;
41824
41826
  }
41825
41827
 
41826
- // src/tools/owner-credentials.ts
41827
- var import_node_fs4 = __toESM(require("fs"), 1);
41828
- var import_node_path4 = __toESM(require("path"), 1);
41829
- function readOwnerCredentials(homeDir, logger) {
41830
- const settingsPath = import_node_path4.default.join(homeDir, ".claude", "settings.json");
41831
- let raw;
41832
- try {
41833
- raw = import_node_fs4.default.readFileSync(settingsPath, "utf8");
41834
- } catch (err) {
41835
- const code = err.code;
41836
- if (code === "ENOENT") return null;
41837
- logger?.warn("owner ~/.claude/settings.json read failed", { code });
41838
- return null;
41839
- }
41840
- let parsed;
41841
- try {
41842
- parsed = JSON.parse(raw);
41843
- } catch {
41844
- logger?.warn("owner ~/.claude/settings.json malformed JSON");
41845
- return null;
41846
- }
41847
- if (!parsed || typeof parsed !== "object") return null;
41848
- const obj = parsed;
41849
- const bundle = {};
41850
- const envRaw = obj.env;
41851
- if (envRaw && typeof envRaw === "object" && !Array.isArray(envRaw)) {
41852
- const filtered = {};
41853
- for (const [k2, v2] of Object.entries(envRaw)) {
41854
- if (k2.startsWith("ANTHROPIC_") && typeof v2 === "string") filtered[k2] = v2;
41855
- }
41856
- if (Object.keys(filtered).length > 0) bundle.env = filtered;
41857
- }
41858
- const helperRaw = obj.apiKeyHelper;
41859
- if (typeof helperRaw === "string" && helperRaw.length > 0) {
41860
- if (!import_node_path4.default.isAbsolute(helperRaw)) {
41861
- logger?.warn(
41862
- "owner apiKeyHelper is not absolute; cc will resolve against guest cwd (persona dir), likely EXEC not found",
41863
- { basename: import_node_path4.default.basename(helperRaw) }
41864
- );
41865
- }
41866
- bundle.apiKeyHelper = helperRaw;
41867
- }
41868
- if (!bundle.env && !bundle.apiKeyHelper) return null;
41869
- return bundle;
41870
- }
41871
- function mergeOwnerCredentials(guestSandbox, bundle) {
41872
- if (!bundle) return guestSandbox;
41873
- return {
41874
- ...guestSandbox,
41875
- ...bundle.env ? { env: bundle.env } : {},
41876
- ...bundle.apiKeyHelper ? { apiKeyHelper: bundle.apiKeyHelper } : {}
41877
- };
41878
- }
41879
-
41880
41828
  // src/shift/wrap.ts
41881
41829
  function wrapShiftFirePrompt(args) {
41882
41830
  return [
@@ -41895,7 +41843,7 @@ function escapeAttr(v2) {
41895
41843
 
41896
41844
  // src/session/runner.ts
41897
41845
  var import_node_os4 = __toESM(require("os"), 1);
41898
- var import_node_path7 = __toESM(require("path"), 1);
41846
+ var import_node_path6 = __toESM(require("path"), 1);
41899
41847
 
41900
41848
  // src/session/reducer.ts
41901
41849
  init_runtime();
@@ -42823,8 +42771,8 @@ init_permission_stdio();
42823
42771
  init_claude_history();
42824
42772
 
42825
42773
  // src/ipc-recorder.ts
42826
- var import_node_fs6 = __toESM(require("fs"), 1);
42827
- var import_node_path6 = __toESM(require("path"), 1);
42774
+ var import_node_fs5 = __toESM(require("fs"), 1);
42775
+ var import_node_path5 = __toESM(require("path"), 1);
42828
42776
  function tsForFilename(ms) {
42829
42777
  return new Date(ms).toISOString().replace(/[:.]/g, "-");
42830
42778
  }
@@ -42835,8 +42783,8 @@ function startRecorder(opts) {
42835
42783
  return null;
42836
42784
  }
42837
42785
  const now = opts.now ?? Date.now;
42838
- const dir = import_node_path6.default.join(opts.dataDir, "ipc-recordings", opts.sessionId);
42839
- const filePath = import_node_path6.default.join(dir, `${tsForFilename(now())}.jsonl`);
42786
+ const dir = import_node_path5.default.join(opts.dataDir, "ipc-recordings", opts.sessionId);
42787
+ const filePath = import_node_path5.default.join(dir, `${tsForFilename(now())}.jsonl`);
42840
42788
  let stream = null;
42841
42789
  let closedResolve;
42842
42790
  const closed = new Promise((resolve6) => {
@@ -42845,8 +42793,8 @@ function startRecorder(opts) {
42845
42793
  let exited = false;
42846
42794
  const ensureStream = () => {
42847
42795
  if (stream) return stream;
42848
- import_node_fs6.default.mkdirSync(dir, { recursive: true });
42849
- stream = import_node_fs6.default.createWriteStream(filePath, { flags: "a" });
42796
+ import_node_fs5.default.mkdirSync(dir, { recursive: true });
42797
+ stream = import_node_fs5.default.createWriteStream(filePath, { flags: "a" });
42850
42798
  stream.on("close", () => closedResolve());
42851
42799
  return stream;
42852
42800
  };
@@ -43226,7 +43174,7 @@ var SessionRunner = class {
43226
43174
  isSubagentActive() {
43227
43175
  const toolSessionId = this.state.file.toolSessionId;
43228
43176
  if (!toolSessionId) return false;
43229
- const projectsRoot = import_node_path7.default.join(this.hooks.home ?? import_node_os4.default.homedir(), ".claude", "projects");
43177
+ const projectsRoot = import_node_path6.default.join(this.hooks.home ?? import_node_os4.default.homedir(), ".claude", "projects");
43230
43178
  const mtime = newestSubagentMtimeMs(projectsRoot, this.state.file.cwd, toolSessionId);
43231
43179
  if (mtime === null) return false;
43232
43180
  const now = (this.hooks.now ?? Date.now)();
@@ -43314,15 +43262,15 @@ function extractEditPath(input) {
43314
43262
  }
43315
43263
 
43316
43264
  // src/debug/pty-probe.ts
43317
- var import_node_fs7 = __toESM(require("fs"), 1);
43318
- var import_node_path8 = __toESM(require("path"), 1);
43265
+ var import_node_fs6 = __toESM(require("fs"), 1);
43266
+ var import_node_path7 = __toESM(require("path"), 1);
43319
43267
  var PROBE_DIR = "/tmp/clawd-probe";
43320
- var EVENTS_FILE = import_node_path8.default.join(PROBE_DIR, "events.jsonl");
43268
+ var EVENTS_FILE = import_node_path7.default.join(PROBE_DIR, "events.jsonl");
43321
43269
  var inited = false;
43322
43270
  function ensureDir() {
43323
43271
  if (inited) return true;
43324
43272
  try {
43325
- import_node_fs7.default.mkdirSync(PROBE_DIR, { recursive: true });
43273
+ import_node_fs6.default.mkdirSync(PROBE_DIR, { recursive: true });
43326
43274
  inited = true;
43327
43275
  return true;
43328
43276
  } catch {
@@ -43333,15 +43281,15 @@ function probeEvent(event, data = {}) {
43333
43281
  try {
43334
43282
  if (!ensureDir()) return;
43335
43283
  const line = JSON.stringify({ ts: Date.now(), event, ...data }) + "\n";
43336
- import_node_fs7.default.appendFileSync(EVENTS_FILE, line);
43284
+ import_node_fs6.default.appendFileSync(EVENTS_FILE, line);
43337
43285
  } catch {
43338
43286
  }
43339
43287
  }
43340
43288
  function probeDumpReplay(sessionId, payload) {
43341
43289
  try {
43342
43290
  if (!ensureDir()) return "";
43343
- const file = import_node_path8.default.join(PROBE_DIR, `replay-${sessionId}-${Date.now()}.ans`);
43344
- import_node_fs7.default.writeFileSync(file, payload, "utf8");
43291
+ const file = import_node_path7.default.join(PROBE_DIR, `replay-${sessionId}-${Date.now()}.ans`);
43292
+ import_node_fs6.default.writeFileSync(file, payload, "utf8");
43345
43293
  return file;
43346
43294
  } catch {
43347
43295
  return "";
@@ -43450,7 +43398,7 @@ function derivePersonaSpawnCwd(file, personaRoot) {
43450
43398
  `derivePersonaSpawnCwd: personaRoot missing for owner session ${file.sessionId} (ownerPersonaId=${personaId})`
43451
43399
  );
43452
43400
  }
43453
- return import_node_path9.default.join(personaRoot, safeFileName(personaId));
43401
+ return import_node_path8.default.join(personaRoot, safeFileName(personaId));
43454
43402
  }
43455
43403
  function makeInitialState(file, subSessionMeta) {
43456
43404
  return {
@@ -43584,10 +43532,10 @@ var SessionManager = class {
43584
43532
  // <dataDir>/sessions/ 列子目录 (排除 'default').
43585
43533
  listPersonaIdsOnDisk() {
43586
43534
  if (!this.deps.dataDir) return [];
43587
- const root = this.deps.storeFactory ? import_node_path9.default.join(this.deps.dataDir, "personas") : import_node_path9.default.join(this.deps.dataDir, "sessions");
43535
+ const root = this.deps.storeFactory ? import_node_path8.default.join(this.deps.dataDir, "personas") : import_node_path8.default.join(this.deps.dataDir, "sessions");
43588
43536
  let entries;
43589
43537
  try {
43590
- entries = import_node_fs8.default.readdirSync(root, { withFileTypes: true });
43538
+ entries = import_node_fs7.default.readdirSync(root, { withFileTypes: true });
43591
43539
  } catch (err) {
43592
43540
  const code = err?.code;
43593
43541
  if (code === "ENOENT") return [];
@@ -43600,7 +43548,7 @@ var SessionManager = class {
43600
43548
  // 只在 storeFactory 注入 (新布局) 下生效, 老布局无 guest 目录.
43601
43549
  listGuestCapIdsForPersona(personaId) {
43602
43550
  if (!this.deps.dataDir || !this.deps.storeFactory) return [];
43603
- const root = import_node_path9.default.join(
43551
+ const root = import_node_path8.default.join(
43604
43552
  this.deps.dataDir,
43605
43553
  "personas",
43606
43554
  personaId,
@@ -43610,7 +43558,7 @@ var SessionManager = class {
43610
43558
  );
43611
43559
  let entries;
43612
43560
  try {
43613
- entries = import_node_fs8.default.readdirSync(root, { withFileTypes: true });
43561
+ entries = import_node_fs7.default.readdirSync(root, { withFileTypes: true });
43614
43562
  } catch (err) {
43615
43563
  const code = err?.code;
43616
43564
  if (code === "ENOENT") return [];
@@ -43729,7 +43677,7 @@ var SessionManager = class {
43729
43677
  callerDisplayName
43730
43678
  );
43731
43679
  if (subSessionMeta?.userWorkDir) {
43732
- import_node_fs8.default.mkdirSync(subSessionMeta.userWorkDir, { recursive: true });
43680
+ import_node_fs7.default.mkdirSync(subSessionMeta.userWorkDir, { recursive: true });
43733
43681
  }
43734
43682
  if (scope.kind === "persona" && scope.mode === "guest") {
43735
43683
  if (!this.deps.personaRoot || !subSessionMeta?.userWorkDir) {
@@ -43738,19 +43686,10 @@ var SessionManager = class {
43738
43686
  );
43739
43687
  }
43740
43688
  const base = this.deps.personaStore?.readSandboxSettings(scope.personaId) ?? null;
43741
- const sandboxSettings = composeGuestSandbox(base, subSessionMeta.userWorkDir, file.cwd);
43742
- const ownerCreds = readOwnerCredentials(import_node_os5.default.homedir(), this.deps.logger);
43743
- const merged = mergeOwnerCredentials(sandboxSettings, ownerCreds);
43744
- if (ownerCreds) {
43745
- this.deps.logger?.info("owner credentials injected into guest spawn", {
43746
- sessionId: file.sessionId,
43747
- envKeys: ownerCreds.env ? Object.keys(ownerCreds.env) : [],
43748
- apiKeyHelper: ownerCreds.apiKeyHelper ? "present" : "absent"
43749
- });
43750
- }
43751
- subSessionMeta.extraSettings = JSON.stringify(merged);
43689
+ const settings = composeGuestSandbox(base, subSessionMeta.userWorkDir, file.cwd);
43690
+ subSessionMeta.extraSettings = JSON.stringify(settings);
43752
43691
  const home = import_node_os5.default.homedir();
43753
- const expand = (p2) => p2 === "~" ? home : p2.startsWith("~/") ? import_node_path9.default.join(home, p2.slice(2)) : p2;
43692
+ const expand = (p2) => p2 === "~" ? home : p2.startsWith("~/") ? import_node_path8.default.join(home, p2.slice(2)) : p2;
43754
43693
  const codexCfg = this.deps.personaStore?.readCodexSandboxSettings(scope.personaId) ?? null;
43755
43694
  subSessionMeta.codexSandbox = {
43756
43695
  writableRoots: [subSessionMeta.userWorkDir, ...(codexCfg?.writableRoots ?? []).map(expand)],
@@ -43911,7 +43850,7 @@ var SessionManager = class {
43911
43850
  throw new ClawdError(ERROR_CODES.INVALID_CWD, "cwd required when ownerPersonaId is absent");
43912
43851
  }
43913
43852
  try {
43914
- const stat = import_node_fs8.default.statSync(cwd);
43853
+ const stat = import_node_fs7.default.statSync(cwd);
43915
43854
  if (!stat.isDirectory()) throw new Error("not dir");
43916
43855
  } catch {
43917
43856
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${cwd}`);
@@ -44445,7 +44384,7 @@ var SessionManager = class {
44445
44384
  */
44446
44385
  createForScope(args) {
44447
44386
  try {
44448
- const stat = import_node_fs8.default.statSync(args.cwd);
44387
+ const stat = import_node_fs7.default.statSync(args.cwd);
44449
44388
  if (!stat.isDirectory()) throw new Error("not dir");
44450
44389
  } catch {
44451
44390
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${args.cwd}`);
@@ -44661,7 +44600,7 @@ var SessionManager = class {
44661
44600
  personaId: args.targetPersona,
44662
44601
  mode: "owner"
44663
44602
  };
44664
- const cwd = import_node_path9.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
44603
+ const cwd = import_node_path8.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
44665
44604
  const now = (/* @__PURE__ */ new Date()).toISOString();
44666
44605
  const file = {
44667
44606
  sessionId,
@@ -44726,7 +44665,7 @@ var SessionManager = class {
44726
44665
  personaId: args.targetPersona,
44727
44666
  mode: "owner"
44728
44667
  };
44729
- const cwd = import_node_path9.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
44668
+ const cwd = import_node_path8.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
44730
44669
  const now = (/* @__PURE__ */ new Date()).toISOString();
44731
44670
  const file = {
44732
44671
  sessionId,
@@ -45214,28 +45153,28 @@ var SessionManager = class {
45214
45153
  };
45215
45154
 
45216
45155
  // src/persona/store.ts
45217
- var fs9 = __toESM(require("fs"), 1);
45218
- var path12 = __toESM(require("path"), 1);
45156
+ var fs8 = __toESM(require("fs"), 1);
45157
+ var path11 = __toESM(require("path"), 1);
45219
45158
  init_protocol();
45220
45159
  var PersonaStore = class {
45221
45160
  constructor(root) {
45222
45161
  this.root = root;
45223
- fs9.mkdirSync(root, { recursive: true });
45162
+ fs8.mkdirSync(root, { recursive: true });
45224
45163
  }
45225
45164
  root;
45226
45165
  personaDir(personaId) {
45227
- return path12.join(this.root, safeFileName(personaId));
45166
+ return path11.join(this.root, safeFileName(personaId));
45228
45167
  }
45229
45168
  metaPath(personaId) {
45230
- return path12.join(this.personaDir(personaId), ".clawd", "persona.json");
45169
+ return path11.join(this.personaDir(personaId), ".clawd", "persona.json");
45231
45170
  }
45232
45171
  claudeMdPath(personaId) {
45233
- return path12.join(this.personaDir(personaId), "CLAUDE.md");
45172
+ return path11.join(this.personaDir(personaId), "CLAUDE.md");
45234
45173
  }
45235
45174
  // codex 原生读 cwd 的 AGENTS.md。人格双写镜像:claude 读 CLAUDE.md、codex 读 AGENTS.md,
45236
45175
  // 两份内容恒一致,persona 切 tool 零迁移。
45237
45176
  agentsMdPath(personaId) {
45238
- return path12.join(this.personaDir(personaId), "AGENTS.md");
45177
+ return path11.join(this.personaDir(personaId), "AGENTS.md");
45239
45178
  }
45240
45179
  /**
45241
45180
  * persona 级 sandbox base 落盘路径 —— 故意放 `.clawd/` 而非 `.claude/`,让 CC 的 project
@@ -45244,11 +45183,11 @@ var PersonaStore = class {
45244
45183
  * spawn 前 per-guest 动态拼到各自 session 目录的那份(base + 强制底座 + 本 guest userWorkDir carve)。
45245
45184
  */
45246
45185
  sandboxSettingsPath(personaId) {
45247
- return path12.join(this.personaDir(personaId), ".clawd", "sandbox-settings.json");
45186
+ return path11.join(this.personaDir(personaId), ".clawd", "sandbox-settings.json");
45248
45187
  }
45249
45188
  write(persona, personality) {
45250
45189
  const dir = this.personaDir(persona.personaId);
45251
- fs9.mkdirSync(path12.join(dir, ".clawd"), { recursive: true });
45190
+ fs8.mkdirSync(path11.join(dir, ".clawd"), { recursive: true });
45252
45191
  this.atomicWrite(this.claudeMdPath(persona.personaId), personality);
45253
45192
  this.atomicWrite(this.agentsMdPath(persona.personaId), personality);
45254
45193
  this.writeSandboxSettings(persona.personaId, buildGuestSettingsV1());
@@ -45267,9 +45206,9 @@ var PersonaStore = class {
45267
45206
  ensureAgentsMirror(personaId) {
45268
45207
  const claudeMd = this.claudeMdPath(personaId);
45269
45208
  const agentsMd = this.agentsMdPath(personaId);
45270
- if (!fs9.existsSync(claudeMd)) return false;
45271
- if (fs9.existsSync(agentsMd)) return false;
45272
- this.atomicWrite(agentsMd, fs9.readFileSync(claudeMd, "utf8"));
45209
+ if (!fs8.existsSync(claudeMd)) return false;
45210
+ if (fs8.existsSync(agentsMd)) return false;
45211
+ this.atomicWrite(agentsMd, fs8.readFileSync(claudeMd, "utf8"));
45273
45212
  return true;
45274
45213
  }
45275
45214
  /**
@@ -45293,22 +45232,22 @@ var PersonaStore = class {
45293
45232
  return { ...s, permissions: { ...s.permissions ?? {}, deny: [...prev, rule] } };
45294
45233
  }
45295
45234
  codexSandboxSettingsPath(personaId) {
45296
- return path12.join(this.personaDir(personaId), ".clawd", "codex-sandbox.json");
45235
+ return path11.join(this.personaDir(personaId), ".clawd", "codex-sandbox.json");
45297
45236
  }
45298
45237
  /** 读 codex-sandbox.json;不存在/损坏 → null。 */
45299
45238
  readCodexSandboxSettings(personaId) {
45300
45239
  const p2 = this.codexSandboxSettingsPath(personaId);
45301
- if (!fs9.existsSync(p2)) return null;
45240
+ if (!fs8.existsSync(p2)) return null;
45302
45241
  try {
45303
- return CodexSandboxSettingsSchema.parse(JSON.parse(fs9.readFileSync(p2, "utf8")));
45242
+ return CodexSandboxSettingsSchema.parse(JSON.parse(fs8.readFileSync(p2, "utf8")));
45304
45243
  } catch {
45305
45244
  return null;
45306
45245
  }
45307
45246
  }
45308
45247
  /** 覆盖写 codex-sandbox.json(seed/migrate 用)。 */
45309
45248
  writeCodexSandboxSettings(personaId, settings) {
45310
- const dir = path12.join(this.personaDir(personaId), ".clawd");
45311
- fs9.mkdirSync(dir, { recursive: true });
45249
+ const dir = path11.join(this.personaDir(personaId), ".clawd");
45250
+ fs8.mkdirSync(dir, { recursive: true });
45312
45251
  this.atomicWrite(this.codexSandboxSettingsPath(personaId), JSON.stringify(settings, null, 2));
45313
45252
  }
45314
45253
  writeMeta(persona) {
@@ -45316,8 +45255,8 @@ var PersonaStore = class {
45316
45255
  }
45317
45256
  read(personaId) {
45318
45257
  const p2 = this.metaPath(personaId);
45319
- if (!fs9.existsSync(p2)) return null;
45320
- const raw = JSON.parse(fs9.readFileSync(p2, "utf8"));
45258
+ if (!fs8.existsSync(p2)) return null;
45259
+ const raw = JSON.parse(fs8.readFileSync(p2, "utf8"));
45321
45260
  if (raw && typeof raw === "object" && "tokenMap" in raw) {
45322
45261
  delete raw.tokenMap;
45323
45262
  this.atomicWrite(p2, JSON.stringify(raw, null, 2));
@@ -45325,13 +45264,13 @@ var PersonaStore = class {
45325
45264
  return PersonaFileSchema.parse(raw);
45326
45265
  }
45327
45266
  has(personaId) {
45328
- return fs9.existsSync(this.metaPath(personaId));
45267
+ return fs8.existsSync(this.metaPath(personaId));
45329
45268
  }
45330
45269
  readPersonality(personaId) {
45331
45270
  const claudeMd = this.claudeMdPath(personaId);
45332
- if (fs9.existsSync(claudeMd)) return fs9.readFileSync(claudeMd, "utf8");
45271
+ if (fs8.existsSync(claudeMd)) return fs8.readFileSync(claudeMd, "utf8");
45333
45272
  const agentsMd = this.agentsMdPath(personaId);
45334
- if (fs9.existsSync(agentsMd)) return fs9.readFileSync(agentsMd, "utf8");
45273
+ if (fs8.existsSync(agentsMd)) return fs8.readFileSync(agentsMd, "utf8");
45335
45274
  return null;
45336
45275
  }
45337
45276
  /**
@@ -45340,23 +45279,23 @@ var PersonaStore = class {
45340
45279
  */
45341
45280
  readSandboxSettings(personaId) {
45342
45281
  const p2 = this.sandboxSettingsPath(personaId);
45343
- if (!fs9.existsSync(p2)) return null;
45282
+ if (!fs8.existsSync(p2)) return null;
45344
45283
  try {
45345
- return JSON.parse(fs9.readFileSync(p2, "utf8"));
45284
+ return JSON.parse(fs8.readFileSync(p2, "utf8"));
45346
45285
  } catch {
45347
45286
  return null;
45348
45287
  }
45349
45288
  }
45350
45289
  /** Persona 私有 skills 目录路径:<personaDir>/.claude/skills */
45351
45290
  skillsDir(personaId) {
45352
- return path12.join(this.personaDir(personaId), ".claude", "skills");
45291
+ return path11.join(this.personaDir(personaId), ".claude", "skills");
45353
45292
  }
45354
45293
  /**
45355
45294
  * Claude Code 项目级 settings 路径:`<personaDir>/.claude/settings.json`。
45356
45295
  * 这里只读 `enabledPlugins` 字段,由 owner 通过 CC `/plugin` 之类命令维护,daemon 不写。
45357
45296
  */
45358
45297
  claudeSettingsPath(personaId) {
45359
- return path12.join(this.personaDir(personaId), ".claude", "settings.json");
45298
+ return path11.join(this.personaDir(personaId), ".claude", "settings.json");
45360
45299
  }
45361
45300
  /**
45362
45301
  * 读取 persona 的 `.claude/settings.json` 中 `enabledPlugins` map,把 value === true
@@ -45371,10 +45310,10 @@ var PersonaStore = class {
45371
45310
  */
45372
45311
  readEnabledPlugins(personaId) {
45373
45312
  const p2 = this.claudeSettingsPath(personaId);
45374
- if (!fs9.existsSync(p2)) return [];
45313
+ if (!fs8.existsSync(p2)) return [];
45375
45314
  let raw;
45376
45315
  try {
45377
- raw = JSON.parse(fs9.readFileSync(p2, "utf8"));
45316
+ raw = JSON.parse(fs8.readFileSync(p2, "utf8"));
45378
45317
  } catch {
45379
45318
  return [];
45380
45319
  }
@@ -45388,22 +45327,22 @@ var PersonaStore = class {
45388
45327
  return out;
45389
45328
  }
45390
45329
  list() {
45391
- if (!fs9.existsSync(this.root)) return [];
45392
- return fs9.readdirSync(this.root).filter((name) => {
45393
- return fs9.existsSync(path12.join(this.root, name, ".clawd", "persona.json"));
45330
+ if (!fs8.existsSync(this.root)) return [];
45331
+ return fs8.readdirSync(this.root).filter((name) => {
45332
+ return fs8.existsSync(path11.join(this.root, name, ".clawd", "persona.json"));
45394
45333
  });
45395
45334
  }
45396
45335
  remove(personaId) {
45397
45336
  const dir = this.personaDir(personaId);
45398
- if (fs9.existsSync(dir)) fs9.rmSync(dir, { recursive: true, force: true });
45337
+ if (fs8.existsSync(dir)) fs8.rmSync(dir, { recursive: true, force: true });
45399
45338
  }
45400
45339
  personaDirPath(personaId) {
45401
45340
  return this.personaDir(personaId);
45402
45341
  }
45403
45342
  atomicWrite(file, content) {
45404
45343
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
45405
- fs9.writeFileSync(tmp, content, { mode: 384 });
45406
- fs9.renameSync(tmp, file);
45344
+ fs8.writeFileSync(tmp, content, { mode: 384 });
45345
+ fs8.renameSync(tmp, file);
45407
45346
  }
45408
45347
  };
45409
45348
 
@@ -45449,9 +45388,9 @@ var PersonaRegistry = class {
45449
45388
  var import_node_crypto3 = __toESM(require("crypto"), 1);
45450
45389
 
45451
45390
  // src/skills/scanner.ts
45452
- var import_node_fs9 = __toESM(require("fs"), 1);
45391
+ var import_node_fs8 = __toESM(require("fs"), 1);
45453
45392
  var import_node_os6 = __toESM(require("os"), 1);
45454
- var import_node_path10 = __toESM(require("path"), 1);
45393
+ var import_node_path9 = __toESM(require("path"), 1);
45455
45394
 
45456
45395
  // src/skills/frontmatter.ts
45457
45396
  var STRIP_QUOTES = /^["']|["']$/g;
@@ -45560,7 +45499,7 @@ function parseDescription(content) {
45560
45499
  }
45561
45500
  function isDirLikeSync(p2) {
45562
45501
  try {
45563
- return import_node_fs9.default.statSync(p2).isDirectory();
45502
+ return import_node_fs8.default.statSync(p2).isDirectory();
45564
45503
  } catch {
45565
45504
  return false;
45566
45505
  }
@@ -45568,19 +45507,19 @@ function isDirLikeSync(p2) {
45568
45507
  function scanSkillDir(dir, source, seen, out, pluginName) {
45569
45508
  let entries;
45570
45509
  try {
45571
- entries = import_node_fs9.default.readdirSync(dir, { withFileTypes: true });
45510
+ entries = import_node_fs8.default.readdirSync(dir, { withFileTypes: true });
45572
45511
  } catch {
45573
45512
  return;
45574
45513
  }
45575
45514
  for (const ent of entries) {
45576
- const entryPath = import_node_path10.default.join(dir, ent.name);
45515
+ const entryPath = import_node_path9.default.join(dir, ent.name);
45577
45516
  if (!ent.isDirectory() && !(ent.isSymbolicLink() && isDirLikeSync(entryPath))) continue;
45578
45517
  let content;
45579
45518
  try {
45580
- content = import_node_fs9.default.readFileSync(import_node_path10.default.join(entryPath, "SKILL.md"), "utf8");
45519
+ content = import_node_fs8.default.readFileSync(import_node_path9.default.join(entryPath, "SKILL.md"), "utf8");
45581
45520
  } catch {
45582
45521
  try {
45583
- content = import_node_fs9.default.readFileSync(import_node_path10.default.join(entryPath, "skill.md"), "utf8");
45522
+ content = import_node_fs8.default.readFileSync(import_node_path9.default.join(entryPath, "skill.md"), "utf8");
45584
45523
  } catch {
45585
45524
  continue;
45586
45525
  }
@@ -45604,26 +45543,26 @@ function listSkillsForDir(dir, source) {
45604
45543
  function scanCommandDir(dir, source, seen, out, pluginName) {
45605
45544
  let entries;
45606
45545
  try {
45607
- entries = import_node_fs9.default.readdirSync(dir, { withFileTypes: true });
45546
+ entries = import_node_fs8.default.readdirSync(dir, { withFileTypes: true });
45608
45547
  } catch {
45609
45548
  return;
45610
45549
  }
45611
45550
  for (const ent of entries) {
45612
- const entryPath = import_node_path10.default.join(dir, ent.name);
45551
+ const entryPath = import_node_path9.default.join(dir, ent.name);
45613
45552
  if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync(entryPath)) {
45614
45553
  const ns = ent.name;
45615
45554
  let subEntries;
45616
45555
  try {
45617
- subEntries = import_node_fs9.default.readdirSync(entryPath, { withFileTypes: true });
45556
+ subEntries = import_node_fs8.default.readdirSync(entryPath, { withFileTypes: true });
45618
45557
  } catch {
45619
45558
  continue;
45620
45559
  }
45621
45560
  for (const se of subEntries) {
45622
45561
  if (!se.name.endsWith(".md")) continue;
45623
- const sePath = import_node_path10.default.join(entryPath, se.name);
45562
+ const sePath = import_node_path9.default.join(entryPath, se.name);
45624
45563
  let content;
45625
45564
  try {
45626
- content = import_node_fs9.default.readFileSync(sePath, "utf8");
45565
+ content = import_node_fs8.default.readFileSync(sePath, "utf8");
45627
45566
  } catch {
45628
45567
  continue;
45629
45568
  }
@@ -45640,7 +45579,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
45640
45579
  } else if (ent.name.endsWith(".md")) {
45641
45580
  let content;
45642
45581
  try {
45643
- content = import_node_fs9.default.readFileSync(entryPath, "utf8");
45582
+ content = import_node_fs8.default.readFileSync(entryPath, "utf8");
45644
45583
  } catch {
45645
45584
  continue;
45646
45585
  }
@@ -45656,10 +45595,10 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
45656
45595
  }
45657
45596
  }
45658
45597
  function readInstalledPlugins(home) {
45659
- const file = import_node_path10.default.join(home, ".claude", "plugins", "installed_plugins.json");
45598
+ const file = import_node_path9.default.join(home, ".claude", "plugins", "installed_plugins.json");
45660
45599
  let raw;
45661
45600
  try {
45662
- raw = import_node_fs9.default.readFileSync(file, "utf8");
45601
+ raw = import_node_fs8.default.readFileSync(file, "utf8");
45663
45602
  } catch {
45664
45603
  return [];
45665
45604
  }
@@ -45707,14 +45646,14 @@ var SkillsScanner = class {
45707
45646
  });
45708
45647
  }
45709
45648
  const fsBlock = [];
45710
- scanSkillDir(import_node_path10.default.join(this.home, ".claude", "skills"), "global", seen, fsBlock);
45711
- scanCommandDir(import_node_path10.default.join(this.home, ".claude", "commands"), "global", seen, fsBlock);
45712
- scanSkillDir(import_node_path10.default.join(args.cwd, ".claude", "skills"), "project", seen, fsBlock);
45713
- scanCommandDir(import_node_path10.default.join(args.cwd, ".claude", "commands"), "project", seen, fsBlock);
45649
+ scanSkillDir(import_node_path9.default.join(this.home, ".claude", "skills"), "global", seen, fsBlock);
45650
+ scanCommandDir(import_node_path9.default.join(this.home, ".claude", "commands"), "global", seen, fsBlock);
45651
+ scanSkillDir(import_node_path9.default.join(args.cwd, ".claude", "skills"), "project", seen, fsBlock);
45652
+ scanCommandDir(import_node_path9.default.join(args.cwd, ".claude", "commands"), "project", seen, fsBlock);
45714
45653
  const plugins = [...readInstalledPlugins(this.home), ...this.extraPluginRoots];
45715
45654
  for (const { name, root } of plugins) {
45716
- scanSkillDir(import_node_path10.default.join(root, "skills"), "plugin", seen, fsBlock, name);
45717
- scanCommandDir(import_node_path10.default.join(root, "commands"), "plugin", seen, fsBlock, name);
45655
+ scanSkillDir(import_node_path9.default.join(root, "skills"), "plugin", seen, fsBlock, name);
45656
+ scanCommandDir(import_node_path9.default.join(root, "commands"), "plugin", seen, fsBlock, name);
45718
45657
  }
45719
45658
  fsBlock.sort((a, b2) => a.name < b2.name ? -1 : a.name > b2.name ? 1 : 0);
45720
45659
  return [...builtinBlock, ...fsBlock];
@@ -45820,8 +45759,8 @@ var PersonaManager = class {
45820
45759
  };
45821
45760
 
45822
45761
  // src/persona/seed.ts
45823
- var fs11 = __toESM(require("fs"), 1);
45824
- var path14 = __toESM(require("path"), 1);
45762
+ var fs10 = __toESM(require("fs"), 1);
45763
+ var path13 = __toESM(require("path"), 1);
45825
45764
  var import_node_url = require("url");
45826
45765
  var import_meta = {};
45827
45766
  var DEFAULT_BYPASS_PROFILE = {
@@ -45991,24 +45930,24 @@ function bundleSiblingFromArgv(argv1, sibling) {
45991
45930
  if (!argv1) return null;
45992
45931
  let real = argv1;
45993
45932
  try {
45994
- real = fs11.realpathSync(argv1);
45933
+ real = fs10.realpathSync(argv1);
45995
45934
  } catch {
45996
45935
  }
45997
- return path14.resolve(path14.dirname(real), sibling);
45936
+ return path13.resolve(path13.dirname(real), sibling);
45998
45937
  }
45999
45938
  function findDefaultsRoot(logger) {
46000
45939
  const candidates = [];
46001
45940
  try {
46002
- const here = path14.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
46003
- candidates.push(path14.resolve(here, "defaults"));
46004
- candidates.push(path14.resolve(here, "persona-defaults"));
45941
+ const here = path13.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
45942
+ candidates.push(path13.resolve(here, "defaults"));
45943
+ candidates.push(path13.resolve(here, "persona-defaults"));
46005
45944
  } catch {
46006
45945
  }
46007
45946
  const fromArgv = bundleSiblingFromArgv(process.argv[1], "persona-defaults");
46008
45947
  if (fromArgv) candidates.push(fromArgv);
46009
45948
  for (const c of candidates) {
46010
45949
  try {
46011
- if (fs11.statSync(c).isDirectory()) {
45950
+ if (fs10.statSync(c).isDirectory()) {
46012
45951
  logger?.info("persona.defaults-root.resolved", { root: c });
46013
45952
  return c;
46014
45953
  }
@@ -46025,8 +45964,8 @@ function seedDefaultPersonas(args) {
46025
45964
  args.logger.info("persona.seed.skip", { personaId: entry.personaId, reason: "exists" });
46026
45965
  continue;
46027
45966
  }
46028
- const bundleDir = path14.join(args.defaultsRoot, entry.personaId);
46029
- if (!fs11.existsSync(bundleDir)) {
45967
+ const bundleDir = path13.join(args.defaultsRoot, entry.personaId);
45968
+ if (!fs10.existsSync(bundleDir)) {
46030
45969
  args.logger.warn("persona.seed.skip", {
46031
45970
  personaId: entry.personaId,
46032
45971
  reason: "bundle-missing",
@@ -46034,8 +45973,8 @@ function seedDefaultPersonas(args) {
46034
45973
  });
46035
45974
  continue;
46036
45975
  }
46037
- const claudeMdPath = path14.join(bundleDir, "CLAUDE.md");
46038
- if (!fs11.existsSync(claudeMdPath)) {
45976
+ const claudeMdPath = path13.join(bundleDir, "CLAUDE.md");
45977
+ if (!fs10.existsSync(claudeMdPath)) {
46039
45978
  args.logger.warn("persona.seed.skip", {
46040
45979
  personaId: entry.personaId,
46041
45980
  reason: "no-CLAUDE.md",
@@ -46043,7 +45982,7 @@ function seedDefaultPersonas(args) {
46043
45982
  });
46044
45983
  continue;
46045
45984
  }
46046
- const personality = fs11.readFileSync(claudeMdPath, "utf8");
45985
+ const personality = fs10.readFileSync(claudeMdPath, "utf8");
46047
45986
  const now = Date.now();
46048
45987
  const persona = {
46049
45988
  personaId: entry.personaId,
@@ -46069,17 +46008,17 @@ function seedDefaultPersonas(args) {
46069
46008
  }
46070
46009
  }
46071
46010
  function skipNodeModulesUnder(srcRoot) {
46072
- return (src) => !path14.relative(srcRoot, src).split(path14.sep).includes("node_modules");
46011
+ return (src) => !path13.relative(srcRoot, src).split(path13.sep).includes("node_modules");
46073
46012
  }
46074
46013
  function copyBundleExtras(srcDir, dstDir) {
46075
- for (const entry of fs11.readdirSync(srcDir, { withFileTypes: true })) {
46014
+ for (const entry of fs10.readdirSync(srcDir, { withFileTypes: true })) {
46076
46015
  if (entry.name === "CLAUDE.md" || entry.name === ".clawd") continue;
46077
- const srcPath = path14.join(srcDir, entry.name);
46078
- const dstPath = path14.join(dstDir, entry.name);
46016
+ const srcPath = path13.join(srcDir, entry.name);
46017
+ const dstPath = path13.join(dstDir, entry.name);
46079
46018
  if (entry.isDirectory()) {
46080
- fs11.cpSync(srcPath, dstPath, { recursive: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
46019
+ fs10.cpSync(srcPath, dstPath, { recursive: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
46081
46020
  } else if (entry.isFile()) {
46082
- fs11.copyFileSync(srcPath, dstPath);
46021
+ fs10.copyFileSync(srcPath, dstPath);
46083
46022
  }
46084
46023
  }
46085
46024
  }
@@ -46087,16 +46026,16 @@ var DAEMON_MANAGED_PATHS = ["extension-kit", "CLAUDE.md", ".mcp.json"];
46087
46026
  function refreshDaemonManagedDirs(args) {
46088
46027
  const entries = args.entries ?? DEFAULT_PERSONAS;
46089
46028
  for (const entry of entries) {
46090
- const bundleDir = path14.join(args.defaultsRoot, entry.personaId);
46091
- if (!fs11.existsSync(bundleDir)) continue;
46029
+ const bundleDir = path13.join(args.defaultsRoot, entry.personaId);
46030
+ if (!fs10.existsSync(bundleDir)) continue;
46092
46031
  const personaDir = args.store.personaDirPath(entry.personaId);
46093
- if (!fs11.existsSync(personaDir)) continue;
46032
+ if (!fs10.existsSync(personaDir)) continue;
46094
46033
  for (const relPath of DAEMON_MANAGED_PATHS) {
46095
- const srcPath = path14.join(bundleDir, relPath);
46096
- if (!fs11.existsSync(srcPath)) continue;
46097
- const dstPath = path14.join(personaDir, relPath);
46034
+ const srcPath = path13.join(bundleDir, relPath);
46035
+ if (!fs10.existsSync(srcPath)) continue;
46036
+ const dstPath = path13.join(personaDir, relPath);
46098
46037
  try {
46099
- fs11.cpSync(srcPath, dstPath, { recursive: true, force: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
46038
+ fs10.cpSync(srcPath, dstPath, { recursive: true, force: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
46100
46039
  args.logger.info("persona.refresh.synced", {
46101
46040
  personaId: entry.personaId,
46102
46041
  path: relPath
@@ -46156,15 +46095,15 @@ function migrateCodexSandbox(args) {
46156
46095
  function findDeployKitRoot(logger) {
46157
46096
  const candidates = [];
46158
46097
  try {
46159
- const here = path14.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
46160
- candidates.push(path14.resolve(here, "..", "deploy-kit"));
46098
+ const here = path13.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
46099
+ candidates.push(path13.resolve(here, "..", "deploy-kit"));
46161
46100
  } catch {
46162
46101
  }
46163
46102
  const fromArgv = bundleSiblingFromArgv(process.argv[1], "deploy-kit");
46164
46103
  if (fromArgv) candidates.push(fromArgv);
46165
46104
  for (const c of candidates) {
46166
46105
  try {
46167
- if (fs11.statSync(c).isDirectory()) {
46106
+ if (fs10.statSync(c).isDirectory()) {
46168
46107
  logger?.info("persona.deploy-kit-root.resolved", { root: c });
46169
46108
  return c;
46170
46109
  }
@@ -46175,8 +46114,8 @@ function findDeployKitRoot(logger) {
46175
46114
  return null;
46176
46115
  }
46177
46116
  function seedDeployKit(args) {
46178
- const dst = path14.join(args.dataDir, "deploy-kit");
46179
- fs11.cpSync(args.deployKitBundleRoot, dst, {
46117
+ const dst = path13.join(args.dataDir, "deploy-kit");
46118
+ fs10.cpSync(args.deployKitBundleRoot, dst, {
46180
46119
  recursive: true,
46181
46120
  dereference: true,
46182
46121
  force: false,
@@ -46185,35 +46124,35 @@ function seedDeployKit(args) {
46185
46124
  args.logger.info("deploy-kit.seed.done", { dst });
46186
46125
  }
46187
46126
  function refreshDeployKit(args) {
46188
- const dst = path14.join(args.dataDir, "deploy-kit");
46189
- if (!fs11.existsSync(dst)) {
46127
+ const dst = path13.join(args.dataDir, "deploy-kit");
46128
+ if (!fs10.existsSync(dst)) {
46190
46129
  seedDeployKit(args);
46191
46130
  return;
46192
46131
  }
46193
46132
  for (const sub of ["scripts", "contract"]) {
46194
- const s = path14.join(args.deployKitBundleRoot, sub);
46195
- if (fs11.existsSync(s)) {
46196
- fs11.cpSync(s, path14.join(dst, sub), { recursive: true, force: true, dereference: true });
46133
+ const s = path13.join(args.deployKitBundleRoot, sub);
46134
+ if (fs10.existsSync(s)) {
46135
+ fs10.cpSync(s, path13.join(dst, sub), { recursive: true, force: true, dereference: true });
46197
46136
  }
46198
46137
  }
46199
- const secretsSrc = path14.join(args.deployKitBundleRoot, ".secrets");
46200
- if (fs11.existsSync(secretsSrc)) {
46201
- fs11.mkdirSync(path14.join(dst, ".secrets"), { recursive: true });
46202
- for (const f of fs11.readdirSync(secretsSrc)) {
46203
- if (f.endsWith(".local")) continue;
46204
- fs11.copyFileSync(path14.join(secretsSrc, f), path14.join(dst, ".secrets", f));
46138
+ const secretsSrc = path13.join(args.deployKitBundleRoot, ".secrets");
46139
+ if (fs10.existsSync(secretsSrc)) {
46140
+ fs10.mkdirSync(path13.join(dst, ".secrets"), { recursive: true });
46141
+ for (const f of fs10.readdirSync(secretsSrc)) {
46142
+ if (!f.endsWith(".example")) continue;
46143
+ fs10.copyFileSync(path13.join(secretsSrc, f), path13.join(dst, ".secrets", f));
46205
46144
  }
46206
46145
  }
46207
46146
  args.logger.info("deploy-kit.refresh.done", { dst });
46208
46147
  }
46209
46148
 
46210
46149
  // src/share-md-viewer/load.ts
46211
- var import_node_fs11 = __toESM(require("fs"), 1);
46212
- var import_node_path11 = __toESM(require("path"), 1);
46150
+ var import_node_fs10 = __toESM(require("fs"), 1);
46151
+ var import_node_path10 = __toESM(require("path"), 1);
46213
46152
  var import_node_url2 = require("url");
46214
46153
 
46215
46154
  // src/share-md-viewer/asset-loader.ts
46216
- var import_node_fs10 = __toESM(require("fs"), 1);
46155
+ var import_node_fs9 = __toESM(require("fs"), 1);
46217
46156
  function htmlEscape(s) {
46218
46157
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
46219
46158
  }
@@ -46221,12 +46160,12 @@ function createViewerAssetLoader(opts) {
46221
46160
  let viewerTemplate;
46222
46161
  let errorTemplate;
46223
46162
  try {
46224
- viewerTemplate = import_node_fs10.default.readFileSync(opts.viewerHtmlPath, "utf8");
46163
+ viewerTemplate = import_node_fs9.default.readFileSync(opts.viewerHtmlPath, "utf8");
46225
46164
  } catch (err) {
46226
46165
  throw new Error(`viewer asset not found at ${opts.viewerHtmlPath}: ${err.message}`);
46227
46166
  }
46228
46167
  try {
46229
- errorTemplate = import_node_fs10.default.readFileSync(opts.errorHtmlPath, "utf8");
46168
+ errorTemplate = import_node_fs9.default.readFileSync(opts.errorHtmlPath, "utf8");
46230
46169
  } catch (err) {
46231
46170
  throw new Error(`viewer error asset not found at ${opts.errorHtmlPath}: ${err.message}`);
46232
46171
  }
@@ -46245,25 +46184,25 @@ var import_meta2 = {};
46245
46184
  function tryLoadViewerAssets(logger) {
46246
46185
  const candidates = [];
46247
46186
  try {
46248
- const here = import_node_path11.default.dirname((0, import_node_url2.fileURLToPath)(import_meta2.url));
46187
+ const here = import_node_path10.default.dirname((0, import_node_url2.fileURLToPath)(import_meta2.url));
46249
46188
  candidates.push(here);
46250
- candidates.push(import_node_path11.default.resolve(here, ".."));
46251
- candidates.push(import_node_path11.default.resolve(here, "..", "..", "dist"));
46189
+ candidates.push(import_node_path10.default.resolve(here, ".."));
46190
+ candidates.push(import_node_path10.default.resolve(here, "..", "..", "dist"));
46252
46191
  } catch {
46253
46192
  }
46254
46193
  if (process.argv[1]) {
46255
46194
  let real = process.argv[1];
46256
46195
  try {
46257
- real = import_node_fs11.default.realpathSync(process.argv[1]);
46196
+ real = import_node_fs10.default.realpathSync(process.argv[1]);
46258
46197
  } catch {
46259
46198
  }
46260
- candidates.push(import_node_path11.default.dirname(real));
46199
+ candidates.push(import_node_path10.default.dirname(real));
46261
46200
  }
46262
46201
  for (const root of candidates) {
46263
- const viewerHtmlPath = import_node_path11.default.join(root, "share-md-viewer.html");
46264
- const errorHtmlPath = import_node_path11.default.join(root, "share-md-viewer-error.html");
46202
+ const viewerHtmlPath = import_node_path10.default.join(root, "share-md-viewer.html");
46203
+ const errorHtmlPath = import_node_path10.default.join(root, "share-md-viewer-error.html");
46265
46204
  try {
46266
- if (import_node_fs11.default.statSync(viewerHtmlPath).isFile() && import_node_fs11.default.statSync(errorHtmlPath).isFile()) {
46205
+ if (import_node_fs10.default.statSync(viewerHtmlPath).isFile() && import_node_fs10.default.statSync(errorHtmlPath).isFile()) {
46267
46206
  logger?.info("share-md-viewer.assets-root.resolved", { root });
46268
46207
  return createViewerAssetLoader({ viewerHtmlPath, errorHtmlPath });
46269
46208
  }
@@ -46278,30 +46217,30 @@ function tryLoadViewerAssets(logger) {
46278
46217
  }
46279
46218
 
46280
46219
  // src/share-ui/load.ts
46281
- var import_node_fs13 = __toESM(require("fs"), 1);
46282
- var import_node_path13 = __toESM(require("path"), 1);
46220
+ var import_node_fs12 = __toESM(require("fs"), 1);
46221
+ var import_node_path12 = __toESM(require("path"), 1);
46283
46222
  var import_node_url3 = require("url");
46284
46223
 
46285
46224
  // src/share-ui/asset-loader.ts
46286
- var import_node_fs12 = __toESM(require("fs"), 1);
46287
- var import_node_path12 = __toESM(require("path"), 1);
46225
+ var import_node_fs11 = __toESM(require("fs"), 1);
46226
+ var import_node_path11 = __toESM(require("path"), 1);
46288
46227
  function createShareUiAssetLoader(opts) {
46289
46228
  let indexHtml;
46290
46229
  try {
46291
- indexHtml = import_node_fs12.default.readFileSync(opts.indexHtmlPath, "utf8");
46230
+ indexHtml = import_node_fs11.default.readFileSync(opts.indexHtmlPath, "utf8");
46292
46231
  } catch (err) {
46293
46232
  throw new Error(`share-ui index.html not found at ${opts.indexHtmlPath}: ${err.message}`);
46294
46233
  }
46295
- const assetsDir = import_node_path12.default.resolve(opts.assetsDir);
46234
+ const assetsDir = import_node_path11.default.resolve(opts.assetsDir);
46296
46235
  return {
46297
46236
  renderIndexHtml() {
46298
46237
  return indexHtml;
46299
46238
  },
46300
46239
  resolveAssetPath(rel) {
46301
- const resolved = import_node_path12.default.resolve(assetsDir, rel);
46302
- if (resolved !== assetsDir && !resolved.startsWith(assetsDir + import_node_path12.default.sep)) return null;
46240
+ const resolved = import_node_path11.default.resolve(assetsDir, rel);
46241
+ if (resolved !== assetsDir && !resolved.startsWith(assetsDir + import_node_path11.default.sep)) return null;
46303
46242
  try {
46304
- if (import_node_fs12.default.statSync(resolved).isFile()) return resolved;
46243
+ if (import_node_fs11.default.statSync(resolved).isFile()) return resolved;
46305
46244
  } catch {
46306
46245
  }
46307
46246
  return null;
@@ -46315,28 +46254,28 @@ function bundleDirFromArgv(argv1) {
46315
46254
  if (!argv1) return null;
46316
46255
  let real = argv1;
46317
46256
  try {
46318
- real = import_node_fs13.default.realpathSync(argv1);
46257
+ real = import_node_fs12.default.realpathSync(argv1);
46319
46258
  } catch {
46320
46259
  }
46321
- return import_node_path13.default.dirname(real);
46260
+ return import_node_path12.default.dirname(real);
46322
46261
  }
46323
46262
  function tryLoadShareUi(logger) {
46324
46263
  const candidates = [];
46325
46264
  try {
46326
- const here = import_node_path13.default.dirname((0, import_node_url3.fileURLToPath)(import_meta3.url));
46265
+ const here = import_node_path12.default.dirname((0, import_node_url3.fileURLToPath)(import_meta3.url));
46327
46266
  candidates.push(here);
46328
- candidates.push(import_node_path13.default.resolve(here, ".."));
46329
- candidates.push(import_node_path13.default.resolve(here, "..", "..", "dist"));
46267
+ candidates.push(import_node_path12.default.resolve(here, ".."));
46268
+ candidates.push(import_node_path12.default.resolve(here, "..", "..", "dist"));
46330
46269
  } catch {
46331
46270
  }
46332
46271
  const argvDir = bundleDirFromArgv(process.argv[1]);
46333
46272
  if (argvDir) candidates.push(argvDir);
46334
46273
  for (const root of candidates) {
46335
- const shareUiDir = import_node_path13.default.join(root, "share-ui");
46336
- const indexHtmlPath = import_node_path13.default.join(shareUiDir, "guest.html");
46337
- const assetsDir = import_node_path13.default.join(shareUiDir, "assets");
46274
+ const shareUiDir = import_node_path12.default.join(root, "share-ui");
46275
+ const indexHtmlPath = import_node_path12.default.join(shareUiDir, "guest.html");
46276
+ const assetsDir = import_node_path12.default.join(shareUiDir, "assets");
46338
46277
  try {
46339
- if (import_node_fs13.default.statSync(indexHtmlPath).isFile() && import_node_fs13.default.statSync(assetsDir).isDirectory()) {
46278
+ if (import_node_fs12.default.statSync(indexHtmlPath).isFile() && import_node_fs12.default.statSync(assetsDir).isDirectory()) {
46340
46279
  logger?.info("share-ui.assets-root.resolved", { root: shareUiDir });
46341
46280
  return createShareUiAssetLoader({ indexHtmlPath, assetsDir });
46342
46281
  }
@@ -46414,20 +46353,20 @@ function buildVisitorLogin(deps) {
46414
46353
  }
46415
46354
 
46416
46355
  // src/visitor/visitor-store.ts
46417
- var import_node_fs14 = __toESM(require("fs"), 1);
46418
- var import_node_path14 = __toESM(require("path"), 1);
46356
+ var import_node_fs13 = __toESM(require("fs"), 1);
46357
+ var import_node_path13 = __toESM(require("path"), 1);
46419
46358
  function createVisitorStore(opts) {
46420
- const file = import_node_path14.default.join(opts.dir, "visitors.json");
46359
+ const file = import_node_path13.default.join(opts.dir, "visitors.json");
46421
46360
  const read = () => {
46422
46361
  try {
46423
- return JSON.parse(import_node_fs14.default.readFileSync(file, "utf8"));
46362
+ return JSON.parse(import_node_fs13.default.readFileSync(file, "utf8"));
46424
46363
  } catch {
46425
46364
  return [];
46426
46365
  }
46427
46366
  };
46428
46367
  const write = (rows) => {
46429
- import_node_fs14.default.mkdirSync(opts.dir, { recursive: true });
46430
- import_node_fs14.default.writeFileSync(file, JSON.stringify(rows, null, 2));
46368
+ import_node_fs13.default.mkdirSync(opts.dir, { recursive: true });
46369
+ import_node_fs13.default.writeFileSync(file, JSON.stringify(rows, null, 2));
46431
46370
  };
46432
46371
  return {
46433
46372
  upsert(r) {
@@ -46461,7 +46400,7 @@ init_claude();
46461
46400
 
46462
46401
  // src/tools/codex.ts
46463
46402
  var import_node_child_process4 = require("child_process");
46464
- var import_node_fs16 = __toESM(require("fs"), 1);
46403
+ var import_node_fs15 = __toESM(require("fs"), 1);
46465
46404
 
46466
46405
  // src/tools/codex-session.ts
46467
46406
  var import_node_child_process3 = require("child_process");
@@ -46709,8 +46648,8 @@ function turnStartInput(text) {
46709
46648
  const items = [];
46710
46649
  let leftover = text;
46711
46650
  for (const m2 of text.matchAll(SKILL_RE)) {
46712
- const [marker, name, path78] = m2;
46713
- items.push({ type: "skill", name, path: path78 });
46651
+ const [marker, name, path77] = m2;
46652
+ items.push({ type: "skill", name, path: path77 });
46714
46653
  leftover = leftover.replace(marker, "");
46715
46654
  }
46716
46655
  for (const m2 of text.matchAll(ATTACHMENT_RE2)) {
@@ -46894,10 +46833,10 @@ function sanitizeCodexModel(model) {
46894
46833
  return CODEX_MODELS.some((m2) => m2.id === model) ? model : void 0;
46895
46834
  }
46896
46835
  async function probeCodex(env = process.env) {
46897
- if (env.CODEX_BIN && import_node_fs16.default.existsSync(env.CODEX_BIN)) return { available: true, path: env.CODEX_BIN };
46836
+ if (env.CODEX_BIN && import_node_fs15.default.existsSync(env.CODEX_BIN)) return { available: true, path: env.CODEX_BIN };
46898
46837
  try {
46899
46838
  const out = (0, import_node_child_process4.execFileSync)("which", ["codex"], { encoding: "utf8" }).trim();
46900
- if (out && import_node_fs16.default.existsSync(out)) return { available: true, path: out };
46839
+ if (out && import_node_fs15.default.existsSync(out)) return { available: true, path: out };
46901
46840
  } catch {
46902
46841
  }
46903
46842
  return { available: false };
@@ -46943,9 +46882,9 @@ var CodexAdapter = class {
46943
46882
 
46944
46883
  // src/tools/claude-tui.ts
46945
46884
  var import_node_crypto5 = require("crypto");
46946
- var import_node_fs17 = __toESM(require("fs"), 1);
46885
+ var import_node_fs16 = __toESM(require("fs"), 1);
46947
46886
  var import_node_os7 = __toESM(require("os"), 1);
46948
- var import_node_path15 = __toESM(require("path"), 1);
46887
+ var import_node_path14 = __toESM(require("path"), 1);
46949
46888
  var import_headless = __toESM(require_xterm_headless(), 1);
46950
46889
 
46951
46890
  // ../node_modules/.pnpm/@xterm+addon-serialize@0.14.0/node_modules/@xterm/addon-serialize/lib/addon-serialize.mjs
@@ -48187,9 +48126,9 @@ function buildTuiSpawnArgs(ctx, isResume = false) {
48187
48126
  function jsonlExistsForCtx(ctx) {
48188
48127
  if (!ctx.toolSessionId) return false;
48189
48128
  const home = import_node_os7.default.homedir();
48190
- const file = import_node_path15.default.join(home, ".claude", "projects", cwdToHashDir(ctx.cwd), `${ctx.toolSessionId}.jsonl`);
48129
+ const file = import_node_path14.default.join(home, ".claude", "projects", cwdToHashDir(ctx.cwd), `${ctx.toolSessionId}.jsonl`);
48191
48130
  try {
48192
- return import_node_fs17.default.statSync(file).isFile();
48131
+ return import_node_fs16.default.statSync(file).isFile();
48193
48132
  } catch {
48194
48133
  return false;
48195
48134
  }
@@ -48258,10 +48197,10 @@ var PersonaDispatchManager = class {
48258
48197
  };
48259
48198
 
48260
48199
  // src/dispatch/mcp-config.ts
48261
- var import_node_fs18 = __toESM(require("fs"), 1);
48262
- var import_node_path16 = __toESM(require("path"), 1);
48200
+ var import_node_fs17 = __toESM(require("fs"), 1);
48201
+ var import_node_path15 = __toESM(require("path"), 1);
48263
48202
  function dispatchMcpConfigPath(dataDir) {
48264
- return import_node_path16.default.join(dataDir, "dispatch.mcp.json");
48203
+ return import_node_path15.default.join(dataDir, "dispatch.mcp.json");
48265
48204
  }
48266
48205
  function writeDispatchMcpConfig(args) {
48267
48206
  const cfgPath = dispatchMcpConfigPath(args.dataDir);
@@ -48276,16 +48215,16 @@ function writeDispatchMcpConfig(args) {
48276
48215
  }
48277
48216
  }
48278
48217
  };
48279
- import_node_fs18.default.mkdirSync(args.dataDir, { recursive: true });
48280
- import_node_fs18.default.writeFileSync(cfgPath, JSON.stringify(content, null, 2), "utf8");
48218
+ import_node_fs17.default.mkdirSync(args.dataDir, { recursive: true });
48219
+ import_node_fs17.default.writeFileSync(cfgPath, JSON.stringify(content, null, 2), "utf8");
48281
48220
  return cfgPath;
48282
48221
  }
48283
48222
 
48284
48223
  // src/ticket/mcp-config.ts
48285
- var import_node_fs19 = __toESM(require("fs"), 1);
48286
- var import_node_path17 = __toESM(require("path"), 1);
48224
+ var import_node_fs18 = __toESM(require("fs"), 1);
48225
+ var import_node_path16 = __toESM(require("path"), 1);
48287
48226
  function ticketMcpConfigPath(dataDir) {
48288
- return import_node_path17.default.join(dataDir, "ticket.mcp.json");
48227
+ return import_node_path16.default.join(dataDir, "ticket.mcp.json");
48289
48228
  }
48290
48229
  function writeTicketMcpConfig(args) {
48291
48230
  const cfgPath = ticketMcpConfigPath(args.dataDir);
@@ -48306,16 +48245,16 @@ function writeTicketMcpConfig(args) {
48306
48245
  }
48307
48246
  }
48308
48247
  };
48309
- import_node_fs19.default.mkdirSync(args.dataDir, { recursive: true });
48310
- import_node_fs19.default.writeFileSync(cfgPath, JSON.stringify(content, null, 2), "utf8");
48248
+ import_node_fs18.default.mkdirSync(args.dataDir, { recursive: true });
48249
+ import_node_fs18.default.writeFileSync(cfgPath, JSON.stringify(content, null, 2), "utf8");
48311
48250
  return cfgPath;
48312
48251
  }
48313
48252
 
48314
48253
  // src/shift/mcp-config.ts
48315
- var import_node_fs20 = __toESM(require("fs"), 1);
48316
- var import_node_path18 = __toESM(require("path"), 1);
48254
+ var import_node_fs19 = __toESM(require("fs"), 1);
48255
+ var import_node_path17 = __toESM(require("path"), 1);
48317
48256
  function shiftMcpConfigPath(dataDir) {
48318
- return import_node_path18.default.join(dataDir, "shift.mcp.json");
48257
+ return import_node_path17.default.join(dataDir, "shift.mcp.json");
48319
48258
  }
48320
48259
  async function writeShiftMcpConfig(args) {
48321
48260
  const cfgPath = shiftMcpConfigPath(args.dataDir);
@@ -48330,16 +48269,16 @@ async function writeShiftMcpConfig(args) {
48330
48269
  }
48331
48270
  }
48332
48271
  };
48333
- await import_node_fs20.default.promises.mkdir(args.dataDir, { recursive: true });
48334
- await import_node_fs20.default.promises.writeFile(cfgPath, JSON.stringify(content, null, 2), "utf8");
48272
+ await import_node_fs19.default.promises.mkdir(args.dataDir, { recursive: true });
48273
+ await import_node_fs19.default.promises.writeFile(cfgPath, JSON.stringify(content, null, 2), "utf8");
48335
48274
  return cfgPath;
48336
48275
  }
48337
48276
 
48338
48277
  // src/inbox/mcp-config.ts
48339
- var import_node_fs21 = __toESM(require("fs"), 1);
48340
- var import_node_path19 = __toESM(require("path"), 1);
48278
+ var import_node_fs20 = __toESM(require("fs"), 1);
48279
+ var import_node_path18 = __toESM(require("path"), 1);
48341
48280
  function inboxMcpConfigPath(dataDir) {
48342
- return import_node_path19.default.join(dataDir, "inbox.mcp.json");
48281
+ return import_node_path18.default.join(dataDir, "inbox.mcp.json");
48343
48282
  }
48344
48283
  async function writeInboxMcpConfig(args) {
48345
48284
  const cfgPath = inboxMcpConfigPath(args.dataDir);
@@ -48354,14 +48293,14 @@ async function writeInboxMcpConfig(args) {
48354
48293
  }
48355
48294
  }
48356
48295
  };
48357
- await import_node_fs21.default.promises.mkdir(args.dataDir, { recursive: true });
48358
- await import_node_fs21.default.promises.writeFile(cfgPath, JSON.stringify(content, null, 2), "utf8");
48296
+ await import_node_fs20.default.promises.mkdir(args.dataDir, { recursive: true });
48297
+ await import_node_fs20.default.promises.writeFile(cfgPath, JSON.stringify(content, null, 2), "utf8");
48359
48298
  return cfgPath;
48360
48299
  }
48361
48300
 
48362
48301
  // src/shift/store.ts
48363
48302
  var import_promises = __toESM(require("fs/promises"), 1);
48364
- var import_node_path20 = __toESM(require("path"), 1);
48303
+ var import_node_path19 = __toESM(require("path"), 1);
48365
48304
  var import_node_crypto6 = require("crypto");
48366
48305
 
48367
48306
  // src/shift/constants.ts
@@ -48430,7 +48369,7 @@ function createShiftStore(deps) {
48430
48369
  flushTimer = null;
48431
48370
  }
48432
48371
  const content = { version: 1, shifts };
48433
- await import_promises.default.mkdir(import_node_path20.default.dirname(deps.filePath), { recursive: true });
48372
+ await import_promises.default.mkdir(import_node_path19.default.dirname(deps.filePath), { recursive: true });
48434
48373
  const tmp = `${deps.filePath}.tmp-${deps.now()}-${Math.floor(Math.random() * 1e6)}`;
48435
48374
  await import_promises.default.writeFile(tmp, JSON.stringify(content, null, 2), "utf8");
48436
48375
  await import_promises.default.rename(tmp, deps.filePath);
@@ -49164,13 +49103,13 @@ function mapSkillsListResponse(res) {
49164
49103
  const r = s ?? {};
49165
49104
  const name = str3(r.name);
49166
49105
  if (!name) continue;
49167
- const path78 = str3(r.path);
49106
+ const path77 = str3(r.path);
49168
49107
  const description = str3(r.description);
49169
49108
  const isPlugin = name.includes(":");
49170
49109
  out.push({
49171
49110
  name,
49172
49111
  source: isPlugin ? "plugin" : "project",
49173
- ...path78 ? { path: path78 } : {},
49112
+ ...path77 ? { path: path77 } : {},
49174
49113
  ...description ? { description } : {},
49175
49114
  ...isPlugin ? { plugin: name.split(":")[0] } : {}
49176
49115
  });
@@ -49209,23 +49148,23 @@ async function listCodexSkills(cwd, deps = {}) {
49209
49148
  }
49210
49149
 
49211
49150
  // src/workspace/browser.ts
49212
- var import_node_fs22 = __toESM(require("fs"), 1);
49151
+ var import_node_fs21 = __toESM(require("fs"), 1);
49213
49152
  var import_node_os8 = __toESM(require("os"), 1);
49214
- var import_node_path21 = __toESM(require("path"), 1);
49153
+ var import_node_path20 = __toESM(require("path"), 1);
49215
49154
  init_protocol();
49216
49155
  var MAX_FILE_BYTES = 2 * 1024 * 1024;
49217
49156
  function resolveInsideCwd(cwd, subpath) {
49218
- const absCwd = import_node_path21.default.resolve(cwd);
49219
- const joined = import_node_path21.default.resolve(absCwd, subpath ?? ".");
49220
- const rel = import_node_path21.default.relative(absCwd, joined);
49221
- if (rel.startsWith("..") || import_node_path21.default.isAbsolute(rel)) {
49157
+ const absCwd = import_node_path20.default.resolve(cwd);
49158
+ const joined = import_node_path20.default.resolve(absCwd, subpath ?? ".");
49159
+ const rel = import_node_path20.default.relative(absCwd, joined);
49160
+ if (rel.startsWith("..") || import_node_path20.default.isAbsolute(rel)) {
49222
49161
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
49223
49162
  }
49224
49163
  return joined;
49225
49164
  }
49226
49165
  function ensureCwd(cwd) {
49227
49166
  try {
49228
- const stat = import_node_fs22.default.statSync(cwd);
49167
+ const stat = import_node_fs21.default.statSync(cwd);
49229
49168
  if (!stat.isDirectory()) {
49230
49169
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${cwd}`);
49231
49170
  }
@@ -49239,7 +49178,7 @@ var WorkspaceBrowser = class {
49239
49178
  const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os8.default.homedir();
49240
49179
  ensureCwd(cwd);
49241
49180
  const full = resolveInsideCwd(cwd, args.path);
49242
- const dirents = import_node_fs22.default.readdirSync(full, { withFileTypes: true });
49181
+ const dirents = import_node_fs21.default.readdirSync(full, { withFileTypes: true });
49243
49182
  const entries = [];
49244
49183
  for (const d of dirents) {
49245
49184
  if (!args.showHidden && d.name.startsWith(".")) continue;
@@ -49249,7 +49188,7 @@ var WorkspaceBrowser = class {
49249
49188
  mtime: ""
49250
49189
  };
49251
49190
  try {
49252
- const st = import_node_fs22.default.statSync(import_node_path21.default.join(full, d.name));
49191
+ const st = import_node_fs21.default.statSync(import_node_path20.default.join(full, d.name));
49253
49192
  entry.mtime = new Date(st.mtimeMs).toISOString();
49254
49193
  if (d.isFile()) entry.size = st.size;
49255
49194
  } catch {
@@ -49265,14 +49204,14 @@ var WorkspaceBrowser = class {
49265
49204
  read(args) {
49266
49205
  ensureCwd(args.cwd);
49267
49206
  const full = resolveInsideCwd(args.cwd, args.path);
49268
- const st = import_node_fs22.default.statSync(full);
49207
+ const st = import_node_fs21.default.statSync(full);
49269
49208
  if (!st.isFile()) {
49270
49209
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `not a file: ${args.path}`);
49271
49210
  }
49272
49211
  if (st.size > MAX_FILE_BYTES) {
49273
49212
  throw new ClawdError(ERROR_CODES.FILE_TOO_LARGE, `file > ${MAX_FILE_BYTES} bytes`);
49274
49213
  }
49275
- const buf = import_node_fs22.default.readFileSync(full);
49214
+ const buf = import_node_fs21.default.readFileSync(full);
49276
49215
  const isBinary = buf.includes(0);
49277
49216
  if (isBinary) {
49278
49217
  return {
@@ -49294,20 +49233,20 @@ var WorkspaceBrowser = class {
49294
49233
  };
49295
49234
 
49296
49235
  // src/skills/agents-scanner.ts
49297
- var import_node_fs23 = __toESM(require("fs"), 1);
49236
+ var import_node_fs22 = __toESM(require("fs"), 1);
49298
49237
  var import_node_os9 = __toESM(require("os"), 1);
49299
- var import_node_path22 = __toESM(require("path"), 1);
49238
+ var import_node_path21 = __toESM(require("path"), 1);
49300
49239
  var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
49301
49240
  function isDirLikeSync2(p2) {
49302
49241
  try {
49303
- return import_node_fs23.default.statSync(p2).isDirectory();
49242
+ return import_node_fs22.default.statSync(p2).isDirectory();
49304
49243
  } catch {
49305
49244
  return false;
49306
49245
  }
49307
49246
  }
49308
49247
  function fileExistsSync(p2) {
49309
49248
  try {
49310
- return import_node_fs23.default.statSync(p2).isFile();
49249
+ return import_node_fs22.default.statSync(p2).isFile();
49311
49250
  } catch {
49312
49251
  return false;
49313
49252
  }
@@ -49315,7 +49254,7 @@ function fileExistsSync(p2) {
49315
49254
  function parseAgentFile(filePath) {
49316
49255
  let content;
49317
49256
  try {
49318
- content = import_node_fs23.default.readFileSync(filePath, "utf8");
49257
+ content = import_node_fs22.default.readFileSync(filePath, "utf8");
49319
49258
  } catch {
49320
49259
  return {};
49321
49260
  }
@@ -49328,16 +49267,16 @@ function parseAgentFile(filePath) {
49328
49267
  function scanAgentsDir(dir, source, seen, out) {
49329
49268
  let entries;
49330
49269
  try {
49331
- entries = import_node_fs23.default.readdirSync(dir, { withFileTypes: true });
49270
+ entries = import_node_fs22.default.readdirSync(dir, { withFileTypes: true });
49332
49271
  } catch {
49333
49272
  return;
49334
49273
  }
49335
49274
  for (const ent of entries) {
49336
49275
  if (!ent.name.endsWith(".md")) continue;
49337
- if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path22.default.join(dir, ent.name)))) {
49276
+ if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path21.default.join(dir, ent.name)))) {
49338
49277
  continue;
49339
49278
  }
49340
- const filePath = import_node_path22.default.join(dir, ent.name);
49279
+ const filePath = import_node_path21.default.join(dir, ent.name);
49341
49280
  const baseName = ent.name.replace(/\.md$/, "");
49342
49281
  if (seen.has(baseName)) continue;
49343
49282
  seen.add(baseName);
@@ -49355,12 +49294,12 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
49355
49294
  function walk2(dir, namespaces) {
49356
49295
  let entries;
49357
49296
  try {
49358
- entries = import_node_fs23.default.readdirSync(dir, { withFileTypes: true });
49297
+ entries = import_node_fs22.default.readdirSync(dir, { withFileTypes: true });
49359
49298
  } catch {
49360
49299
  return;
49361
49300
  }
49362
49301
  for (const ent of entries) {
49363
- const childPath = import_node_path22.default.join(dir, ent.name);
49302
+ const childPath = import_node_path21.default.join(dir, ent.name);
49364
49303
  if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
49365
49304
  walk2(childPath, [...namespaces, ent.name]);
49366
49305
  continue;
@@ -49385,13 +49324,13 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
49385
49324
  walk2(root, []);
49386
49325
  }
49387
49326
  function readInstalledPlugins2(home) {
49388
- const pluginsDir = import_node_path22.default.join(home, ".claude", "plugins");
49389
- const v2 = import_node_path22.default.join(pluginsDir, "installed_plugins_v2.json");
49390
- const v1 = import_node_path22.default.join(pluginsDir, "installed_plugins.json");
49327
+ const pluginsDir = import_node_path21.default.join(home, ".claude", "plugins");
49328
+ const v2 = import_node_path21.default.join(pluginsDir, "installed_plugins_v2.json");
49329
+ const v1 = import_node_path21.default.join(pluginsDir, "installed_plugins.json");
49391
49330
  let raw = null;
49392
49331
  for (const candidate of [v2, v1]) {
49393
49332
  try {
49394
- raw = import_node_fs23.default.readFileSync(candidate, "utf8");
49333
+ raw = import_node_fs22.default.readFileSync(candidate, "utf8");
49395
49334
  break;
49396
49335
  } catch {
49397
49336
  }
@@ -49416,19 +49355,19 @@ function readInstalledPlugins2(home) {
49416
49355
  return out;
49417
49356
  }
49418
49357
  function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
49419
- let cur = import_node_path22.default.resolve(startCwd);
49420
- const fsRoot = import_node_path22.default.parse(cur).root;
49358
+ let cur = import_node_path21.default.resolve(startCwd);
49359
+ const fsRoot = import_node_path21.default.parse(cur).root;
49421
49360
  while (true) {
49422
- scanAgentsDir(import_node_path22.default.join(cur, ".claude", "agents"), "project", seen, out);
49361
+ scanAgentsDir(import_node_path21.default.join(cur, ".claude", "agents"), "project", seen, out);
49423
49362
  let hasGit = false;
49424
49363
  try {
49425
- hasGit = import_node_fs23.default.existsSync(import_node_path22.default.join(cur, ".git"));
49364
+ hasGit = import_node_fs22.default.existsSync(import_node_path21.default.join(cur, ".git"));
49426
49365
  } catch {
49427
49366
  }
49428
49367
  if (hasGit) return;
49429
49368
  if (cur === home) return;
49430
49369
  if (cur === fsRoot) return;
49431
- const parent = import_node_path22.default.dirname(cur);
49370
+ const parent = import_node_path21.default.dirname(cur);
49432
49371
  if (parent === cur) return;
49433
49372
  cur = parent;
49434
49373
  }
@@ -49463,7 +49402,7 @@ var AgentsScanner = class {
49463
49402
  }
49464
49403
  const fsBlock = [];
49465
49404
  scanAgentsDir(
49466
- import_node_path22.default.join(this.home, ".claude", "agents"),
49405
+ import_node_path21.default.join(this.home, ".claude", "agents"),
49467
49406
  "global",
49468
49407
  seen,
49469
49408
  fsBlock
@@ -49477,7 +49416,7 @@ var AgentsScanner = class {
49477
49416
  ...this.extraPluginRoots
49478
49417
  ];
49479
49418
  for (const { name, root } of plugins) {
49480
- const agentsRoot = import_node_path22.default.join(root, "agents");
49419
+ const agentsRoot = import_node_path21.default.join(root, "agents");
49481
49420
  scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
49482
49421
  }
49483
49422
  return [...builtinBlock, ...fsBlock];
@@ -49485,15 +49424,15 @@ var AgentsScanner = class {
49485
49424
  };
49486
49425
 
49487
49426
  // src/observer/session-observer.ts
49488
- var import_node_fs25 = __toESM(require("fs"), 1);
49427
+ var import_node_fs24 = __toESM(require("fs"), 1);
49489
49428
  var import_node_os11 = __toESM(require("os"), 1);
49490
- var import_node_path24 = __toESM(require("path"), 1);
49429
+ var import_node_path23 = __toESM(require("path"), 1);
49491
49430
  init_claude_history();
49492
49431
 
49493
49432
  // src/observer/subagent-meta-observer.ts
49494
- var import_node_fs24 = __toESM(require("fs"), 1);
49433
+ var import_node_fs23 = __toESM(require("fs"), 1);
49495
49434
  var import_node_os10 = __toESM(require("os"), 1);
49496
- var import_node_path23 = __toESM(require("path"), 1);
49435
+ var import_node_path22 = __toESM(require("path"), 1);
49497
49436
  init_claude_history();
49498
49437
  var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
49499
49438
  var SubagentMetaObserver = class {
@@ -49506,7 +49445,7 @@ var SubagentMetaObserver = class {
49506
49445
  watches = /* @__PURE__ */ new Map();
49507
49446
  // public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
49508
49447
  resolveSubagentDir(cwd, toolSessionId) {
49509
- return import_node_path23.default.join(
49448
+ return import_node_path22.default.join(
49510
49449
  this.home,
49511
49450
  ".claude",
49512
49451
  "projects",
@@ -49536,7 +49475,7 @@ var SubagentMetaObserver = class {
49536
49475
  attachWatcher(w2) {
49537
49476
  if (w2.watcher) return;
49538
49477
  try {
49539
- w2.watcher = import_node_fs24.default.watch(w2.dirPath, { persistent: false }, (_evt, name) => {
49478
+ w2.watcher = import_node_fs23.default.watch(w2.dirPath, { persistent: false }, (_evt, name) => {
49540
49479
  if (!name) return;
49541
49480
  const m2 = META_RE.exec(String(name));
49542
49481
  if (!m2) return;
@@ -49548,7 +49487,7 @@ var SubagentMetaObserver = class {
49548
49487
  scan(w2) {
49549
49488
  let entries;
49550
49489
  try {
49551
- entries = import_node_fs24.default.readdirSync(w2.dirPath);
49490
+ entries = import_node_fs23.default.readdirSync(w2.dirPath);
49552
49491
  } catch {
49553
49492
  return;
49554
49493
  }
@@ -49562,10 +49501,10 @@ var SubagentMetaObserver = class {
49562
49501
  if (!m2) return;
49563
49502
  const agentId = m2[1];
49564
49503
  if (w2.emitted.has(agentId)) return;
49565
- const file = import_node_path23.default.join(w2.dirPath, name);
49504
+ const file = import_node_path22.default.join(w2.dirPath, name);
49566
49505
  let raw;
49567
49506
  try {
49568
- raw = import_node_fs24.default.readFileSync(file, "utf8");
49507
+ raw = import_node_fs23.default.readFileSync(file, "utf8");
49569
49508
  } catch {
49570
49509
  return;
49571
49510
  }
@@ -49622,14 +49561,14 @@ var SessionObserver = class {
49622
49561
  metaObserver;
49623
49562
  resolveJsonlPath(cwd, toolSessionId, override) {
49624
49563
  if (override) return override;
49625
- return import_node_path24.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
49564
+ return import_node_path23.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
49626
49565
  }
49627
49566
  start(args) {
49628
49567
  this.stop(args.sessionId);
49629
49568
  const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
49630
49569
  let size = 0;
49631
49570
  try {
49632
- size = import_node_fs25.default.statSync(filePath).size;
49571
+ size = import_node_fs24.default.statSync(filePath).size;
49633
49572
  } catch {
49634
49573
  }
49635
49574
  const w2 = {
@@ -49643,10 +49582,10 @@ var SessionObserver = class {
49643
49582
  prevIsRejectSentinel: false
49644
49583
  };
49645
49584
  try {
49646
- import_node_fs25.default.mkdirSync(import_node_path24.default.dirname(filePath), { recursive: true });
49585
+ import_node_fs24.default.mkdirSync(import_node_path23.default.dirname(filePath), { recursive: true });
49647
49586
  } catch {
49648
49587
  }
49649
- w2.watcher = import_node_fs25.default.watch(import_node_path24.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
49588
+ w2.watcher = import_node_fs24.default.watch(import_node_path23.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
49650
49589
  if (!changedName || !filePath.endsWith(changedName)) return;
49651
49590
  this.poll(w2);
49652
49591
  });
@@ -49669,7 +49608,7 @@ var SessionObserver = class {
49669
49608
  // 异常静默吞,不阻塞 watcher 启动
49670
49609
  hydrateMetaTail(w2, maxLines = 200) {
49671
49610
  try {
49672
- const raw = import_node_fs25.default.readFileSync(w2.filePath, "utf8");
49611
+ const raw = import_node_fs24.default.readFileSync(w2.filePath, "utf8");
49673
49612
  if (!raw) return;
49674
49613
  const allLines = raw.split("\n").filter((l) => l.trim().length > 0);
49675
49614
  if (allLines.length === 0) return;
@@ -49693,7 +49632,7 @@ var SessionObserver = class {
49693
49632
  poll(w2) {
49694
49633
  let size = 0;
49695
49634
  try {
49696
- size = import_node_fs25.default.statSync(w2.filePath).size;
49635
+ size = import_node_fs24.default.statSync(w2.filePath).size;
49697
49636
  } catch {
49698
49637
  return;
49699
49638
  }
@@ -49702,11 +49641,11 @@ var SessionObserver = class {
49702
49641
  w2.buf = "";
49703
49642
  }
49704
49643
  if (size === w2.lastSize) return;
49705
- const fd = import_node_fs25.default.openSync(w2.filePath, "r");
49644
+ const fd = import_node_fs24.default.openSync(w2.filePath, "r");
49706
49645
  try {
49707
49646
  const len = size - w2.lastSize;
49708
49647
  const buf = Buffer.alloc(len);
49709
- import_node_fs25.default.readSync(fd, buf, 0, len, w2.lastSize);
49648
+ import_node_fs24.default.readSync(fd, buf, 0, len, w2.lastSize);
49710
49649
  w2.lastSize = size;
49711
49650
  w2.buf += buf.toString("utf8");
49712
49651
  let newlineIndex;
@@ -49729,7 +49668,7 @@ var SessionObserver = class {
49729
49668
  }
49730
49669
  }
49731
49670
  } finally {
49732
- import_node_fs25.default.closeSync(fd);
49671
+ import_node_fs24.default.closeSync(fd);
49733
49672
  }
49734
49673
  }
49735
49674
  // 解析 JSONL 单行:仅当是主链 user 文本行(非 sidechain / 非 sub-agent / message.role='user'
@@ -50532,15 +50471,15 @@ async function authenticate(token, deps) {
50532
50471
  }
50533
50472
 
50534
50473
  // src/permission/capability-store.ts
50535
- var fs29 = __toESM(require("fs"), 1);
50536
- var path29 = __toESM(require("path"), 1);
50474
+ var fs28 = __toESM(require("fs"), 1);
50475
+ var path28 = __toESM(require("path"), 1);
50537
50476
  init_src();
50538
50477
  var CAPABILITIES_FILE_NAME = "capabilities.json";
50539
50478
  var FILE_VERSION = 1;
50540
50479
  var CapabilityStore = class {
50541
50480
  constructor(dataDir) {
50542
50481
  this.dataDir = dataDir;
50543
- fs29.mkdirSync(dataDir, { recursive: true });
50482
+ fs28.mkdirSync(dataDir, { recursive: true });
50544
50483
  this.cache = this.readFromDisk();
50545
50484
  }
50546
50485
  dataDir;
@@ -50564,13 +50503,13 @@ var CapabilityStore = class {
50564
50503
  this.flush();
50565
50504
  }
50566
50505
  filePath() {
50567
- return path29.join(this.dataDir, CAPABILITIES_FILE_NAME);
50506
+ return path28.join(this.dataDir, CAPABILITIES_FILE_NAME);
50568
50507
  }
50569
50508
  readFromDisk() {
50570
50509
  const file = this.filePath();
50571
50510
  let raw;
50572
50511
  try {
50573
- raw = fs29.readFileSync(file, "utf8");
50512
+ raw = fs28.readFileSync(file, "utf8");
50574
50513
  } catch (err) {
50575
50514
  if (err?.code === "ENOENT") return [];
50576
50515
  return [];
@@ -50598,10 +50537,10 @@ var CapabilityStore = class {
50598
50537
  }
50599
50538
  atomicWrite(file, content) {
50600
50539
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
50601
- fs29.writeFileSync(tmp, content, { mode: 384 });
50602
- fs29.renameSync(tmp, file);
50540
+ fs28.writeFileSync(tmp, content, { mode: 384 });
50541
+ fs28.renameSync(tmp, file);
50603
50542
  try {
50604
- fs29.chmodSync(file, 384);
50543
+ fs28.chmodSync(file, 384);
50605
50544
  } catch {
50606
50545
  }
50607
50546
  }
@@ -50694,14 +50633,14 @@ var CapabilityManager = class {
50694
50633
  };
50695
50634
 
50696
50635
  // src/permission/cleanup.ts
50697
- var fs30 = __toESM(require("fs"), 1);
50636
+ var fs29 = __toESM(require("fs"), 1);
50698
50637
  function cleanupGuestSessionsForCapability(cap, factory) {
50699
50638
  const removed = [];
50700
50639
  for (const g2 of cap.grants) {
50701
50640
  if (g2.resource.type !== "persona") continue;
50702
50641
  const dir = factory.vmGuestRoot(g2.resource.id, cap.id);
50703
50642
  try {
50704
- fs30.rmSync(dir, { recursive: true, force: true });
50643
+ fs29.rmSync(dir, { recursive: true, force: true });
50705
50644
  removed.push(dir);
50706
50645
  } catch {
50707
50646
  }
@@ -50710,14 +50649,14 @@ function cleanupGuestSessionsForCapability(cap, factory) {
50710
50649
  }
50711
50650
 
50712
50651
  // src/inbox/inbox-store.ts
50713
- var fs31 = __toESM(require("fs"), 1);
50714
- var path30 = __toESM(require("path"), 1);
50652
+ var fs30 = __toESM(require("fs"), 1);
50653
+ var path29 = __toESM(require("path"), 1);
50715
50654
  init_src();
50716
50655
  var INBOX_SUBDIR = "inbox";
50717
50656
  var InboxStore = class {
50718
50657
  constructor(dataDir) {
50719
50658
  this.dataDir = dataDir;
50720
- fs31.mkdirSync(this.dirPath(), { recursive: true });
50659
+ fs30.mkdirSync(this.dirPath(), { recursive: true });
50721
50660
  }
50722
50661
  dataDir;
50723
50662
  /**
@@ -50729,7 +50668,7 @@ var InboxStore = class {
50729
50668
  const file = this.filePath(peerDeviceId);
50730
50669
  let raw;
50731
50670
  try {
50732
- raw = fs31.readFileSync(file, "utf8");
50671
+ raw = fs30.readFileSync(file, "utf8");
50733
50672
  } catch (err) {
50734
50673
  if (err?.code === "ENOENT") return [];
50735
50674
  return [];
@@ -50745,7 +50684,7 @@ var InboxStore = class {
50745
50684
  const dir = this.dirPath();
50746
50685
  let entries;
50747
50686
  try {
50748
- entries = fs31.readdirSync(dir);
50687
+ entries = fs30.readdirSync(dir);
50749
50688
  } catch (err) {
50750
50689
  if (err?.code === "ENOENT") return [];
50751
50690
  return [];
@@ -50761,9 +50700,9 @@ var InboxStore = class {
50761
50700
  if (existing.some((m2) => m2.id === message.id)) return;
50762
50701
  const file = this.filePath(message.peerDeviceId);
50763
50702
  const line = JSON.stringify(message) + "\n";
50764
- fs31.appendFileSync(file, line, { mode: 384 });
50703
+ fs30.appendFileSync(file, line, { mode: 384 });
50765
50704
  try {
50766
- fs31.chmodSync(file, 384);
50705
+ fs30.chmodSync(file, 384);
50767
50706
  } catch {
50768
50707
  }
50769
50708
  }
@@ -50793,7 +50732,7 @@ var InboxStore = class {
50793
50732
  removeByPeerDeviceId(peerDeviceId) {
50794
50733
  const file = this.filePath(peerDeviceId);
50795
50734
  try {
50796
- fs31.unlinkSync(file);
50735
+ fs30.unlinkSync(file);
50797
50736
  } catch (err) {
50798
50737
  if (err?.code === "ENOENT") return;
50799
50738
  }
@@ -50802,18 +50741,18 @@ var InboxStore = class {
50802
50741
  const file = this.filePath(peerDeviceId);
50803
50742
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
50804
50743
  const content = messages.map((m2) => JSON.stringify(m2)).join("\n") + (messages.length > 0 ? "\n" : "");
50805
- fs31.writeFileSync(tmp, content, { mode: 384 });
50806
- fs31.renameSync(tmp, file);
50744
+ fs30.writeFileSync(tmp, content, { mode: 384 });
50745
+ fs30.renameSync(tmp, file);
50807
50746
  try {
50808
- fs31.chmodSync(file, 384);
50747
+ fs30.chmodSync(file, 384);
50809
50748
  } catch {
50810
50749
  }
50811
50750
  }
50812
50751
  dirPath() {
50813
- return path30.join(this.dataDir, INBOX_SUBDIR);
50752
+ return path29.join(this.dataDir, INBOX_SUBDIR);
50814
50753
  }
50815
50754
  filePath(peerDeviceId) {
50816
- return path30.join(this.dirPath(), `${peerDeviceId}.jsonl`);
50755
+ return path29.join(this.dirPath(), `${peerDeviceId}.jsonl`);
50817
50756
  }
50818
50757
  };
50819
50758
  function parseAllLines(raw) {
@@ -50901,8 +50840,8 @@ var InboxManager = class {
50901
50840
  };
50902
50841
 
50903
50842
  // src/state/contact-store.ts
50904
- var fs32 = __toESM(require("fs"), 1);
50905
- var path31 = __toESM(require("path"), 1);
50843
+ var fs31 = __toESM(require("fs"), 1);
50844
+ var path30 = __toESM(require("path"), 1);
50906
50845
  init_src();
50907
50846
  var FILE_NAME = "contacts.json";
50908
50847
  var ContactStore = class {
@@ -50913,10 +50852,10 @@ var ContactStore = class {
50913
50852
  contacts = /* @__PURE__ */ new Map();
50914
50853
  load() {
50915
50854
  this.contacts.clear();
50916
- const file = path31.join(this.dataDir, FILE_NAME);
50855
+ const file = path30.join(this.dataDir, FILE_NAME);
50917
50856
  let raw;
50918
50857
  try {
50919
- raw = fs32.readFileSync(file, "utf8");
50858
+ raw = fs31.readFileSync(file, "utf8");
50920
50859
  } catch (err) {
50921
50860
  if (err?.code !== "ENOENT") this.renameBak(file);
50922
50861
  return;
@@ -50988,20 +50927,20 @@ var ContactStore = class {
50988
50927
  return true;
50989
50928
  }
50990
50929
  flush() {
50991
- const file = path31.join(this.dataDir, FILE_NAME);
50930
+ const file = path30.join(this.dataDir, FILE_NAME);
50992
50931
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
50993
50932
  const content = JSON.stringify(
50994
50933
  { contacts: Array.from(this.contacts.values()) },
50995
50934
  null,
50996
50935
  2
50997
50936
  );
50998
- fs32.mkdirSync(this.dataDir, { recursive: true });
50999
- fs32.writeFileSync(tmp, content, { mode: 384 });
51000
- fs32.renameSync(tmp, file);
50937
+ fs31.mkdirSync(this.dataDir, { recursive: true });
50938
+ fs31.writeFileSync(tmp, content, { mode: 384 });
50939
+ fs31.renameSync(tmp, file);
51001
50940
  }
51002
50941
  renameBak(file) {
51003
50942
  try {
51004
- fs32.renameSync(file, `${file}.bak`);
50943
+ fs31.renameSync(file, `${file}.bak`);
51005
50944
  } catch {
51006
50945
  }
51007
50946
  }
@@ -51158,61 +51097,61 @@ async function autoReverseContact(args) {
51158
51097
  init_src();
51159
51098
 
51160
51099
  // src/migrations/2026-05-20-flatten-sessions.ts
51161
- var fs33 = __toESM(require("fs"), 1);
51162
- var path32 = __toESM(require("path"), 1);
51100
+ var fs32 = __toESM(require("fs"), 1);
51101
+ var path31 = __toESM(require("path"), 1);
51163
51102
  var MIGRATION_FLAG_NAME = ".migration.v1.done";
51164
51103
  function migrateFlattenSessions(opts) {
51165
51104
  const dataDir = opts.dataDir;
51166
51105
  const now = opts.now ?? Date.now;
51167
- const sessionsDir = path32.join(dataDir, "sessions");
51168
- const flagPath = path32.join(sessionsDir, MIGRATION_FLAG_NAME);
51106
+ const sessionsDir = path31.join(dataDir, "sessions");
51107
+ const flagPath = path31.join(sessionsDir, MIGRATION_FLAG_NAME);
51169
51108
  if (existsSync3(flagPath)) {
51170
51109
  return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
51171
51110
  }
51172
51111
  let movedBare = 0;
51173
51112
  let movedVmOwner = 0;
51174
51113
  let archivedListener = 0;
51175
- const defaultDir = path32.join(sessionsDir, "default");
51114
+ const defaultDir = path31.join(sessionsDir, "default");
51176
51115
  if (existsSync3(defaultDir)) {
51177
51116
  for (const entry of readdirSafe(defaultDir)) {
51178
51117
  if (!entry.endsWith(".json")) continue;
51179
- const src = path32.join(defaultDir, entry);
51180
- const dst = path32.join(sessionsDir, entry);
51181
- fs33.renameSync(src, dst);
51118
+ const src = path31.join(defaultDir, entry);
51119
+ const dst = path31.join(sessionsDir, entry);
51120
+ fs32.renameSync(src, dst);
51182
51121
  movedBare += 1;
51183
51122
  }
51184
51123
  rmdirIfEmpty(defaultDir);
51185
51124
  }
51186
51125
  for (const pid of readdirSafe(sessionsDir)) {
51187
- const personaDir = path32.join(sessionsDir, pid);
51126
+ const personaDir = path31.join(sessionsDir, pid);
51188
51127
  if (!isDir(personaDir)) continue;
51189
51128
  if (pid === "default") continue;
51190
- const ownerSrc = path32.join(personaDir, "owner");
51129
+ const ownerSrc = path31.join(personaDir, "owner");
51191
51130
  if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
51192
- const ownerDst = path32.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
51193
- fs33.mkdirSync(ownerDst, { recursive: true });
51131
+ const ownerDst = path31.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
51132
+ fs32.mkdirSync(ownerDst, { recursive: true });
51194
51133
  for (const file of readdirSafe(ownerSrc)) {
51195
51134
  if (!file.endsWith(".json")) continue;
51196
- fs33.renameSync(path32.join(ownerSrc, file), path32.join(ownerDst, file));
51135
+ fs32.renameSync(path31.join(ownerSrc, file), path31.join(ownerDst, file));
51197
51136
  movedVmOwner += 1;
51198
51137
  }
51199
51138
  rmdirIfEmpty(ownerSrc);
51200
51139
  }
51201
- const listenerSrc = path32.join(personaDir, "listener");
51140
+ const listenerSrc = path31.join(personaDir, "listener");
51202
51141
  if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
51203
- const archiveDst = path32.join(dataDir, ".legacy", `listener-${pid}`);
51204
- fs33.mkdirSync(archiveDst, { recursive: true });
51142
+ const archiveDst = path31.join(dataDir, ".legacy", `listener-${pid}`);
51143
+ fs32.mkdirSync(archiveDst, { recursive: true });
51205
51144
  for (const file of readdirSafe(listenerSrc)) {
51206
51145
  if (!file.endsWith(".json")) continue;
51207
- fs33.renameSync(path32.join(listenerSrc, file), path32.join(archiveDst, file));
51146
+ fs32.renameSync(path31.join(listenerSrc, file), path31.join(archiveDst, file));
51208
51147
  archivedListener += 1;
51209
51148
  }
51210
51149
  rmdirIfEmpty(listenerSrc);
51211
51150
  }
51212
51151
  rmdirIfEmpty(personaDir);
51213
51152
  }
51214
- fs33.mkdirSync(sessionsDir, { recursive: true });
51215
- fs33.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
51153
+ fs32.mkdirSync(sessionsDir, { recursive: true });
51154
+ fs32.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
51216
51155
  return {
51217
51156
  skipped: false,
51218
51157
  flagWritten: true,
@@ -51223,7 +51162,7 @@ function migrateFlattenSessions(opts) {
51223
51162
  }
51224
51163
  function existsSync3(p2) {
51225
51164
  try {
51226
- fs33.statSync(p2);
51165
+ fs32.statSync(p2);
51227
51166
  return true;
51228
51167
  } catch {
51229
51168
  return false;
@@ -51231,31 +51170,31 @@ function existsSync3(p2) {
51231
51170
  }
51232
51171
  function isDir(p2) {
51233
51172
  try {
51234
- return fs33.statSync(p2).isDirectory();
51173
+ return fs32.statSync(p2).isDirectory();
51235
51174
  } catch {
51236
51175
  return false;
51237
51176
  }
51238
51177
  }
51239
51178
  function readdirSafe(p2) {
51240
51179
  try {
51241
- return fs33.readdirSync(p2);
51180
+ return fs32.readdirSync(p2);
51242
51181
  } catch {
51243
51182
  return [];
51244
51183
  }
51245
51184
  }
51246
51185
  function rmdirIfEmpty(p2) {
51247
51186
  try {
51248
- fs33.rmdirSync(p2);
51187
+ fs32.rmdirSync(p2);
51249
51188
  } catch {
51250
51189
  }
51251
51190
  }
51252
51191
 
51253
51192
  // src/transport/http-router.ts
51254
- var import_node_fs27 = __toESM(require("fs"), 1);
51255
- var import_node_path28 = __toESM(require("path"), 1);
51193
+ var import_node_fs26 = __toESM(require("fs"), 1);
51194
+ var import_node_path27 = __toESM(require("path"), 1);
51256
51195
 
51257
51196
  // src/attachment/mime.ts
51258
- var import_node_path25 = __toESM(require("path"), 1);
51197
+ var import_node_path24 = __toESM(require("path"), 1);
51259
51198
  var TEXT_PLAIN = "text/plain; charset=utf-8";
51260
51199
  var EXT_TO_NATIVE_MIME = {
51261
51200
  // 图片
@@ -51362,7 +51301,7 @@ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
51362
51301
  ".mk"
51363
51302
  ]);
51364
51303
  function lookupMime(filePathOrName) {
51365
- const ext = import_node_path25.default.extname(filePathOrName).toLowerCase();
51304
+ const ext = import_node_path24.default.extname(filePathOrName).toLowerCase();
51366
51305
  if (EXT_TO_NATIVE_MIME[ext]) return EXT_TO_NATIVE_MIME[ext];
51367
51306
  if (TEXT_EXTENSIONS.has(ext)) return TEXT_PLAIN;
51368
51307
  return "application/octet-stream";
@@ -51431,8 +51370,8 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
51431
51370
  }
51432
51371
 
51433
51372
  // src/attachment/upload.ts
51434
- var import_node_fs26 = __toESM(require("fs"), 1);
51435
- var import_node_path26 = __toESM(require("path"), 1);
51373
+ var import_node_fs25 = __toESM(require("fs"), 1);
51374
+ var import_node_path25 = __toESM(require("path"), 1);
51436
51375
  var import_node_crypto8 = __toESM(require("crypto"), 1);
51437
51376
  var import_promises2 = require("stream/promises");
51438
51377
  var UploadError = class extends Error {
@@ -51444,22 +51383,22 @@ var UploadError = class extends Error {
51444
51383
  code;
51445
51384
  };
51446
51385
  function assertValidFileName(fileName) {
51447
- if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path26.default.basename(fileName)) {
51386
+ if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path25.default.basename(fileName)) {
51448
51387
  throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
51449
51388
  }
51450
51389
  }
51451
51390
  var HASH_PREFIX_LEN = 16;
51452
51391
  async function writeUploadedAttachment(args) {
51453
51392
  assertValidFileName(args.fileName);
51454
- const attachmentsRoot = import_node_path26.default.join(args.sessionDir, ".attachments");
51393
+ const attachmentsRoot = import_node_path25.default.join(args.sessionDir, ".attachments");
51455
51394
  try {
51456
- import_node_fs26.default.mkdirSync(attachmentsRoot, { recursive: true });
51395
+ import_node_fs25.default.mkdirSync(attachmentsRoot, { recursive: true });
51457
51396
  } catch (err) {
51458
51397
  throw new UploadError("STORAGE_ERROR", `mkdir failed: ${err.message}`);
51459
51398
  }
51460
51399
  const hasher = import_node_crypto8.default.createHash("sha256");
51461
51400
  let actualSize = 0;
51462
- const tmpPath = import_node_path26.default.join(
51401
+ const tmpPath = import_node_path25.default.join(
51463
51402
  attachmentsRoot,
51464
51403
  `.upload-${process.pid}-${Date.now()}-${import_node_crypto8.default.randomBytes(4).toString("hex")}`
51465
51404
  );
@@ -51474,18 +51413,18 @@ async function writeUploadedAttachment(args) {
51474
51413
  yield buf;
51475
51414
  }
51476
51415
  },
51477
- import_node_fs26.default.createWriteStream(tmpPath, { mode: 384 })
51416
+ import_node_fs25.default.createWriteStream(tmpPath, { mode: 384 })
51478
51417
  );
51479
51418
  } catch (err) {
51480
51419
  try {
51481
- import_node_fs26.default.unlinkSync(tmpPath);
51420
+ import_node_fs25.default.unlinkSync(tmpPath);
51482
51421
  } catch {
51483
51422
  }
51484
51423
  throw new UploadError("STORAGE_ERROR", `write failed: ${err.message}`);
51485
51424
  }
51486
51425
  if (actualSize !== args.contentLength) {
51487
51426
  try {
51488
- import_node_fs26.default.unlinkSync(tmpPath);
51427
+ import_node_fs25.default.unlinkSync(tmpPath);
51489
51428
  } catch {
51490
51429
  }
51491
51430
  throw new UploadError(
@@ -51494,35 +51433,35 @@ async function writeUploadedAttachment(args) {
51494
51433
  );
51495
51434
  }
51496
51435
  const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
51497
- const hashDir = import_node_path26.default.join(attachmentsRoot, attachmentId);
51436
+ const hashDir = import_node_path25.default.join(attachmentsRoot, attachmentId);
51498
51437
  let finalFileName;
51499
51438
  let hashDirExists = false;
51500
51439
  try {
51501
- hashDirExists = import_node_fs26.default.statSync(hashDir).isDirectory();
51440
+ hashDirExists = import_node_fs25.default.statSync(hashDir).isDirectory();
51502
51441
  } catch {
51503
51442
  }
51504
51443
  if (hashDirExists) {
51505
- const existing = import_node_fs26.default.readdirSync(hashDir).filter((n) => !n.startsWith("."));
51444
+ const existing = import_node_fs25.default.readdirSync(hashDir).filter((n) => !n.startsWith("."));
51506
51445
  finalFileName = existing[0] ?? args.fileName;
51507
51446
  try {
51508
- import_node_fs26.default.unlinkSync(tmpPath);
51447
+ import_node_fs25.default.unlinkSync(tmpPath);
51509
51448
  } catch {
51510
51449
  }
51511
51450
  } else {
51512
51451
  try {
51513
- import_node_fs26.default.mkdirSync(hashDir, { recursive: true });
51452
+ import_node_fs25.default.mkdirSync(hashDir, { recursive: true });
51514
51453
  finalFileName = args.fileName;
51515
- import_node_fs26.default.renameSync(tmpPath, import_node_path26.default.join(hashDir, finalFileName));
51454
+ import_node_fs25.default.renameSync(tmpPath, import_node_path25.default.join(hashDir, finalFileName));
51516
51455
  } catch (err) {
51517
51456
  try {
51518
- import_node_fs26.default.unlinkSync(tmpPath);
51457
+ import_node_fs25.default.unlinkSync(tmpPath);
51519
51458
  } catch {
51520
51459
  }
51521
51460
  throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
51522
51461
  }
51523
51462
  }
51524
- const absPath = import_node_path26.default.join(hashDir, finalFileName);
51525
- const relPath = import_node_path26.default.relative(args.sessionDir, absPath);
51463
+ const absPath = import_node_path25.default.join(hashDir, finalFileName);
51464
+ const relPath = import_node_path25.default.relative(args.sessionDir, absPath);
51526
51465
  args.groupFileStore.upsert(args.scope, args.sessionId, {
51527
51466
  relPath: absPath,
51528
51467
  // 存绝对路径,与现有 agent 入清单的形态一致(attachment.ts:144 双形态兼容)
@@ -51536,7 +51475,7 @@ async function writeUploadedAttachment(args) {
51536
51475
 
51537
51476
  // src/extension/import.ts
51538
51477
  var import_promises3 = __toESM(require("fs/promises"), 1);
51539
- var import_node_path27 = __toESM(require("path"), 1);
51478
+ var import_node_path26 = __toESM(require("path"), 1);
51540
51479
  var import_node_os12 = __toESM(require("os"), 1);
51541
51480
  var import_jszip = __toESM(require_lib3(), 1);
51542
51481
  init_src();
@@ -51555,7 +51494,7 @@ async function importZip(buf, root) {
51555
51494
  throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
51556
51495
  }
51557
51496
  for (const name of Object.keys(zip.files)) {
51558
- if (name.includes("..") || name.startsWith("/") || import_node_path27.default.isAbsolute(name)) {
51497
+ if (name.includes("..") || name.startsWith("/") || import_node_path26.default.isAbsolute(name)) {
51559
51498
  throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
51560
51499
  }
51561
51500
  }
@@ -51588,7 +51527,7 @@ async function importZip(buf, root) {
51588
51527
  );
51589
51528
  }
51590
51529
  }
51591
- const destDir = import_node_path27.default.join(root, manifest.id);
51530
+ const destDir = import_node_path26.default.join(root, manifest.id);
51592
51531
  let destExists = false;
51593
51532
  try {
51594
51533
  await import_promises3.default.access(destDir);
@@ -51598,15 +51537,15 @@ async function importZip(buf, root) {
51598
51537
  if (destExists) {
51599
51538
  throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
51600
51539
  }
51601
- const stage = await import_promises3.default.mkdtemp(import_node_path27.default.join(import_node_os12.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
51540
+ const stage = await import_promises3.default.mkdtemp(import_node_path26.default.join(import_node_os12.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
51602
51541
  try {
51603
51542
  for (const [name, entry] of Object.entries(zip.files)) {
51604
- const dest = import_node_path27.default.join(stage, name);
51543
+ const dest = import_node_path26.default.join(stage, name);
51605
51544
  if (entry.dir) {
51606
51545
  await import_promises3.default.mkdir(dest, { recursive: true });
51607
51546
  continue;
51608
51547
  }
51609
- await import_promises3.default.mkdir(import_node_path27.default.dirname(dest), { recursive: true });
51548
+ await import_promises3.default.mkdir(import_node_path26.default.dirname(dest), { recursive: true });
51610
51549
  const content = await entry.async("nodebuffer");
51611
51550
  await import_promises3.default.writeFile(dest, content);
51612
51551
  }
@@ -51637,7 +51576,7 @@ var SHARE_UI_ASSET_MIME = {
51637
51576
  ".wasm": "application/wasm"
51638
51577
  };
51639
51578
  function shareUiAssetMime(filePath) {
51640
- const ext = import_node_path28.default.extname(filePath).toLowerCase();
51579
+ const ext = import_node_path27.default.extname(filePath).toLowerCase();
51641
51580
  return SHARE_UI_ASSET_MIME[ext] ?? lookupMime(filePath);
51642
51581
  }
51643
51582
  var DISPATCH_HEARTBEAT_MS = 25e3;
@@ -51724,7 +51663,7 @@ function isValidUploadFileName(fileName) {
51724
51663
  if (fileName === "." || fileName === "..") return false;
51725
51664
  if (fileName.startsWith(".")) return false;
51726
51665
  if (fileName.includes("/") || fileName.includes("\\")) return false;
51727
- return fileName === import_node_path28.default.basename(fileName);
51666
+ return fileName === import_node_path27.default.basename(fileName);
51728
51667
  }
51729
51668
  function createHttpRouter(deps) {
51730
51669
  return async (req, res) => {
@@ -51796,7 +51735,7 @@ function createHttpRouter(deps) {
51796
51735
  }
51797
51736
  let buf;
51798
51737
  try {
51799
- buf = await import_node_fs27.default.promises.readFile(abs);
51738
+ buf = await import_node_fs26.default.promises.readFile(abs);
51800
51739
  } catch {
51801
51740
  sendJson(res, 404, { code: "NOT_FOUND", message: "asset not found" });
51802
51741
  return true;
@@ -52020,7 +51959,7 @@ function createHttpRouter(deps) {
52020
51959
  sendHtml(res, statusByCode[r.code], loader.renderErrorHtml(r.code, msgByCode[r.code]));
52021
51960
  return true;
52022
51961
  }
52023
- sendHtml(res, 200, loader.renderViewerHtml(import_node_path28.default.basename(r.absPath)));
51962
+ sendHtml(res, 200, loader.renderViewerHtml(import_node_path27.default.basename(r.absPath)));
52024
51963
  return true;
52025
51964
  }
52026
51965
  const ctx = deps.authResolver.resolveFromHeader(
@@ -52141,7 +52080,7 @@ function createHttpRouter(deps) {
52141
52080
  return true;
52142
52081
  }
52143
52082
  let absPath;
52144
- if (import_node_path28.default.isAbsolute(pathParam)) {
52083
+ if (import_node_path27.default.isAbsolute(pathParam)) {
52145
52084
  absPath = pathParam;
52146
52085
  } else if (deps.sessionStore) {
52147
52086
  const file = deps.sessionStore.read(sid);
@@ -52149,7 +52088,7 @@ function createHttpRouter(deps) {
52149
52088
  sendJson(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
52150
52089
  return true;
52151
52090
  }
52152
- absPath = import_node_path28.default.join(file.cwd, pathParam);
52091
+ absPath = import_node_path27.default.join(file.cwd, pathParam);
52153
52092
  } else {
52154
52093
  sendJson(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
52155
52094
  return true;
@@ -52236,7 +52175,7 @@ function withCtx(ctx, body) {
52236
52175
  function streamFile(res, absPath, logger) {
52237
52176
  let stat;
52238
52177
  try {
52239
- stat = import_node_fs27.default.statSync(absPath);
52178
+ stat = import_node_fs26.default.statSync(absPath);
52240
52179
  } catch (err) {
52241
52180
  const code = err?.code;
52242
52181
  if (code === "ENOENT") {
@@ -52251,7 +52190,7 @@ function streamFile(res, absPath, logger) {
52251
52190
  return;
52252
52191
  }
52253
52192
  const mime = lookupMime(absPath);
52254
- const basename = import_node_path28.default.basename(absPath);
52193
+ const basename = import_node_path27.default.basename(absPath);
52255
52194
  res.writeHead(200, {
52256
52195
  "Content-Type": mime,
52257
52196
  "Content-Length": String(stat.size),
@@ -52259,7 +52198,7 @@ function streamFile(res, absPath, logger) {
52259
52198
  // 防止浏览器把任意 mime 当 html 渲染
52260
52199
  "X-Content-Type-Options": "nosniff"
52261
52200
  });
52262
- const stream = import_node_fs27.default.createReadStream(absPath);
52201
+ const stream = import_node_fs26.default.createReadStream(absPath);
52263
52202
  stream.on("error", (err) => {
52264
52203
  logger?.warn("streamFile read error", { absPath, err: err.message });
52265
52204
  res.destroy();
@@ -52268,8 +52207,8 @@ function streamFile(res, absPath, logger) {
52268
52207
  }
52269
52208
 
52270
52209
  // src/attachment/gc.ts
52271
- var import_node_fs28 = __toESM(require("fs"), 1);
52272
- var import_node_path29 = __toESM(require("path"), 1);
52210
+ var import_node_fs27 = __toESM(require("fs"), 1);
52211
+ var import_node_path28 = __toESM(require("path"), 1);
52273
52212
  var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
52274
52213
  function runAttachmentGc(args) {
52275
52214
  const now = (args.now ?? Date.now)();
@@ -52278,38 +52217,38 @@ function runAttachmentGc(args) {
52278
52217
  for (const { scope, sessionId } of args.sessionScopes) {
52279
52218
  for (const entry of args.groupFileStore.list(scope, sessionId)) {
52280
52219
  if (entry.stale) continue;
52281
- if (import_node_path29.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
52220
+ if (import_node_path28.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
52282
52221
  }
52283
52222
  }
52284
52223
  for (const { scope, sessionId } of args.sessionScopes) {
52285
- const sessionDir = args.getSessionCwd?.(sessionId) ?? import_node_path29.default.join(
52224
+ const sessionDir = args.getSessionCwd?.(sessionId) ?? import_node_path28.default.join(
52286
52225
  args.dataDir,
52287
52226
  "sessions",
52288
52227
  ...scopeSubPath(scope).map(safeFileName),
52289
52228
  safeFileName(sessionId)
52290
52229
  );
52291
- const attRoot = import_node_path29.default.join(sessionDir, ".attachments");
52230
+ const attRoot = import_node_path28.default.join(sessionDir, ".attachments");
52292
52231
  let hashDirs;
52293
52232
  try {
52294
- hashDirs = import_node_fs28.default.readdirSync(attRoot);
52233
+ hashDirs = import_node_fs27.default.readdirSync(attRoot);
52295
52234
  } catch (err) {
52296
52235
  if (err.code === "ENOENT") continue;
52297
52236
  args.logger?.warn("attachment gc: readdir failed", { attRoot, err: err.message });
52298
52237
  continue;
52299
52238
  }
52300
52239
  for (const hashDir of hashDirs) {
52301
- const hashDirAbs = import_node_path29.default.join(attRoot, hashDir);
52240
+ const hashDirAbs = import_node_path28.default.join(attRoot, hashDir);
52302
52241
  let files;
52303
52242
  try {
52304
- files = import_node_fs28.default.readdirSync(hashDirAbs);
52243
+ files = import_node_fs27.default.readdirSync(hashDirAbs);
52305
52244
  } catch {
52306
52245
  continue;
52307
52246
  }
52308
52247
  for (const name of files) {
52309
- const file = import_node_path29.default.join(hashDirAbs, name);
52248
+ const file = import_node_path28.default.join(hashDirAbs, name);
52310
52249
  let stat;
52311
52250
  try {
52312
- stat = import_node_fs28.default.statSync(file);
52251
+ stat = import_node_fs27.default.statSync(file);
52313
52252
  } catch {
52314
52253
  continue;
52315
52254
  }
@@ -52318,26 +52257,26 @@ function runAttachmentGc(args) {
52318
52257
  if (age < ttlMs) continue;
52319
52258
  if (liveAbs.has(file)) continue;
52320
52259
  try {
52321
- import_node_fs28.default.unlinkSync(file);
52260
+ import_node_fs27.default.unlinkSync(file);
52322
52261
  } catch (err) {
52323
52262
  args.logger?.warn("attachment gc: unlink failed", { file, err: err.message });
52324
52263
  }
52325
52264
  }
52326
52265
  try {
52327
- if (import_node_fs28.default.readdirSync(hashDirAbs).length === 0) import_node_fs28.default.rmdirSync(hashDirAbs);
52266
+ if (import_node_fs27.default.readdirSync(hashDirAbs).length === 0) import_node_fs27.default.rmdirSync(hashDirAbs);
52328
52267
  } catch {
52329
52268
  }
52330
52269
  }
52331
52270
  try {
52332
- if (import_node_fs28.default.readdirSync(attRoot).length === 0) import_node_fs28.default.rmdirSync(attRoot);
52271
+ if (import_node_fs27.default.readdirSync(attRoot).length === 0) import_node_fs27.default.rmdirSync(attRoot);
52333
52272
  } catch {
52334
52273
  }
52335
52274
  }
52336
52275
  }
52337
52276
 
52338
52277
  // src/attachment/group.ts
52339
- var import_node_fs29 = __toESM(require("fs"), 1);
52340
- var import_node_path30 = __toESM(require("path"), 1);
52278
+ var import_node_fs28 = __toESM(require("fs"), 1);
52279
+ var import_node_path29 = __toESM(require("path"), 1);
52341
52280
  var import_node_crypto9 = __toESM(require("crypto"), 1);
52342
52281
  init_protocol();
52343
52282
  var GroupFileStore = class {
@@ -52349,11 +52288,11 @@ var GroupFileStore = class {
52349
52288
  this.logger = opts.logger;
52350
52289
  }
52351
52290
  rootForScope(scope) {
52352
- return import_node_path30.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
52291
+ return import_node_path29.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
52353
52292
  }
52354
52293
  /** 与 SessionStore.filePath 平级,扩展名 .group-files.json */
52355
52294
  filePath(scope, sessionId) {
52356
- return import_node_path30.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
52295
+ return import_node_path29.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
52357
52296
  }
52358
52297
  cacheKey(scope, sessionId) {
52359
52298
  return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
@@ -52362,7 +52301,7 @@ var GroupFileStore = class {
52362
52301
  readFile(scope, sessionId) {
52363
52302
  const file = this.filePath(scope, sessionId);
52364
52303
  try {
52365
- const raw = import_node_fs29.default.readFileSync(file, "utf8");
52304
+ const raw = import_node_fs28.default.readFileSync(file, "utf8");
52366
52305
  const parsed = JSON.parse(raw);
52367
52306
  if (!Array.isArray(parsed)) {
52368
52307
  this.logger?.warn("GroupFileStore.readFile: not an array; resetting session entries", {
@@ -52388,10 +52327,10 @@ var GroupFileStore = class {
52388
52327
  }
52389
52328
  writeFile(scope, sessionId, entries) {
52390
52329
  const file = this.filePath(scope, sessionId);
52391
- import_node_fs29.default.mkdirSync(import_node_path30.default.dirname(file), { recursive: true });
52330
+ import_node_fs28.default.mkdirSync(import_node_path29.default.dirname(file), { recursive: true });
52392
52331
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
52393
- import_node_fs29.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
52394
- import_node_fs29.default.renameSync(tmp, file);
52332
+ import_node_fs28.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
52333
+ import_node_fs28.default.renameSync(tmp, file);
52395
52334
  }
52396
52335
  /** 拉一份当前 session 的清单。读盘 → cache;之后调用复用 cache */
52397
52336
  list(scope, sessionId) {
@@ -52477,10 +52416,10 @@ var GroupFileStore = class {
52477
52416
  };
52478
52417
 
52479
52418
  // src/discovery/state-file.ts
52480
- var import_node_fs30 = __toESM(require("fs"), 1);
52481
- var import_node_path31 = __toESM(require("path"), 1);
52419
+ var import_node_fs29 = __toESM(require("fs"), 1);
52420
+ var import_node_path30 = __toESM(require("path"), 1);
52482
52421
  function defaultStateFilePath(dataDir) {
52483
- return import_node_path31.default.join(dataDir, "state.json");
52422
+ return import_node_path30.default.join(dataDir, "state.json");
52484
52423
  }
52485
52424
  function isPidAlive(pid) {
52486
52425
  if (!Number.isFinite(pid) || pid <= 0) return false;
@@ -52502,7 +52441,7 @@ var StateFileManager = class {
52502
52441
  }
52503
52442
  read() {
52504
52443
  try {
52505
- const raw = import_node_fs30.default.readFileSync(this.file, "utf8");
52444
+ const raw = import_node_fs29.default.readFileSync(this.file, "utf8");
52506
52445
  const parsed = JSON.parse(raw);
52507
52446
  return parsed;
52508
52447
  } catch {
@@ -52516,20 +52455,20 @@ var StateFileManager = class {
52516
52455
  return { status: "stale", existing };
52517
52456
  }
52518
52457
  write(state) {
52519
- import_node_fs30.default.mkdirSync(import_node_path31.default.dirname(this.file), { recursive: true });
52458
+ import_node_fs29.default.mkdirSync(import_node_path30.default.dirname(this.file), { recursive: true });
52520
52459
  const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
52521
- import_node_fs30.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
52522
- import_node_fs30.default.renameSync(tmp, this.file);
52460
+ import_node_fs29.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
52461
+ import_node_fs29.default.renameSync(tmp, this.file);
52523
52462
  if (process.platform !== "win32") {
52524
52463
  try {
52525
- import_node_fs30.default.chmodSync(this.file, 384);
52464
+ import_node_fs29.default.chmodSync(this.file, 384);
52526
52465
  } catch {
52527
52466
  }
52528
52467
  }
52529
52468
  }
52530
52469
  delete() {
52531
52470
  try {
52532
- import_node_fs30.default.unlinkSync(this.file);
52471
+ import_node_fs29.default.unlinkSync(this.file);
52533
52472
  } catch {
52534
52473
  }
52535
52474
  }
@@ -52544,14 +52483,14 @@ function readDaemonSourceFromEnv(env = process.env) {
52544
52483
  }
52545
52484
 
52546
52485
  // src/tunnel/tunnel-manager.ts
52547
- var import_node_fs34 = __toESM(require("fs"), 1);
52548
- var import_node_path35 = __toESM(require("path"), 1);
52486
+ var import_node_fs33 = __toESM(require("fs"), 1);
52487
+ var import_node_path34 = __toESM(require("path"), 1);
52549
52488
  var import_node_crypto10 = __toESM(require("crypto"), 1);
52550
52489
  var import_node_child_process9 = require("child_process");
52551
52490
 
52552
52491
  // src/tunnel/tunnel-store.ts
52553
- var import_node_fs31 = __toESM(require("fs"), 1);
52554
- var import_node_path32 = __toESM(require("path"), 1);
52492
+ var import_node_fs30 = __toESM(require("fs"), 1);
52493
+ var import_node_path31 = __toESM(require("path"), 1);
52555
52494
  var TunnelStore = class {
52556
52495
  constructor(filePath) {
52557
52496
  this.filePath = filePath;
@@ -52559,7 +52498,7 @@ var TunnelStore = class {
52559
52498
  filePath;
52560
52499
  async get() {
52561
52500
  try {
52562
- const raw = await import_node_fs31.default.promises.readFile(this.filePath, "utf8");
52501
+ const raw = await import_node_fs30.default.promises.readFile(this.filePath, "utf8");
52563
52502
  const obj = JSON.parse(raw);
52564
52503
  if (!isPersistedTunnel(obj)) return null;
52565
52504
  return obj;
@@ -52570,22 +52509,22 @@ var TunnelStore = class {
52570
52509
  }
52571
52510
  }
52572
52511
  async set(v2) {
52573
- const dir = import_node_path32.default.dirname(this.filePath);
52574
- await import_node_fs31.default.promises.mkdir(dir, { recursive: true });
52512
+ const dir = import_node_path31.default.dirname(this.filePath);
52513
+ await import_node_fs30.default.promises.mkdir(dir, { recursive: true });
52575
52514
  const data = JSON.stringify(v2, null, 2);
52576
52515
  const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
52577
- await import_node_fs31.default.promises.writeFile(tmp, data, { mode: 384 });
52516
+ await import_node_fs30.default.promises.writeFile(tmp, data, { mode: 384 });
52578
52517
  if (process.platform !== "win32") {
52579
52518
  try {
52580
- await import_node_fs31.default.promises.chmod(tmp, 384);
52519
+ await import_node_fs30.default.promises.chmod(tmp, 384);
52581
52520
  } catch {
52582
52521
  }
52583
52522
  }
52584
- await import_node_fs31.default.promises.rename(tmp, this.filePath);
52523
+ await import_node_fs30.default.promises.rename(tmp, this.filePath);
52585
52524
  }
52586
52525
  async clear() {
52587
52526
  try {
52588
- await import_node_fs31.default.promises.unlink(this.filePath);
52527
+ await import_node_fs30.default.promises.unlink(this.filePath);
52589
52528
  } catch (err) {
52590
52529
  const code = err?.code;
52591
52530
  if (code !== "ENOENT") throw err;
@@ -52680,9 +52619,9 @@ function escape(v2) {
52680
52619
  }
52681
52620
 
52682
52621
  // src/tunnel/frpc-binary.ts
52683
- var import_node_fs32 = __toESM(require("fs"), 1);
52622
+ var import_node_fs31 = __toESM(require("fs"), 1);
52684
52623
  var import_node_os13 = __toESM(require("os"), 1);
52685
- var import_node_path33 = __toESM(require("path"), 1);
52624
+ var import_node_path32 = __toESM(require("path"), 1);
52686
52625
  var import_node_child_process7 = require("child_process");
52687
52626
  var import_node_stream3 = require("stream");
52688
52627
  var import_promises4 = require("stream/promises");
@@ -52714,20 +52653,20 @@ function frpcDownloadUrl(version2, p2) {
52714
52653
  }
52715
52654
  async function ensureFrpcBinary(opts) {
52716
52655
  if (opts.override) {
52717
- if (!import_node_fs32.default.existsSync(opts.override)) {
52656
+ if (!import_node_fs31.default.existsSync(opts.override)) {
52718
52657
  throw new Error(`frpc binary not found at override path: ${opts.override}`);
52719
52658
  }
52720
52659
  return opts.override;
52721
52660
  }
52722
52661
  const version2 = opts.version ?? FRPC_VERSION;
52723
52662
  const platform = opts.platform ?? detectPlatform();
52724
- const binDir = import_node_path33.default.join(opts.dataDir, "bin");
52725
- import_node_fs32.default.mkdirSync(binDir, { recursive: true });
52663
+ const binDir = import_node_path32.default.join(opts.dataDir, "bin");
52664
+ import_node_fs31.default.mkdirSync(binDir, { recursive: true });
52726
52665
  cleanupStaleArtifacts(binDir);
52727
- const stableBin = import_node_path33.default.join(binDir, "frpc");
52728
- if (import_node_fs32.default.existsSync(stableBin)) return stableBin;
52666
+ const stableBin = import_node_path32.default.join(binDir, "frpc");
52667
+ if (import_node_fs31.default.existsSync(stableBin)) return stableBin;
52729
52668
  const partialBin = `${stableBin}.partial`;
52730
- const tarballPath = import_node_path33.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
52669
+ const tarballPath = import_node_path32.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
52731
52670
  try {
52732
52671
  const url = frpcDownloadUrl(version2, platform);
52733
52672
  await downloadToFile(url, tarballPath, opts.fetchImpl);
@@ -52736,8 +52675,8 @@ async function ensureFrpcBinary(opts) {
52736
52675
  } else {
52737
52676
  await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
52738
52677
  }
52739
- import_node_fs32.default.chmodSync(partialBin, 493);
52740
- import_node_fs32.default.renameSync(partialBin, stableBin);
52678
+ import_node_fs31.default.chmodSync(partialBin, 493);
52679
+ import_node_fs31.default.renameSync(partialBin, stableBin);
52741
52680
  } finally {
52742
52681
  safeUnlink(tarballPath);
52743
52682
  safeUnlink(partialBin);
@@ -52747,15 +52686,15 @@ async function ensureFrpcBinary(opts) {
52747
52686
  function cleanupStaleArtifacts(binDir) {
52748
52687
  let entries;
52749
52688
  try {
52750
- entries = import_node_fs32.default.readdirSync(binDir);
52689
+ entries = import_node_fs31.default.readdirSync(binDir);
52751
52690
  } catch {
52752
52691
  return;
52753
52692
  }
52754
52693
  for (const name of entries) {
52755
52694
  if (name.endsWith(".partial") || name.startsWith("extract-")) {
52756
- const full = import_node_path33.default.join(binDir, name);
52695
+ const full = import_node_path32.default.join(binDir, name);
52757
52696
  try {
52758
- import_node_fs32.default.rmSync(full, { recursive: true, force: true });
52697
+ import_node_fs31.default.rmSync(full, { recursive: true, force: true });
52759
52698
  } catch {
52760
52699
  }
52761
52700
  }
@@ -52763,7 +52702,7 @@ function cleanupStaleArtifacts(binDir) {
52763
52702
  }
52764
52703
  function safeUnlink(p2) {
52765
52704
  try {
52766
- import_node_fs32.default.unlinkSync(p2);
52705
+ import_node_fs31.default.unlinkSync(p2);
52767
52706
  } catch {
52768
52707
  }
52769
52708
  }
@@ -52774,13 +52713,13 @@ async function downloadToFile(url, dest, fetchImpl) {
52774
52713
  if (!res.ok || !res.body) {
52775
52714
  throw new Error(`download failed: ${res.status} ${res.statusText}`);
52776
52715
  }
52777
- const out = import_node_fs32.default.createWriteStream(dest);
52716
+ const out = import_node_fs31.default.createWriteStream(dest);
52778
52717
  const nodeStream = import_node_stream3.Readable.fromWeb(res.body);
52779
52718
  await (0, import_promises4.pipeline)(nodeStream, out);
52780
52719
  }
52781
52720
  async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
52782
- const work = import_node_path33.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
52783
- import_node_fs32.default.mkdirSync(work, { recursive: true });
52721
+ const work = import_node_path32.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
52722
+ import_node_fs31.default.mkdirSync(work, { recursive: true });
52784
52723
  try {
52785
52724
  await new Promise((resolve6, reject) => {
52786
52725
  const proc = (0, import_node_child_process7.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
@@ -52788,32 +52727,32 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
52788
52727
  proc.on("exit", (code) => code === 0 ? resolve6() : reject(new Error(`tar exited ${code}`)));
52789
52728
  });
52790
52729
  const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
52791
- const src = import_node_path33.default.join(work, dirName, "frpc");
52792
- if (!import_node_fs32.default.existsSync(src)) {
52730
+ const src = import_node_path32.default.join(work, dirName, "frpc");
52731
+ if (!import_node_fs31.default.existsSync(src)) {
52793
52732
  throw new Error(`frpc not found inside tarball at ${src}`);
52794
52733
  }
52795
- import_node_fs32.default.copyFileSync(src, destBin);
52734
+ import_node_fs31.default.copyFileSync(src, destBin);
52796
52735
  } finally {
52797
- import_node_fs32.default.rmSync(work, { recursive: true, force: true });
52736
+ import_node_fs31.default.rmSync(work, { recursive: true, force: true });
52798
52737
  }
52799
52738
  }
52800
52739
 
52801
52740
  // src/tunnel/frpc-process.ts
52802
- var import_node_fs33 = __toESM(require("fs"), 1);
52803
- var import_node_path34 = __toESM(require("path"), 1);
52741
+ var import_node_fs32 = __toESM(require("fs"), 1);
52742
+ var import_node_path33 = __toESM(require("path"), 1);
52804
52743
  var import_node_child_process8 = require("child_process");
52805
52744
  function frpcPidFilePath(dataDir) {
52806
- return import_node_path34.default.join(dataDir, "frpc.pid");
52745
+ return import_node_path33.default.join(dataDir, "frpc.pid");
52807
52746
  }
52808
52747
  function writeFrpcPid(dataDir, pid) {
52809
52748
  try {
52810
- import_node_fs33.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
52749
+ import_node_fs32.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
52811
52750
  } catch {
52812
52751
  }
52813
52752
  }
52814
52753
  function clearFrpcPid(dataDir) {
52815
52754
  try {
52816
- import_node_fs33.default.unlinkSync(frpcPidFilePath(dataDir));
52755
+ import_node_fs32.default.unlinkSync(frpcPidFilePath(dataDir));
52817
52756
  } catch {
52818
52757
  }
52819
52758
  }
@@ -52829,7 +52768,7 @@ function defaultIsPidAlive(pid) {
52829
52768
  }
52830
52769
  function defaultReadPidFile(file) {
52831
52770
  try {
52832
- return import_node_fs33.default.readFileSync(file, "utf8");
52771
+ return import_node_fs32.default.readFileSync(file, "utf8");
52833
52772
  } catch {
52834
52773
  return null;
52835
52774
  }
@@ -52845,7 +52784,7 @@ function defaultSleep(ms) {
52845
52784
  }
52846
52785
  async function killStaleFrpc(deps) {
52847
52786
  const pidFile = frpcPidFilePath(deps.dataDir);
52848
- const tomlPath = import_node_path34.default.join(deps.dataDir, "frpc.toml");
52787
+ const tomlPath = import_node_path33.default.join(deps.dataDir, "frpc.toml");
52849
52788
  const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
52850
52789
  const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
52851
52790
  const killPid = deps.killPidImpl ?? defaultKillPid;
@@ -52869,7 +52808,7 @@ async function killStaleFrpc(deps) {
52869
52808
  }
52870
52809
  if (victims.size === 0) {
52871
52810
  try {
52872
- import_node_fs33.default.unlinkSync(pidFile);
52811
+ import_node_fs32.default.unlinkSync(pidFile);
52873
52812
  } catch {
52874
52813
  }
52875
52814
  return;
@@ -52880,7 +52819,7 @@ async function killStaleFrpc(deps) {
52880
52819
  }
52881
52820
  await sleep2(deps.reapWaitMs ?? 300);
52882
52821
  try {
52883
- import_node_fs33.default.unlinkSync(pidFile);
52822
+ import_node_fs32.default.unlinkSync(pidFile);
52884
52823
  } catch {
52885
52824
  }
52886
52825
  }
@@ -52917,7 +52856,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
52917
52856
  var TunnelManager = class {
52918
52857
  constructor(deps) {
52919
52858
  this.deps = deps;
52920
- this.store = deps.store ?? new TunnelStore(import_node_path35.default.join(deps.dataDir, "tunnel.json"));
52859
+ this.store = deps.store ?? new TunnelStore(import_node_path34.default.join(deps.dataDir, "tunnel.json"));
52921
52860
  this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
52922
52861
  this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
52923
52862
  }
@@ -53044,7 +52983,7 @@ var TunnelManager = class {
53044
52983
  dataDir: this.deps.dataDir,
53045
52984
  override: this.deps.frpcBinaryOverride ?? void 0
53046
52985
  });
53047
- const tomlPath = import_node_path35.default.join(this.deps.dataDir, "frpc.toml");
52986
+ const tomlPath = import_node_path34.default.join(this.deps.dataDir, "frpc.toml");
53048
52987
  const proxyName = `clawd-${t.subdomain}-${localPort}-${import_node_crypto10.default.randomBytes(3).toString("hex")}`;
53049
52988
  const toml = buildFrpcToml({
53050
52989
  serverAddr: t.frpsHost,
@@ -53055,12 +52994,12 @@ var TunnelManager = class {
53055
52994
  localPort,
53056
52995
  logLevel: "info"
53057
52996
  });
53058
- await import_node_fs34.default.promises.writeFile(tomlPath, toml, { mode: 384 });
52997
+ await import_node_fs33.default.promises.writeFile(tomlPath, toml, { mode: 384 });
53059
52998
  const proc = (this.deps.spawnImpl ?? import_node_child_process9.spawn)(frpcBin, ["-c", tomlPath], {
53060
52999
  stdio: ["ignore", "pipe", "pipe"]
53061
53000
  });
53062
- const logFilePath = import_node_path35.default.join(this.deps.dataDir, "frpc.log");
53063
- const logStream = import_node_fs34.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
53001
+ const logFilePath = import_node_path34.default.join(this.deps.dataDir, "frpc.log");
53002
+ const logStream = import_node_fs33.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
53064
53003
  logStream.on("error", () => {
53065
53004
  });
53066
53005
  const tee = (chunk) => {
@@ -53142,8 +53081,8 @@ async function waitForFrpcReady(proc, timeoutMs) {
53142
53081
  }
53143
53082
 
53144
53083
  // src/sshd/sshd-manager.ts
53145
- var import_node_fs38 = __toESM(require("fs"), 1);
53146
- var import_node_path39 = __toESM(require("path"), 1);
53084
+ var import_node_fs37 = __toESM(require("fs"), 1);
53085
+ var import_node_path38 = __toESM(require("path"), 1);
53147
53086
  var import_node_child_process11 = require("child_process");
53148
53087
 
53149
53088
  // src/sshd/sshd-config.ts
@@ -53168,23 +53107,23 @@ function buildSshdConfig(input) {
53168
53107
  }
53169
53108
 
53170
53109
  // src/sshd/sshd-process.ts
53171
- var import_node_fs35 = __toESM(require("fs"), 1);
53172
- var import_node_path36 = __toESM(require("path"), 1);
53110
+ var import_node_fs34 = __toESM(require("fs"), 1);
53111
+ var import_node_path35 = __toESM(require("path"), 1);
53173
53112
  var import_node_child_process10 = require("child_process");
53174
53113
  function sshdPidFilePath(dataDir) {
53175
- return import_node_path36.default.join(dataDir, "sshd", "sshd.pid");
53114
+ return import_node_path35.default.join(dataDir, "sshd", "sshd.pid");
53176
53115
  }
53177
53116
  function writeSshdPid(dataDir, pid) {
53178
53117
  try {
53179
53118
  const p2 = sshdPidFilePath(dataDir);
53180
- import_node_fs35.default.mkdirSync(import_node_path36.default.dirname(p2), { recursive: true, mode: 448 });
53181
- import_node_fs35.default.writeFileSync(p2, String(pid), { mode: 384 });
53119
+ import_node_fs34.default.mkdirSync(import_node_path35.default.dirname(p2), { recursive: true, mode: 448 });
53120
+ import_node_fs34.default.writeFileSync(p2, String(pid), { mode: 384 });
53182
53121
  } catch {
53183
53122
  }
53184
53123
  }
53185
53124
  function clearSshdPid(dataDir) {
53186
53125
  try {
53187
- import_node_fs35.default.unlinkSync(sshdPidFilePath(dataDir));
53126
+ import_node_fs34.default.unlinkSync(sshdPidFilePath(dataDir));
53188
53127
  } catch {
53189
53128
  }
53190
53129
  }
@@ -53200,7 +53139,7 @@ function defaultIsPidAlive2(pid) {
53200
53139
  }
53201
53140
  function defaultReadPidFile2(file) {
53202
53141
  try {
53203
- return import_node_fs35.default.readFileSync(file, "utf8");
53142
+ return import_node_fs34.default.readFileSync(file, "utf8");
53204
53143
  } catch {
53205
53144
  return null;
53206
53145
  }
@@ -53216,7 +53155,7 @@ function defaultSleep2(ms) {
53216
53155
  }
53217
53156
  async function killStaleSshd(deps) {
53218
53157
  const pidFile = sshdPidFilePath(deps.dataDir);
53219
- const configPath = import_node_path36.default.join(deps.dataDir, "sshd", "sshd_config");
53158
+ const configPath = import_node_path35.default.join(deps.dataDir, "sshd", "sshd_config");
53220
53159
  const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile2;
53221
53160
  const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive2;
53222
53161
  const killPid = deps.killPidImpl ?? defaultKillPid2;
@@ -53240,7 +53179,7 @@ async function killStaleSshd(deps) {
53240
53179
  }
53241
53180
  if (victims.size === 0) {
53242
53181
  try {
53243
- import_node_fs35.default.unlinkSync(pidFile);
53182
+ import_node_fs34.default.unlinkSync(pidFile);
53244
53183
  } catch {
53245
53184
  }
53246
53185
  return;
@@ -53251,7 +53190,7 @@ async function killStaleSshd(deps) {
53251
53190
  }
53252
53191
  await sleep2(deps.reapWaitMs ?? 300);
53253
53192
  try {
53254
- import_node_fs35.default.unlinkSync(pidFile);
53193
+ import_node_fs34.default.unlinkSync(pidFile);
53255
53194
  } catch {
53256
53195
  }
53257
53196
  }
@@ -53284,8 +53223,8 @@ async function defaultScanSshdPidsByCmdline(configPath, logger) {
53284
53223
  }
53285
53224
 
53286
53225
  // src/sshd/jail-script.ts
53287
- var import_node_fs36 = __toESM(require("fs"), 1);
53288
- var import_node_path37 = __toESM(require("path"), 1);
53226
+ var import_node_fs35 = __toESM(require("fs"), 1);
53227
+ var import_node_path36 = __toESM(require("path"), 1);
53289
53228
  var CLAWD_SSH_JAIL_SCRIPT = String.raw`#!/usr/bin/env bash
53290
53229
  # clawd-ssh-jail — SSH reverse access sandbox wrapper (managed by clawd; do not edit)
53291
53230
  #
@@ -53419,16 +53358,16 @@ case "$(uname -s)" in
53419
53358
  esac
53420
53359
  `;
53421
53360
  function ensureJailScript(dataDir) {
53422
- const binDir = import_node_path37.default.join(dataDir, "bin");
53423
- import_node_fs36.default.mkdirSync(binDir, { recursive: true, mode: 493 });
53424
- const target = import_node_path37.default.join(binDir, "clawd-ssh-jail");
53425
- import_node_fs36.default.writeFileSync(target, CLAWD_SSH_JAIL_SCRIPT, { mode: 493 });
53361
+ const binDir = import_node_path36.default.join(dataDir, "bin");
53362
+ import_node_fs35.default.mkdirSync(binDir, { recursive: true, mode: 493 });
53363
+ const target = import_node_path36.default.join(binDir, "clawd-ssh-jail");
53364
+ import_node_fs35.default.writeFileSync(target, CLAWD_SSH_JAIL_SCRIPT, { mode: 493 });
53426
53365
  return target;
53427
53366
  }
53428
53367
 
53429
53368
  // src/sshd/clawd-shim.ts
53430
- var import_node_fs37 = __toESM(require("fs"), 1);
53431
- var import_node_path38 = __toESM(require("path"), 1);
53369
+ var import_node_fs36 = __toESM(require("fs"), 1);
53370
+ var import_node_path37 = __toESM(require("path"), 1);
53432
53371
  function shellQuote(s) {
53433
53372
  return `'${s.replace(/'/g, "'\\''")}'`;
53434
53373
  }
@@ -53443,10 +53382,10 @@ exec ${shellQuote(execPath)} ${shellQuote(cliPath)} "$@"
53443
53382
  `;
53444
53383
  }
53445
53384
  function ensureClawdShim(dataDir, execPath, cliPath) {
53446
- const binDir = import_node_path38.default.join(dataDir, "bin");
53447
- import_node_fs37.default.mkdirSync(binDir, { recursive: true, mode: 493 });
53448
- const target = import_node_path38.default.join(binDir, "clawd");
53449
- import_node_fs37.default.writeFileSync(target, buildClawdShim(execPath, cliPath), { mode: 493 });
53385
+ const binDir = import_node_path37.default.join(dataDir, "bin");
53386
+ import_node_fs36.default.mkdirSync(binDir, { recursive: true, mode: 493 });
53387
+ const target = import_node_path37.default.join(binDir, "clawd");
53388
+ import_node_fs36.default.writeFileSync(target, buildClawdShim(execPath, cliPath), { mode: 493 });
53450
53389
  return target;
53451
53390
  }
53452
53391
 
@@ -53454,7 +53393,7 @@ function ensureClawdShim(dataDir, execPath, cliPath) {
53454
53393
  var SshdManager = class {
53455
53394
  constructor(deps) {
53456
53395
  this.deps = deps;
53457
- this.sshdDir = import_node_path39.default.join(deps.dataDir, "sshd");
53396
+ this.sshdDir = import_node_path38.default.join(deps.dataDir, "sshd");
53458
53397
  this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
53459
53398
  }
53460
53399
  deps;
@@ -53473,32 +53412,32 @@ var SshdManager = class {
53473
53412
  ownPid: process.pid,
53474
53413
  logger
53475
53414
  });
53476
- import_node_fs38.default.mkdirSync(this.sshdDir, { recursive: true, mode: 448 });
53477
- import_node_fs38.default.mkdirSync(import_node_path39.default.join(this.sshdDir, "authorized_keys.d"), { recursive: true, mode: 448 });
53415
+ import_node_fs37.default.mkdirSync(this.sshdDir, { recursive: true, mode: 448 });
53416
+ import_node_fs37.default.mkdirSync(import_node_path38.default.join(this.sshdDir, "authorized_keys.d"), { recursive: true, mode: 448 });
53478
53417
  ensureJailScript(this.deps.dataDir);
53479
53418
  ensureClawdShim(this.deps.dataDir, process.execPath, process.argv[1] ?? "");
53480
- const hostKeyPath = import_node_path39.default.join(this.sshdDir, "host_key");
53481
- if (!import_node_fs38.default.existsSync(hostKeyPath)) {
53419
+ const hostKeyPath = import_node_path38.default.join(this.sshdDir, "host_key");
53420
+ if (!import_node_fs37.default.existsSync(hostKeyPath)) {
53482
53421
  await this.generateHostKey(hostKeyPath);
53483
53422
  }
53484
- const akFile = import_node_path39.default.join(this.sshdDir, "authorized_keys.d", "clawd-contacts");
53485
- if (!import_node_fs38.default.existsSync(akFile)) {
53486
- import_node_fs38.default.writeFileSync(akFile, "", { mode: 384 });
53423
+ const akFile = import_node_path38.default.join(this.sshdDir, "authorized_keys.d", "clawd-contacts");
53424
+ if (!import_node_fs37.default.existsSync(akFile)) {
53425
+ import_node_fs37.default.writeFileSync(akFile, "", { mode: 384 });
53487
53426
  }
53488
- const configPath = import_node_path39.default.join(this.sshdDir, "sshd_config");
53427
+ const configPath = import_node_path38.default.join(this.sshdDir, "sshd_config");
53489
53428
  const config = buildSshdConfig({
53490
53429
  listenAddress: "127.0.0.1",
53491
53430
  port: this.deps.port,
53492
53431
  hostKeyPath,
53493
53432
  authorizedKeysFile: akFile,
53494
- pidFilePath: import_node_path39.default.join(this.sshdDir, "sshd.pid")
53433
+ pidFilePath: import_node_path38.default.join(this.sshdDir, "sshd.pid")
53495
53434
  });
53496
- import_node_fs38.default.writeFileSync(configPath, config, { mode: 384 });
53435
+ import_node_fs37.default.writeFileSync(configPath, config, { mode: 384 });
53497
53436
  const sshdBin = this.deps.sshdBin ?? "/usr/sbin/sshd";
53498
53437
  const proc = (this.deps.spawnImpl ?? import_node_child_process11.spawn)(sshdBin, ["-D", "-e", "-f", configPath], {
53499
53438
  stdio: ["ignore", "pipe", "pipe"]
53500
53439
  });
53501
- const logStream = import_node_fs38.default.createWriteStream(import_node_path39.default.join(this.sshdDir, "sshd.log"), {
53440
+ const logStream = import_node_fs37.default.createWriteStream(import_node_path38.default.join(this.sshdDir, "sshd.log"), {
53502
53441
  flags: "a",
53503
53442
  mode: 384
53504
53443
  });
@@ -53591,7 +53530,7 @@ ${tail}` : ready.error;
53591
53530
  p2.on("error", reject);
53592
53531
  });
53593
53532
  try {
53594
- import_node_fs38.default.chmodSync(hostKeyPath, 384);
53533
+ import_node_fs37.default.chmodSync(hostKeyPath, 384);
53595
53534
  } catch {
53596
53535
  }
53597
53536
  }
@@ -53634,17 +53573,17 @@ async function waitForSshdReady(proc, timeoutMs) {
53634
53573
  }
53635
53574
 
53636
53575
  // src/sshd/authorized-keys.ts
53637
- var import_node_fs39 = __toESM(require("fs"), 1);
53638
- var import_node_path40 = __toESM(require("path"), 1);
53576
+ var import_node_fs38 = __toESM(require("fs"), 1);
53577
+ var import_node_path39 = __toESM(require("path"), 1);
53639
53578
  var JAIL_BIN_PATH_ENV = "CLAWD_JAIL_BIN_PATH";
53640
53579
  var AUTHORIZED_KEYS_FILE = "clawd-contacts";
53641
53580
  function jailBinPath() {
53642
- return process.env[JAIL_BIN_PATH_ENV] ?? import_node_path40.default.join(process.env.HOME ?? "", ".clawd", "bin", "clawd-ssh-jail");
53581
+ return process.env[JAIL_BIN_PATH_ENV] ?? import_node_path39.default.join(process.env.HOME ?? "", ".clawd", "bin", "clawd-ssh-jail");
53643
53582
  }
53644
53583
  function rebuildAuthorizedKeys(store, sshdDir) {
53645
- const akDir = import_node_path40.default.join(sshdDir, "authorized_keys.d");
53646
- const target = import_node_path40.default.join(akDir, AUTHORIZED_KEYS_FILE);
53647
- import_node_fs39.default.mkdirSync(akDir, { recursive: true, mode: 448 });
53584
+ const akDir = import_node_path39.default.join(sshdDir, "authorized_keys.d");
53585
+ const target = import_node_path39.default.join(akDir, AUTHORIZED_KEYS_FILE);
53586
+ import_node_fs38.default.mkdirSync(akDir, { recursive: true, mode: 448 });
53648
53587
  const lines = ["# managed by clawd; do not edit", ""];
53649
53588
  for (const c of store.list()) {
53650
53589
  if (!c.sshAllowed) continue;
@@ -53658,28 +53597,28 @@ function rebuildAuthorizedKeys(store, sshdDir) {
53658
53597
  }
53659
53598
  const body = lines.join("\n") + "\n";
53660
53599
  const tmp = `${target}.tmp-${process.pid}-${Date.now()}`;
53661
- import_node_fs39.default.writeFileSync(tmp, body, { mode: 384 });
53662
- import_node_fs39.default.renameSync(tmp, target);
53600
+ import_node_fs38.default.writeFileSync(tmp, body, { mode: 384 });
53601
+ import_node_fs38.default.renameSync(tmp, target);
53663
53602
  }
53664
53603
  function readIssuedPubkey(sshdDir, deviceId) {
53665
53604
  const safeId = deviceId.replace(/[\/\\]/g, "_");
53666
- const p2 = import_node_path40.default.join(sshdDir, "keys", `${safeId}.ed25519.pub`);
53605
+ const p2 = import_node_path39.default.join(sshdDir, "keys", `${safeId}.ed25519.pub`);
53667
53606
  try {
53668
- return import_node_fs39.default.readFileSync(p2, "utf8");
53607
+ return import_node_fs38.default.readFileSync(p2, "utf8");
53669
53608
  } catch {
53670
53609
  return null;
53671
53610
  }
53672
53611
  }
53673
53612
 
53674
53613
  // src/sshd/contact-key-puller.ts
53675
- var import_node_fs41 = __toESM(require("fs"), 1);
53676
- var import_node_path42 = __toESM(require("path"), 1);
53614
+ var import_node_fs40 = __toESM(require("fs"), 1);
53615
+ var import_node_path41 = __toESM(require("path"), 1);
53677
53616
  init_peer_forward();
53678
53617
  init_contact_ssh_log();
53679
53618
  var CONTACT_KEYS_DIR = "contact-ssh-keys";
53680
53619
  function safeContactKeyPath(dataDir, deviceId) {
53681
53620
  const safeId = deviceId.replace(/[\/\\]/g, "_");
53682
- return import_node_path42.default.join(dataDir, CONTACT_KEYS_DIR, `${safeId}.ed25519`);
53621
+ return import_node_path41.default.join(dataDir, CONTACT_KEYS_DIR, `${safeId}.ed25519`);
53683
53622
  }
53684
53623
  async function pullContactSshKeyOnce(deps) {
53685
53624
  const forward = deps.forwardImpl ?? ((c) => forwardContactSshKeyIssueToPeer({
@@ -53745,12 +53684,12 @@ async function pullContactSshKeyOnce(deps) {
53745
53684
  }
53746
53685
  function writeKeyFile(dataDir, deviceId, pem) {
53747
53686
  const p2 = safeContactKeyPath(dataDir, deviceId);
53748
- import_node_fs41.default.mkdirSync(import_node_path42.default.dirname(p2), { recursive: true, mode: 448 });
53749
- import_node_fs41.default.writeFileSync(p2, pem, { mode: 384 });
53687
+ import_node_fs40.default.mkdirSync(import_node_path41.default.dirname(p2), { recursive: true, mode: 448 });
53688
+ import_node_fs40.default.writeFileSync(p2, pem, { mode: 384 });
53750
53689
  }
53751
53690
  function removeKeyFile(dataDir, deviceId) {
53752
53691
  try {
53753
- import_node_fs41.default.unlinkSync(safeContactKeyPath(dataDir, deviceId));
53692
+ import_node_fs40.default.unlinkSync(safeContactKeyPath(dataDir, deviceId));
53754
53693
  return true;
53755
53694
  } catch {
53756
53695
  return false;
@@ -53900,27 +53839,27 @@ init_contact_ssh_log();
53900
53839
 
53901
53840
  // src/tunnel/device-key.ts
53902
53841
  var import_node_os14 = __toESM(require("os"), 1);
53903
- var import_node_path43 = __toESM(require("path"), 1);
53842
+ var import_node_path42 = __toESM(require("path"), 1);
53904
53843
  var import_node_crypto11 = __toESM(require("crypto"), 1);
53905
53844
  var DERIVE_SALT = "clawd-tunnel-device-v1";
53906
53845
  function deriveStableDeviceKey(opts = {}) {
53907
53846
  const hostname = opts.hostname ?? import_node_os14.default.hostname();
53908
53847
  const uid = opts.uid ?? (typeof import_node_os14.default.userInfo === "function" ? import_node_os14.default.userInfo().uid : 0);
53909
53848
  const home = opts.home ?? import_node_os14.default.homedir();
53910
- const defaultDataDir = import_node_path43.default.resolve(import_node_path43.default.join(home, ".clawd"));
53911
- const normalizedDataDir = opts.dataDir ? import_node_path43.default.resolve(opts.dataDir) : null;
53849
+ const defaultDataDir = import_node_path42.default.resolve(import_node_path42.default.join(home, ".clawd"));
53850
+ const normalizedDataDir = opts.dataDir ? import_node_path42.default.resolve(opts.dataDir) : null;
53912
53851
  const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
53913
53852
  const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
53914
53853
  return import_node_crypto11.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
53915
53854
  }
53916
53855
 
53917
53856
  // src/auth-store.ts
53918
- var import_node_fs42 = __toESM(require("fs"), 1);
53919
- var import_node_path44 = __toESM(require("path"), 1);
53857
+ var import_node_fs41 = __toESM(require("fs"), 1);
53858
+ var import_node_path43 = __toESM(require("path"), 1);
53920
53859
  var import_node_crypto12 = __toESM(require("crypto"), 1);
53921
53860
  var AUTH_FILE_NAME = "auth.json";
53922
53861
  function authFilePath(dataDir) {
53923
- return import_node_path44.default.join(dataDir, AUTH_FILE_NAME);
53862
+ return import_node_path43.default.join(dataDir, AUTH_FILE_NAME);
53924
53863
  }
53925
53864
  function loadOrCreateAuthFile(opts) {
53926
53865
  const file = authFilePath(opts.dataDir);
@@ -53956,7 +53895,7 @@ function defaultGenerateOwnerPrincipalId() {
53956
53895
  }
53957
53896
  function readAuthFile(file) {
53958
53897
  try {
53959
- const raw = import_node_fs42.default.readFileSync(file, "utf8");
53898
+ const raw = import_node_fs41.default.readFileSync(file, "utf8");
53960
53899
  const parsed = JSON.parse(raw);
53961
53900
  if (typeof parsed?.token !== "string" || parsed.token.length === 0) {
53962
53901
  return null;
@@ -53976,25 +53915,25 @@ function readAuthFile(file) {
53976
53915
  }
53977
53916
  }
53978
53917
  function writeAuthFile(file, content) {
53979
- import_node_fs42.default.mkdirSync(import_node_path44.default.dirname(file), { recursive: true });
53980
- import_node_fs42.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
53918
+ import_node_fs41.default.mkdirSync(import_node_path43.default.dirname(file), { recursive: true });
53919
+ import_node_fs41.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
53981
53920
  try {
53982
- import_node_fs42.default.chmodSync(file, 384);
53921
+ import_node_fs41.default.chmodSync(file, 384);
53983
53922
  } catch {
53984
53923
  }
53985
53924
  }
53986
53925
 
53987
53926
  // src/owner-profile.ts
53988
- var import_node_fs43 = __toESM(require("fs"), 1);
53927
+ var import_node_fs42 = __toESM(require("fs"), 1);
53989
53928
  var import_node_os15 = __toESM(require("os"), 1);
53990
- var import_node_path45 = __toESM(require("path"), 1);
53929
+ var import_node_path44 = __toESM(require("path"), 1);
53991
53930
  var PROFILE_FILENAME = "profile.json";
53992
53931
  function loadOwnerDisplayName(dataDir) {
53993
53932
  const fallback = import_node_os15.default.userInfo().username;
53994
- const profilePath = import_node_path45.default.join(dataDir, PROFILE_FILENAME);
53933
+ const profilePath = import_node_path44.default.join(dataDir, PROFILE_FILENAME);
53995
53934
  let raw;
53996
53935
  try {
53997
- raw = import_node_fs43.default.readFileSync(profilePath, "utf8");
53936
+ raw = import_node_fs42.default.readFileSync(profilePath, "utf8");
53998
53937
  } catch {
53999
53938
  return fallback;
54000
53939
  }
@@ -54017,18 +53956,18 @@ function loadOwnerDisplayName(dataDir) {
54017
53956
  }
54018
53957
 
54019
53958
  // src/feishu-auth/owner-identity-store.ts
54020
- var import_node_fs44 = __toESM(require("fs"), 1);
54021
- var import_node_path46 = __toESM(require("path"), 1);
53959
+ var import_node_fs43 = __toESM(require("fs"), 1);
53960
+ var import_node_path45 = __toESM(require("path"), 1);
54022
53961
  var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
54023
53962
  var OwnerIdentityStore = class {
54024
53963
  file;
54025
53964
  constructor(dataDir) {
54026
- this.file = import_node_path46.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
53965
+ this.file = import_node_path45.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
54027
53966
  }
54028
53967
  read() {
54029
53968
  let raw;
54030
53969
  try {
54031
- raw = import_node_fs44.default.readFileSync(this.file, "utf8");
53970
+ raw = import_node_fs43.default.readFileSync(this.file, "utf8");
54032
53971
  } catch {
54033
53972
  return null;
54034
53973
  }
@@ -54056,16 +53995,16 @@ var OwnerIdentityStore = class {
54056
53995
  };
54057
53996
  }
54058
53997
  write(record) {
54059
- import_node_fs44.default.mkdirSync(import_node_path46.default.dirname(this.file), { recursive: true });
54060
- import_node_fs44.default.writeFileSync(this.file, JSON.stringify(record, null, 2), { mode: 384 });
53998
+ import_node_fs43.default.mkdirSync(import_node_path45.default.dirname(this.file), { recursive: true });
53999
+ import_node_fs43.default.writeFileSync(this.file, JSON.stringify(record, null, 2), { mode: 384 });
54061
54000
  try {
54062
- import_node_fs44.default.chmodSync(this.file, 384);
54001
+ import_node_fs43.default.chmodSync(this.file, 384);
54063
54002
  } catch {
54064
54003
  }
54065
54004
  }
54066
54005
  clear() {
54067
54006
  try {
54068
- import_node_fs44.default.unlinkSync(this.file);
54007
+ import_node_fs43.default.unlinkSync(this.file);
54069
54008
  } catch (err) {
54070
54009
  const code = err?.code;
54071
54010
  if (code !== "ENOENT") throw err;
@@ -54186,9 +54125,9 @@ var CentralClientError = class extends Error {
54186
54125
  code;
54187
54126
  cause;
54188
54127
  };
54189
- async function centralRequest(opts, path78, init) {
54128
+ async function centralRequest(opts, path77, init) {
54190
54129
  const f = opts.fetchImpl ?? globalThis.fetch;
54191
- const url = `${opts.api.replace(/\/+$/, "")}${path78}`;
54130
+ const url = `${opts.api.replace(/\/+$/, "")}${path77}`;
54192
54131
  const ctrl = new AbortController();
54193
54132
  const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
54194
54133
  let res;
@@ -54330,8 +54269,8 @@ function verifyConnectToken(args) {
54330
54269
  }
54331
54270
 
54332
54271
  // src/feishu-auth/server-key.ts
54333
- var fs54 = __toESM(require("fs"), 1);
54334
- var path55 = __toESM(require("path"), 1);
54272
+ var fs53 = __toESM(require("fs"), 1);
54273
+ var path54 = __toESM(require("path"), 1);
54335
54274
  var FILE_NAME2 = "server-signing-key.json";
54336
54275
  var ServerKeyStore = class {
54337
54276
  constructor(dataDir) {
@@ -54339,12 +54278,12 @@ var ServerKeyStore = class {
54339
54278
  }
54340
54279
  dataDir;
54341
54280
  filePath() {
54342
- return path55.join(this.dataDir, FILE_NAME2);
54281
+ return path54.join(this.dataDir, FILE_NAME2);
54343
54282
  }
54344
54283
  /** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
54345
54284
  read() {
54346
54285
  try {
54347
- const raw = fs54.readFileSync(this.filePath(), "utf8");
54286
+ const raw = fs53.readFileSync(this.filePath(), "utf8");
54348
54287
  const parsed = JSON.parse(raw);
54349
54288
  if (typeof parsed.publicKeyPem === "string" && parsed.publicKeyPem.includes("PUBLIC KEY")) {
54350
54289
  return parsed.publicKeyPem;
@@ -54359,12 +54298,12 @@ var ServerKeyStore = class {
54359
54298
  publicKeyPem,
54360
54299
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
54361
54300
  };
54362
- fs54.mkdirSync(this.dataDir, { recursive: true });
54363
- fs54.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
54301
+ fs53.mkdirSync(this.dataDir, { recursive: true });
54302
+ fs53.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
54364
54303
  }
54365
54304
  clear() {
54366
54305
  try {
54367
- fs54.unlinkSync(this.filePath());
54306
+ fs53.unlinkSync(this.filePath());
54368
54307
  } catch {
54369
54308
  }
54370
54309
  }
@@ -54377,12 +54316,12 @@ init_protocol();
54377
54316
  init_protocol();
54378
54317
 
54379
54318
  // src/session/fork.ts
54380
- var import_node_fs45 = __toESM(require("fs"), 1);
54319
+ var import_node_fs44 = __toESM(require("fs"), 1);
54381
54320
  var import_node_os16 = __toESM(require("os"), 1);
54382
- var import_node_path47 = __toESM(require("path"), 1);
54321
+ var import_node_path46 = __toESM(require("path"), 1);
54383
54322
  init_claude_history();
54384
54323
  function readJsonlEntries(file) {
54385
- const raw = import_node_fs45.default.readFileSync(file, "utf8");
54324
+ const raw = import_node_fs44.default.readFileSync(file, "utf8");
54386
54325
  const out = [];
54387
54326
  for (const line of raw.split("\n")) {
54388
54327
  const t = line.trim();
@@ -54395,10 +54334,10 @@ function readJsonlEntries(file) {
54395
54334
  return out;
54396
54335
  }
54397
54336
  function forkSession(input) {
54398
- const baseDir = input.baseDir ?? import_node_path47.default.join(import_node_os16.default.homedir(), ".claude");
54399
- const projectDir = import_node_path47.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
54400
- const sourceFile = import_node_path47.default.join(projectDir, `${input.toolSessionId}.jsonl`);
54401
- if (!import_node_fs45.default.existsSync(sourceFile)) {
54337
+ const baseDir = input.baseDir ?? import_node_path46.default.join(import_node_os16.default.homedir(), ".claude");
54338
+ const projectDir = import_node_path46.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
54339
+ const sourceFile = import_node_path46.default.join(projectDir, `${input.toolSessionId}.jsonl`);
54340
+ if (!import_node_fs44.default.existsSync(sourceFile)) {
54402
54341
  throw new Error(`fork: source transcript not found: ${sourceFile}`);
54403
54342
  }
54404
54343
  const entries = readJsonlEntries(sourceFile);
@@ -54428,9 +54367,9 @@ function forkSession(input) {
54428
54367
  }
54429
54368
  forkedLines.push(JSON.stringify(forked));
54430
54369
  }
54431
- const forkedFilePath = import_node_path47.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
54432
- import_node_fs45.default.mkdirSync(projectDir, { recursive: true });
54433
- import_node_fs45.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
54370
+ const forkedFilePath = import_node_path46.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
54371
+ import_node_fs44.default.mkdirSync(projectDir, { recursive: true });
54372
+ import_node_fs44.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
54434
54373
  return { forkedToolSessionId, forkedFilePath };
54435
54374
  }
54436
54375
 
@@ -54782,7 +54721,7 @@ function buildPermissionHandlers(deps) {
54782
54721
  }
54783
54722
 
54784
54723
  // src/handlers/history.ts
54785
- var path58 = __toESM(require("path"), 1);
54724
+ var path57 = __toESM(require("path"), 1);
54786
54725
  init_protocol();
54787
54726
 
54788
54727
  // src/session/recent-dirs.ts
@@ -54800,7 +54739,7 @@ function listRecentDirs(store, limit = 50) {
54800
54739
  }
54801
54740
 
54802
54741
  // src/permission/persona-paths.ts
54803
- var path57 = __toESM(require("path"), 1);
54742
+ var path56 = __toESM(require("path"), 1);
54804
54743
  function getAllowedPersonaIds(grants, action) {
54805
54744
  const ids = /* @__PURE__ */ new Set();
54806
54745
  for (const g2 of grants) {
@@ -54813,42 +54752,42 @@ function getAllowedPersonaIds(grants, action) {
54813
54752
  return ids;
54814
54753
  }
54815
54754
  function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
54816
- const target = path57.resolve(absPath);
54755
+ const target = path56.resolve(absPath);
54817
54756
  if (userWorkDir) {
54818
- const u = path57.resolve(userWorkDir);
54819
- const usep = u.endsWith(path57.sep) ? "" : path57.sep;
54757
+ const u = path56.resolve(userWorkDir);
54758
+ const usep = u.endsWith(path56.sep) ? "" : path56.sep;
54820
54759
  if (target === u || target.startsWith(u + usep)) return true;
54821
54760
  }
54822
- const root = path57.resolve(personaRoot);
54823
- const sep3 = root.endsWith(path57.sep) ? "" : path57.sep;
54761
+ const root = path56.resolve(personaRoot);
54762
+ const sep3 = root.endsWith(path56.sep) ? "" : path56.sep;
54824
54763
  if (!target.startsWith(root + sep3)) return false;
54825
- const rel = path57.relative(root, target);
54764
+ const rel = path56.relative(root, target);
54826
54765
  if (!rel || rel.startsWith("..")) return false;
54827
- const personaId = rel.split(path57.sep)[0];
54766
+ const personaId = rel.split(path56.sep)[0];
54828
54767
  if (!personaId) return false;
54829
54768
  const allowed = getAllowedPersonaIds(grants, action);
54830
54769
  if (allowed === "*") return true;
54831
54770
  return allowed.has(personaId);
54832
54771
  }
54833
54772
  function personaIdFromPath(absPath, personaRoot) {
54834
- const root = path57.resolve(personaRoot);
54835
- const target = path57.resolve(absPath);
54836
- const sep3 = root.endsWith(path57.sep) ? "" : path57.sep;
54773
+ const root = path56.resolve(personaRoot);
54774
+ const target = path56.resolve(absPath);
54775
+ const sep3 = root.endsWith(path56.sep) ? "" : path56.sep;
54837
54776
  if (!target.startsWith(root + sep3)) return null;
54838
- const rel = path57.relative(root, target);
54777
+ const rel = path56.relative(root, target);
54839
54778
  if (!rel || rel.startsWith("..")) return null;
54840
- const id = rel.split(path57.sep)[0];
54779
+ const id = rel.split(path56.sep)[0];
54841
54780
  return id || null;
54842
54781
  }
54843
54782
  function isPathWithin(dir, absPath) {
54844
- const d = path57.resolve(dir);
54845
- const t = path57.resolve(absPath);
54846
- const sep3 = d.endsWith(path57.sep) ? "" : path57.sep;
54783
+ const d = path56.resolve(dir);
54784
+ const t = path56.resolve(absPath);
54785
+ const sep3 = d.endsWith(path56.sep) ? "" : path56.sep;
54847
54786
  return t === d || t.startsWith(d + sep3);
54848
54787
  }
54849
54788
  function isPathInGuestBoundary(personaRoot, personaId, userWorkDir, absPath) {
54850
54789
  if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
54851
- return personaIdFromPath(path57.resolve(absPath), personaRoot) === personaId;
54790
+ return personaIdFromPath(path56.resolve(absPath), personaRoot) === personaId;
54852
54791
  }
54853
54792
 
54854
54793
  // src/handlers/history.ts
@@ -54874,7 +54813,7 @@ function buildHistoryHandlers(deps) {
54874
54813
  if (!pid) return false;
54875
54814
  return isGuestPathAllowed(
54876
54815
  ctx.grants,
54877
- path58.join(personaRoot, pid),
54816
+ path57.join(personaRoot, pid),
54878
54817
  personaRoot,
54879
54818
  "read",
54880
54819
  userWorkDir
@@ -54886,7 +54825,7 @@ function buildHistoryHandlers(deps) {
54886
54825
  };
54887
54826
  const list = async (frame, _client, ctx) => {
54888
54827
  const args = HistoryListArgs.parse(frame);
54889
- assertGuestPath(ctx, path58.resolve(args.projectPath), personaRoot, "history:list");
54828
+ assertGuestPath(ctx, path57.resolve(args.projectPath), personaRoot, "history:list");
54890
54829
  const sessions = await history.listSessions(args);
54891
54830
  return { response: { type: "history:list", sessions } };
54892
54831
  };
@@ -54918,13 +54857,13 @@ function buildHistoryHandlers(deps) {
54918
54857
  };
54919
54858
  const subagents = async (frame, _client, ctx) => {
54920
54859
  const args = HistorySubagentsArgs.parse(frame);
54921
- assertGuestPath(ctx, path58.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
54860
+ assertGuestPath(ctx, path57.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
54922
54861
  const subs = await history.listSubagents(args);
54923
54862
  return { response: { type: "history:subagents", subagents: subs } };
54924
54863
  };
54925
54864
  const subagentRead = async (frame, _client, ctx) => {
54926
54865
  const args = HistorySubagentReadArgs.parse(frame);
54927
- assertGuestPath(ctx, path58.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
54866
+ assertGuestPath(ctx, path57.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
54928
54867
  const res = await history.readSubagent(args);
54929
54868
  return { response: { type: "history:subagent-read", ...res } };
54930
54869
  };
@@ -54933,7 +54872,7 @@ function buildHistoryHandlers(deps) {
54933
54872
  if (ctx?.principal.kind === "guest" && personaRoot) {
54934
54873
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
54935
54874
  const filtered = dirs.filter(
54936
- (d) => isGuestPathAllowed(ctx.grants, path58.resolve(d.cwd), personaRoot, "read", userWorkDir)
54875
+ (d) => isGuestPathAllowed(ctx.grants, path57.resolve(d.cwd), personaRoot, "read", userWorkDir)
54937
54876
  );
54938
54877
  return { response: { type: "history:recentDirs", dirs: filtered } };
54939
54878
  }
@@ -54950,7 +54889,7 @@ function buildHistoryHandlers(deps) {
54950
54889
  }
54951
54890
 
54952
54891
  // src/handlers/workspace.ts
54953
- var path59 = __toESM(require("path"), 1);
54892
+ var path58 = __toESM(require("path"), 1);
54954
54893
  var os16 = __toESM(require("os"), 1);
54955
54894
  init_protocol();
54956
54895
  init_protocol();
@@ -54992,22 +54931,22 @@ function buildWorkspaceHandlers(deps) {
54992
54931
  const args = WorkspaceListArgs.parse(frame);
54993
54932
  const isGuest = ctx?.principal.kind === "guest";
54994
54933
  const fallbackCwd = isGuest && personaRoot ? personaRoot : os16.homedir();
54995
- const resolvedCwd = path59.resolve(args.cwd ?? fallbackCwd);
54996
- const target = args.path ? path59.resolve(resolvedCwd, args.path) : resolvedCwd;
54934
+ const resolvedCwd = path58.resolve(args.cwd ?? fallbackCwd);
54935
+ const target = args.path ? path58.resolve(resolvedCwd, args.path) : resolvedCwd;
54997
54936
  assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
54998
54937
  const res = workspace.list({ ...args, cwd: resolvedCwd });
54999
54938
  return { response: { type: "workspace:list", ...res } };
55000
54939
  };
55001
54940
  const read = async (frame, _client, ctx) => {
55002
54941
  const args = WorkspaceReadArgs.parse(frame);
55003
- const target = path59.isAbsolute(args.path) ? path59.resolve(args.path) : path59.resolve(args.cwd, args.path);
54942
+ const target = path58.isAbsolute(args.path) ? path58.resolve(args.path) : path58.resolve(args.cwd, args.path);
55004
54943
  assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
55005
54944
  const res = workspace.read(args);
55006
54945
  return { response: { type: "workspace:read", ...res } };
55007
54946
  };
55008
54947
  const skillsList = async (frame, _client, ctx) => {
55009
54948
  const args = SkillsListArgs.parse(frame);
55010
- const cwdAbs = path59.resolve(args.cwd);
54949
+ const cwdAbs = path58.resolve(args.cwd);
55011
54950
  assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
55012
54951
  const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
55013
54952
  if (ctx?.principal.kind === "guest" && personaRoot) {
@@ -55019,7 +54958,7 @@ function buildWorkspaceHandlers(deps) {
55019
54958
  };
55020
54959
  const agentsList = async (frame, _client, ctx) => {
55021
54960
  const args = AgentsListArgs.parse(frame);
55022
- const cwdAbs = path59.resolve(args.cwd);
54961
+ const cwdAbs = path58.resolve(args.cwd);
55023
54962
  assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
55024
54963
  if (args.tool === "codex") {
55025
54964
  return { response: { type: "agents:list", agents: [] } };
@@ -55041,20 +54980,20 @@ function buildWorkspaceHandlers(deps) {
55041
54980
  }
55042
54981
 
55043
54982
  // src/handlers/git.ts
55044
- var path61 = __toESM(require("path"), 1);
54983
+ var path60 = __toESM(require("path"), 1);
55045
54984
  init_protocol();
55046
54985
  init_protocol();
55047
54986
 
55048
54987
  // src/workspace/git.ts
55049
54988
  var import_node_child_process12 = require("child_process");
55050
- var import_node_fs46 = __toESM(require("fs"), 1);
55051
- var import_node_path48 = __toESM(require("path"), 1);
54989
+ var import_node_fs45 = __toESM(require("fs"), 1);
54990
+ var import_node_path47 = __toESM(require("path"), 1);
55052
54991
  var import_node_util = require("util");
55053
54992
  var pexec = (0, import_node_util.promisify)(import_node_child_process12.execFile);
55054
54993
  function normalizePath(p2) {
55055
- const resolved = import_node_path48.default.resolve(p2);
54994
+ const resolved = import_node_path47.default.resolve(p2);
55056
54995
  try {
55057
- return import_node_fs46.default.realpathSync(resolved);
54996
+ return import_node_fs45.default.realpathSync(resolved);
55058
54997
  } catch {
55059
54998
  return resolved;
55060
54999
  }
@@ -55128,7 +55067,7 @@ async function listGitBranches(cwd) {
55128
55067
  function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
55129
55068
  if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
55130
55069
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
55131
- if (!isGuestPathAllowed(ctx.grants, path61.resolve(cwd), personaRoot, "read", userWorkDir)) {
55070
+ if (!isGuestPathAllowed(ctx.grants, path60.resolve(cwd), personaRoot, "read", userWorkDir)) {
55132
55071
  throw new ClawdError(
55133
55072
  ERROR_CODES.UNAUTHORIZED,
55134
55073
  `guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
@@ -55469,22 +55408,22 @@ init_src();
55469
55408
  init_protocol();
55470
55409
 
55471
55410
  // src/sshd/key-issue.ts
55472
- var import_node_fs47 = __toESM(require("fs"), 1);
55473
- var import_node_path49 = __toESM(require("path"), 1);
55411
+ var import_node_fs46 = __toESM(require("fs"), 1);
55412
+ var import_node_path48 = __toESM(require("path"), 1);
55474
55413
  var import_node_child_process13 = require("child_process");
55475
55414
  function safeDeviceId(deviceId) {
55476
55415
  return deviceId.replace(/[\/\\]/g, "_");
55477
55416
  }
55478
55417
  async function issueContactSshKey(deviceId, sshdDir, opts = {}) {
55479
55418
  const safeId = safeDeviceId(deviceId);
55480
- const keysDir = import_node_path49.default.join(sshdDir, "keys");
55481
- import_node_fs47.default.mkdirSync(keysDir, { recursive: true, mode: 448 });
55482
- const privPath = import_node_path49.default.join(keysDir, `${safeId}.ed25519`);
55419
+ const keysDir = import_node_path48.default.join(sshdDir, "keys");
55420
+ import_node_fs46.default.mkdirSync(keysDir, { recursive: true, mode: 448 });
55421
+ const privPath = import_node_path48.default.join(keysDir, `${safeId}.ed25519`);
55483
55422
  const pubPath = `${privPath}.pub`;
55484
- if (import_node_fs47.default.existsSync(privPath) && import_node_fs47.default.existsSync(pubPath)) {
55423
+ if (import_node_fs46.default.existsSync(privPath) && import_node_fs46.default.existsSync(pubPath)) {
55485
55424
  return {
55486
- privateKeyPem: import_node_fs47.default.readFileSync(privPath, "utf8"),
55487
- publicKeyLine: import_node_fs47.default.readFileSync(pubPath, "utf8").trim()
55425
+ privateKeyPem: import_node_fs46.default.readFileSync(privPath, "utf8"),
55426
+ publicKeyLine: import_node_fs46.default.readFileSync(pubPath, "utf8").trim()
55488
55427
  };
55489
55428
  }
55490
55429
  const bin = opts.keygenBin ?? "/usr/bin/ssh-keygen";
@@ -55498,16 +55437,16 @@ async function issueContactSshKey(deviceId, sshdDir, opts = {}) {
55498
55437
  p2.on("error", reject);
55499
55438
  });
55500
55439
  try {
55501
- import_node_fs47.default.chmodSync(privPath, 384);
55440
+ import_node_fs46.default.chmodSync(privPath, 384);
55502
55441
  } catch {
55503
55442
  }
55504
55443
  try {
55505
- import_node_fs47.default.chmodSync(pubPath, 420);
55444
+ import_node_fs46.default.chmodSync(pubPath, 420);
55506
55445
  } catch {
55507
55446
  }
55508
55447
  return {
55509
- privateKeyPem: import_node_fs47.default.readFileSync(privPath, "utf8"),
55510
- publicKeyLine: import_node_fs47.default.readFileSync(pubPath, "utf8").trim()
55448
+ privateKeyPem: import_node_fs46.default.readFileSync(privPath, "utf8"),
55449
+ publicKeyLine: import_node_fs46.default.readFileSync(pubPath, "utf8").trim()
55511
55450
  };
55512
55451
  }
55513
55452
 
@@ -55927,7 +55866,7 @@ function buildPersonaHandlers(deps) {
55927
55866
  }
55928
55867
 
55929
55868
  // src/handlers/attachment.ts
55930
- var import_node_path50 = __toESM(require("path"), 1);
55869
+ var import_node_path49 = __toESM(require("path"), 1);
55931
55870
  init_protocol();
55932
55871
  init_protocol();
55933
55872
  var DEFAULT_TTL_SECONDS = 24 * 3600;
@@ -56007,12 +55946,12 @@ function buildAttachmentHandlers(deps) {
56007
55946
  `session ${args.sessionId} scope unresolved`
56008
55947
  );
56009
55948
  }
56010
- const cwdAbs = import_node_path50.default.resolve(sessionFile.cwd);
56011
- const candidateAbs = import_node_path50.default.isAbsolute(args.relPath) ? import_node_path50.default.resolve(args.relPath) : import_node_path50.default.resolve(cwdAbs, args.relPath);
55949
+ const cwdAbs = import_node_path49.default.resolve(sessionFile.cwd);
55950
+ const candidateAbs = import_node_path49.default.isAbsolute(args.relPath) ? import_node_path49.default.resolve(args.relPath) : import_node_path49.default.resolve(cwdAbs, args.relPath);
56012
55951
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
56013
55952
  const entries = deps.groupFileStore.list(scope, args.sessionId);
56014
55953
  const entry = entries.find((e) => {
56015
- const storedAbs = import_node_path50.default.isAbsolute(e.relPath) ? import_node_path50.default.resolve(e.relPath) : import_node_path50.default.resolve(cwdAbs, e.relPath);
55954
+ const storedAbs = import_node_path49.default.isAbsolute(e.relPath) ? import_node_path49.default.resolve(e.relPath) : import_node_path49.default.resolve(cwdAbs, e.relPath);
56016
55955
  return storedAbs === candidateAbs && !e.stale;
56017
55956
  });
56018
55957
  if (!entry) {
@@ -56037,7 +55976,7 @@ function buildAttachmentHandlers(deps) {
56037
55976
  if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
56038
55977
  const f = deps.sessionStore.read(sessionId);
56039
55978
  if (!f) return;
56040
- assertGuestAttachmentPath(ctx, import_node_path50.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
55979
+ assertGuestAttachmentPath(ctx, import_node_path49.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
56041
55980
  }
56042
55981
  const groupAdd = async (frame, _client, ctx) => {
56043
55982
  if (!deps.groupFileStore || !deps.getSessionScope) {
@@ -56052,8 +55991,8 @@ function buildAttachmentHandlers(deps) {
56052
55991
  if (!scope) {
56053
55992
  throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
56054
55993
  }
56055
- const cwdAbs = import_node_path50.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
56056
- const candidateAbs = import_node_path50.default.isAbsolute(args.relPath) ? import_node_path50.default.resolve(args.relPath) : import_node_path50.default.resolve(cwdAbs, args.relPath);
55994
+ const cwdAbs = import_node_path49.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
55995
+ const candidateAbs = import_node_path49.default.isAbsolute(args.relPath) ? import_node_path49.default.resolve(args.relPath) : import_node_path49.default.resolve(cwdAbs, args.relPath);
56057
55996
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
56058
55997
  const from = ctx?.principal.kind === "owner" ? "owner" : "agent";
56059
55998
  const size = 0;
@@ -56112,20 +56051,20 @@ function buildAttachmentHandlers(deps) {
56112
56051
 
56113
56052
  // src/handlers/extension.ts
56114
56053
  var import_promises8 = __toESM(require("fs/promises"), 1);
56115
- var import_node_path55 = __toESM(require("path"), 1);
56054
+ var import_node_path54 = __toESM(require("path"), 1);
56116
56055
  init_protocol();
56117
56056
  init_src();
56118
56057
 
56119
56058
  // src/extension/bundle-zip.ts
56120
56059
  var import_promises5 = __toESM(require("fs/promises"), 1);
56121
- var import_node_path51 = __toESM(require("path"), 1);
56060
+ var import_node_path50 = __toESM(require("path"), 1);
56122
56061
  var import_node_crypto14 = __toESM(require("crypto"), 1);
56123
56062
  var import_jszip2 = __toESM(require_lib3(), 1);
56124
56063
  async function bundleExtensionDir(dir) {
56125
56064
  const entries = await listFilesSorted(dir);
56126
56065
  const zip = new import_jszip2.default();
56127
56066
  for (const rel of entries) {
56128
- const abs = import_node_path51.default.join(dir, rel);
56067
+ const abs = import_node_path50.default.join(dir, rel);
56129
56068
  const content = await import_promises5.default.readFile(abs);
56130
56069
  zip.file(rel, content, { date: FIXED_DATE });
56131
56070
  }
@@ -56146,7 +56085,7 @@ async function listFilesSorted(rootDir) {
56146
56085
  return out;
56147
56086
  }
56148
56087
  async function walk(absRoot, relPrefix, out) {
56149
- const dirAbs = import_node_path51.default.join(absRoot, relPrefix);
56088
+ const dirAbs = import_node_path50.default.join(absRoot, relPrefix);
56150
56089
  const entries = await import_promises5.default.readdir(dirAbs, { withFileTypes: true });
56151
56090
  for (const e of entries) {
56152
56091
  if (IGNORE_BASENAMES.has(e.name)) continue;
@@ -56202,7 +56141,7 @@ function computePublishCheck(args) {
56202
56141
 
56203
56142
  // src/extension/install-flow.ts
56204
56143
  var import_promises6 = __toESM(require("fs/promises"), 1);
56205
- var import_node_path53 = __toESM(require("path"), 1);
56144
+ var import_node_path52 = __toESM(require("path"), 1);
56206
56145
  var import_node_os19 = __toESM(require("os"), 1);
56207
56146
  var import_node_crypto15 = __toESM(require("crypto"), 1);
56208
56147
  var import_jszip3 = __toESM(require_lib3(), 1);
@@ -56210,19 +56149,19 @@ init_src();
56210
56149
 
56211
56150
  // src/extension/paths.ts
56212
56151
  var import_node_os18 = __toESM(require("os"), 1);
56213
- var import_node_path52 = __toESM(require("path"), 1);
56152
+ var import_node_path51 = __toESM(require("path"), 1);
56214
56153
  init_src();
56215
56154
  function clawdHomeRoot(override) {
56216
- return override ?? process.env.CLAWD_HOME ?? import_node_path52.default.join(import_node_os18.default.homedir(), ".clawd");
56155
+ return override ?? process.env.CLAWD_HOME ?? import_node_path51.default.join(import_node_os18.default.homedir(), ".clawd");
56217
56156
  }
56218
56157
  function extensionsRoot(override) {
56219
- return import_node_path52.default.join(clawdHomeRoot(override), "extensions");
56158
+ return import_node_path51.default.join(clawdHomeRoot(override), "extensions");
56220
56159
  }
56221
56160
  function publishedChannelsFile(override) {
56222
- return import_node_path52.default.join(clawdHomeRoot(override), "extensions-published.json");
56161
+ return import_node_path51.default.join(clawdHomeRoot(override), "extensions-published.json");
56223
56162
  }
56224
56163
  function bundleCacheRoot(override) {
56225
- return import_node_path52.default.join(clawdHomeRoot(override), "extension-bundles");
56164
+ return import_node_path51.default.join(clawdHomeRoot(override), "extension-bundles");
56226
56165
  }
56227
56166
 
56228
56167
  // src/extension/install-flow.ts
@@ -56249,7 +56188,7 @@ async function installFromChannel(args, deps) {
56249
56188
  throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
56250
56189
  }
56251
56190
  for (const name of Object.keys(zip.files)) {
56252
- if (name.includes("..") || name.startsWith("/") || import_node_path53.default.isAbsolute(name)) {
56191
+ if (name.includes("..") || name.startsWith("/") || import_node_path52.default.isAbsolute(name)) {
56253
56192
  throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
56254
56193
  }
56255
56194
  }
@@ -56281,7 +56220,7 @@ async function installFromChannel(args, deps) {
56281
56220
  );
56282
56221
  }
56283
56222
  const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
56284
- const destDir = import_node_path53.default.join(deps.extensionsRoot, localExtId);
56223
+ const destDir = import_node_path52.default.join(deps.extensionsRoot, localExtId);
56285
56224
  let destExists = false;
56286
56225
  try {
56287
56226
  await import_promises6.default.access(destDir);
@@ -56295,16 +56234,16 @@ async function installFromChannel(args, deps) {
56295
56234
  );
56296
56235
  }
56297
56236
  const stage = await import_promises6.default.mkdtemp(
56298
- import_node_path53.default.join(import_node_os19.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
56237
+ import_node_path52.default.join(import_node_os19.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
56299
56238
  );
56300
56239
  try {
56301
56240
  for (const [name, entry] of Object.entries(zip.files)) {
56302
- const dest = import_node_path53.default.join(stage, name);
56241
+ const dest = import_node_path52.default.join(stage, name);
56303
56242
  if (entry.dir) {
56304
56243
  await import_promises6.default.mkdir(dest, { recursive: true });
56305
56244
  continue;
56306
56245
  }
56307
- await import_promises6.default.mkdir(import_node_path53.default.dirname(dest), { recursive: true });
56246
+ await import_promises6.default.mkdir(import_node_path52.default.dirname(dest), { recursive: true });
56308
56247
  if (name === "manifest.json") {
56309
56248
  const rewritten = { ...parsed.data, id: localExtId };
56310
56249
  await import_promises6.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -56325,7 +56264,7 @@ async function installFromChannel(args, deps) {
56325
56264
 
56326
56265
  // src/extension/update-flow.ts
56327
56266
  var import_promises7 = __toESM(require("fs/promises"), 1);
56328
- var import_node_path54 = __toESM(require("path"), 1);
56267
+ var import_node_path53 = __toESM(require("path"), 1);
56329
56268
  var import_node_os20 = __toESM(require("os"), 1);
56330
56269
  var import_node_crypto16 = __toESM(require("crypto"), 1);
56331
56270
  var import_jszip4 = __toESM(require_lib3(), 1);
@@ -56343,11 +56282,11 @@ async function updateFromChannel(args, deps) {
56343
56282
  channelRef.extId,
56344
56283
  channelRef.ownerPrincipalId
56345
56284
  );
56346
- const liveDir = import_node_path54.default.join(deps.extensionsRoot, localExtId);
56285
+ const liveDir = import_node_path53.default.join(deps.extensionsRoot, localExtId);
56347
56286
  const prevDir = `${liveDir}.prev`;
56348
56287
  let existingVersion;
56349
56288
  try {
56350
- const raw = await import_promises7.default.readFile(import_node_path54.default.join(liveDir, "manifest.json"), "utf8");
56289
+ const raw = await import_promises7.default.readFile(import_node_path53.default.join(liveDir, "manifest.json"), "utf8");
56351
56290
  const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
56352
56291
  if (!parsed2.success) {
56353
56292
  throw new UpdateError(
@@ -56380,7 +56319,7 @@ async function updateFromChannel(args, deps) {
56380
56319
  throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
56381
56320
  }
56382
56321
  for (const name of Object.keys(zip.files)) {
56383
- if (name.includes("..") || name.startsWith("/") || import_node_path54.default.isAbsolute(name)) {
56322
+ if (name.includes("..") || name.startsWith("/") || import_node_path53.default.isAbsolute(name)) {
56384
56323
  throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
56385
56324
  }
56386
56325
  }
@@ -56415,16 +56354,16 @@ async function updateFromChannel(args, deps) {
56415
56354
  await import_promises7.default.rm(prevDir, { recursive: true, force: true });
56416
56355
  await import_promises7.default.rename(liveDir, prevDir);
56417
56356
  const stage = await import_promises7.default.mkdtemp(
56418
- import_node_path54.default.join(import_node_os20.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
56357
+ import_node_path53.default.join(import_node_os20.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
56419
56358
  );
56420
56359
  try {
56421
56360
  for (const [name, entry] of Object.entries(zip.files)) {
56422
- const dest = import_node_path54.default.join(stage, name);
56361
+ const dest = import_node_path53.default.join(stage, name);
56423
56362
  if (entry.dir) {
56424
56363
  await import_promises7.default.mkdir(dest, { recursive: true });
56425
56364
  continue;
56426
56365
  }
56427
- await import_promises7.default.mkdir(import_node_path54.default.dirname(dest), { recursive: true });
56366
+ await import_promises7.default.mkdir(import_node_path53.default.dirname(dest), { recursive: true });
56428
56367
  if (name === "manifest.json") {
56429
56368
  const rewritten = { ...parsed.data, id: localExtId };
56430
56369
  await import_promises7.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -56518,7 +56457,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
56518
56457
  );
56519
56458
  }
56520
56459
  }
56521
- const manifestPath = import_node_path55.default.join(root, extId, "manifest.json");
56460
+ const manifestPath = import_node_path54.default.join(root, extId, "manifest.json");
56522
56461
  const manifest = await readManifest(root, extId);
56523
56462
  const next = { ...manifest, version: newVersion };
56524
56463
  const tmp = `${manifestPath}.tmp`;
@@ -56526,7 +56465,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
56526
56465
  await import_promises8.default.rename(tmp, manifestPath);
56527
56466
  }
56528
56467
  async function readManifest(root, extId) {
56529
- const file = import_node_path55.default.join(root, extId, "manifest.json");
56468
+ const file = import_node_path54.default.join(root, extId, "manifest.json");
56530
56469
  let raw;
56531
56470
  try {
56532
56471
  raw = await import_promises8.default.readFile(file, "utf8");
@@ -56617,7 +56556,7 @@ function buildExtensionHandlers(deps) {
56617
56556
  };
56618
56557
  async function buildSnapshotMeta(extId) {
56619
56558
  const manifest = await readManifest(deps.root, extId);
56620
- const { sha256, buffer } = await bundleExtensionDir(import_node_path55.default.join(deps.root, extId));
56559
+ const { sha256, buffer } = await bundleExtensionDir(import_node_path54.default.join(deps.root, extId));
56621
56560
  return { manifest, contentHash: sha256, buffer };
56622
56561
  }
56623
56562
  const publish = async (frame, _client, ctx) => {
@@ -56798,9 +56737,9 @@ function buildExtensionHandlers(deps) {
56798
56737
  }
56799
56738
 
56800
56739
  // src/app-builder/project-store.ts
56801
- var import_node_fs48 = require("fs");
56740
+ var import_node_fs47 = require("fs");
56802
56741
  var import_node_child_process14 = require("child_process");
56803
- var import_node_path56 = require("path");
56742
+ var import_node_path55 = require("path");
56804
56743
  init_protocol();
56805
56744
  var PROJECTS_DIR = "projects";
56806
56745
  var META_FILE = ".clawd-project.json";
@@ -56814,19 +56753,19 @@ var ProjectStore = class {
56814
56753
  root;
56815
56754
  /** projects/<name>/.clawd-project.json 路径 */
56816
56755
  metaPath(name) {
56817
- return (0, import_node_path56.join)(this.projectsRoot(), name, META_FILE);
56756
+ return (0, import_node_path55.join)(this.projectsRoot(), name, META_FILE);
56818
56757
  }
56819
56758
  /** projects/<name>/ 目录路径(cwd 用) */
56820
56759
  projectDir(name) {
56821
- return (0, import_node_path56.join)(this.projectsRoot(), name);
56760
+ return (0, import_node_path55.join)(this.projectsRoot(), name);
56822
56761
  }
56823
56762
  projectsRoot() {
56824
- return (0, import_node_path56.join)(this.root, PROJECTS_DIR);
56763
+ return (0, import_node_path55.join)(this.root, PROJECTS_DIR);
56825
56764
  }
56826
56765
  async list() {
56827
56766
  let entries;
56828
56767
  try {
56829
- entries = await import_node_fs48.promises.readdir(this.projectsRoot());
56768
+ entries = await import_node_fs47.promises.readdir(this.projectsRoot());
56830
56769
  } catch (err) {
56831
56770
  if (err.code === "ENOENT") return [];
56832
56771
  throw err;
@@ -56834,7 +56773,7 @@ var ProjectStore = class {
56834
56773
  const out = [];
56835
56774
  for (const name of entries) {
56836
56775
  try {
56837
- const raw = await import_node_fs48.promises.readFile(this.metaPath(name), "utf8");
56776
+ const raw = await import_node_fs47.promises.readFile(this.metaPath(name), "utf8");
56838
56777
  const json = JSON.parse(raw);
56839
56778
  let migrated = false;
56840
56779
  if (typeof json.devCommand !== "string" || json.devCommand.length === 0) {
@@ -56845,7 +56784,7 @@ var ProjectStore = class {
56845
56784
  if (parsed.success) {
56846
56785
  out.push(parsed.data);
56847
56786
  if (migrated) {
56848
- void import_node_fs48.promises.writeFile(this.metaPath(name), JSON.stringify(parsed.data, null, 2) + "\n", "utf8").catch(() => {
56787
+ void import_node_fs47.promises.writeFile(this.metaPath(name), JSON.stringify(parsed.data, null, 2) + "\n", "utf8").catch(() => {
56849
56788
  });
56850
56789
  }
56851
56790
  }
@@ -56889,8 +56828,8 @@ var ProjectStore = class {
56889
56828
  throw new Error(`invalid name "${name}": ${validated.error.message}`);
56890
56829
  }
56891
56830
  const dir = this.projectDir(name);
56892
- await import_node_fs48.promises.mkdir(dir, { recursive: true });
56893
- await import_node_fs48.promises.writeFile(this.metaPath(name), JSON.stringify(meta, null, 2) + "\n", "utf8");
56831
+ await import_node_fs47.promises.mkdir(dir, { recursive: true });
56832
+ await import_node_fs47.promises.writeFile(this.metaPath(name), JSON.stringify(meta, null, 2) + "\n", "utf8");
56894
56833
  return meta;
56895
56834
  }
56896
56835
  /**
@@ -56933,7 +56872,7 @@ var ProjectStore = class {
56933
56872
  }
56934
56873
  async delete(name) {
56935
56874
  const dir = this.projectDir(name);
56936
- await import_node_fs48.promises.rm(dir, { recursive: true, force: true });
56875
+ await import_node_fs47.promises.rm(dir, { recursive: true, force: true });
56937
56876
  }
56938
56877
  async updatePort(name, newPort) {
56939
56878
  if (newPort < PROJECT_PORT_MIN || newPort > PROJECT_PORT_MAX) {
@@ -56949,7 +56888,7 @@ var ProjectStore = class {
56949
56888
  throw new Error(`port ${newPort} already used / \u5DF2\u88AB project "${conflict.name}" \u5360\u7528`);
56950
56889
  }
56951
56890
  const updated = { ...target, port: newPort };
56952
- await import_node_fs48.promises.writeFile(this.metaPath(name), JSON.stringify(updated, null, 2) + "\n", "utf8");
56891
+ await import_node_fs47.promises.writeFile(this.metaPath(name), JSON.stringify(updated, null, 2) + "\n", "utf8");
56953
56892
  return updated;
56954
56893
  }
56955
56894
  /**
@@ -56966,7 +56905,7 @@ var ProjectStore = class {
56966
56905
  if (!validated.success) {
56967
56906
  throw new Error(`invalid prodUrl "${url}": ${validated.error.message}`);
56968
56907
  }
56969
- await import_node_fs48.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
56908
+ await import_node_fs47.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
56970
56909
  return validated.data;
56971
56910
  }
56972
56911
  /**
@@ -56987,7 +56926,7 @@ var ProjectStore = class {
56987
56926
  if (!validated.success) {
56988
56927
  throw new Error(`invalid publishJob: ${validated.error.message}`);
56989
56928
  }
56990
- await import_node_fs48.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
56929
+ await import_node_fs47.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
56991
56930
  return validated.data;
56992
56931
  }
56993
56932
  /** 清掉 .clawd-project.json.publishJob 字段。其他字段保持原样。 */
@@ -57002,7 +56941,7 @@ var ProjectStore = class {
57002
56941
  if (!validated.success) {
57003
56942
  throw new Error(`failed to clear publishJob: ${validated.error.message}`);
57004
56943
  }
57005
- await import_node_fs48.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
56944
+ await import_node_fs47.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
57006
56945
  return validated.data;
57007
56946
  }
57008
56947
  };
@@ -57123,8 +57062,8 @@ var PublishJobRegistry = class {
57123
57062
 
57124
57063
  // src/app-builder/publish-job-runner.ts
57125
57064
  var import_node_child_process16 = require("child_process");
57126
- var import_node_fs49 = require("fs");
57127
- var import_node_path57 = require("path");
57065
+ var import_node_fs48 = require("fs");
57066
+ var import_node_path56 = require("path");
57128
57067
 
57129
57068
  // src/app-builder/publish-stage-parser.ts
57130
57069
  var STAGE_RE = /^\s*::stage::(build|deploy|verify)\s*$/;
@@ -57156,10 +57095,10 @@ async function startPublishJob(deps, args) {
57156
57095
  return { jobId: registry2.get(args.name).jobId, status: "already-publishing" };
57157
57096
  }
57158
57097
  const projDir = projectDir(args.name);
57159
- const logPath = (0, import_node_path57.join)(projDir, ".publish.log");
57098
+ const logPath = (0, import_node_path56.join)(projDir, ".publish.log");
57160
57099
  let logStream = null;
57161
57100
  try {
57162
- logStream = (0, import_node_fs49.createWriteStream)(logPath, { flags: "w" });
57101
+ logStream = (0, import_node_fs48.createWriteStream)(logPath, { flags: "w" });
57163
57102
  } catch {
57164
57103
  logStream = null;
57165
57104
  }
@@ -57416,8 +57355,8 @@ async function recoverInterruptedJobs(deps) {
57416
57355
 
57417
57356
  // src/handlers/app-builder.ts
57418
57357
  init_protocol();
57419
- var import_node_path58 = require("path");
57420
- var import_node_fs50 = require("fs");
57358
+ var import_node_path57 = require("path");
57359
+ var import_node_fs49 = require("fs");
57421
57360
  var APP_BUILDER_PERSONAS = ["persona-app-builder", "persona-dataclaw-builder"];
57422
57361
  var DEV_SERVER_READY_TIMEOUT_MS = 3e4;
57423
57362
  async function recoverInterruptedPublishJobs(store, logger) {
@@ -57498,7 +57437,7 @@ function buildAppBuilderHandlers(deps) {
57498
57437
  async function listAllUsersProjects() {
57499
57438
  if (!deps.usersRoot || !deps.getStore) return [];
57500
57439
  const getStore = deps.getStore;
57501
- const userIds = await import_node_fs50.promises.readdir(deps.usersRoot).catch(() => []);
57440
+ const userIds = await import_node_fs49.promises.readdir(deps.usersRoot).catch(() => []);
57502
57441
  const perUser = await Promise.all(
57503
57442
  userIds.map((uid) => getStore(uid).list().catch(() => []))
57504
57443
  );
@@ -57574,8 +57513,8 @@ function buildAppBuilderHandlers(deps) {
57574
57513
  const project = await userStore.create(f.name, reservedPorts);
57575
57514
  try {
57576
57515
  const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(session.ownerPersonaId ?? "") : deps.personaRoot;
57577
- const templateSrcDir = (0, import_node_path58.join)(personaRoot, "extension-kit", "examples", DEFAULT_TEMPLATE);
57578
- const scaffoldScript = (0, import_node_path58.join)(deps.deployKitRoot, "scripts", "new-extension.sh");
57516
+ const templateSrcDir = (0, import_node_path57.join)(personaRoot, "extension-kit", "examples", DEFAULT_TEMPLATE);
57517
+ const scaffoldScript = (0, import_node_path57.join)(deps.deployKitRoot, "scripts", "new-extension.sh");
57579
57518
  const scaffoldResult = await userStore.scaffold(project.name, templateSrcDir, scaffoldScript);
57580
57519
  deps.logger?.info("app-builder.scaffold.done", {
57581
57520
  name: project.name,
@@ -57796,7 +57735,7 @@ function buildAppBuilderHandlers(deps) {
57796
57735
  await userStore.clearPublishJob(args.name);
57797
57736
  }
57798
57737
  const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(boundSession.ownerPersonaId ?? "") : deps.personaRoot;
57799
- const scriptPath = (0, import_node_path58.join)(deps.deployKitRoot, "scripts", "publish.sh");
57738
+ const scriptPath = (0, import_node_path57.join)(deps.deployKitRoot, "scripts", "publish.sh");
57800
57739
  deps.logger?.info("app-builder.publish.start", {
57801
57740
  name: args.name,
57802
57741
  sessionId: boundSession.sessionId,
@@ -57965,7 +57904,7 @@ function buildVisitorHandlers(deps) {
57965
57904
 
57966
57905
  // src/extension/registry.ts
57967
57906
  var import_promises9 = __toESM(require("fs/promises"), 1);
57968
- var import_node_path59 = __toESM(require("path"), 1);
57907
+ var import_node_path58 = __toESM(require("path"), 1);
57969
57908
  init_src();
57970
57909
  async function loadAll(root) {
57971
57910
  let entries;
@@ -57979,13 +57918,13 @@ async function loadAll(root) {
57979
57918
  for (const ent of entries) {
57980
57919
  if (!ent.isDirectory()) continue;
57981
57920
  if (ent.name.startsWith(".")) continue;
57982
- records.push(await loadOne(import_node_path59.default.join(root, ent.name), ent.name));
57921
+ records.push(await loadOne(import_node_path58.default.join(root, ent.name), ent.name));
57983
57922
  }
57984
57923
  records.sort((a, b2) => a.extId < b2.extId ? -1 : a.extId > b2.extId ? 1 : 0);
57985
57924
  return records;
57986
57925
  }
57987
57926
  async function loadOne(dir, dirName) {
57988
- const manifestPath = import_node_path59.default.join(dir, "manifest.json");
57927
+ const manifestPath = import_node_path58.default.join(dir, "manifest.json");
57989
57928
  let raw;
57990
57929
  try {
57991
57930
  raw = await import_promises9.default.readFile(manifestPath, "utf8");
@@ -58030,7 +57969,7 @@ async function loadOne(dir, dirName) {
58030
57969
 
58031
57970
  // src/extension/uninstall.ts
58032
57971
  var import_promises10 = __toESM(require("fs/promises"), 1);
58033
- var import_node_path60 = __toESM(require("path"), 1);
57972
+ var import_node_path59 = __toESM(require("path"), 1);
58034
57973
  var UninstallError = class extends Error {
58035
57974
  constructor(code, message) {
58036
57975
  super(message);
@@ -58039,7 +57978,7 @@ var UninstallError = class extends Error {
58039
57978
  code;
58040
57979
  };
58041
57980
  async function uninstall(deps) {
58042
- const dir = import_node_path60.default.join(deps.root, deps.extId);
57981
+ const dir = import_node_path59.default.join(deps.root, deps.extId);
58043
57982
  try {
58044
57983
  await import_promises10.default.access(dir);
58045
57984
  } catch {
@@ -58623,7 +58562,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
58623
58562
 
58624
58563
  // src/extension/runtime.ts
58625
58564
  var import_node_child_process18 = require("child_process");
58626
- var import_node_path61 = __toESM(require("path"), 1);
58565
+ var import_node_path60 = __toESM(require("path"), 1);
58627
58566
  var import_promises11 = require("timers/promises");
58628
58567
  init_src();
58629
58568
 
@@ -58725,7 +58664,7 @@ var Runtime = class {
58725
58664
  /\$CLAWOS_EXT_PORT/g,
58726
58665
  String(port)
58727
58666
  );
58728
- const dir = import_node_path61.default.join(this.root, extId);
58667
+ const dir = import_node_path60.default.join(this.root, extId);
58729
58668
  const env = {
58730
58669
  ...process.env,
58731
58670
  CLAWOS_EXT_PORT: String(port),
@@ -58837,7 +58776,7 @@ ${handle.stderrTail}`
58837
58776
 
58838
58777
  // src/extension/published-channels.ts
58839
58778
  var import_promises12 = __toESM(require("fs/promises"), 1);
58840
- var import_node_path62 = __toESM(require("path"), 1);
58779
+ var import_node_path61 = __toESM(require("path"), 1);
58841
58780
  init_src();
58842
58781
  init_zod();
58843
58782
  var PublishedChannelsError = class extends Error {
@@ -58937,7 +58876,7 @@ var PublishedChannelStore = class {
58937
58876
  )
58938
58877
  };
58939
58878
  const tmp = `${this.filePath}.tmp`;
58940
- await import_promises12.default.mkdir(import_node_path62.default.dirname(this.filePath), { recursive: true });
58879
+ await import_promises12.default.mkdir(import_node_path61.default.dirname(this.filePath), { recursive: true });
58941
58880
  await import_promises12.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
58942
58881
  await import_promises12.default.rename(tmp, this.filePath);
58943
58882
  }
@@ -58945,7 +58884,7 @@ var PublishedChannelStore = class {
58945
58884
 
58946
58885
  // src/extension/bundle-cache.ts
58947
58886
  var import_promises13 = __toESM(require("fs/promises"), 1);
58948
- var import_node_path63 = __toESM(require("path"), 1);
58887
+ var import_node_path62 = __toESM(require("path"), 1);
58949
58888
  var BundleCache = class {
58950
58889
  constructor(rootDir) {
58951
58890
  this.rootDir = rootDir;
@@ -58954,14 +58893,14 @@ var BundleCache = class {
58954
58893
  /** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
58955
58894
  async write(snapshotHash, buffer) {
58956
58895
  await import_promises13.default.mkdir(this.rootDir, { recursive: true });
58957
- const file = import_node_path63.default.join(this.rootDir, `${snapshotHash}.zip`);
58896
+ const file = import_node_path62.default.join(this.rootDir, `${snapshotHash}.zip`);
58958
58897
  const tmp = `${file}.tmp`;
58959
58898
  await import_promises13.default.writeFile(tmp, buffer, { mode: 384 });
58960
58899
  await import_promises13.default.rename(tmp, file);
58961
58900
  }
58962
58901
  /** Returns the bundle bytes, or null when the file doesn't exist. */
58963
58902
  async read(snapshotHash) {
58964
- const file = import_node_path63.default.join(this.rootDir, `${snapshotHash}.zip`);
58903
+ const file = import_node_path62.default.join(this.rootDir, `${snapshotHash}.zip`);
58965
58904
  try {
58966
58905
  return await import_promises13.default.readFile(file);
58967
58906
  } catch (e) {
@@ -58971,7 +58910,7 @@ var BundleCache = class {
58971
58910
  }
58972
58911
  /** Idempotent — missing file is not an error. */
58973
58912
  async delete(snapshotHash) {
58974
- const file = import_node_path63.default.join(this.rootDir, `${snapshotHash}.zip`);
58913
+ const file = import_node_path62.default.join(this.rootDir, `${snapshotHash}.zip`);
58975
58914
  await import_promises13.default.rm(file, { force: true });
58976
58915
  }
58977
58916
  };
@@ -58996,16 +58935,16 @@ async function startDaemon(config) {
58996
58935
  });
58997
58936
  const logger = createLogger({
58998
58937
  level: config.logLevel,
58999
- file: import_node_path64.default.join(config.dataDir, "clawd.log"),
58938
+ file: import_node_path63.default.join(config.dataDir, "clawd.log"),
59000
58939
  logClient
59001
58940
  });
59002
58941
  logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
59003
58942
  const screenIdleProbeLogger = createFileOnlyLogger({
59004
- file: import_node_path64.default.join(config.dataDir, "screen-idle-probe.log"),
58943
+ file: import_node_path63.default.join(config.dataDir, "screen-idle-probe.log"),
59005
58944
  level: "debug"
59006
58945
  });
59007
58946
  logger.info("screen-idle probe logger enabled", {
59008
- file: import_node_path64.default.join(config.dataDir, "screen-idle-probe.log")
58947
+ file: import_node_path63.default.join(config.dataDir, "screen-idle-probe.log")
59009
58948
  });
59010
58949
  const stateMgr = new StateFileManager({ dataDir: config.dataDir });
59011
58950
  const pre = stateMgr.preflight();
@@ -59143,8 +59082,8 @@ async function startDaemon(config) {
59143
59082
  const agents = new AgentsScanner();
59144
59083
  const history = new ClaudeHistoryReader();
59145
59084
  let transport = null;
59146
- const personaStore = new PersonaStore(import_node_path64.default.join(config.dataDir, "personas"));
59147
- const usersRoot = import_node_path64.default.join(config.dataDir, "users");
59085
+ const personaStore = new PersonaStore(import_node_path63.default.join(config.dataDir, "personas"));
59086
+ const usersRoot = import_node_path63.default.join(config.dataDir, "users");
59148
59087
  const defaultsRoot = findDefaultsRoot(logger);
59149
59088
  if (defaultsRoot) {
59150
59089
  seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
@@ -59164,17 +59103,17 @@ async function startDaemon(config) {
59164
59103
  migrateCodexSandbox({ store: personaStore, logger });
59165
59104
  const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
59166
59105
  const personaDispatchManager = new PersonaDispatchManager({ genId: () => v4_default() });
59167
- const here = typeof __dirname === "string" ? __dirname : import_node_path64.default.dirname((0, import_node_url4.fileURLToPath)(import_meta6.url));
59106
+ const here = typeof __dirname === "string" ? __dirname : import_node_path63.default.dirname((0, import_node_url4.fileURLToPath)(import_meta6.url));
59168
59107
  const dispatchServerCandidates = [
59169
- import_node_path64.default.join(here, "dispatch", "mcp-server.cjs"),
59108
+ import_node_path63.default.join(here, "dispatch", "mcp-server.cjs"),
59170
59109
  // 生产 dist/index → dist/dispatch/mcp-server.cjs
59171
- import_node_path64.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
59110
+ import_node_path63.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
59172
59111
  // dev tsx src/index → ../dist/dispatch/mcp-server.cjs
59173
59112
  ];
59174
- const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs51.default.existsSync(p2));
59113
+ const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs50.default.existsSync(p2));
59175
59114
  let dispatchMcpConfigPath2;
59176
59115
  if (dispatchServerScriptPath) {
59177
- const dispatchLogPath = import_node_path64.default.join(config.dataDir, "dispatch-mcp-server.log");
59116
+ const dispatchLogPath = import_node_path63.default.join(config.dataDir, "dispatch-mcp-server.log");
59178
59117
  dispatchMcpConfigPath2 = writeDispatchMcpConfig({
59179
59118
  dataDir: config.dataDir,
59180
59119
  serverScriptPath: dispatchServerScriptPath,
@@ -59191,15 +59130,15 @@ async function startDaemon(config) {
59191
59130
  });
59192
59131
  }
59193
59132
  const ticketServerCandidates = [
59194
- import_node_path64.default.join(here, "ticket", "mcp-server.cjs"),
59195
- import_node_path64.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
59133
+ import_node_path63.default.join(here, "ticket", "mcp-server.cjs"),
59134
+ import_node_path63.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
59196
59135
  ];
59197
- const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs51.default.existsSync(p2));
59136
+ const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs50.default.existsSync(p2));
59198
59137
  const ticketOwnerUnionId = feishuIdentity?.identity.unionId ?? "";
59199
59138
  const ticketOwnerName = feishuIdentity?.identity.displayName ?? "";
59200
59139
  let ticketMcpConfigPath2;
59201
59140
  if (ticketServerScriptPath && ticketOwnerUnionId) {
59202
- const ticketLogPath = import_node_path64.default.join(config.dataDir, "ticket-mcp-server.log");
59141
+ const ticketLogPath = import_node_path63.default.join(config.dataDir, "ticket-mcp-server.log");
59203
59142
  ticketMcpConfigPath2 = writeTicketMcpConfig({
59204
59143
  dataDir: config.dataDir,
59205
59144
  serverScriptPath: ticketServerScriptPath,
@@ -59220,13 +59159,13 @@ async function startDaemon(config) {
59220
59159
  });
59221
59160
  }
59222
59161
  const shiftServerCandidates = [
59223
- import_node_path64.default.join(here, "shift", "mcp-server.cjs"),
59224
- import_node_path64.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
59162
+ import_node_path63.default.join(here, "shift", "mcp-server.cjs"),
59163
+ import_node_path63.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
59225
59164
  ];
59226
- const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs51.default.existsSync(p2));
59165
+ const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs50.default.existsSync(p2));
59227
59166
  let shiftMcpConfigPath2;
59228
59167
  if (shiftServerScriptPath) {
59229
- const shiftLogPath = import_node_path64.default.join(config.dataDir, "shift-mcp-server.log");
59168
+ const shiftLogPath = import_node_path63.default.join(config.dataDir, "shift-mcp-server.log");
59230
59169
  shiftMcpConfigPath2 = await writeShiftMcpConfig({
59231
59170
  dataDir: config.dataDir,
59232
59171
  serverScriptPath: shiftServerScriptPath,
@@ -59244,13 +59183,13 @@ async function startDaemon(config) {
59244
59183
  );
59245
59184
  }
59246
59185
  const inboxServerCandidates = [
59247
- import_node_path64.default.join(here, "inbox", "mcp-server.cjs"),
59248
- import_node_path64.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
59186
+ import_node_path63.default.join(here, "inbox", "mcp-server.cjs"),
59187
+ import_node_path63.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
59249
59188
  ];
59250
- const inboxServerScriptPath = inboxServerCandidates.find((p2) => import_node_fs51.default.existsSync(p2));
59189
+ const inboxServerScriptPath = inboxServerCandidates.find((p2) => import_node_fs50.default.existsSync(p2));
59251
59190
  let inboxMcpConfigPath2;
59252
59191
  if (inboxServerScriptPath) {
59253
- const inboxLogPath = import_node_path64.default.join(config.dataDir, "inbox-mcp-server.log");
59192
+ const inboxLogPath = import_node_path63.default.join(config.dataDir, "inbox-mcp-server.log");
59254
59193
  inboxMcpConfigPath2 = await writeInboxMcpConfig({
59255
59194
  dataDir: config.dataDir,
59256
59195
  serverScriptPath: inboxServerScriptPath,
@@ -59268,7 +59207,7 @@ async function startDaemon(config) {
59268
59207
  );
59269
59208
  }
59270
59209
  const shiftStore = createShiftStore({
59271
- filePath: import_node_path64.default.join(config.dataDir, "shift.json"),
59210
+ filePath: import_node_path63.default.join(config.dataDir, "shift.json"),
59272
59211
  ownerIdProvider: () => ownerPrincipalId,
59273
59212
  now: () => Date.now()
59274
59213
  });
@@ -59290,7 +59229,7 @@ async function startDaemon(config) {
59290
59229
  getAdapter,
59291
59230
  historyReader: history,
59292
59231
  dataDir: config.dataDir,
59293
- personaRoot: import_node_path64.default.join(config.dataDir, "personas"),
59232
+ personaRoot: import_node_path63.default.join(config.dataDir, "personas"),
59294
59233
  usersRoot,
59295
59234
  personaStore,
59296
59235
  ownerDisplayName,
@@ -59333,10 +59272,10 @@ async function startDaemon(config) {
59333
59272
  // 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
59334
59273
  attachmentGroup: {
59335
59274
  onFileEdit: (input) => {
59336
- const absPath = import_node_path64.default.isAbsolute(input.relPath) ? input.relPath : import_node_path64.default.join(input.cwd, input.relPath);
59275
+ const absPath = import_node_path63.default.isAbsolute(input.relPath) ? input.relPath : import_node_path63.default.join(input.cwd, input.relPath);
59337
59276
  let size = 0;
59338
59277
  try {
59339
- size = import_node_fs51.default.statSync(absPath).size;
59278
+ size = import_node_fs50.default.statSync(absPath).size;
59340
59279
  } catch (err) {
59341
59280
  logger.warn("attachment.onFileEdit stat failed", {
59342
59281
  sessionId: input.sessionId,
@@ -59535,11 +59474,11 @@ async function startDaemon(config) {
59535
59474
  // 'persona/<pid>/owner',default 走 'default'。
59536
59475
  getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
59537
59476
  // guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
59538
- personaRoot: import_node_path64.default.join(config.dataDir, "personas"),
59477
+ personaRoot: import_node_path63.default.join(config.dataDir, "personas"),
59539
59478
  usersRoot
59540
59479
  },
59541
59480
  // workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
59542
- personaRoot: import_node_path64.default.join(config.dataDir, "personas"),
59481
+ personaRoot: import_node_path63.default.join(config.dataDir, "personas"),
59543
59482
  // v2 多人 persona 隔离:handler 派生 guest user-dir 放行
59544
59483
  usersRoot,
59545
59484
  // capability:list / delete handler 依赖
@@ -59561,7 +59500,7 @@ async function startDaemon(config) {
59561
59500
  contactStore,
59562
59501
  // <dataDir>/sshd 绝对路径 —— contact-ssh handlers 用它拼 authorized_keys / keys/ 子路径
59563
59502
  // Task 10 会加 SshdManager 起 sshd;handlers wire 提前挂 sshdDir 让 typecheck 过
59564
- sshdDir: import_node_path64.default.join(config.dataDir, "sshd"),
59503
+ sshdDir: import_node_path63.default.join(config.dataDir, "sshd"),
59565
59504
  contactSshLog: sshLog,
59566
59505
  // inbox:sendDm 用:sessionId → session 出身(复用 attachment 同款 findOwnedSessionScope)
59567
59506
  getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
@@ -59652,11 +59591,11 @@ async function startDaemon(config) {
59652
59591
  // 发布上线脚手架化 (spec 2026-06-03 §5.2):
59653
59592
  // appBuilderPersonaRoot 用于拼 publish.sh 绝对路径(persona-app-builder 安装在
59654
59593
  // dataDir/personas/persona-app-builder 之下,extension-kit/scripts/publish.sh 是相对路径)。
59655
- appBuilderPersonaRoot: import_node_path64.default.join(config.dataDir, "personas", "persona-app-builder"),
59594
+ appBuilderPersonaRoot: import_node_path63.default.join(config.dataDir, "personas", "persona-app-builder"),
59656
59595
  // 共享 deploy-kit 根:scaffold/publish 脚本骨架 + 阿里云凭证单一真源。
59657
- deployKitRoot: import_node_path64.default.join(config.dataDir, "deploy-kit"),
59596
+ deployKitRoot: import_node_path63.default.join(config.dataDir, "deploy-kit"),
59658
59597
  // scaffold/publish 按当前 session 的 persona 解析其安装根,让每个 persona 用自己的模板/注入配置。
59659
- resolvePersonaRoot: (personaId) => import_node_path64.default.join(config.dataDir, "personas", personaId),
59598
+ resolvePersonaRoot: (personaId) => import_node_path63.default.join(config.dataDir, "personas", personaId),
59660
59599
  // 发布上线脚手架化 (spec 2026-06-03 §5.2.2):
59661
59600
  // 复用 SessionManagerDeps.broadcastFrame 同款 dispatch 逻辑 —— runner 调 manager.send
59662
59601
  // 取回 broadcast 帧后逐帧 push 到 transport,跟 manager 自身的 deps 一致。
@@ -59699,7 +59638,7 @@ async function startDaemon(config) {
59699
59638
  }
59700
59639
  let sourceJsonlPath = "(no transcript yet \u2014 operate from the task description alone)";
59701
59640
  if (sourceFile && sourceFile.toolSessionId) {
59702
- sourceJsonlPath = import_node_path64.default.join(
59641
+ sourceJsonlPath = import_node_path63.default.join(
59703
59642
  import_node_os21.default.homedir(),
59704
59643
  ".claude",
59705
59644
  "projects",
@@ -60029,8 +59968,8 @@ async function startDaemon(config) {
60029
59968
  const lines = [
60030
59969
  `Tunnel: ${r.url}`,
60031
59970
  ...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
60032
- `Frpc config: ${import_node_path64.default.join(config.dataDir, "frpc.toml")}`,
60033
- `Frpc log: ${import_node_path64.default.join(config.dataDir, "frpc.log")}`
59971
+ `Frpc config: ${import_node_path63.default.join(config.dataDir, "frpc.toml")}`,
59972
+ `Frpc log: ${import_node_path63.default.join(config.dataDir, "frpc.log")}`
60034
59973
  ];
60035
59974
  const width = Math.max(...lines.map((l) => l.length));
60036
59975
  const bar = "\u2550".repeat(width + 4);
@@ -60043,8 +59982,8 @@ ${bar}
60043
59982
 
60044
59983
  `);
60045
59984
  try {
60046
- const connectPath = import_node_path64.default.join(config.dataDir, "connect.txt");
60047
- import_node_fs51.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
59985
+ const connectPath = import_node_path63.default.join(config.dataDir, "connect.txt");
59986
+ import_node_fs50.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
60048
59987
  } catch {
60049
59988
  }
60050
59989
  } catch (err) {
@@ -60078,7 +60017,7 @@ ${bar}
60078
60017
  });
60079
60018
  try {
60080
60019
  await sshdMgr.start();
60081
- rebuildAuthorizedKeys(contactStore, import_node_path64.default.join(config.dataDir, "sshd"));
60020
+ rebuildAuthorizedKeys(contactStore, import_node_path63.default.join(config.dataDir, "sshd"));
60082
60021
  logger.info("sshd: contact-ssh sandbox ready", { port: config.sshdPort });
60083
60022
  } catch (err) {
60084
60023
  logger.warn("sshd start failed; contact SSH grant will not work until fixed", {
@@ -60146,9 +60085,9 @@ ${bar}
60146
60085
  };
60147
60086
  }
60148
60087
  function migrateDropPersonsDir(dataDir) {
60149
- const dir = import_node_path64.default.join(dataDir, "persons");
60088
+ const dir = import_node_path63.default.join(dataDir, "persons");
60150
60089
  try {
60151
- import_node_fs51.default.rmSync(dir, { recursive: true, force: true });
60090
+ import_node_fs50.default.rmSync(dir, { recursive: true, force: true });
60152
60091
  } catch {
60153
60092
  }
60154
60093
  }