@clawos-dev/clawd 0.2.204-beta.408.945e0d5 → 0.2.205-beta.409.d6f7a21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.cjs +372 -441
  2. package/package.json +1 -1
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: path77, errorMaps, issueData } = params;
746
- const fullPath = [...path77, ...issueData.path || []];
745
+ const { data, path: path76, errorMaps, issueData } = params;
746
+ const fullPath = [...path76, ...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, path77, key) {
1057
+ constructor(parent, value, path76, key) {
1058
1058
  this._cachedPath = [];
1059
1059
  this.parent = parent;
1060
1060
  this.data = value;
1061
- this._path = path77;
1061
+ this._path = path76;
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 path77 = req.path;
6453
- _req.url = typeof path77 === "string" ? path77 : req.url ? req.url.path || req.url : void 0;
6452
+ const path76 = req.path;
6453
+ _req.url = typeof path76 === "string" ? path76 : 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(path77) {
6618
+ function parsePath(path76) {
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 < path77.length; i++) {
6625
- const char = path77[i];
6624
+ for (let i = 0; i < path76.length; i++) {
6625
+ const char = path76[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 path77 of paths) {
6757
- const parts = parsePath(path77);
6756
+ for (const path76 of paths) {
6757
+ const parts = parsePath(path76);
6758
6758
  if (parts.includes("*")) {
6759
- redactWildcardPath(obj, parts, censor, path77, remove);
6759
+ redactWildcardPath(obj, parts, censor, path76, 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, path77) => {
6845
- const fullPath = [...pathArray.slice(0, pathLength), ...path77];
6844
+ const wrappedCensor = typeof censor === "function" ? (value, path76) => {
6845
+ const fullPath = [...pathArray.slice(0, pathLength), ...path76];
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 path77 of pathsToClone) {
6881
- const parts = parsePath(path77);
6880
+ for (const path76 of pathsToClone) {
6881
+ const parts = parsePath(path76);
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(path77) {
6934
- if (typeof path77 !== "string") {
6933
+ function validatePath(path76) {
6934
+ if (typeof path76 !== "string") {
6935
6935
  throw new Error("Paths must be (non-empty) strings");
6936
6936
  }
6937
- if (path77 === "") {
6937
+ if (path76 === "") {
6938
6938
  throw new Error("Invalid redaction path ()");
6939
6939
  }
6940
- if (path77.includes("..")) {
6941
- throw new Error(`Invalid redaction path (${path77})`);
6940
+ if (path76.includes("..")) {
6941
+ throw new Error(`Invalid redaction path (${path76})`);
6942
6942
  }
6943
- if (path77.includes(",")) {
6944
- throw new Error(`Invalid redaction path (${path77})`);
6943
+ if (path76.includes(",")) {
6944
+ throw new Error(`Invalid redaction path (${path76})`);
6945
6945
  }
6946
6946
  let bracketCount = 0;
6947
6947
  let inQuotes = false;
6948
6948
  let quoteChar = "";
6949
- for (let i = 0; i < path77.length; i++) {
6950
- const char = path77[i];
6949
+ for (let i = 0; i < path76.length; i++) {
6950
+ const char = path76[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 (${path77})`);
6964
+ throw new Error(`Invalid redaction path (${path76})`);
6965
6965
  }
6966
6966
  }
6967
6967
  }
6968
6968
  if (bracketCount !== 0) {
6969
- throw new Error(`Invalid redaction path (${path77})`);
6969
+ throw new Error(`Invalid redaction path (${path76})`);
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 path77 of paths) {
6977
- validatePath(path77);
6976
+ for (const path76 of paths) {
6977
+ validatePath(path76);
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, path77) => {
7146
- return censor(value, [k2, ...path77]);
7145
+ const wrappedCensor = typeof censor === "function" ? (value, path76) => {
7146
+ return censor(value, [k2, ...path76]);
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 fs70 = require("fs");
7364
+ var fs69 = require("fs");
7365
7365
  var EventEmitter3 = require("events");
7366
7366
  var inherits = require("util").inherits;
7367
- var path77 = require("path");
7367
+ var path76 = 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) fs70.mkdirSync(path77.dirname(file), { recursive: true });
7422
- const fd = fs70.openSync(file, flags, mode);
7421
+ if (sonic.mkdir) fs69.mkdirSync(path76.dirname(file), { recursive: true });
7422
+ const fd = fs69.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
- fs70.mkdir(path77.dirname(file), { recursive: true }, (err) => {
7429
+ fs69.mkdir(path76.dirname(file), { recursive: true }, (err) => {
7430
7430
  if (err) return fileOpened(err);
7431
- fs70.open(file, flags, mode, fileOpened);
7431
+ fs69.open(file, flags, mode, fileOpened);
7432
7432
  });
7433
7433
  } else {
7434
- fs70.open(file, flags, mode, fileOpened);
7434
+ fs69.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 = () => fs70.writeSync(this.fd, this._writingBuf);
7476
- fsWrite = () => fs70.write(this.fd, this._writingBuf, this.release);
7475
+ fsWriteSync = () => fs69.writeSync(this.fd, this._writingBuf);
7476
+ fsWrite = () => fs69.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 fs70.writeSync(this.fd, this._writingBuf);
7485
+ return fs69.writeSync(this.fd, this._writingBuf);
7486
7486
  }
7487
- return fs70.writeSync(this.fd, this._writingBuf, "utf8");
7487
+ return fs69.writeSync(this.fd, this._writingBuf, "utf8");
7488
7488
  };
7489
7489
  fsWrite = () => {
7490
7490
  if (Buffer.isBuffer(this._writingBuf)) {
7491
- return fs70.write(this.fd, this._writingBuf, this.release);
7491
+ return fs69.write(this.fd, this._writingBuf, this.release);
7492
7492
  }
7493
- return fs70.write(this.fd, this._writingBuf, "utf8", this.release);
7493
+ return fs69.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
- fs70.fsyncSync(this.fd);
7550
+ fs69.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
- fs70.fsync(this.fd, (err) => {
7664
+ fs69.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
- fs70.close(fd, (err) => {
7766
+ fs69.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) ? fs70.writeSync(this.fd, buf) : fs70.writeSync(this.fd, buf, "utf8");
7815
+ const n = Buffer.isBuffer(buf) ? fs69.writeSync(this.fd, buf) : fs69.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
- fs70.fsyncSync(this.fd);
7831
+ fs69.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 = fs70.writeSync(this.fd, buf);
7852
+ const n = fs69.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) ? fs70.writeSync(this.fd, this._writingBuf) : fs70.writeSync(this.fd, this._writingBuf, "utf8");
7880
+ const written = Buffer.isBuffer(this._writingBuf) ? fs69.writeSync(this.fd, this._writingBuf) : fs69.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
- fs70.write(this.fd, this._writingBuf, release);
7886
+ fs69.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 = fs70.writeSync(this.fd, this._writingBuf);
7895
+ const written = fs69.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
- fs70.write(this.fd, this._writingBuf, release);
7904
+ fs69.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
- fs70.fsync(sonic.fd, closeWrapped);
7920
+ fs69.fsync(sonic.fd, closeWrapped);
7921
7921
  } catch {
7922
7922
  }
7923
7923
  function closeWrapped() {
7924
7924
  if (sonic.fd !== 1 && sonic.fd !== 2) {
7925
- fs70.close(sonic.fd, done);
7925
+ fs69.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(path77, added, removed, oldPosInc, options) {
11061
- var last = path77.lastComponent;
11060
+ addToPath: function addToPath(path76, added, removed, oldPosInc, options) {
11061
+ var last = path76.lastComponent;
11062
11062
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
11063
11063
  return {
11064
- oldPos: path77.oldPos + oldPosInc,
11064
+ oldPos: path76.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: path77.oldPos + oldPosInc,
11074
+ oldPos: path76.oldPos + oldPosInc,
11075
11075
  lastComponent: {
11076
11076
  count: 1,
11077
11077
  added,
@@ -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 path77 = typeof rec3.path === "string" ? rec3.path : null;
11540
+ const path76 = typeof rec3.path === "string" ? rec3.path : null;
11541
11541
  const content = typeof rec3.content === "string" ? rec3.content : null;
11542
- if (!path77 || content == null) return null;
11543
- const entry = { path: path77, content };
11542
+ if (!path76 || content == null) return null;
11543
+ const entry = { path: path76, content };
11544
11544
  if (typeof rec3.mtimeMs === "number") entry.mtimeMs = rec3.mtimeMs;
11545
11545
  return entry;
11546
11546
  }).filter((m2) => m2 !== null);
@@ -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 path77 = typeof rec3.path === "string" ? rec3.path : null;
12363
+ const path76 = typeof rec3.path === "string" ? rec3.path : null;
12364
12364
  const content = typeof rec3.content === "string" ? rec3.content : null;
12365
- if (!path77 || content == null) return null;
12366
- const out = { path: path77, content };
12365
+ if (!path76 || content == null) return null;
12366
+ const out = { path: path76, content };
12367
12367
  if (typeof rec3.mtimeMs === "number") out.mtimeMs = rec3.mtimeMs;
12368
12368
  return out;
12369
12369
  }).filter((m2) => m2 !== null);
@@ -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(path77) {
33464
- var parts = path77.split("/");
33463
+ exports2.resolve = function(path76) {
33464
+ var parts = path76.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(path77) {
39318
- if (path77.slice(-1) === "/") {
39319
- path77 = path77.substring(0, path77.length - 1);
39317
+ var parentFolder = function(path76) {
39318
+ if (path76.slice(-1) === "/") {
39319
+ path76 = path76.substring(0, path76.length - 1);
39320
39320
  }
39321
- var lastSlash = path77.lastIndexOf("/");
39322
- return lastSlash > 0 ? path77.substring(0, lastSlash) : "";
39321
+ var lastSlash = path76.lastIndexOf("/");
39322
+ return lastSlash > 0 ? path76.substring(0, lastSlash) : "";
39323
39323
  };
39324
- var forceTrailingSlash = function(path77) {
39325
- if (path77.slice(-1) !== "/") {
39326
- path77 += "/";
39324
+ var forceTrailingSlash = function(path76) {
39325
+ if (path76.slice(-1) !== "/") {
39326
+ path76 += "/";
39327
39327
  }
39328
- return path77;
39328
+ return path76;
39329
39329
  };
39330
39330
  var folderAdd = function(name, createFolders) {
39331
39331
  createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
@@ -40324,53 +40324,10 @@ var require_lib3 = __commonJS({
40324
40324
  }
40325
40325
  });
40326
40326
 
40327
- // src/sshd/contact-ssh-log.ts
40328
- function createContactSshLog(dataDir) {
40329
- const file = import_node_path40.default.join(dataDir, "contact-ssh.log");
40330
- function append(level, tag, message, meta) {
40331
- const time = (/* @__PURE__ */ new Date()).toISOString();
40332
- let line = `[${time}] [${level}] [${tag}] ${message}`;
40333
- if (meta && Object.keys(meta).length > 0) {
40334
- try {
40335
- line += " " + JSON.stringify(meta);
40336
- } catch {
40337
- line += " [meta-serialize-failed]";
40338
- }
40339
- }
40340
- line += "\n";
40341
- try {
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
- } catch {
40345
- }
40346
- }
40347
- return {
40348
- info: (tag, message, meta) => append("INFO", tag, message, meta),
40349
- warn: (tag, message, meta) => append("WARN", tag, message, meta),
40350
- error: (tag, message, meta) => append("ERROR", tag, message, meta)
40351
- };
40352
- }
40353
- var import_node_fs39, import_node_path40, nullContactSshLog;
40354
- var init_contact_ssh_log = __esm({
40355
- "src/sshd/contact-ssh-log.ts"() {
40356
- "use strict";
40357
- import_node_fs39 = __toESM(require("fs"), 1);
40358
- import_node_path40 = __toESM(require("path"), 1);
40359
- nullContactSshLog = {
40360
- info: () => {
40361
- },
40362
- warn: () => {
40363
- },
40364
- error: () => {
40365
- }
40366
- };
40367
- }
40368
- });
40369
-
40370
40327
  // src/run-case/recorder.ts
40371
40328
  function startRunCaseRecorder(opts) {
40372
40329
  const now = opts.now ?? Date.now;
40373
- const dir = import_node_path64.default.dirname(opts.recordPath);
40330
+ const dir = import_node_path63.default.dirname(opts.recordPath);
40374
40331
  let stream = null;
40375
40332
  let closing = false;
40376
40333
  let closedSettled = false;
@@ -40384,8 +40341,8 @@ function startRunCaseRecorder(opts) {
40384
40341
  });
40385
40342
  const ensureStream = () => {
40386
40343
  if (stream) return stream;
40387
- import_node_fs51.default.mkdirSync(dir, { recursive: true });
40388
- stream = import_node_fs51.default.createWriteStream(opts.recordPath, { flags: "a" });
40344
+ import_node_fs50.default.mkdirSync(dir, { recursive: true });
40345
+ stream = import_node_fs50.default.createWriteStream(opts.recordPath, { flags: "a" });
40389
40346
  stream.on("close", () => closedResolve());
40390
40347
  return stream;
40391
40348
  };
@@ -40410,12 +40367,12 @@ function startRunCaseRecorder(opts) {
40410
40367
  };
40411
40368
  return { tap, close, closed };
40412
40369
  }
40413
- var import_node_fs51, import_node_path64;
40370
+ var import_node_fs50, import_node_path63;
40414
40371
  var init_recorder = __esm({
40415
40372
  "src/run-case/recorder.ts"() {
40416
40373
  "use strict";
40417
- import_node_fs51 = __toESM(require("fs"), 1);
40418
- import_node_path64 = __toESM(require("path"), 1);
40374
+ import_node_fs50 = __toESM(require("fs"), 1);
40375
+ import_node_path63 = __toESM(require("path"), 1);
40419
40376
  }
40420
40377
  });
40421
40378
 
@@ -40458,7 +40415,7 @@ var init_wire = __esm({
40458
40415
  // src/run-case/controller.ts
40459
40416
  async function runController(opts) {
40460
40417
  const now = opts.now ?? Date.now;
40461
- const cwd = opts.cwd ?? (0, import_node_fs52.mkdtempSync)(import_node_path65.default.join(import_node_os22.default.tmpdir(), "clawd-runcase-"));
40418
+ const cwd = opts.cwd ?? (0, import_node_fs51.mkdtempSync)(import_node_path64.default.join(import_node_os22.default.tmpdir(), "clawd-runcase-"));
40462
40419
  const ownsCwd = opts.cwd === void 0;
40463
40420
  const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
40464
40421
  const spawnCtx = { cwd };
@@ -40619,19 +40576,19 @@ async function runController(opts) {
40619
40576
  if (sigintHandler) process.off("SIGINT", sigintHandler);
40620
40577
  if (ownsCwd) {
40621
40578
  try {
40622
- (0, import_node_fs52.rmSync)(cwd, { recursive: true, force: true });
40579
+ (0, import_node_fs51.rmSync)(cwd, { recursive: true, force: true });
40623
40580
  } catch {
40624
40581
  }
40625
40582
  }
40626
40583
  return exitCode ?? 0;
40627
40584
  }
40628
- var import_node_fs52, import_node_os22, import_node_path65;
40585
+ var import_node_fs51, import_node_os22, import_node_path64;
40629
40586
  var init_controller = __esm({
40630
40587
  "src/run-case/controller.ts"() {
40631
40588
  "use strict";
40632
- import_node_fs52 = require("fs");
40589
+ import_node_fs51 = require("fs");
40633
40590
  import_node_os22 = __toESM(require("os"), 1);
40634
- import_node_path65 = __toESM(require("path"), 1);
40591
+ import_node_path64 = __toESM(require("path"), 1);
40635
40592
  init_claude();
40636
40593
  init_stdout_splitter();
40637
40594
  init_permission_stdio();
@@ -40742,23 +40699,14 @@ async function sshRelay(argv) {
40742
40699
  process.stderr.write("clawd ssh-relay: missing <peer-device-id>\n" + SSH_RELAY_HELP);
40743
40700
  return 2;
40744
40701
  }
40745
- const dataDir = args.dataDir ?? import_node_path66.default.join(import_node_os23.default.homedir(), ".clawd");
40746
- const sshLog = createContactSshLog(dataDir);
40702
+ const dataDir = args.dataDir ?? import_node_path65.default.join(import_node_os23.default.homedir(), ".clawd");
40747
40703
  const contact = findContact(dataDir, args.peerDeviceId);
40748
40704
  if (!contact) {
40749
- sshLog.error("relay.contact-not-found", "ssh-relay \u627E\u4E0D\u5230 peer contact", {
40750
- peerDeviceId: args.peerDeviceId,
40751
- contactsPath: import_node_path66.default.join(dataDir, "contacts.json")
40752
- });
40753
40705
  process.stderr.write(`clawd ssh-relay: contact ${args.peerDeviceId} not found in ${dataDir}/contacts.json
40754
40706
  `);
40755
40707
  return 2;
40756
40708
  }
40757
40709
  if (!contact.connectToken) {
40758
- sshLog.error("relay.token-missing", "contact \u6709\u8BB0\u5F55\u4F46\u7F3A connectToken\uFF08auto-reverse \u672A\u6362\u7968\uFF09", {
40759
- peerDeviceId: args.peerDeviceId,
40760
- peerDisplayName: contact.displayName
40761
- });
40762
40710
  process.stderr.write(
40763
40711
  `clawd ssh-relay: contact ${args.peerDeviceId} has no connectToken (auto-reverse \u672A\u6362\u7968)
40764
40712
  `
@@ -40768,11 +40716,6 @@ async function sshRelay(argv) {
40768
40716
  const baseHttp = wsUrlToHttp(contact.remoteUrl).replace(/\/+$/, "");
40769
40717
  const wsBase = baseHttp.replace(/^http:/, "ws:").replace(/^https:/, "wss:");
40770
40718
  const url = `${wsBase}/rpc/ssh-tunnel`;
40771
- sshLog.info("relay.dial", "\u5F00\u59CB\u62E8 A \u4FA7 /rpc/ssh-tunnel", {
40772
- peerDeviceId: args.peerDeviceId,
40773
- peerDisplayName: contact.displayName,
40774
- url
40775
- });
40776
40719
  return new Promise((resolve6) => {
40777
40720
  const ws = new import_websocket.default(url, {
40778
40721
  headers: {
@@ -40792,9 +40735,6 @@ async function sshRelay(argv) {
40792
40735
  resolve6(exitCode);
40793
40736
  };
40794
40737
  ws.on("open", () => {
40795
- sshLog.info("relay.dial-open", "ws open\uFF0C\u8FDB\u5165 stdio \u2194 ws \u4E2D\u7EE7", {
40796
- peerDeviceId: args.peerDeviceId
40797
- });
40798
40738
  process.stdin.on("data", (chunk) => {
40799
40739
  if (ws.readyState === ws.OPEN) {
40800
40740
  ws.send(chunk, { binary: true });
@@ -40819,25 +40759,9 @@ async function sshRelay(argv) {
40819
40759
  }
40820
40760
  });
40821
40761
  ws.on("close", (code) => {
40822
- if (code === 1e3) {
40823
- sshLog.info("relay.dial-close", "ws \u6B63\u5E38\u5173\u95ED", {
40824
- peerDeviceId: args.peerDeviceId,
40825
- code
40826
- });
40827
- } else {
40828
- sshLog.warn("relay.dial-close-abnormal", "ws \u975E\u6B63\u5E38\u5173\u95ED\uFF08A \u4FA7\u62D2 auth / \u7F51\u7EDC\u65AD / peer \u5D29\uFF09", {
40829
- peerDeviceId: args.peerDeviceId,
40830
- code
40831
- });
40832
- }
40833
40762
  settle(code === 1e3 ? 0 : 1);
40834
40763
  });
40835
40764
  ws.on("error", (err) => {
40836
- sshLog.error("relay.dial-error", "ws \u8FDE\u63A5\u9519\u8BEF\uFF08peer \u4E0D\u53EF\u8FBE / \u7AEF\u53E3\u4E0D\u901A / TLS \u5931\u8D25\uFF09", {
40837
- peerDeviceId: args.peerDeviceId,
40838
- url,
40839
- message: err.message
40840
- });
40841
40765
  process.stderr.write(`clawd ssh-relay: ws error ${err.message}
40842
40766
  `);
40843
40767
  settle(1);
@@ -40869,10 +40793,10 @@ function parseSshRelayArgs(argv) {
40869
40793
  return out;
40870
40794
  }
40871
40795
  function findContact(dataDir, deviceId) {
40872
- const file = import_node_path66.default.join(dataDir, "contacts.json");
40796
+ const file = import_node_path65.default.join(dataDir, "contacts.json");
40873
40797
  let raw;
40874
40798
  try {
40875
- raw = import_node_fs53.default.readFileSync(file, "utf8");
40799
+ raw = import_node_fs52.default.readFileSync(file, "utf8");
40876
40800
  } catch {
40877
40801
  return null;
40878
40802
  }
@@ -40890,17 +40814,16 @@ function findContact(dataDir, deviceId) {
40890
40814
  }
40891
40815
  return null;
40892
40816
  }
40893
- var import_node_fs53, import_node_os23, import_node_path66, SSH_RELAY_HELP;
40817
+ var import_node_fs52, import_node_os23, import_node_path65, SSH_RELAY_HELP;
40894
40818
  var init_sshd_cli_relay = __esm({
40895
40819
  "src/sshd/sshd-cli-relay.ts"() {
40896
40820
  "use strict";
40897
- import_node_fs53 = __toESM(require("fs"), 1);
40821
+ import_node_fs52 = __toESM(require("fs"), 1);
40898
40822
  import_node_os23 = __toESM(require("os"), 1);
40899
- import_node_path66 = __toESM(require("path"), 1);
40823
+ import_node_path65 = __toESM(require("path"), 1);
40900
40824
  init_wrapper();
40901
40825
  init_src();
40902
40826
  init_peer_forward();
40903
- init_contact_ssh_log();
40904
40827
  SSH_RELAY_HELP = `clawd ssh-relay <peer-device-id> [options]
40905
40828
 
40906
40829
  WebSocket relay to a peer daemon's /rpc/ssh-tunnel, exposing raw SSH bytes on
@@ -41100,8 +41023,8 @@ Env (advanced):
41100
41023
  `;
41101
41024
 
41102
41025
  // src/index.ts
41103
- var import_node_path63 = __toESM(require("path"), 1);
41104
- var import_node_fs50 = __toESM(require("fs"), 1);
41026
+ var import_node_path62 = __toESM(require("path"), 1);
41027
+ var import_node_fs49 = __toESM(require("fs"), 1);
41105
41028
  var import_node_os21 = __toESM(require("os"), 1);
41106
41029
 
41107
41030
  // ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/stringify.js
@@ -41815,7 +41738,9 @@ function composeGuestSandbox(base, userWorkDir, spawnCwd) {
41815
41738
  fsv.allowRead = unionArr(fsv.allowRead, [
41816
41739
  "~/.clawd/contact-ssh-keys",
41817
41740
  "~/.clawd/contacts.json",
41818
- "~/.clawd/bin"
41741
+ "~/Library/Application Support/@clawos/clawd-desktop/ota-bundles",
41742
+ "~/.clawd/config.json",
41743
+ "~/.clawd/auth.json"
41819
41744
  ]);
41820
41745
  return s;
41821
41746
  }
@@ -41966,14 +41891,12 @@ var CONTACT_SSH_SYSTEM_PROMPT_HINT = `## \u8DE8\u8BBE\u5907\u6587\u4EF6\u8BBF\u9
41966
41891
  \uFF08\u6BCF\u4E2A \`<deviceId>.ed25519\` \u5C31\u662F\u4E00\u628A privkey\uFF0C\u53BB\u6389\u540E\u7F00\u5C31\u662F deviceId\uFF09
41967
41892
  2. \u7528 SSH \u62E8\u53F7\uFF08\u628A \`<A>\` \u6362\u6210\u5B9E\u9645 deviceId\uFF09\uFF1A
41968
41893
  \`\`\`bash
41969
- ssh -o ProxyCommand='~/.clawd/bin/clawd ssh-relay <A>' \\
41894
+ ssh -o ProxyCommand='clawd ssh-relay <A>' \\
41970
41895
  -i ~/.clawd/contact-ssh-keys/<A>.ed25519 \\
41971
41896
  -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \\
41972
41897
  $USER@127.0.0.1 <command>
41973
41898
  # \u4F8B\u5982\uFF1A... $USER@127.0.0.1 cat /Users/xxx/some/file.md
41974
41899
  # ... $USER@127.0.0.1 ls -la /Users/xxx/proj
41975
- # \u8BF4\u660E\uFF1A\`~/.clawd/bin/clawd\` \u662F daemon \u542F\u52A8\u65F6 seed \u7684 shim\uFF0C\u786C\u7F16\u7801\u5F53\u524D daemon \u7684
41976
- # execPath+cliPath\uFF0C\u4FDD\u8BC1 relay \u8DDF daemon \u7248\u672C\u540C\u6B65\u3002\u4E0D\u8981\u7528\u88F8 \`clawd\`\uFF08\u8D70 $PATH \u4F1A\u6F02\uFF09\u3002
41977
41900
  \`\`\`
41978
41901
 
41979
41902
  **A \u6388\u6743\u54EA\u4E9B\u76EE\u5F55\u4E0D\u7528\u4F60\u63D0\u524D\u8BB0**\uFF1AA \u4FA7\u7684 sshd \u62E8\u53F7\u4F1A\u5F3A\u5236\u8D70 sandbox jail\uFF0C\u8FDB\u6C99\u7BB1\u524D\u4F1A\u628A\u6388\u6743\u76EE\u5F55\u5217\u8868\u5199\u5230 stderr\uFF08\u683C\u5F0F \`[clawd-ssh-jail] Access allowed to these directories: ...\`\uFF09\u3002\u4F60\u5373\u4F7F\u731C\u9519\u8DEF\u5F84\u4E5F\u4F1A\u88AB sandbox deny\uFF0C\u4F46 stderr \u91CC\u5C31\u81EA\u5E26\u7B54\u6848\uFF0C\u8BD5\u9519\u4E00\u6B21\u5C31\u5B66\u5230 A \u6388\u6743\u4E86\u54EA\u4E9B\u76EE\u5F55\uFF0C\u4E0B\u6B21\u76F4\u63A5\u7528\u5BF9\u7684\u8DEF\u5F84\u3002
@@ -46643,8 +46566,8 @@ function turnStartInput(text) {
46643
46566
  const items = [];
46644
46567
  let leftover = text;
46645
46568
  for (const m2 of text.matchAll(SKILL_RE)) {
46646
- const [marker, name, path77] = m2;
46647
- items.push({ type: "skill", name, path: path77 });
46569
+ const [marker, name, path76] = m2;
46570
+ items.push({ type: "skill", name, path: path76 });
46648
46571
  leftover = leftover.replace(marker, "");
46649
46572
  }
46650
46573
  for (const m2 of text.matchAll(ATTACHMENT_RE2)) {
@@ -49098,13 +49021,13 @@ function mapSkillsListResponse(res) {
49098
49021
  const r = s ?? {};
49099
49022
  const name = str3(r.name);
49100
49023
  if (!name) continue;
49101
- const path77 = str3(r.path);
49024
+ const path76 = str3(r.path);
49102
49025
  const description = str3(r.description);
49103
49026
  const isPlugin = name.includes(":");
49104
49027
  out.push({
49105
49028
  name,
49106
49029
  source: isPlugin ? "plugin" : "project",
49107
- ...path77 ? { path: path77 } : {},
49030
+ ...path76 ? { path: path76 } : {},
49108
49031
  ...description ? { description } : {},
49109
49032
  ...isPlugin ? { plugin: name.split(":")[0] } : {}
49110
49033
  });
@@ -53076,8 +52999,8 @@ async function waitForFrpcReady(proc, timeoutMs) {
53076
52999
  }
53077
53000
 
53078
53001
  // src/sshd/sshd-manager.ts
53079
- var import_node_fs37 = __toESM(require("fs"), 1);
53080
- var import_node_path38 = __toESM(require("path"), 1);
53002
+ var import_node_fs36 = __toESM(require("fs"), 1);
53003
+ var import_node_path37 = __toESM(require("path"), 1);
53081
53004
  var import_node_child_process11 = require("child_process");
53082
53005
 
53083
53006
  // src/sshd/sshd-config.ts
@@ -53360,35 +53283,11 @@ function ensureJailScript(dataDir) {
53360
53283
  return target;
53361
53284
  }
53362
53285
 
53363
- // src/sshd/clawd-shim.ts
53364
- var import_node_fs36 = __toESM(require("fs"), 1);
53365
- var import_node_path37 = __toESM(require("path"), 1);
53366
- function shellQuote(s) {
53367
- return `'${s.replace(/'/g, "'\\''")}'`;
53368
- }
53369
- function buildClawdShim(execPath, cliPath) {
53370
- return `#!/usr/bin/env bash
53371
- # clawd shim (managed by clawd; do not edit)
53372
- #
53373
- # \u786C\u7F16\u7801\u672C daemon \u542F\u52A8\u65F6\u7528\u7684 execPath + cliPath\uFF1Bdaemon \u91CD\u542F\u4F1A\u8986\u5199\u672C\u6587\u4EF6\uFF08\u5E42\u7B49 seed\uFF09\u3002
53374
- # guest CC \u7528 SSH ProxyCommand \u8D70 ~/.clawd/bin/clawd ssh-relay \u65F6\u4F1A\u547D\u4E2D\u672C shim\uFF0C\u4FDD\u8BC1
53375
- # relay \u4E8C\u8FDB\u5236\u8DDF\u5F53\u524D\u8DD1\u7740\u7684 daemon \u540C\u6E90\u540C\u7248\u672C\u3002
53376
- exec ${shellQuote(execPath)} ${shellQuote(cliPath)} "$@"
53377
- `;
53378
- }
53379
- function ensureClawdShim(dataDir, execPath, cliPath) {
53380
- const binDir = import_node_path37.default.join(dataDir, "bin");
53381
- import_node_fs36.default.mkdirSync(binDir, { recursive: true, mode: 493 });
53382
- const target = import_node_path37.default.join(binDir, "clawd");
53383
- import_node_fs36.default.writeFileSync(target, buildClawdShim(execPath, cliPath), { mode: 493 });
53384
- return target;
53385
- }
53386
-
53387
53286
  // src/sshd/sshd-manager.ts
53388
53287
  var SshdManager = class {
53389
53288
  constructor(deps) {
53390
53289
  this.deps = deps;
53391
- this.sshdDir = import_node_path38.default.join(deps.dataDir, "sshd");
53290
+ this.sshdDir = import_node_path37.default.join(deps.dataDir, "sshd");
53392
53291
  this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
53393
53292
  }
53394
53293
  deps;
@@ -53407,32 +53306,31 @@ var SshdManager = class {
53407
53306
  ownPid: process.pid,
53408
53307
  logger
53409
53308
  });
53410
- import_node_fs37.default.mkdirSync(this.sshdDir, { recursive: true, mode: 448 });
53411
- import_node_fs37.default.mkdirSync(import_node_path38.default.join(this.sshdDir, "authorized_keys.d"), { recursive: true, mode: 448 });
53309
+ import_node_fs36.default.mkdirSync(this.sshdDir, { recursive: true, mode: 448 });
53310
+ import_node_fs36.default.mkdirSync(import_node_path37.default.join(this.sshdDir, "authorized_keys.d"), { recursive: true, mode: 448 });
53412
53311
  ensureJailScript(this.deps.dataDir);
53413
- ensureClawdShim(this.deps.dataDir, process.execPath, process.argv[1] ?? "");
53414
- const hostKeyPath = import_node_path38.default.join(this.sshdDir, "host_key");
53415
- if (!import_node_fs37.default.existsSync(hostKeyPath)) {
53312
+ const hostKeyPath = import_node_path37.default.join(this.sshdDir, "host_key");
53313
+ if (!import_node_fs36.default.existsSync(hostKeyPath)) {
53416
53314
  await this.generateHostKey(hostKeyPath);
53417
53315
  }
53418
- const akFile = import_node_path38.default.join(this.sshdDir, "authorized_keys.d", "clawd-contacts");
53419
- if (!import_node_fs37.default.existsSync(akFile)) {
53420
- import_node_fs37.default.writeFileSync(akFile, "", { mode: 384 });
53316
+ const akFile = import_node_path37.default.join(this.sshdDir, "authorized_keys.d", "clawd-contacts");
53317
+ if (!import_node_fs36.default.existsSync(akFile)) {
53318
+ import_node_fs36.default.writeFileSync(akFile, "", { mode: 384 });
53421
53319
  }
53422
- const configPath = import_node_path38.default.join(this.sshdDir, "sshd_config");
53320
+ const configPath = import_node_path37.default.join(this.sshdDir, "sshd_config");
53423
53321
  const config = buildSshdConfig({
53424
53322
  listenAddress: "127.0.0.1",
53425
53323
  port: this.deps.port,
53426
53324
  hostKeyPath,
53427
53325
  authorizedKeysFile: akFile,
53428
- pidFilePath: import_node_path38.default.join(this.sshdDir, "sshd.pid")
53326
+ pidFilePath: import_node_path37.default.join(this.sshdDir, "sshd.pid")
53429
53327
  });
53430
- import_node_fs37.default.writeFileSync(configPath, config, { mode: 384 });
53328
+ import_node_fs36.default.writeFileSync(configPath, config, { mode: 384 });
53431
53329
  const sshdBin = this.deps.sshdBin ?? "/usr/sbin/sshd";
53432
53330
  const proc = (this.deps.spawnImpl ?? import_node_child_process11.spawn)(sshdBin, ["-D", "-e", "-f", configPath], {
53433
53331
  stdio: ["ignore", "pipe", "pipe"]
53434
53332
  });
53435
- const logStream = import_node_fs37.default.createWriteStream(import_node_path38.default.join(this.sshdDir, "sshd.log"), {
53333
+ const logStream = import_node_fs36.default.createWriteStream(import_node_path37.default.join(this.sshdDir, "sshd.log"), {
53436
53334
  flags: "a",
53437
53335
  mode: 384
53438
53336
  });
@@ -53525,7 +53423,7 @@ ${tail}` : ready.error;
53525
53423
  p2.on("error", reject);
53526
53424
  });
53527
53425
  try {
53528
- import_node_fs37.default.chmodSync(hostKeyPath, 384);
53426
+ import_node_fs36.default.chmodSync(hostKeyPath, 384);
53529
53427
  } catch {
53530
53428
  }
53531
53429
  }
@@ -53568,17 +53466,17 @@ async function waitForSshdReady(proc, timeoutMs) {
53568
53466
  }
53569
53467
 
53570
53468
  // src/sshd/authorized-keys.ts
53571
- var import_node_fs38 = __toESM(require("fs"), 1);
53572
- var import_node_path39 = __toESM(require("path"), 1);
53469
+ var import_node_fs37 = __toESM(require("fs"), 1);
53470
+ var import_node_path38 = __toESM(require("path"), 1);
53573
53471
  var JAIL_BIN_PATH_ENV = "CLAWD_JAIL_BIN_PATH";
53574
53472
  var AUTHORIZED_KEYS_FILE = "clawd-contacts";
53575
53473
  function jailBinPath() {
53576
- return process.env[JAIL_BIN_PATH_ENV] ?? import_node_path39.default.join(process.env.HOME ?? "", ".clawd", "bin", "clawd-ssh-jail");
53474
+ return process.env[JAIL_BIN_PATH_ENV] ?? import_node_path38.default.join(process.env.HOME ?? "", ".clawd", "bin", "clawd-ssh-jail");
53577
53475
  }
53578
53476
  function rebuildAuthorizedKeys(store, sshdDir) {
53579
- const akDir = import_node_path39.default.join(sshdDir, "authorized_keys.d");
53580
- const target = import_node_path39.default.join(akDir, AUTHORIZED_KEYS_FILE);
53581
- import_node_fs38.default.mkdirSync(akDir, { recursive: true, mode: 448 });
53477
+ const akDir = import_node_path38.default.join(sshdDir, "authorized_keys.d");
53478
+ const target = import_node_path38.default.join(akDir, AUTHORIZED_KEYS_FILE);
53479
+ import_node_fs37.default.mkdirSync(akDir, { recursive: true, mode: 448 });
53582
53480
  const lines = ["# managed by clawd; do not edit", ""];
53583
53481
  for (const c of store.list()) {
53584
53482
  if (!c.sshAllowed) continue;
@@ -53592,28 +53490,66 @@ function rebuildAuthorizedKeys(store, sshdDir) {
53592
53490
  }
53593
53491
  const body = lines.join("\n") + "\n";
53594
53492
  const tmp = `${target}.tmp-${process.pid}-${Date.now()}`;
53595
- import_node_fs38.default.writeFileSync(tmp, body, { mode: 384 });
53596
- import_node_fs38.default.renameSync(tmp, target);
53493
+ import_node_fs37.default.writeFileSync(tmp, body, { mode: 384 });
53494
+ import_node_fs37.default.renameSync(tmp, target);
53597
53495
  }
53598
53496
  function readIssuedPubkey(sshdDir, deviceId) {
53599
53497
  const safeId = deviceId.replace(/[\/\\]/g, "_");
53600
- const p2 = import_node_path39.default.join(sshdDir, "keys", `${safeId}.ed25519.pub`);
53498
+ const p2 = import_node_path38.default.join(sshdDir, "keys", `${safeId}.ed25519.pub`);
53601
53499
  try {
53602
- return import_node_fs38.default.readFileSync(p2, "utf8");
53500
+ return import_node_fs37.default.readFileSync(p2, "utf8");
53603
53501
  } catch {
53604
53502
  return null;
53605
53503
  }
53606
53504
  }
53607
53505
 
53608
53506
  // src/sshd/contact-key-puller.ts
53609
- var import_node_fs40 = __toESM(require("fs"), 1);
53610
- var import_node_path41 = __toESM(require("path"), 1);
53507
+ var import_node_fs39 = __toESM(require("fs"), 1);
53508
+ var import_node_path40 = __toESM(require("path"), 1);
53611
53509
  init_peer_forward();
53612
- init_contact_ssh_log();
53510
+
53511
+ // src/sshd/contact-ssh-log.ts
53512
+ var import_node_fs38 = __toESM(require("fs"), 1);
53513
+ var import_node_path39 = __toESM(require("path"), 1);
53514
+ function createContactSshLog(dataDir) {
53515
+ const file = import_node_path39.default.join(dataDir, "contact-ssh.log");
53516
+ function append(level, tag, message, meta) {
53517
+ const time = (/* @__PURE__ */ new Date()).toISOString();
53518
+ let line = `[${time}] [${level}] [${tag}] ${message}`;
53519
+ if (meta && Object.keys(meta).length > 0) {
53520
+ try {
53521
+ line += " " + JSON.stringify(meta);
53522
+ } catch {
53523
+ line += " [meta-serialize-failed]";
53524
+ }
53525
+ }
53526
+ line += "\n";
53527
+ try {
53528
+ import_node_fs38.default.mkdirSync(import_node_path39.default.dirname(file), { recursive: true });
53529
+ import_node_fs38.default.appendFileSync(file, line, { mode: 384 });
53530
+ } catch {
53531
+ }
53532
+ }
53533
+ return {
53534
+ info: (tag, message, meta) => append("INFO", tag, message, meta),
53535
+ warn: (tag, message, meta) => append("WARN", tag, message, meta),
53536
+ error: (tag, message, meta) => append("ERROR", tag, message, meta)
53537
+ };
53538
+ }
53539
+ var nullContactSshLog = {
53540
+ info: () => {
53541
+ },
53542
+ warn: () => {
53543
+ },
53544
+ error: () => {
53545
+ }
53546
+ };
53547
+
53548
+ // src/sshd/contact-key-puller.ts
53613
53549
  var CONTACT_KEYS_DIR = "contact-ssh-keys";
53614
53550
  function safeContactKeyPath(dataDir, deviceId) {
53615
53551
  const safeId = deviceId.replace(/[\/\\]/g, "_");
53616
- return import_node_path41.default.join(dataDir, CONTACT_KEYS_DIR, `${safeId}.ed25519`);
53552
+ return import_node_path40.default.join(dataDir, CONTACT_KEYS_DIR, `${safeId}.ed25519`);
53617
53553
  }
53618
53554
  async function pullContactSshKeyOnce(deps) {
53619
53555
  const forward = deps.forwardImpl ?? ((c) => forwardContactSshKeyIssueToPeer({
@@ -53679,12 +53615,12 @@ async function pullContactSshKeyOnce(deps) {
53679
53615
  }
53680
53616
  function writeKeyFile(dataDir, deviceId, pem) {
53681
53617
  const p2 = safeContactKeyPath(dataDir, deviceId);
53682
- import_node_fs40.default.mkdirSync(import_node_path41.default.dirname(p2), { recursive: true, mode: 448 });
53683
- import_node_fs40.default.writeFileSync(p2, pem, { mode: 384 });
53618
+ import_node_fs39.default.mkdirSync(import_node_path40.default.dirname(p2), { recursive: true, mode: 448 });
53619
+ import_node_fs39.default.writeFileSync(p2, pem, { mode: 384 });
53684
53620
  }
53685
53621
  function removeKeyFile(dataDir, deviceId) {
53686
53622
  try {
53687
- import_node_fs40.default.unlinkSync(safeContactKeyPath(dataDir, deviceId));
53623
+ import_node_fs39.default.unlinkSync(safeContactKeyPath(dataDir, deviceId));
53688
53624
  return true;
53689
53625
  } catch {
53690
53626
  return false;
@@ -53721,7 +53657,6 @@ var ContactKeyPuller = class {
53721
53657
 
53722
53658
  // src/sshd/ssh-tunnel-relay.ts
53723
53659
  var import_node_net2 = __toESM(require("net"), 1);
53724
- init_contact_ssh_log();
53725
53660
  async function handleSshTunnelUpgrade(req, socket, head, deps) {
53726
53661
  const sshLog = deps.sshLog ?? nullContactSshLog;
53727
53662
  const clientAddr = (req.socket && "remoteAddress" in req.socket ? req.socket.remoteAddress : null) ?? "unknown";
@@ -53829,32 +53764,29 @@ function pumpWsToSshd(ws, deps, clientAddr) {
53829
53764
  });
53830
53765
  }
53831
53766
 
53832
- // src/index.ts
53833
- init_contact_ssh_log();
53834
-
53835
53767
  // src/tunnel/device-key.ts
53836
53768
  var import_node_os14 = __toESM(require("os"), 1);
53837
- var import_node_path42 = __toESM(require("path"), 1);
53769
+ var import_node_path41 = __toESM(require("path"), 1);
53838
53770
  var import_node_crypto11 = __toESM(require("crypto"), 1);
53839
53771
  var DERIVE_SALT = "clawd-tunnel-device-v1";
53840
53772
  function deriveStableDeviceKey(opts = {}) {
53841
53773
  const hostname = opts.hostname ?? import_node_os14.default.hostname();
53842
53774
  const uid = opts.uid ?? (typeof import_node_os14.default.userInfo === "function" ? import_node_os14.default.userInfo().uid : 0);
53843
53775
  const home = opts.home ?? import_node_os14.default.homedir();
53844
- const defaultDataDir = import_node_path42.default.resolve(import_node_path42.default.join(home, ".clawd"));
53845
- const normalizedDataDir = opts.dataDir ? import_node_path42.default.resolve(opts.dataDir) : null;
53776
+ const defaultDataDir = import_node_path41.default.resolve(import_node_path41.default.join(home, ".clawd"));
53777
+ const normalizedDataDir = opts.dataDir ? import_node_path41.default.resolve(opts.dataDir) : null;
53846
53778
  const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
53847
53779
  const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
53848
53780
  return import_node_crypto11.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
53849
53781
  }
53850
53782
 
53851
53783
  // src/auth-store.ts
53852
- var import_node_fs41 = __toESM(require("fs"), 1);
53853
- var import_node_path43 = __toESM(require("path"), 1);
53784
+ var import_node_fs40 = __toESM(require("fs"), 1);
53785
+ var import_node_path42 = __toESM(require("path"), 1);
53854
53786
  var import_node_crypto12 = __toESM(require("crypto"), 1);
53855
53787
  var AUTH_FILE_NAME = "auth.json";
53856
53788
  function authFilePath(dataDir) {
53857
- return import_node_path43.default.join(dataDir, AUTH_FILE_NAME);
53789
+ return import_node_path42.default.join(dataDir, AUTH_FILE_NAME);
53858
53790
  }
53859
53791
  function loadOrCreateAuthFile(opts) {
53860
53792
  const file = authFilePath(opts.dataDir);
@@ -53890,7 +53822,7 @@ function defaultGenerateOwnerPrincipalId() {
53890
53822
  }
53891
53823
  function readAuthFile(file) {
53892
53824
  try {
53893
- const raw = import_node_fs41.default.readFileSync(file, "utf8");
53825
+ const raw = import_node_fs40.default.readFileSync(file, "utf8");
53894
53826
  const parsed = JSON.parse(raw);
53895
53827
  if (typeof parsed?.token !== "string" || parsed.token.length === 0) {
53896
53828
  return null;
@@ -53910,25 +53842,25 @@ function readAuthFile(file) {
53910
53842
  }
53911
53843
  }
53912
53844
  function writeAuthFile(file, content) {
53913
- import_node_fs41.default.mkdirSync(import_node_path43.default.dirname(file), { recursive: true });
53914
- import_node_fs41.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
53845
+ import_node_fs40.default.mkdirSync(import_node_path42.default.dirname(file), { recursive: true });
53846
+ import_node_fs40.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
53915
53847
  try {
53916
- import_node_fs41.default.chmodSync(file, 384);
53848
+ import_node_fs40.default.chmodSync(file, 384);
53917
53849
  } catch {
53918
53850
  }
53919
53851
  }
53920
53852
 
53921
53853
  // src/owner-profile.ts
53922
- var import_node_fs42 = __toESM(require("fs"), 1);
53854
+ var import_node_fs41 = __toESM(require("fs"), 1);
53923
53855
  var import_node_os15 = __toESM(require("os"), 1);
53924
- var import_node_path44 = __toESM(require("path"), 1);
53856
+ var import_node_path43 = __toESM(require("path"), 1);
53925
53857
  var PROFILE_FILENAME = "profile.json";
53926
53858
  function loadOwnerDisplayName(dataDir) {
53927
53859
  const fallback = import_node_os15.default.userInfo().username;
53928
- const profilePath = import_node_path44.default.join(dataDir, PROFILE_FILENAME);
53860
+ const profilePath = import_node_path43.default.join(dataDir, PROFILE_FILENAME);
53929
53861
  let raw;
53930
53862
  try {
53931
- raw = import_node_fs42.default.readFileSync(profilePath, "utf8");
53863
+ raw = import_node_fs41.default.readFileSync(profilePath, "utf8");
53932
53864
  } catch {
53933
53865
  return fallback;
53934
53866
  }
@@ -53951,18 +53883,18 @@ function loadOwnerDisplayName(dataDir) {
53951
53883
  }
53952
53884
 
53953
53885
  // src/feishu-auth/owner-identity-store.ts
53954
- var import_node_fs43 = __toESM(require("fs"), 1);
53955
- var import_node_path45 = __toESM(require("path"), 1);
53886
+ var import_node_fs42 = __toESM(require("fs"), 1);
53887
+ var import_node_path44 = __toESM(require("path"), 1);
53956
53888
  var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
53957
53889
  var OwnerIdentityStore = class {
53958
53890
  file;
53959
53891
  constructor(dataDir) {
53960
- this.file = import_node_path45.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
53892
+ this.file = import_node_path44.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
53961
53893
  }
53962
53894
  read() {
53963
53895
  let raw;
53964
53896
  try {
53965
- raw = import_node_fs43.default.readFileSync(this.file, "utf8");
53897
+ raw = import_node_fs42.default.readFileSync(this.file, "utf8");
53966
53898
  } catch {
53967
53899
  return null;
53968
53900
  }
@@ -53990,16 +53922,16 @@ var OwnerIdentityStore = class {
53990
53922
  };
53991
53923
  }
53992
53924
  write(record) {
53993
- import_node_fs43.default.mkdirSync(import_node_path45.default.dirname(this.file), { recursive: true });
53994
- import_node_fs43.default.writeFileSync(this.file, JSON.stringify(record, null, 2), { mode: 384 });
53925
+ import_node_fs42.default.mkdirSync(import_node_path44.default.dirname(this.file), { recursive: true });
53926
+ import_node_fs42.default.writeFileSync(this.file, JSON.stringify(record, null, 2), { mode: 384 });
53995
53927
  try {
53996
- import_node_fs43.default.chmodSync(this.file, 384);
53928
+ import_node_fs42.default.chmodSync(this.file, 384);
53997
53929
  } catch {
53998
53930
  }
53999
53931
  }
54000
53932
  clear() {
54001
53933
  try {
54002
- import_node_fs43.default.unlinkSync(this.file);
53934
+ import_node_fs42.default.unlinkSync(this.file);
54003
53935
  } catch (err) {
54004
53936
  const code = err?.code;
54005
53937
  if (code !== "ENOENT") throw err;
@@ -54120,9 +54052,9 @@ var CentralClientError = class extends Error {
54120
54052
  code;
54121
54053
  cause;
54122
54054
  };
54123
- async function centralRequest(opts, path77, init) {
54055
+ async function centralRequest(opts, path76, init) {
54124
54056
  const f = opts.fetchImpl ?? globalThis.fetch;
54125
- const url = `${opts.api.replace(/\/+$/, "")}${path77}`;
54057
+ const url = `${opts.api.replace(/\/+$/, "")}${path76}`;
54126
54058
  const ctrl = new AbortController();
54127
54059
  const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
54128
54060
  let res;
@@ -54264,8 +54196,8 @@ function verifyConnectToken(args) {
54264
54196
  }
54265
54197
 
54266
54198
  // src/feishu-auth/server-key.ts
54267
- var fs53 = __toESM(require("fs"), 1);
54268
- var path54 = __toESM(require("path"), 1);
54199
+ var fs52 = __toESM(require("fs"), 1);
54200
+ var path53 = __toESM(require("path"), 1);
54269
54201
  var FILE_NAME2 = "server-signing-key.json";
54270
54202
  var ServerKeyStore = class {
54271
54203
  constructor(dataDir) {
@@ -54273,12 +54205,12 @@ var ServerKeyStore = class {
54273
54205
  }
54274
54206
  dataDir;
54275
54207
  filePath() {
54276
- return path54.join(this.dataDir, FILE_NAME2);
54208
+ return path53.join(this.dataDir, FILE_NAME2);
54277
54209
  }
54278
54210
  /** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
54279
54211
  read() {
54280
54212
  try {
54281
- const raw = fs53.readFileSync(this.filePath(), "utf8");
54213
+ const raw = fs52.readFileSync(this.filePath(), "utf8");
54282
54214
  const parsed = JSON.parse(raw);
54283
54215
  if (typeof parsed.publicKeyPem === "string" && parsed.publicKeyPem.includes("PUBLIC KEY")) {
54284
54216
  return parsed.publicKeyPem;
@@ -54293,12 +54225,12 @@ var ServerKeyStore = class {
54293
54225
  publicKeyPem,
54294
54226
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
54295
54227
  };
54296
- fs53.mkdirSync(this.dataDir, { recursive: true });
54297
- fs53.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
54228
+ fs52.mkdirSync(this.dataDir, { recursive: true });
54229
+ fs52.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
54298
54230
  }
54299
54231
  clear() {
54300
54232
  try {
54301
- fs53.unlinkSync(this.filePath());
54233
+ fs52.unlinkSync(this.filePath());
54302
54234
  } catch {
54303
54235
  }
54304
54236
  }
@@ -54311,12 +54243,12 @@ init_protocol();
54311
54243
  init_protocol();
54312
54244
 
54313
54245
  // src/session/fork.ts
54314
- var import_node_fs44 = __toESM(require("fs"), 1);
54246
+ var import_node_fs43 = __toESM(require("fs"), 1);
54315
54247
  var import_node_os16 = __toESM(require("os"), 1);
54316
- var import_node_path46 = __toESM(require("path"), 1);
54248
+ var import_node_path45 = __toESM(require("path"), 1);
54317
54249
  init_claude_history();
54318
54250
  function readJsonlEntries(file) {
54319
- const raw = import_node_fs44.default.readFileSync(file, "utf8");
54251
+ const raw = import_node_fs43.default.readFileSync(file, "utf8");
54320
54252
  const out = [];
54321
54253
  for (const line of raw.split("\n")) {
54322
54254
  const t = line.trim();
@@ -54329,10 +54261,10 @@ function readJsonlEntries(file) {
54329
54261
  return out;
54330
54262
  }
54331
54263
  function forkSession(input) {
54332
- const baseDir = input.baseDir ?? import_node_path46.default.join(import_node_os16.default.homedir(), ".claude");
54333
- const projectDir = import_node_path46.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
54334
- const sourceFile = import_node_path46.default.join(projectDir, `${input.toolSessionId}.jsonl`);
54335
- if (!import_node_fs44.default.existsSync(sourceFile)) {
54264
+ const baseDir = input.baseDir ?? import_node_path45.default.join(import_node_os16.default.homedir(), ".claude");
54265
+ const projectDir = import_node_path45.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
54266
+ const sourceFile = import_node_path45.default.join(projectDir, `${input.toolSessionId}.jsonl`);
54267
+ if (!import_node_fs43.default.existsSync(sourceFile)) {
54336
54268
  throw new Error(`fork: source transcript not found: ${sourceFile}`);
54337
54269
  }
54338
54270
  const entries = readJsonlEntries(sourceFile);
@@ -54362,9 +54294,9 @@ function forkSession(input) {
54362
54294
  }
54363
54295
  forkedLines.push(JSON.stringify(forked));
54364
54296
  }
54365
- const forkedFilePath = import_node_path46.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
54366
- import_node_fs44.default.mkdirSync(projectDir, { recursive: true });
54367
- import_node_fs44.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
54297
+ const forkedFilePath = import_node_path45.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
54298
+ import_node_fs43.default.mkdirSync(projectDir, { recursive: true });
54299
+ import_node_fs43.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
54368
54300
  return { forkedToolSessionId, forkedFilePath };
54369
54301
  }
54370
54302
 
@@ -54716,7 +54648,7 @@ function buildPermissionHandlers(deps) {
54716
54648
  }
54717
54649
 
54718
54650
  // src/handlers/history.ts
54719
- var path57 = __toESM(require("path"), 1);
54651
+ var path56 = __toESM(require("path"), 1);
54720
54652
  init_protocol();
54721
54653
 
54722
54654
  // src/session/recent-dirs.ts
@@ -54734,7 +54666,7 @@ function listRecentDirs(store, limit = 50) {
54734
54666
  }
54735
54667
 
54736
54668
  // src/permission/persona-paths.ts
54737
- var path56 = __toESM(require("path"), 1);
54669
+ var path55 = __toESM(require("path"), 1);
54738
54670
  function getAllowedPersonaIds(grants, action) {
54739
54671
  const ids = /* @__PURE__ */ new Set();
54740
54672
  for (const g2 of grants) {
@@ -54747,42 +54679,42 @@ function getAllowedPersonaIds(grants, action) {
54747
54679
  return ids;
54748
54680
  }
54749
54681
  function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
54750
- const target = path56.resolve(absPath);
54682
+ const target = path55.resolve(absPath);
54751
54683
  if (userWorkDir) {
54752
- const u = path56.resolve(userWorkDir);
54753
- const usep = u.endsWith(path56.sep) ? "" : path56.sep;
54684
+ const u = path55.resolve(userWorkDir);
54685
+ const usep = u.endsWith(path55.sep) ? "" : path55.sep;
54754
54686
  if (target === u || target.startsWith(u + usep)) return true;
54755
54687
  }
54756
- const root = path56.resolve(personaRoot);
54757
- const sep3 = root.endsWith(path56.sep) ? "" : path56.sep;
54688
+ const root = path55.resolve(personaRoot);
54689
+ const sep3 = root.endsWith(path55.sep) ? "" : path55.sep;
54758
54690
  if (!target.startsWith(root + sep3)) return false;
54759
- const rel = path56.relative(root, target);
54691
+ const rel = path55.relative(root, target);
54760
54692
  if (!rel || rel.startsWith("..")) return false;
54761
- const personaId = rel.split(path56.sep)[0];
54693
+ const personaId = rel.split(path55.sep)[0];
54762
54694
  if (!personaId) return false;
54763
54695
  const allowed = getAllowedPersonaIds(grants, action);
54764
54696
  if (allowed === "*") return true;
54765
54697
  return allowed.has(personaId);
54766
54698
  }
54767
54699
  function personaIdFromPath(absPath, personaRoot) {
54768
- const root = path56.resolve(personaRoot);
54769
- const target = path56.resolve(absPath);
54770
- const sep3 = root.endsWith(path56.sep) ? "" : path56.sep;
54700
+ const root = path55.resolve(personaRoot);
54701
+ const target = path55.resolve(absPath);
54702
+ const sep3 = root.endsWith(path55.sep) ? "" : path55.sep;
54771
54703
  if (!target.startsWith(root + sep3)) return null;
54772
- const rel = path56.relative(root, target);
54704
+ const rel = path55.relative(root, target);
54773
54705
  if (!rel || rel.startsWith("..")) return null;
54774
- const id = rel.split(path56.sep)[0];
54706
+ const id = rel.split(path55.sep)[0];
54775
54707
  return id || null;
54776
54708
  }
54777
54709
  function isPathWithin(dir, absPath) {
54778
- const d = path56.resolve(dir);
54779
- const t = path56.resolve(absPath);
54780
- const sep3 = d.endsWith(path56.sep) ? "" : path56.sep;
54710
+ const d = path55.resolve(dir);
54711
+ const t = path55.resolve(absPath);
54712
+ const sep3 = d.endsWith(path55.sep) ? "" : path55.sep;
54781
54713
  return t === d || t.startsWith(d + sep3);
54782
54714
  }
54783
54715
  function isPathInGuestBoundary(personaRoot, personaId, userWorkDir, absPath) {
54784
54716
  if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
54785
- return personaIdFromPath(path56.resolve(absPath), personaRoot) === personaId;
54717
+ return personaIdFromPath(path55.resolve(absPath), personaRoot) === personaId;
54786
54718
  }
54787
54719
 
54788
54720
  // src/handlers/history.ts
@@ -54808,7 +54740,7 @@ function buildHistoryHandlers(deps) {
54808
54740
  if (!pid) return false;
54809
54741
  return isGuestPathAllowed(
54810
54742
  ctx.grants,
54811
- path57.join(personaRoot, pid),
54743
+ path56.join(personaRoot, pid),
54812
54744
  personaRoot,
54813
54745
  "read",
54814
54746
  userWorkDir
@@ -54820,7 +54752,7 @@ function buildHistoryHandlers(deps) {
54820
54752
  };
54821
54753
  const list = async (frame, _client, ctx) => {
54822
54754
  const args = HistoryListArgs.parse(frame);
54823
- assertGuestPath(ctx, path57.resolve(args.projectPath), personaRoot, "history:list");
54755
+ assertGuestPath(ctx, path56.resolve(args.projectPath), personaRoot, "history:list");
54824
54756
  const sessions = await history.listSessions(args);
54825
54757
  return { response: { type: "history:list", sessions } };
54826
54758
  };
@@ -54852,13 +54784,13 @@ function buildHistoryHandlers(deps) {
54852
54784
  };
54853
54785
  const subagents = async (frame, _client, ctx) => {
54854
54786
  const args = HistorySubagentsArgs.parse(frame);
54855
- assertGuestPath(ctx, path57.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
54787
+ assertGuestPath(ctx, path56.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
54856
54788
  const subs = await history.listSubagents(args);
54857
54789
  return { response: { type: "history:subagents", subagents: subs } };
54858
54790
  };
54859
54791
  const subagentRead = async (frame, _client, ctx) => {
54860
54792
  const args = HistorySubagentReadArgs.parse(frame);
54861
- assertGuestPath(ctx, path57.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
54793
+ assertGuestPath(ctx, path56.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
54862
54794
  const res = await history.readSubagent(args);
54863
54795
  return { response: { type: "history:subagent-read", ...res } };
54864
54796
  };
@@ -54867,7 +54799,7 @@ function buildHistoryHandlers(deps) {
54867
54799
  if (ctx?.principal.kind === "guest" && personaRoot) {
54868
54800
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
54869
54801
  const filtered = dirs.filter(
54870
- (d) => isGuestPathAllowed(ctx.grants, path57.resolve(d.cwd), personaRoot, "read", userWorkDir)
54802
+ (d) => isGuestPathAllowed(ctx.grants, path56.resolve(d.cwd), personaRoot, "read", userWorkDir)
54871
54803
  );
54872
54804
  return { response: { type: "history:recentDirs", dirs: filtered } };
54873
54805
  }
@@ -54884,7 +54816,7 @@ function buildHistoryHandlers(deps) {
54884
54816
  }
54885
54817
 
54886
54818
  // src/handlers/workspace.ts
54887
- var path58 = __toESM(require("path"), 1);
54819
+ var path57 = __toESM(require("path"), 1);
54888
54820
  var os16 = __toESM(require("os"), 1);
54889
54821
  init_protocol();
54890
54822
  init_protocol();
@@ -54926,22 +54858,22 @@ function buildWorkspaceHandlers(deps) {
54926
54858
  const args = WorkspaceListArgs.parse(frame);
54927
54859
  const isGuest = ctx?.principal.kind === "guest";
54928
54860
  const fallbackCwd = isGuest && personaRoot ? personaRoot : os16.homedir();
54929
- const resolvedCwd = path58.resolve(args.cwd ?? fallbackCwd);
54930
- const target = args.path ? path58.resolve(resolvedCwd, args.path) : resolvedCwd;
54861
+ const resolvedCwd = path57.resolve(args.cwd ?? fallbackCwd);
54862
+ const target = args.path ? path57.resolve(resolvedCwd, args.path) : resolvedCwd;
54931
54863
  assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
54932
54864
  const res = workspace.list({ ...args, cwd: resolvedCwd });
54933
54865
  return { response: { type: "workspace:list", ...res } };
54934
54866
  };
54935
54867
  const read = async (frame, _client, ctx) => {
54936
54868
  const args = WorkspaceReadArgs.parse(frame);
54937
- const target = path58.isAbsolute(args.path) ? path58.resolve(args.path) : path58.resolve(args.cwd, args.path);
54869
+ const target = path57.isAbsolute(args.path) ? path57.resolve(args.path) : path57.resolve(args.cwd, args.path);
54938
54870
  assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
54939
54871
  const res = workspace.read(args);
54940
54872
  return { response: { type: "workspace:read", ...res } };
54941
54873
  };
54942
54874
  const skillsList = async (frame, _client, ctx) => {
54943
54875
  const args = SkillsListArgs.parse(frame);
54944
- const cwdAbs = path58.resolve(args.cwd);
54876
+ const cwdAbs = path57.resolve(args.cwd);
54945
54877
  assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
54946
54878
  const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
54947
54879
  if (ctx?.principal.kind === "guest" && personaRoot) {
@@ -54953,7 +54885,7 @@ function buildWorkspaceHandlers(deps) {
54953
54885
  };
54954
54886
  const agentsList = async (frame, _client, ctx) => {
54955
54887
  const args = AgentsListArgs.parse(frame);
54956
- const cwdAbs = path58.resolve(args.cwd);
54888
+ const cwdAbs = path57.resolve(args.cwd);
54957
54889
  assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
54958
54890
  if (args.tool === "codex") {
54959
54891
  return { response: { type: "agents:list", agents: [] } };
@@ -54975,20 +54907,20 @@ function buildWorkspaceHandlers(deps) {
54975
54907
  }
54976
54908
 
54977
54909
  // src/handlers/git.ts
54978
- var path60 = __toESM(require("path"), 1);
54910
+ var path59 = __toESM(require("path"), 1);
54979
54911
  init_protocol();
54980
54912
  init_protocol();
54981
54913
 
54982
54914
  // src/workspace/git.ts
54983
54915
  var import_node_child_process12 = require("child_process");
54984
- var import_node_fs45 = __toESM(require("fs"), 1);
54985
- var import_node_path47 = __toESM(require("path"), 1);
54916
+ var import_node_fs44 = __toESM(require("fs"), 1);
54917
+ var import_node_path46 = __toESM(require("path"), 1);
54986
54918
  var import_node_util = require("util");
54987
54919
  var pexec = (0, import_node_util.promisify)(import_node_child_process12.execFile);
54988
54920
  function normalizePath(p2) {
54989
- const resolved = import_node_path47.default.resolve(p2);
54921
+ const resolved = import_node_path46.default.resolve(p2);
54990
54922
  try {
54991
- return import_node_fs45.default.realpathSync(resolved);
54923
+ return import_node_fs44.default.realpathSync(resolved);
54992
54924
  } catch {
54993
54925
  return resolved;
54994
54926
  }
@@ -55062,7 +54994,7 @@ async function listGitBranches(cwd) {
55062
54994
  function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
55063
54995
  if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
55064
54996
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
55065
- if (!isGuestPathAllowed(ctx.grants, path60.resolve(cwd), personaRoot, "read", userWorkDir)) {
54997
+ if (!isGuestPathAllowed(ctx.grants, path59.resolve(cwd), personaRoot, "read", userWorkDir)) {
55066
54998
  throw new ClawdError(
55067
54999
  ERROR_CODES.UNAUTHORIZED,
55068
55000
  `guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
@@ -55403,22 +55335,22 @@ init_src();
55403
55335
  init_protocol();
55404
55336
 
55405
55337
  // src/sshd/key-issue.ts
55406
- var import_node_fs46 = __toESM(require("fs"), 1);
55407
- var import_node_path48 = __toESM(require("path"), 1);
55338
+ var import_node_fs45 = __toESM(require("fs"), 1);
55339
+ var import_node_path47 = __toESM(require("path"), 1);
55408
55340
  var import_node_child_process13 = require("child_process");
55409
55341
  function safeDeviceId(deviceId) {
55410
55342
  return deviceId.replace(/[\/\\]/g, "_");
55411
55343
  }
55412
55344
  async function issueContactSshKey(deviceId, sshdDir, opts = {}) {
55413
55345
  const safeId = safeDeviceId(deviceId);
55414
- const keysDir = import_node_path48.default.join(sshdDir, "keys");
55415
- import_node_fs46.default.mkdirSync(keysDir, { recursive: true, mode: 448 });
55416
- const privPath = import_node_path48.default.join(keysDir, `${safeId}.ed25519`);
55346
+ const keysDir = import_node_path47.default.join(sshdDir, "keys");
55347
+ import_node_fs45.default.mkdirSync(keysDir, { recursive: true, mode: 448 });
55348
+ const privPath = import_node_path47.default.join(keysDir, `${safeId}.ed25519`);
55417
55349
  const pubPath = `${privPath}.pub`;
55418
- if (import_node_fs46.default.existsSync(privPath) && import_node_fs46.default.existsSync(pubPath)) {
55350
+ if (import_node_fs45.default.existsSync(privPath) && import_node_fs45.default.existsSync(pubPath)) {
55419
55351
  return {
55420
- privateKeyPem: import_node_fs46.default.readFileSync(privPath, "utf8"),
55421
- publicKeyLine: import_node_fs46.default.readFileSync(pubPath, "utf8").trim()
55352
+ privateKeyPem: import_node_fs45.default.readFileSync(privPath, "utf8"),
55353
+ publicKeyLine: import_node_fs45.default.readFileSync(pubPath, "utf8").trim()
55422
55354
  };
55423
55355
  }
55424
55356
  const bin = opts.keygenBin ?? "/usr/bin/ssh-keygen";
@@ -55432,21 +55364,20 @@ async function issueContactSshKey(deviceId, sshdDir, opts = {}) {
55432
55364
  p2.on("error", reject);
55433
55365
  });
55434
55366
  try {
55435
- import_node_fs46.default.chmodSync(privPath, 384);
55367
+ import_node_fs45.default.chmodSync(privPath, 384);
55436
55368
  } catch {
55437
55369
  }
55438
55370
  try {
55439
- import_node_fs46.default.chmodSync(pubPath, 420);
55371
+ import_node_fs45.default.chmodSync(pubPath, 420);
55440
55372
  } catch {
55441
55373
  }
55442
55374
  return {
55443
- privateKeyPem: import_node_fs46.default.readFileSync(privPath, "utf8"),
55444
- publicKeyLine: import_node_fs46.default.readFileSync(pubPath, "utf8").trim()
55375
+ privateKeyPem: import_node_fs45.default.readFileSync(privPath, "utf8"),
55376
+ publicKeyLine: import_node_fs45.default.readFileSync(pubPath, "utf8").trim()
55445
55377
  };
55446
55378
  }
55447
55379
 
55448
55380
  // src/handlers/contact-ssh.ts
55449
- init_contact_ssh_log();
55450
55381
  function ensureOwner2(ctx) {
55451
55382
  if (!ctx || ctx.principal.kind !== "owner") {
55452
55383
  throw new ClawdError(
@@ -55861,7 +55792,7 @@ function buildPersonaHandlers(deps) {
55861
55792
  }
55862
55793
 
55863
55794
  // src/handlers/attachment.ts
55864
- var import_node_path49 = __toESM(require("path"), 1);
55795
+ var import_node_path48 = __toESM(require("path"), 1);
55865
55796
  init_protocol();
55866
55797
  init_protocol();
55867
55798
  var DEFAULT_TTL_SECONDS = 24 * 3600;
@@ -55941,12 +55872,12 @@ function buildAttachmentHandlers(deps) {
55941
55872
  `session ${args.sessionId} scope unresolved`
55942
55873
  );
55943
55874
  }
55944
- const cwdAbs = import_node_path49.default.resolve(sessionFile.cwd);
55945
- const candidateAbs = import_node_path49.default.isAbsolute(args.relPath) ? import_node_path49.default.resolve(args.relPath) : import_node_path49.default.resolve(cwdAbs, args.relPath);
55875
+ const cwdAbs = import_node_path48.default.resolve(sessionFile.cwd);
55876
+ const candidateAbs = import_node_path48.default.isAbsolute(args.relPath) ? import_node_path48.default.resolve(args.relPath) : import_node_path48.default.resolve(cwdAbs, args.relPath);
55946
55877
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
55947
55878
  const entries = deps.groupFileStore.list(scope, args.sessionId);
55948
55879
  const entry = entries.find((e) => {
55949
- const storedAbs = import_node_path49.default.isAbsolute(e.relPath) ? import_node_path49.default.resolve(e.relPath) : import_node_path49.default.resolve(cwdAbs, e.relPath);
55880
+ const storedAbs = import_node_path48.default.isAbsolute(e.relPath) ? import_node_path48.default.resolve(e.relPath) : import_node_path48.default.resolve(cwdAbs, e.relPath);
55950
55881
  return storedAbs === candidateAbs && !e.stale;
55951
55882
  });
55952
55883
  if (!entry) {
@@ -55971,7 +55902,7 @@ function buildAttachmentHandlers(deps) {
55971
55902
  if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
55972
55903
  const f = deps.sessionStore.read(sessionId);
55973
55904
  if (!f) return;
55974
- assertGuestAttachmentPath(ctx, import_node_path49.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
55905
+ assertGuestAttachmentPath(ctx, import_node_path48.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
55975
55906
  }
55976
55907
  const groupAdd = async (frame, _client, ctx) => {
55977
55908
  if (!deps.groupFileStore || !deps.getSessionScope) {
@@ -55986,8 +55917,8 @@ function buildAttachmentHandlers(deps) {
55986
55917
  if (!scope) {
55987
55918
  throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
55988
55919
  }
55989
- const cwdAbs = import_node_path49.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
55990
- const candidateAbs = import_node_path49.default.isAbsolute(args.relPath) ? import_node_path49.default.resolve(args.relPath) : import_node_path49.default.resolve(cwdAbs, args.relPath);
55920
+ const cwdAbs = import_node_path48.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
55921
+ const candidateAbs = import_node_path48.default.isAbsolute(args.relPath) ? import_node_path48.default.resolve(args.relPath) : import_node_path48.default.resolve(cwdAbs, args.relPath);
55991
55922
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
55992
55923
  const from = ctx?.principal.kind === "owner" ? "owner" : "agent";
55993
55924
  const size = 0;
@@ -56046,20 +55977,20 @@ function buildAttachmentHandlers(deps) {
56046
55977
 
56047
55978
  // src/handlers/extension.ts
56048
55979
  var import_promises8 = __toESM(require("fs/promises"), 1);
56049
- var import_node_path54 = __toESM(require("path"), 1);
55980
+ var import_node_path53 = __toESM(require("path"), 1);
56050
55981
  init_protocol();
56051
55982
  init_src();
56052
55983
 
56053
55984
  // src/extension/bundle-zip.ts
56054
55985
  var import_promises5 = __toESM(require("fs/promises"), 1);
56055
- var import_node_path50 = __toESM(require("path"), 1);
55986
+ var import_node_path49 = __toESM(require("path"), 1);
56056
55987
  var import_node_crypto14 = __toESM(require("crypto"), 1);
56057
55988
  var import_jszip2 = __toESM(require_lib3(), 1);
56058
55989
  async function bundleExtensionDir(dir) {
56059
55990
  const entries = await listFilesSorted(dir);
56060
55991
  const zip = new import_jszip2.default();
56061
55992
  for (const rel of entries) {
56062
- const abs = import_node_path50.default.join(dir, rel);
55993
+ const abs = import_node_path49.default.join(dir, rel);
56063
55994
  const content = await import_promises5.default.readFile(abs);
56064
55995
  zip.file(rel, content, { date: FIXED_DATE });
56065
55996
  }
@@ -56080,7 +56011,7 @@ async function listFilesSorted(rootDir) {
56080
56011
  return out;
56081
56012
  }
56082
56013
  async function walk(absRoot, relPrefix, out) {
56083
- const dirAbs = import_node_path50.default.join(absRoot, relPrefix);
56014
+ const dirAbs = import_node_path49.default.join(absRoot, relPrefix);
56084
56015
  const entries = await import_promises5.default.readdir(dirAbs, { withFileTypes: true });
56085
56016
  for (const e of entries) {
56086
56017
  if (IGNORE_BASENAMES.has(e.name)) continue;
@@ -56136,7 +56067,7 @@ function computePublishCheck(args) {
56136
56067
 
56137
56068
  // src/extension/install-flow.ts
56138
56069
  var import_promises6 = __toESM(require("fs/promises"), 1);
56139
- var import_node_path52 = __toESM(require("path"), 1);
56070
+ var import_node_path51 = __toESM(require("path"), 1);
56140
56071
  var import_node_os19 = __toESM(require("os"), 1);
56141
56072
  var import_node_crypto15 = __toESM(require("crypto"), 1);
56142
56073
  var import_jszip3 = __toESM(require_lib3(), 1);
@@ -56144,19 +56075,19 @@ init_src();
56144
56075
 
56145
56076
  // src/extension/paths.ts
56146
56077
  var import_node_os18 = __toESM(require("os"), 1);
56147
- var import_node_path51 = __toESM(require("path"), 1);
56078
+ var import_node_path50 = __toESM(require("path"), 1);
56148
56079
  init_src();
56149
56080
  function clawdHomeRoot(override) {
56150
- return override ?? process.env.CLAWD_HOME ?? import_node_path51.default.join(import_node_os18.default.homedir(), ".clawd");
56081
+ return override ?? process.env.CLAWD_HOME ?? import_node_path50.default.join(import_node_os18.default.homedir(), ".clawd");
56151
56082
  }
56152
56083
  function extensionsRoot(override) {
56153
- return import_node_path51.default.join(clawdHomeRoot(override), "extensions");
56084
+ return import_node_path50.default.join(clawdHomeRoot(override), "extensions");
56154
56085
  }
56155
56086
  function publishedChannelsFile(override) {
56156
- return import_node_path51.default.join(clawdHomeRoot(override), "extensions-published.json");
56087
+ return import_node_path50.default.join(clawdHomeRoot(override), "extensions-published.json");
56157
56088
  }
56158
56089
  function bundleCacheRoot(override) {
56159
- return import_node_path51.default.join(clawdHomeRoot(override), "extension-bundles");
56090
+ return import_node_path50.default.join(clawdHomeRoot(override), "extension-bundles");
56160
56091
  }
56161
56092
 
56162
56093
  // src/extension/install-flow.ts
@@ -56183,7 +56114,7 @@ async function installFromChannel(args, deps) {
56183
56114
  throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
56184
56115
  }
56185
56116
  for (const name of Object.keys(zip.files)) {
56186
- if (name.includes("..") || name.startsWith("/") || import_node_path52.default.isAbsolute(name)) {
56117
+ if (name.includes("..") || name.startsWith("/") || import_node_path51.default.isAbsolute(name)) {
56187
56118
  throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
56188
56119
  }
56189
56120
  }
@@ -56215,7 +56146,7 @@ async function installFromChannel(args, deps) {
56215
56146
  );
56216
56147
  }
56217
56148
  const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
56218
- const destDir = import_node_path52.default.join(deps.extensionsRoot, localExtId);
56149
+ const destDir = import_node_path51.default.join(deps.extensionsRoot, localExtId);
56219
56150
  let destExists = false;
56220
56151
  try {
56221
56152
  await import_promises6.default.access(destDir);
@@ -56229,16 +56160,16 @@ async function installFromChannel(args, deps) {
56229
56160
  );
56230
56161
  }
56231
56162
  const stage = await import_promises6.default.mkdtemp(
56232
- import_node_path52.default.join(import_node_os19.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
56163
+ import_node_path51.default.join(import_node_os19.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
56233
56164
  );
56234
56165
  try {
56235
56166
  for (const [name, entry] of Object.entries(zip.files)) {
56236
- const dest = import_node_path52.default.join(stage, name);
56167
+ const dest = import_node_path51.default.join(stage, name);
56237
56168
  if (entry.dir) {
56238
56169
  await import_promises6.default.mkdir(dest, { recursive: true });
56239
56170
  continue;
56240
56171
  }
56241
- await import_promises6.default.mkdir(import_node_path52.default.dirname(dest), { recursive: true });
56172
+ await import_promises6.default.mkdir(import_node_path51.default.dirname(dest), { recursive: true });
56242
56173
  if (name === "manifest.json") {
56243
56174
  const rewritten = { ...parsed.data, id: localExtId };
56244
56175
  await import_promises6.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -56259,7 +56190,7 @@ async function installFromChannel(args, deps) {
56259
56190
 
56260
56191
  // src/extension/update-flow.ts
56261
56192
  var import_promises7 = __toESM(require("fs/promises"), 1);
56262
- var import_node_path53 = __toESM(require("path"), 1);
56193
+ var import_node_path52 = __toESM(require("path"), 1);
56263
56194
  var import_node_os20 = __toESM(require("os"), 1);
56264
56195
  var import_node_crypto16 = __toESM(require("crypto"), 1);
56265
56196
  var import_jszip4 = __toESM(require_lib3(), 1);
@@ -56277,11 +56208,11 @@ async function updateFromChannel(args, deps) {
56277
56208
  channelRef.extId,
56278
56209
  channelRef.ownerPrincipalId
56279
56210
  );
56280
- const liveDir = import_node_path53.default.join(deps.extensionsRoot, localExtId);
56211
+ const liveDir = import_node_path52.default.join(deps.extensionsRoot, localExtId);
56281
56212
  const prevDir = `${liveDir}.prev`;
56282
56213
  let existingVersion;
56283
56214
  try {
56284
- const raw = await import_promises7.default.readFile(import_node_path53.default.join(liveDir, "manifest.json"), "utf8");
56215
+ const raw = await import_promises7.default.readFile(import_node_path52.default.join(liveDir, "manifest.json"), "utf8");
56285
56216
  const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
56286
56217
  if (!parsed2.success) {
56287
56218
  throw new UpdateError(
@@ -56314,7 +56245,7 @@ async function updateFromChannel(args, deps) {
56314
56245
  throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
56315
56246
  }
56316
56247
  for (const name of Object.keys(zip.files)) {
56317
- if (name.includes("..") || name.startsWith("/") || import_node_path53.default.isAbsolute(name)) {
56248
+ if (name.includes("..") || name.startsWith("/") || import_node_path52.default.isAbsolute(name)) {
56318
56249
  throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
56319
56250
  }
56320
56251
  }
@@ -56349,16 +56280,16 @@ async function updateFromChannel(args, deps) {
56349
56280
  await import_promises7.default.rm(prevDir, { recursive: true, force: true });
56350
56281
  await import_promises7.default.rename(liveDir, prevDir);
56351
56282
  const stage = await import_promises7.default.mkdtemp(
56352
- import_node_path53.default.join(import_node_os20.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
56283
+ import_node_path52.default.join(import_node_os20.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
56353
56284
  );
56354
56285
  try {
56355
56286
  for (const [name, entry] of Object.entries(zip.files)) {
56356
- const dest = import_node_path53.default.join(stage, name);
56287
+ const dest = import_node_path52.default.join(stage, name);
56357
56288
  if (entry.dir) {
56358
56289
  await import_promises7.default.mkdir(dest, { recursive: true });
56359
56290
  continue;
56360
56291
  }
56361
- await import_promises7.default.mkdir(import_node_path53.default.dirname(dest), { recursive: true });
56292
+ await import_promises7.default.mkdir(import_node_path52.default.dirname(dest), { recursive: true });
56362
56293
  if (name === "manifest.json") {
56363
56294
  const rewritten = { ...parsed.data, id: localExtId };
56364
56295
  await import_promises7.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -56452,7 +56383,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
56452
56383
  );
56453
56384
  }
56454
56385
  }
56455
- const manifestPath = import_node_path54.default.join(root, extId, "manifest.json");
56386
+ const manifestPath = import_node_path53.default.join(root, extId, "manifest.json");
56456
56387
  const manifest = await readManifest(root, extId);
56457
56388
  const next = { ...manifest, version: newVersion };
56458
56389
  const tmp = `${manifestPath}.tmp`;
@@ -56460,7 +56391,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
56460
56391
  await import_promises8.default.rename(tmp, manifestPath);
56461
56392
  }
56462
56393
  async function readManifest(root, extId) {
56463
- const file = import_node_path54.default.join(root, extId, "manifest.json");
56394
+ const file = import_node_path53.default.join(root, extId, "manifest.json");
56464
56395
  let raw;
56465
56396
  try {
56466
56397
  raw = await import_promises8.default.readFile(file, "utf8");
@@ -56551,7 +56482,7 @@ function buildExtensionHandlers(deps) {
56551
56482
  };
56552
56483
  async function buildSnapshotMeta(extId) {
56553
56484
  const manifest = await readManifest(deps.root, extId);
56554
- const { sha256, buffer } = await bundleExtensionDir(import_node_path54.default.join(deps.root, extId));
56485
+ const { sha256, buffer } = await bundleExtensionDir(import_node_path53.default.join(deps.root, extId));
56555
56486
  return { manifest, contentHash: sha256, buffer };
56556
56487
  }
56557
56488
  const publish = async (frame, _client, ctx) => {
@@ -56732,9 +56663,9 @@ function buildExtensionHandlers(deps) {
56732
56663
  }
56733
56664
 
56734
56665
  // src/app-builder/project-store.ts
56735
- var import_node_fs47 = require("fs");
56666
+ var import_node_fs46 = require("fs");
56736
56667
  var import_node_child_process14 = require("child_process");
56737
- var import_node_path55 = require("path");
56668
+ var import_node_path54 = require("path");
56738
56669
  init_protocol();
56739
56670
  var PROJECTS_DIR = "projects";
56740
56671
  var META_FILE = ".clawd-project.json";
@@ -56748,19 +56679,19 @@ var ProjectStore = class {
56748
56679
  root;
56749
56680
  /** projects/<name>/.clawd-project.json 路径 */
56750
56681
  metaPath(name) {
56751
- return (0, import_node_path55.join)(this.projectsRoot(), name, META_FILE);
56682
+ return (0, import_node_path54.join)(this.projectsRoot(), name, META_FILE);
56752
56683
  }
56753
56684
  /** projects/<name>/ 目录路径(cwd 用) */
56754
56685
  projectDir(name) {
56755
- return (0, import_node_path55.join)(this.projectsRoot(), name);
56686
+ return (0, import_node_path54.join)(this.projectsRoot(), name);
56756
56687
  }
56757
56688
  projectsRoot() {
56758
- return (0, import_node_path55.join)(this.root, PROJECTS_DIR);
56689
+ return (0, import_node_path54.join)(this.root, PROJECTS_DIR);
56759
56690
  }
56760
56691
  async list() {
56761
56692
  let entries;
56762
56693
  try {
56763
- entries = await import_node_fs47.promises.readdir(this.projectsRoot());
56694
+ entries = await import_node_fs46.promises.readdir(this.projectsRoot());
56764
56695
  } catch (err) {
56765
56696
  if (err.code === "ENOENT") return [];
56766
56697
  throw err;
@@ -56768,7 +56699,7 @@ var ProjectStore = class {
56768
56699
  const out = [];
56769
56700
  for (const name of entries) {
56770
56701
  try {
56771
- const raw = await import_node_fs47.promises.readFile(this.metaPath(name), "utf8");
56702
+ const raw = await import_node_fs46.promises.readFile(this.metaPath(name), "utf8");
56772
56703
  const json = JSON.parse(raw);
56773
56704
  let migrated = false;
56774
56705
  if (typeof json.devCommand !== "string" || json.devCommand.length === 0) {
@@ -56779,7 +56710,7 @@ var ProjectStore = class {
56779
56710
  if (parsed.success) {
56780
56711
  out.push(parsed.data);
56781
56712
  if (migrated) {
56782
- void import_node_fs47.promises.writeFile(this.metaPath(name), JSON.stringify(parsed.data, null, 2) + "\n", "utf8").catch(() => {
56713
+ void import_node_fs46.promises.writeFile(this.metaPath(name), JSON.stringify(parsed.data, null, 2) + "\n", "utf8").catch(() => {
56783
56714
  });
56784
56715
  }
56785
56716
  }
@@ -56823,8 +56754,8 @@ var ProjectStore = class {
56823
56754
  throw new Error(`invalid name "${name}": ${validated.error.message}`);
56824
56755
  }
56825
56756
  const dir = this.projectDir(name);
56826
- await import_node_fs47.promises.mkdir(dir, { recursive: true });
56827
- await import_node_fs47.promises.writeFile(this.metaPath(name), JSON.stringify(meta, null, 2) + "\n", "utf8");
56757
+ await import_node_fs46.promises.mkdir(dir, { recursive: true });
56758
+ await import_node_fs46.promises.writeFile(this.metaPath(name), JSON.stringify(meta, null, 2) + "\n", "utf8");
56828
56759
  return meta;
56829
56760
  }
56830
56761
  /**
@@ -56867,7 +56798,7 @@ var ProjectStore = class {
56867
56798
  }
56868
56799
  async delete(name) {
56869
56800
  const dir = this.projectDir(name);
56870
- await import_node_fs47.promises.rm(dir, { recursive: true, force: true });
56801
+ await import_node_fs46.promises.rm(dir, { recursive: true, force: true });
56871
56802
  }
56872
56803
  async updatePort(name, newPort) {
56873
56804
  if (newPort < PROJECT_PORT_MIN || newPort > PROJECT_PORT_MAX) {
@@ -56883,7 +56814,7 @@ var ProjectStore = class {
56883
56814
  throw new Error(`port ${newPort} already used / \u5DF2\u88AB project "${conflict.name}" \u5360\u7528`);
56884
56815
  }
56885
56816
  const updated = { ...target, port: newPort };
56886
- await import_node_fs47.promises.writeFile(this.metaPath(name), JSON.stringify(updated, null, 2) + "\n", "utf8");
56817
+ await import_node_fs46.promises.writeFile(this.metaPath(name), JSON.stringify(updated, null, 2) + "\n", "utf8");
56887
56818
  return updated;
56888
56819
  }
56889
56820
  /**
@@ -56900,7 +56831,7 @@ var ProjectStore = class {
56900
56831
  if (!validated.success) {
56901
56832
  throw new Error(`invalid prodUrl "${url}": ${validated.error.message}`);
56902
56833
  }
56903
- await import_node_fs47.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
56834
+ await import_node_fs46.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
56904
56835
  return validated.data;
56905
56836
  }
56906
56837
  /**
@@ -56921,7 +56852,7 @@ var ProjectStore = class {
56921
56852
  if (!validated.success) {
56922
56853
  throw new Error(`invalid publishJob: ${validated.error.message}`);
56923
56854
  }
56924
- await import_node_fs47.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
56855
+ await import_node_fs46.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
56925
56856
  return validated.data;
56926
56857
  }
56927
56858
  /** 清掉 .clawd-project.json.publishJob 字段。其他字段保持原样。 */
@@ -56936,7 +56867,7 @@ var ProjectStore = class {
56936
56867
  if (!validated.success) {
56937
56868
  throw new Error(`failed to clear publishJob: ${validated.error.message}`);
56938
56869
  }
56939
- await import_node_fs47.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
56870
+ await import_node_fs46.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
56940
56871
  return validated.data;
56941
56872
  }
56942
56873
  };
@@ -57057,8 +56988,8 @@ var PublishJobRegistry = class {
57057
56988
 
57058
56989
  // src/app-builder/publish-job-runner.ts
57059
56990
  var import_node_child_process16 = require("child_process");
57060
- var import_node_fs48 = require("fs");
57061
- var import_node_path56 = require("path");
56991
+ var import_node_fs47 = require("fs");
56992
+ var import_node_path55 = require("path");
57062
56993
 
57063
56994
  // src/app-builder/publish-stage-parser.ts
57064
56995
  var STAGE_RE = /^\s*::stage::(build|deploy|verify)\s*$/;
@@ -57090,10 +57021,10 @@ async function startPublishJob(deps, args) {
57090
57021
  return { jobId: registry2.get(args.name).jobId, status: "already-publishing" };
57091
57022
  }
57092
57023
  const projDir = projectDir(args.name);
57093
- const logPath = (0, import_node_path56.join)(projDir, ".publish.log");
57024
+ const logPath = (0, import_node_path55.join)(projDir, ".publish.log");
57094
57025
  let logStream = null;
57095
57026
  try {
57096
- logStream = (0, import_node_fs48.createWriteStream)(logPath, { flags: "w" });
57027
+ logStream = (0, import_node_fs47.createWriteStream)(logPath, { flags: "w" });
57097
57028
  } catch {
57098
57029
  logStream = null;
57099
57030
  }
@@ -57350,8 +57281,8 @@ async function recoverInterruptedJobs(deps) {
57350
57281
 
57351
57282
  // src/handlers/app-builder.ts
57352
57283
  init_protocol();
57353
- var import_node_path57 = require("path");
57354
- var import_node_fs49 = require("fs");
57284
+ var import_node_path56 = require("path");
57285
+ var import_node_fs48 = require("fs");
57355
57286
  var APP_BUILDER_PERSONAS = ["persona-app-builder", "persona-dataclaw-builder"];
57356
57287
  var DEV_SERVER_READY_TIMEOUT_MS = 3e4;
57357
57288
  async function recoverInterruptedPublishJobs(store, logger) {
@@ -57432,7 +57363,7 @@ function buildAppBuilderHandlers(deps) {
57432
57363
  async function listAllUsersProjects() {
57433
57364
  if (!deps.usersRoot || !deps.getStore) return [];
57434
57365
  const getStore = deps.getStore;
57435
- const userIds = await import_node_fs49.promises.readdir(deps.usersRoot).catch(() => []);
57366
+ const userIds = await import_node_fs48.promises.readdir(deps.usersRoot).catch(() => []);
57436
57367
  const perUser = await Promise.all(
57437
57368
  userIds.map((uid) => getStore(uid).list().catch(() => []))
57438
57369
  );
@@ -57508,8 +57439,8 @@ function buildAppBuilderHandlers(deps) {
57508
57439
  const project = await userStore.create(f.name, reservedPorts);
57509
57440
  try {
57510
57441
  const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(session.ownerPersonaId ?? "") : deps.personaRoot;
57511
- const templateSrcDir = (0, import_node_path57.join)(personaRoot, "extension-kit", "examples", DEFAULT_TEMPLATE);
57512
- const scaffoldScript = (0, import_node_path57.join)(deps.deployKitRoot, "scripts", "new-extension.sh");
57442
+ const templateSrcDir = (0, import_node_path56.join)(personaRoot, "extension-kit", "examples", DEFAULT_TEMPLATE);
57443
+ const scaffoldScript = (0, import_node_path56.join)(deps.deployKitRoot, "scripts", "new-extension.sh");
57513
57444
  const scaffoldResult = await userStore.scaffold(project.name, templateSrcDir, scaffoldScript);
57514
57445
  deps.logger?.info("app-builder.scaffold.done", {
57515
57446
  name: project.name,
@@ -57730,7 +57661,7 @@ function buildAppBuilderHandlers(deps) {
57730
57661
  await userStore.clearPublishJob(args.name);
57731
57662
  }
57732
57663
  const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(boundSession.ownerPersonaId ?? "") : deps.personaRoot;
57733
- const scriptPath = (0, import_node_path57.join)(deps.deployKitRoot, "scripts", "publish.sh");
57664
+ const scriptPath = (0, import_node_path56.join)(deps.deployKitRoot, "scripts", "publish.sh");
57734
57665
  deps.logger?.info("app-builder.publish.start", {
57735
57666
  name: args.name,
57736
57667
  sessionId: boundSession.sessionId,
@@ -57899,7 +57830,7 @@ function buildVisitorHandlers(deps) {
57899
57830
 
57900
57831
  // src/extension/registry.ts
57901
57832
  var import_promises9 = __toESM(require("fs/promises"), 1);
57902
- var import_node_path58 = __toESM(require("path"), 1);
57833
+ var import_node_path57 = __toESM(require("path"), 1);
57903
57834
  init_src();
57904
57835
  async function loadAll(root) {
57905
57836
  let entries;
@@ -57913,13 +57844,13 @@ async function loadAll(root) {
57913
57844
  for (const ent of entries) {
57914
57845
  if (!ent.isDirectory()) continue;
57915
57846
  if (ent.name.startsWith(".")) continue;
57916
- records.push(await loadOne(import_node_path58.default.join(root, ent.name), ent.name));
57847
+ records.push(await loadOne(import_node_path57.default.join(root, ent.name), ent.name));
57917
57848
  }
57918
57849
  records.sort((a, b2) => a.extId < b2.extId ? -1 : a.extId > b2.extId ? 1 : 0);
57919
57850
  return records;
57920
57851
  }
57921
57852
  async function loadOne(dir, dirName) {
57922
- const manifestPath = import_node_path58.default.join(dir, "manifest.json");
57853
+ const manifestPath = import_node_path57.default.join(dir, "manifest.json");
57923
57854
  let raw;
57924
57855
  try {
57925
57856
  raw = await import_promises9.default.readFile(manifestPath, "utf8");
@@ -57964,7 +57895,7 @@ async function loadOne(dir, dirName) {
57964
57895
 
57965
57896
  // src/extension/uninstall.ts
57966
57897
  var import_promises10 = __toESM(require("fs/promises"), 1);
57967
- var import_node_path59 = __toESM(require("path"), 1);
57898
+ var import_node_path58 = __toESM(require("path"), 1);
57968
57899
  var UninstallError = class extends Error {
57969
57900
  constructor(code, message) {
57970
57901
  super(message);
@@ -57973,7 +57904,7 @@ var UninstallError = class extends Error {
57973
57904
  code;
57974
57905
  };
57975
57906
  async function uninstall(deps) {
57976
- const dir = import_node_path59.default.join(deps.root, deps.extId);
57907
+ const dir = import_node_path58.default.join(deps.root, deps.extId);
57977
57908
  try {
57978
57909
  await import_promises10.default.access(dir);
57979
57910
  } catch {
@@ -58557,7 +58488,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
58557
58488
 
58558
58489
  // src/extension/runtime.ts
58559
58490
  var import_node_child_process18 = require("child_process");
58560
- var import_node_path60 = __toESM(require("path"), 1);
58491
+ var import_node_path59 = __toESM(require("path"), 1);
58561
58492
  var import_promises11 = require("timers/promises");
58562
58493
  init_src();
58563
58494
 
@@ -58659,7 +58590,7 @@ var Runtime = class {
58659
58590
  /\$CLAWOS_EXT_PORT/g,
58660
58591
  String(port)
58661
58592
  );
58662
- const dir = import_node_path60.default.join(this.root, extId);
58593
+ const dir = import_node_path59.default.join(this.root, extId);
58663
58594
  const env = {
58664
58595
  ...process.env,
58665
58596
  CLAWOS_EXT_PORT: String(port),
@@ -58771,7 +58702,7 @@ ${handle.stderrTail}`
58771
58702
 
58772
58703
  // src/extension/published-channels.ts
58773
58704
  var import_promises12 = __toESM(require("fs/promises"), 1);
58774
- var import_node_path61 = __toESM(require("path"), 1);
58705
+ var import_node_path60 = __toESM(require("path"), 1);
58775
58706
  init_src();
58776
58707
  init_zod();
58777
58708
  var PublishedChannelsError = class extends Error {
@@ -58871,7 +58802,7 @@ var PublishedChannelStore = class {
58871
58802
  )
58872
58803
  };
58873
58804
  const tmp = `${this.filePath}.tmp`;
58874
- await import_promises12.default.mkdir(import_node_path61.default.dirname(this.filePath), { recursive: true });
58805
+ await import_promises12.default.mkdir(import_node_path60.default.dirname(this.filePath), { recursive: true });
58875
58806
  await import_promises12.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
58876
58807
  await import_promises12.default.rename(tmp, this.filePath);
58877
58808
  }
@@ -58879,7 +58810,7 @@ var PublishedChannelStore = class {
58879
58810
 
58880
58811
  // src/extension/bundle-cache.ts
58881
58812
  var import_promises13 = __toESM(require("fs/promises"), 1);
58882
- var import_node_path62 = __toESM(require("path"), 1);
58813
+ var import_node_path61 = __toESM(require("path"), 1);
58883
58814
  var BundleCache = class {
58884
58815
  constructor(rootDir) {
58885
58816
  this.rootDir = rootDir;
@@ -58888,14 +58819,14 @@ var BundleCache = class {
58888
58819
  /** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
58889
58820
  async write(snapshotHash, buffer) {
58890
58821
  await import_promises13.default.mkdir(this.rootDir, { recursive: true });
58891
- const file = import_node_path62.default.join(this.rootDir, `${snapshotHash}.zip`);
58822
+ const file = import_node_path61.default.join(this.rootDir, `${snapshotHash}.zip`);
58892
58823
  const tmp = `${file}.tmp`;
58893
58824
  await import_promises13.default.writeFile(tmp, buffer, { mode: 384 });
58894
58825
  await import_promises13.default.rename(tmp, file);
58895
58826
  }
58896
58827
  /** Returns the bundle bytes, or null when the file doesn't exist. */
58897
58828
  async read(snapshotHash) {
58898
- const file = import_node_path62.default.join(this.rootDir, `${snapshotHash}.zip`);
58829
+ const file = import_node_path61.default.join(this.rootDir, `${snapshotHash}.zip`);
58899
58830
  try {
58900
58831
  return await import_promises13.default.readFile(file);
58901
58832
  } catch (e) {
@@ -58905,7 +58836,7 @@ var BundleCache = class {
58905
58836
  }
58906
58837
  /** Idempotent — missing file is not an error. */
58907
58838
  async delete(snapshotHash) {
58908
- const file = import_node_path62.default.join(this.rootDir, `${snapshotHash}.zip`);
58839
+ const file = import_node_path61.default.join(this.rootDir, `${snapshotHash}.zip`);
58909
58840
  await import_promises13.default.rm(file, { force: true });
58910
58841
  }
58911
58842
  };
@@ -58930,16 +58861,16 @@ async function startDaemon(config) {
58930
58861
  });
58931
58862
  const logger = createLogger({
58932
58863
  level: config.logLevel,
58933
- file: import_node_path63.default.join(config.dataDir, "clawd.log"),
58864
+ file: import_node_path62.default.join(config.dataDir, "clawd.log"),
58934
58865
  logClient
58935
58866
  });
58936
58867
  logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
58937
58868
  const screenIdleProbeLogger = createFileOnlyLogger({
58938
- file: import_node_path63.default.join(config.dataDir, "screen-idle-probe.log"),
58869
+ file: import_node_path62.default.join(config.dataDir, "screen-idle-probe.log"),
58939
58870
  level: "debug"
58940
58871
  });
58941
58872
  logger.info("screen-idle probe logger enabled", {
58942
- file: import_node_path63.default.join(config.dataDir, "screen-idle-probe.log")
58873
+ file: import_node_path62.default.join(config.dataDir, "screen-idle-probe.log")
58943
58874
  });
58944
58875
  const stateMgr = new StateFileManager({ dataDir: config.dataDir });
58945
58876
  const pre = stateMgr.preflight();
@@ -59077,8 +59008,8 @@ async function startDaemon(config) {
59077
59008
  const agents = new AgentsScanner();
59078
59009
  const history = new ClaudeHistoryReader();
59079
59010
  let transport = null;
59080
- const personaStore = new PersonaStore(import_node_path63.default.join(config.dataDir, "personas"));
59081
- const usersRoot = import_node_path63.default.join(config.dataDir, "users");
59011
+ const personaStore = new PersonaStore(import_node_path62.default.join(config.dataDir, "personas"));
59012
+ const usersRoot = import_node_path62.default.join(config.dataDir, "users");
59082
59013
  const defaultsRoot = findDefaultsRoot(logger);
59083
59014
  if (defaultsRoot) {
59084
59015
  seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
@@ -59098,17 +59029,17 @@ async function startDaemon(config) {
59098
59029
  migrateCodexSandbox({ store: personaStore, logger });
59099
59030
  const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
59100
59031
  const personaDispatchManager = new PersonaDispatchManager({ genId: () => v4_default() });
59101
- const here = typeof __dirname === "string" ? __dirname : import_node_path63.default.dirname((0, import_node_url4.fileURLToPath)(import_meta6.url));
59032
+ const here = typeof __dirname === "string" ? __dirname : import_node_path62.default.dirname((0, import_node_url4.fileURLToPath)(import_meta6.url));
59102
59033
  const dispatchServerCandidates = [
59103
- import_node_path63.default.join(here, "dispatch", "mcp-server.cjs"),
59034
+ import_node_path62.default.join(here, "dispatch", "mcp-server.cjs"),
59104
59035
  // 生产 dist/index → dist/dispatch/mcp-server.cjs
59105
- import_node_path63.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
59036
+ import_node_path62.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
59106
59037
  // dev tsx src/index → ../dist/dispatch/mcp-server.cjs
59107
59038
  ];
59108
- const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs50.default.existsSync(p2));
59039
+ const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs49.default.existsSync(p2));
59109
59040
  let dispatchMcpConfigPath2;
59110
59041
  if (dispatchServerScriptPath) {
59111
- const dispatchLogPath = import_node_path63.default.join(config.dataDir, "dispatch-mcp-server.log");
59042
+ const dispatchLogPath = import_node_path62.default.join(config.dataDir, "dispatch-mcp-server.log");
59112
59043
  dispatchMcpConfigPath2 = writeDispatchMcpConfig({
59113
59044
  dataDir: config.dataDir,
59114
59045
  serverScriptPath: dispatchServerScriptPath,
@@ -59125,15 +59056,15 @@ async function startDaemon(config) {
59125
59056
  });
59126
59057
  }
59127
59058
  const ticketServerCandidates = [
59128
- import_node_path63.default.join(here, "ticket", "mcp-server.cjs"),
59129
- import_node_path63.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
59059
+ import_node_path62.default.join(here, "ticket", "mcp-server.cjs"),
59060
+ import_node_path62.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
59130
59061
  ];
59131
- const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs50.default.existsSync(p2));
59062
+ const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs49.default.existsSync(p2));
59132
59063
  const ticketOwnerUnionId = feishuIdentity?.identity.unionId ?? "";
59133
59064
  const ticketOwnerName = feishuIdentity?.identity.displayName ?? "";
59134
59065
  let ticketMcpConfigPath2;
59135
59066
  if (ticketServerScriptPath && ticketOwnerUnionId) {
59136
- const ticketLogPath = import_node_path63.default.join(config.dataDir, "ticket-mcp-server.log");
59067
+ const ticketLogPath = import_node_path62.default.join(config.dataDir, "ticket-mcp-server.log");
59137
59068
  ticketMcpConfigPath2 = writeTicketMcpConfig({
59138
59069
  dataDir: config.dataDir,
59139
59070
  serverScriptPath: ticketServerScriptPath,
@@ -59154,13 +59085,13 @@ async function startDaemon(config) {
59154
59085
  });
59155
59086
  }
59156
59087
  const shiftServerCandidates = [
59157
- import_node_path63.default.join(here, "shift", "mcp-server.cjs"),
59158
- import_node_path63.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
59088
+ import_node_path62.default.join(here, "shift", "mcp-server.cjs"),
59089
+ import_node_path62.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
59159
59090
  ];
59160
- const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs50.default.existsSync(p2));
59091
+ const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs49.default.existsSync(p2));
59161
59092
  let shiftMcpConfigPath2;
59162
59093
  if (shiftServerScriptPath) {
59163
- const shiftLogPath = import_node_path63.default.join(config.dataDir, "shift-mcp-server.log");
59094
+ const shiftLogPath = import_node_path62.default.join(config.dataDir, "shift-mcp-server.log");
59164
59095
  shiftMcpConfigPath2 = await writeShiftMcpConfig({
59165
59096
  dataDir: config.dataDir,
59166
59097
  serverScriptPath: shiftServerScriptPath,
@@ -59178,13 +59109,13 @@ async function startDaemon(config) {
59178
59109
  );
59179
59110
  }
59180
59111
  const inboxServerCandidates = [
59181
- import_node_path63.default.join(here, "inbox", "mcp-server.cjs"),
59182
- import_node_path63.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
59112
+ import_node_path62.default.join(here, "inbox", "mcp-server.cjs"),
59113
+ import_node_path62.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
59183
59114
  ];
59184
- const inboxServerScriptPath = inboxServerCandidates.find((p2) => import_node_fs50.default.existsSync(p2));
59115
+ const inboxServerScriptPath = inboxServerCandidates.find((p2) => import_node_fs49.default.existsSync(p2));
59185
59116
  let inboxMcpConfigPath2;
59186
59117
  if (inboxServerScriptPath) {
59187
- const inboxLogPath = import_node_path63.default.join(config.dataDir, "inbox-mcp-server.log");
59118
+ const inboxLogPath = import_node_path62.default.join(config.dataDir, "inbox-mcp-server.log");
59188
59119
  inboxMcpConfigPath2 = await writeInboxMcpConfig({
59189
59120
  dataDir: config.dataDir,
59190
59121
  serverScriptPath: inboxServerScriptPath,
@@ -59202,7 +59133,7 @@ async function startDaemon(config) {
59202
59133
  );
59203
59134
  }
59204
59135
  const shiftStore = createShiftStore({
59205
- filePath: import_node_path63.default.join(config.dataDir, "shift.json"),
59136
+ filePath: import_node_path62.default.join(config.dataDir, "shift.json"),
59206
59137
  ownerIdProvider: () => ownerPrincipalId,
59207
59138
  now: () => Date.now()
59208
59139
  });
@@ -59224,7 +59155,7 @@ async function startDaemon(config) {
59224
59155
  getAdapter,
59225
59156
  historyReader: history,
59226
59157
  dataDir: config.dataDir,
59227
- personaRoot: import_node_path63.default.join(config.dataDir, "personas"),
59158
+ personaRoot: import_node_path62.default.join(config.dataDir, "personas"),
59228
59159
  usersRoot,
59229
59160
  personaStore,
59230
59161
  ownerDisplayName,
@@ -59267,10 +59198,10 @@ async function startDaemon(config) {
59267
59198
  // 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
59268
59199
  attachmentGroup: {
59269
59200
  onFileEdit: (input) => {
59270
- const absPath = import_node_path63.default.isAbsolute(input.relPath) ? input.relPath : import_node_path63.default.join(input.cwd, input.relPath);
59201
+ const absPath = import_node_path62.default.isAbsolute(input.relPath) ? input.relPath : import_node_path62.default.join(input.cwd, input.relPath);
59271
59202
  let size = 0;
59272
59203
  try {
59273
- size = import_node_fs50.default.statSync(absPath).size;
59204
+ size = import_node_fs49.default.statSync(absPath).size;
59274
59205
  } catch (err) {
59275
59206
  logger.warn("attachment.onFileEdit stat failed", {
59276
59207
  sessionId: input.sessionId,
@@ -59469,11 +59400,11 @@ async function startDaemon(config) {
59469
59400
  // 'persona/<pid>/owner',default 走 'default'。
59470
59401
  getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
59471
59402
  // guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
59472
- personaRoot: import_node_path63.default.join(config.dataDir, "personas"),
59403
+ personaRoot: import_node_path62.default.join(config.dataDir, "personas"),
59473
59404
  usersRoot
59474
59405
  },
59475
59406
  // workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
59476
- personaRoot: import_node_path63.default.join(config.dataDir, "personas"),
59407
+ personaRoot: import_node_path62.default.join(config.dataDir, "personas"),
59477
59408
  // v2 多人 persona 隔离:handler 派生 guest user-dir 放行
59478
59409
  usersRoot,
59479
59410
  // capability:list / delete handler 依赖
@@ -59495,7 +59426,7 @@ async function startDaemon(config) {
59495
59426
  contactStore,
59496
59427
  // <dataDir>/sshd 绝对路径 —— contact-ssh handlers 用它拼 authorized_keys / keys/ 子路径
59497
59428
  // Task 10 会加 SshdManager 起 sshd;handlers wire 提前挂 sshdDir 让 typecheck 过
59498
- sshdDir: import_node_path63.default.join(config.dataDir, "sshd"),
59429
+ sshdDir: import_node_path62.default.join(config.dataDir, "sshd"),
59499
59430
  contactSshLog: sshLog,
59500
59431
  // inbox:sendDm 用:sessionId → session 出身(复用 attachment 同款 findOwnedSessionScope)
59501
59432
  getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
@@ -59586,11 +59517,11 @@ async function startDaemon(config) {
59586
59517
  // 发布上线脚手架化 (spec 2026-06-03 §5.2):
59587
59518
  // appBuilderPersonaRoot 用于拼 publish.sh 绝对路径(persona-app-builder 安装在
59588
59519
  // dataDir/personas/persona-app-builder 之下,extension-kit/scripts/publish.sh 是相对路径)。
59589
- appBuilderPersonaRoot: import_node_path63.default.join(config.dataDir, "personas", "persona-app-builder"),
59520
+ appBuilderPersonaRoot: import_node_path62.default.join(config.dataDir, "personas", "persona-app-builder"),
59590
59521
  // 共享 deploy-kit 根:scaffold/publish 脚本骨架 + 阿里云凭证单一真源。
59591
- deployKitRoot: import_node_path63.default.join(config.dataDir, "deploy-kit"),
59522
+ deployKitRoot: import_node_path62.default.join(config.dataDir, "deploy-kit"),
59592
59523
  // scaffold/publish 按当前 session 的 persona 解析其安装根,让每个 persona 用自己的模板/注入配置。
59593
- resolvePersonaRoot: (personaId) => import_node_path63.default.join(config.dataDir, "personas", personaId),
59524
+ resolvePersonaRoot: (personaId) => import_node_path62.default.join(config.dataDir, "personas", personaId),
59594
59525
  // 发布上线脚手架化 (spec 2026-06-03 §5.2.2):
59595
59526
  // 复用 SessionManagerDeps.broadcastFrame 同款 dispatch 逻辑 —— runner 调 manager.send
59596
59527
  // 取回 broadcast 帧后逐帧 push 到 transport,跟 manager 自身的 deps 一致。
@@ -59633,7 +59564,7 @@ async function startDaemon(config) {
59633
59564
  }
59634
59565
  let sourceJsonlPath = "(no transcript yet \u2014 operate from the task description alone)";
59635
59566
  if (sourceFile && sourceFile.toolSessionId) {
59636
- sourceJsonlPath = import_node_path63.default.join(
59567
+ sourceJsonlPath = import_node_path62.default.join(
59637
59568
  import_node_os21.default.homedir(),
59638
59569
  ".claude",
59639
59570
  "projects",
@@ -59963,8 +59894,8 @@ async function startDaemon(config) {
59963
59894
  const lines = [
59964
59895
  `Tunnel: ${r.url}`,
59965
59896
  ...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
59966
- `Frpc config: ${import_node_path63.default.join(config.dataDir, "frpc.toml")}`,
59967
- `Frpc log: ${import_node_path63.default.join(config.dataDir, "frpc.log")}`
59897
+ `Frpc config: ${import_node_path62.default.join(config.dataDir, "frpc.toml")}`,
59898
+ `Frpc log: ${import_node_path62.default.join(config.dataDir, "frpc.log")}`
59968
59899
  ];
59969
59900
  const width = Math.max(...lines.map((l) => l.length));
59970
59901
  const bar = "\u2550".repeat(width + 4);
@@ -59977,8 +59908,8 @@ ${bar}
59977
59908
 
59978
59909
  `);
59979
59910
  try {
59980
- const connectPath = import_node_path63.default.join(config.dataDir, "connect.txt");
59981
- import_node_fs50.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
59911
+ const connectPath = import_node_path62.default.join(config.dataDir, "connect.txt");
59912
+ import_node_fs49.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
59982
59913
  } catch {
59983
59914
  }
59984
59915
  } catch (err) {
@@ -60012,7 +59943,7 @@ ${bar}
60012
59943
  });
60013
59944
  try {
60014
59945
  await sshdMgr.start();
60015
- rebuildAuthorizedKeys(contactStore, import_node_path63.default.join(config.dataDir, "sshd"));
59946
+ rebuildAuthorizedKeys(contactStore, import_node_path62.default.join(config.dataDir, "sshd"));
60016
59947
  logger.info("sshd: contact-ssh sandbox ready", { port: config.sshdPort });
60017
59948
  } catch (err) {
60018
59949
  logger.warn("sshd start failed; contact SSH grant will not work until fixed", {
@@ -60080,9 +60011,9 @@ ${bar}
60080
60011
  };
60081
60012
  }
60082
60013
  function migrateDropPersonsDir(dataDir) {
60083
- const dir = import_node_path63.default.join(dataDir, "persons");
60014
+ const dir = import_node_path62.default.join(dataDir, "persons");
60084
60015
  try {
60085
- import_node_fs50.default.rmSync(dir, { recursive: true, force: true });
60016
+ import_node_fs49.default.rmSync(dir, { recursive: true, force: true });
60086
60017
  } catch {
60087
60018
  }
60088
60019
  }