@clawos-dev/clawd 0.2.546 → 0.2.548

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 (33) hide show
  1. package/dist/app-builder-plugin/mcp-server.cjs +35 -35
  2. package/dist/cli.cjs +518 -663
  3. package/dist/persona-defaults/persona-app-builder/.mcp.json +17 -2
  4. package/dist/persona-defaults/persona-app-builder/CLAUDE.md +8 -9
  5. package/dist/persona-defaults/persona-app-builder/extension-kit/README.md +6 -7
  6. package/dist/persona-defaults/persona-app-builder/extension-kit/contract/s.yaml.tmpl +3 -2
  7. package/dist/persona-defaults/persona-app-builder/mcp/clawd-app-builder/deploy-kit/scripts/ensure-credentials.sh +96 -0
  8. package/dist/{deploy-kit → persona-defaults/persona-app-builder/mcp/clawd-app-builder/deploy-kit}/scripts/publish.sh +3 -3
  9. package/dist/{deploy-kit → persona-defaults/persona-app-builder/mcp/clawd-app-builder/deploy-kit}/scripts/remove-extension.sh +2 -2
  10. package/dist/persona-defaults/persona-app-builder/mcp/clawd-app-builder/mcp-server.cjs +25397 -0
  11. package/dist/persona-defaults/persona-dataclaw-builder/.mcp.json +14 -1
  12. package/dist/persona-defaults/persona-dataclaw-builder/CLAUDE.md +1 -1
  13. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/README.md +6 -7
  14. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/config.env +1 -1
  15. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/contract/s.yaml.tmpl +3 -2
  16. package/dist/persona-defaults/persona-dataclaw-builder/mcp/clawd-app-builder/deploy-kit/contract/bootstrap +22 -0
  17. package/dist/persona-defaults/persona-dataclaw-builder/mcp/clawd-app-builder/deploy-kit/scripts/ensure-credentials.sh +96 -0
  18. package/dist/persona-defaults/persona-dataclaw-builder/mcp/clawd-app-builder/deploy-kit/scripts/ensure-toolchain.sh +65 -0
  19. package/dist/persona-defaults/persona-dataclaw-builder/mcp/clawd-app-builder/deploy-kit/scripts/new-extension.sh +71 -0
  20. package/dist/persona-defaults/persona-dataclaw-builder/mcp/clawd-app-builder/deploy-kit/scripts/publish.sh +205 -0
  21. package/dist/persona-defaults/persona-dataclaw-builder/mcp/clawd-app-builder/deploy-kit/scripts/remove-extension.sh +89 -0
  22. package/dist/persona-defaults/persona-dataclaw-builder/mcp/clawd-app-builder/deploy-kit/scripts/verify.sh +49 -0
  23. package/dist/persona-defaults/persona-dataclaw-builder/mcp/clawd-app-builder/mcp-server.cjs +25397 -0
  24. package/package.json +1 -1
  25. package/dist/deploy-kit/.secrets/aliyun.env.example +0 -7
  26. package/dist/deploy-kit/.secrets/aliyun.env.local.example +0 -12
  27. package/dist/deploy-kit/scripts/ensure-credentials.sh +0 -111
  28. package/dist/deploy-kit/scripts/ensure-credentials.spec.ts +0 -438
  29. package/dist/deploy-kit/scripts/publish.spec.ts +0 -278
  30. /package/dist/{deploy-kit → persona-defaults/persona-app-builder/mcp/clawd-app-builder/deploy-kit}/contract/bootstrap +0 -0
  31. /package/dist/{deploy-kit → persona-defaults/persona-app-builder/mcp/clawd-app-builder/deploy-kit}/scripts/ensure-toolchain.sh +0 -0
  32. /package/dist/{deploy-kit → persona-defaults/persona-app-builder/mcp/clawd-app-builder/deploy-kit}/scripts/new-extension.sh +0 -0
  33. /package/dist/{deploy-kit → persona-defaults/persona-app-builder/mcp/clawd-app-builder/deploy-kit}/scripts/verify.sh +0 -0
package/dist/cli.cjs CHANGED
@@ -450,8 +450,8 @@ var init_parseUtil = __esm({
450
450
  init_errors();
451
451
  init_en();
452
452
  makeIssue = (params) => {
453
- const { data, path: path102, errorMaps, issueData } = params;
454
- const fullPath = [...path102, ...issueData.path || []];
453
+ const { data, path: path100, errorMaps, issueData } = params;
454
+ const fullPath = [...path100, ...issueData.path || []];
455
455
  const fullIssue = {
456
456
  ...issueData,
457
457
  path: fullPath
@@ -762,11 +762,11 @@ var init_types = __esm({
762
762
  init_parseUtil();
763
763
  init_util();
764
764
  ParseInputLazyPath = class {
765
- constructor(parent, value, path102, key) {
765
+ constructor(parent, value, path100, key) {
766
766
  this._cachedPath = [];
767
767
  this.parent = parent;
768
768
  this.data = value;
769
- this._path = path102;
769
+ this._path = path100;
770
770
  this._key = key;
771
771
  }
772
772
  get path() {
@@ -10033,8 +10033,8 @@ var require_req = __commonJS({
10033
10033
  if (req.originalUrl) {
10034
10034
  _req.url = req.originalUrl;
10035
10035
  } else {
10036
- const path102 = req.path;
10037
- _req.url = typeof path102 === "string" ? path102 : req.url ? req.url.path || req.url : void 0;
10036
+ const path100 = req.path;
10037
+ _req.url = typeof path100 === "string" ? path100 : req.url ? req.url.path || req.url : void 0;
10038
10038
  }
10039
10039
  if (req.query) {
10040
10040
  _req.query = req.query;
@@ -10199,14 +10199,14 @@ var require_redact = __commonJS({
10199
10199
  }
10200
10200
  return obj;
10201
10201
  }
10202
- function parsePath(path102) {
10202
+ function parsePath(path100) {
10203
10203
  const parts = [];
10204
10204
  let current = "";
10205
10205
  let inBrackets = false;
10206
10206
  let inQuotes = false;
10207
10207
  let quoteChar = "";
10208
- for (let i2 = 0; i2 < path102.length; i2++) {
10209
- const char = path102[i2];
10208
+ for (let i2 = 0; i2 < path100.length; i2++) {
10209
+ const char = path100[i2];
10210
10210
  if (!inBrackets && char === ".") {
10211
10211
  if (current) {
10212
10212
  parts.push(current);
@@ -10337,10 +10337,10 @@ var require_redact = __commonJS({
10337
10337
  return current;
10338
10338
  }
10339
10339
  function redactPaths(obj, paths, censor, remove = false) {
10340
- for (const path102 of paths) {
10341
- const parts = parsePath(path102);
10340
+ for (const path100 of paths) {
10341
+ const parts = parsePath(path100);
10342
10342
  if (parts.includes("*")) {
10343
- redactWildcardPath(obj, parts, censor, path102, remove);
10343
+ redactWildcardPath(obj, parts, censor, path100, remove);
10344
10344
  } else {
10345
10345
  if (remove) {
10346
10346
  removeKey(obj, parts);
@@ -10425,8 +10425,8 @@ var require_redact = __commonJS({
10425
10425
  }
10426
10426
  } else {
10427
10427
  if (afterWildcard.includes("*")) {
10428
- const wrappedCensor = typeof censor === "function" ? (value, path102) => {
10429
- const fullPath = [...pathArray.slice(0, pathLength), ...path102];
10428
+ const wrappedCensor = typeof censor === "function" ? (value, path100) => {
10429
+ const fullPath = [...pathArray.slice(0, pathLength), ...path100];
10430
10430
  return censor(value, fullPath);
10431
10431
  } : censor;
10432
10432
  redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
@@ -10461,8 +10461,8 @@ var require_redact = __commonJS({
10461
10461
  return null;
10462
10462
  }
10463
10463
  const pathStructure = /* @__PURE__ */ new Map();
10464
- for (const path102 of pathsToClone) {
10465
- const parts = parsePath(path102);
10464
+ for (const path100 of pathsToClone) {
10465
+ const parts = parsePath(path100);
10466
10466
  let current = pathStructure;
10467
10467
  for (let i2 = 0; i2 < parts.length; i2++) {
10468
10468
  const part = parts[i2];
@@ -10514,24 +10514,24 @@ var require_redact = __commonJS({
10514
10514
  }
10515
10515
  return cloneSelectively(obj, pathStructure);
10516
10516
  }
10517
- function validatePath(path102) {
10518
- if (typeof path102 !== "string") {
10517
+ function validatePath(path100) {
10518
+ if (typeof path100 !== "string") {
10519
10519
  throw new Error("Paths must be (non-empty) strings");
10520
10520
  }
10521
- if (path102 === "") {
10521
+ if (path100 === "") {
10522
10522
  throw new Error("Invalid redaction path ()");
10523
10523
  }
10524
- if (path102.includes("..")) {
10525
- throw new Error(`Invalid redaction path (${path102})`);
10524
+ if (path100.includes("..")) {
10525
+ throw new Error(`Invalid redaction path (${path100})`);
10526
10526
  }
10527
- if (path102.includes(",")) {
10528
- throw new Error(`Invalid redaction path (${path102})`);
10527
+ if (path100.includes(",")) {
10528
+ throw new Error(`Invalid redaction path (${path100})`);
10529
10529
  }
10530
10530
  let bracketCount = 0;
10531
10531
  let inQuotes = false;
10532
10532
  let quoteChar = "";
10533
- for (let i2 = 0; i2 < path102.length; i2++) {
10534
- const char = path102[i2];
10533
+ for (let i2 = 0; i2 < path100.length; i2++) {
10534
+ const char = path100[i2];
10535
10535
  if ((char === '"' || char === "'") && bracketCount > 0) {
10536
10536
  if (!inQuotes) {
10537
10537
  inQuotes = true;
@@ -10545,20 +10545,20 @@ var require_redact = __commonJS({
10545
10545
  } else if (char === "]" && !inQuotes) {
10546
10546
  bracketCount--;
10547
10547
  if (bracketCount < 0) {
10548
- throw new Error(`Invalid redaction path (${path102})`);
10548
+ throw new Error(`Invalid redaction path (${path100})`);
10549
10549
  }
10550
10550
  }
10551
10551
  }
10552
10552
  if (bracketCount !== 0) {
10553
- throw new Error(`Invalid redaction path (${path102})`);
10553
+ throw new Error(`Invalid redaction path (${path100})`);
10554
10554
  }
10555
10555
  }
10556
10556
  function validatePaths(paths) {
10557
10557
  if (!Array.isArray(paths)) {
10558
10558
  throw new TypeError("paths must be an array");
10559
10559
  }
10560
- for (const path102 of paths) {
10561
- validatePath(path102);
10560
+ for (const path100 of paths) {
10561
+ validatePath(path100);
10562
10562
  }
10563
10563
  }
10564
10564
  function slowRedact(options = {}) {
@@ -10726,8 +10726,8 @@ var require_redaction = __commonJS({
10726
10726
  if (shape[k3] === null) {
10727
10727
  o2[k3] = (value) => topCensor(value, [k3]);
10728
10728
  } else {
10729
- const wrappedCensor = typeof censor === "function" ? (value, path102) => {
10730
- return censor(value, [k3, ...path102]);
10729
+ const wrappedCensor = typeof censor === "function" ? (value, path100) => {
10730
+ return censor(value, [k3, ...path100]);
10731
10731
  } : censor;
10732
10732
  o2[k3] = Redact({
10733
10733
  paths: shape[k3],
@@ -10945,10 +10945,10 @@ var require_atomic_sleep = __commonJS({
10945
10945
  var require_sonic_boom = __commonJS({
10946
10946
  "../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
10947
10947
  "use strict";
10948
- var fs91 = require("fs");
10948
+ var fs90 = require("fs");
10949
10949
  var EventEmitter2 = require("events");
10950
10950
  var inherits = require("util").inherits;
10951
- var path102 = require("path");
10951
+ var path100 = require("path");
10952
10952
  var sleep2 = require_atomic_sleep();
10953
10953
  var assert = require("assert");
10954
10954
  var BUSY_WRITE_TIMEOUT = 100;
@@ -11002,20 +11002,20 @@ var require_sonic_boom = __commonJS({
11002
11002
  const mode = sonic.mode;
11003
11003
  if (sonic.sync) {
11004
11004
  try {
11005
- if (sonic.mkdir) fs91.mkdirSync(path102.dirname(file), { recursive: true });
11006
- const fd = fs91.openSync(file, flags, mode);
11005
+ if (sonic.mkdir) fs90.mkdirSync(path100.dirname(file), { recursive: true });
11006
+ const fd = fs90.openSync(file, flags, mode);
11007
11007
  fileOpened(null, fd);
11008
11008
  } catch (err) {
11009
11009
  fileOpened(err);
11010
11010
  throw err;
11011
11011
  }
11012
11012
  } else if (sonic.mkdir) {
11013
- fs91.mkdir(path102.dirname(file), { recursive: true }, (err) => {
11013
+ fs90.mkdir(path100.dirname(file), { recursive: true }, (err) => {
11014
11014
  if (err) return fileOpened(err);
11015
- fs91.open(file, flags, mode, fileOpened);
11015
+ fs90.open(file, flags, mode, fileOpened);
11016
11016
  });
11017
11017
  } else {
11018
- fs91.open(file, flags, mode, fileOpened);
11018
+ fs90.open(file, flags, mode, fileOpened);
11019
11019
  }
11020
11020
  }
11021
11021
  function SonicBoom(opts) {
@@ -11056,8 +11056,8 @@ var require_sonic_boom = __commonJS({
11056
11056
  this.flush = flushBuffer;
11057
11057
  this.flushSync = flushBufferSync;
11058
11058
  this._actualWrite = actualWriteBuffer;
11059
- fsWriteSync = () => fs91.writeSync(this.fd, this._writingBuf);
11060
- fsWrite = () => fs91.write(this.fd, this._writingBuf, this.release);
11059
+ fsWriteSync = () => fs90.writeSync(this.fd, this._writingBuf);
11060
+ fsWrite = () => fs90.write(this.fd, this._writingBuf, this.release);
11061
11061
  } else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
11062
11062
  this._writingBuf = "";
11063
11063
  this.write = write;
@@ -11066,15 +11066,15 @@ var require_sonic_boom = __commonJS({
11066
11066
  this._actualWrite = actualWrite;
11067
11067
  fsWriteSync = () => {
11068
11068
  if (Buffer.isBuffer(this._writingBuf)) {
11069
- return fs91.writeSync(this.fd, this._writingBuf);
11069
+ return fs90.writeSync(this.fd, this._writingBuf);
11070
11070
  }
11071
- return fs91.writeSync(this.fd, this._writingBuf, "utf8");
11071
+ return fs90.writeSync(this.fd, this._writingBuf, "utf8");
11072
11072
  };
11073
11073
  fsWrite = () => {
11074
11074
  if (Buffer.isBuffer(this._writingBuf)) {
11075
- return fs91.write(this.fd, this._writingBuf, this.release);
11075
+ return fs90.write(this.fd, this._writingBuf, this.release);
11076
11076
  }
11077
- return fs91.write(this.fd, this._writingBuf, "utf8", this.release);
11077
+ return fs90.write(this.fd, this._writingBuf, "utf8", this.release);
11078
11078
  };
11079
11079
  } else {
11080
11080
  throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
@@ -11131,7 +11131,7 @@ var require_sonic_boom = __commonJS({
11131
11131
  }
11132
11132
  }
11133
11133
  if (this._fsync) {
11134
- fs91.fsyncSync(this.fd);
11134
+ fs90.fsyncSync(this.fd);
11135
11135
  }
11136
11136
  const len = this._len;
11137
11137
  if (this._reopening) {
@@ -11245,7 +11245,7 @@ var require_sonic_boom = __commonJS({
11245
11245
  const onDrain = () => {
11246
11246
  if (!this._fsync) {
11247
11247
  try {
11248
- fs91.fsync(this.fd, (err) => {
11248
+ fs90.fsync(this.fd, (err) => {
11249
11249
  this._flushPending = false;
11250
11250
  cb(err);
11251
11251
  });
@@ -11347,7 +11347,7 @@ var require_sonic_boom = __commonJS({
11347
11347
  const fd = this.fd;
11348
11348
  this.once("ready", () => {
11349
11349
  if (fd !== this.fd) {
11350
- fs91.close(fd, (err) => {
11350
+ fs90.close(fd, (err) => {
11351
11351
  if (err) {
11352
11352
  return this.emit("error", err);
11353
11353
  }
@@ -11396,7 +11396,7 @@ var require_sonic_boom = __commonJS({
11396
11396
  buf = this._bufs[0];
11397
11397
  }
11398
11398
  try {
11399
- const n2 = Buffer.isBuffer(buf) ? fs91.writeSync(this.fd, buf) : fs91.writeSync(this.fd, buf, "utf8");
11399
+ const n2 = Buffer.isBuffer(buf) ? fs90.writeSync(this.fd, buf) : fs90.writeSync(this.fd, buf, "utf8");
11400
11400
  const releasedBufObj = releaseWritingBuf(buf, this._len, n2);
11401
11401
  buf = releasedBufObj.writingBuf;
11402
11402
  this._len = releasedBufObj.len;
@@ -11412,7 +11412,7 @@ var require_sonic_boom = __commonJS({
11412
11412
  }
11413
11413
  }
11414
11414
  try {
11415
- fs91.fsyncSync(this.fd);
11415
+ fs90.fsyncSync(this.fd);
11416
11416
  } catch {
11417
11417
  }
11418
11418
  }
@@ -11433,7 +11433,7 @@ var require_sonic_boom = __commonJS({
11433
11433
  buf = mergeBuf(this._bufs[0], this._lens[0]);
11434
11434
  }
11435
11435
  try {
11436
- const n2 = fs91.writeSync(this.fd, buf);
11436
+ const n2 = fs90.writeSync(this.fd, buf);
11437
11437
  buf = buf.subarray(n2);
11438
11438
  this._len = Math.max(this._len - n2, 0);
11439
11439
  if (buf.length <= 0) {
@@ -11461,13 +11461,13 @@ var require_sonic_boom = __commonJS({
11461
11461
  this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
11462
11462
  if (this.sync) {
11463
11463
  try {
11464
- const written = Buffer.isBuffer(this._writingBuf) ? fs91.writeSync(this.fd, this._writingBuf) : fs91.writeSync(this.fd, this._writingBuf, "utf8");
11464
+ const written = Buffer.isBuffer(this._writingBuf) ? fs90.writeSync(this.fd, this._writingBuf) : fs90.writeSync(this.fd, this._writingBuf, "utf8");
11465
11465
  release2(null, written);
11466
11466
  } catch (err) {
11467
11467
  release2(err);
11468
11468
  }
11469
11469
  } else {
11470
- fs91.write(this.fd, this._writingBuf, release2);
11470
+ fs90.write(this.fd, this._writingBuf, release2);
11471
11471
  }
11472
11472
  }
11473
11473
  function actualWriteBuffer() {
@@ -11476,7 +11476,7 @@ var require_sonic_boom = __commonJS({
11476
11476
  this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
11477
11477
  if (this.sync) {
11478
11478
  try {
11479
- const written = fs91.writeSync(this.fd, this._writingBuf);
11479
+ const written = fs90.writeSync(this.fd, this._writingBuf);
11480
11480
  release2(null, written);
11481
11481
  } catch (err) {
11482
11482
  release2(err);
@@ -11485,7 +11485,7 @@ var require_sonic_boom = __commonJS({
11485
11485
  if (kCopyBuffer) {
11486
11486
  this._writingBuf = Buffer.from(this._writingBuf);
11487
11487
  }
11488
- fs91.write(this.fd, this._writingBuf, release2);
11488
+ fs90.write(this.fd, this._writingBuf, release2);
11489
11489
  }
11490
11490
  }
11491
11491
  function actualClose(sonic) {
@@ -11501,12 +11501,12 @@ var require_sonic_boom = __commonJS({
11501
11501
  sonic._lens = [];
11502
11502
  assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
11503
11503
  try {
11504
- fs91.fsync(sonic.fd, closeWrapped);
11504
+ fs90.fsync(sonic.fd, closeWrapped);
11505
11505
  } catch {
11506
11506
  }
11507
11507
  function closeWrapped() {
11508
11508
  if (sonic.fd !== 1 && sonic.fd !== 2) {
11509
- fs91.close(sonic.fd, done);
11509
+ fs90.close(sonic.fd, done);
11510
11510
  } else {
11511
11511
  done();
11512
11512
  }
@@ -14641,11 +14641,11 @@ var init_lib = __esm({
14641
14641
  }
14642
14642
  }
14643
14643
  },
14644
- addToPath: function addToPath(path102, added, removed, oldPosInc, options) {
14645
- var last = path102.lastComponent;
14644
+ addToPath: function addToPath(path100, added, removed, oldPosInc, options) {
14645
+ var last = path100.lastComponent;
14646
14646
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
14647
14647
  return {
14648
- oldPos: path102.oldPos + oldPosInc,
14648
+ oldPos: path100.oldPos + oldPosInc,
14649
14649
  lastComponent: {
14650
14650
  count: last.count + 1,
14651
14651
  added,
@@ -14655,7 +14655,7 @@ var init_lib = __esm({
14655
14655
  };
14656
14656
  } else {
14657
14657
  return {
14658
- oldPos: path102.oldPos + oldPosInc,
14658
+ oldPos: path100.oldPos + oldPosInc,
14659
14659
  lastComponent: {
14660
14660
  count: 1,
14661
14661
  added,
@@ -15237,10 +15237,10 @@ function attachmentToHistoryMessage(o2, ts) {
15237
15237
  const memories = raw.map((m3) => {
15238
15238
  if (!m3 || typeof m3 !== "object") return null;
15239
15239
  const rec6 = m3;
15240
- const path102 = typeof rec6.path === "string" ? rec6.path : null;
15240
+ const path100 = typeof rec6.path === "string" ? rec6.path : null;
15241
15241
  const content = typeof rec6.content === "string" ? rec6.content : null;
15242
- if (!path102 || content == null) return null;
15243
- const entry = { path: path102, content };
15242
+ if (!path100 || content == null) return null;
15243
+ const entry = { path: path100, content };
15244
15244
  if (typeof rec6.mtimeMs === "number") entry.mtimeMs = rec6.mtimeMs;
15245
15245
  return entry;
15246
15246
  }).filter((m3) => m3 !== null);
@@ -16106,10 +16106,10 @@ function parseAttachment(obj) {
16106
16106
  const memories = raw.map((m3) => {
16107
16107
  if (!m3 || typeof m3 !== "object") return null;
16108
16108
  const rec6 = m3;
16109
- const path102 = typeof rec6.path === "string" ? rec6.path : null;
16109
+ const path100 = typeof rec6.path === "string" ? rec6.path : null;
16110
16110
  const content = typeof rec6.content === "string" ? rec6.content : null;
16111
- if (!path102 || content == null) return null;
16112
- const out = { path: path102, content };
16111
+ if (!path100 || content == null) return null;
16112
+ const out = { path: path100, content };
16113
16113
  if (typeof rec6.mtimeMs === "number") out.mtimeMs = rec6.mtimeMs;
16114
16114
  return out;
16115
16115
  }).filter((m3) => m3 !== null);
@@ -37083,8 +37083,8 @@ var require_utils = __commonJS({
37083
37083
  var result = transform[inputType][outputType](input);
37084
37084
  return result;
37085
37085
  };
37086
- exports2.resolve = function(path102) {
37087
- var parts = path102.split("/");
37086
+ exports2.resolve = function(path100) {
37087
+ var parts = path100.split("/");
37088
37088
  var result = [];
37089
37089
  for (var index = 0; index < parts.length; index++) {
37090
37090
  var part = parts[index];
@@ -42937,18 +42937,18 @@ var require_object = __commonJS({
42937
42937
  var object = new ZipObject(name, zipObjectContent, o2);
42938
42938
  this.files[name] = object;
42939
42939
  };
42940
- var parentFolder = function(path102) {
42941
- if (path102.slice(-1) === "/") {
42942
- path102 = path102.substring(0, path102.length - 1);
42940
+ var parentFolder = function(path100) {
42941
+ if (path100.slice(-1) === "/") {
42942
+ path100 = path100.substring(0, path100.length - 1);
42943
42943
  }
42944
- var lastSlash = path102.lastIndexOf("/");
42945
- return lastSlash > 0 ? path102.substring(0, lastSlash) : "";
42944
+ var lastSlash = path100.lastIndexOf("/");
42945
+ return lastSlash > 0 ? path100.substring(0, lastSlash) : "";
42946
42946
  };
42947
- var forceTrailingSlash = function(path102) {
42948
- if (path102.slice(-1) !== "/") {
42949
- path102 += "/";
42947
+ var forceTrailingSlash = function(path100) {
42948
+ if (path100.slice(-1) !== "/") {
42949
+ path100 += "/";
42950
42950
  }
42951
- return path102;
42951
+ return path100;
42952
42952
  };
42953
42953
  var folderAdd = function(name, createFolders) {
42954
42954
  createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
@@ -43950,7 +43950,7 @@ var require_lib3 = __commonJS({
43950
43950
  // src/run-case/recorder.ts
43951
43951
  function startRunCaseRecorder(opts) {
43952
43952
  const now = opts.now ?? Date.now;
43953
- const dir = import_node_path81.default.dirname(opts.recordPath);
43953
+ const dir = import_node_path79.default.dirname(opts.recordPath);
43954
43954
  let stream = null;
43955
43955
  let closing = false;
43956
43956
  let closedSettled = false;
@@ -43964,8 +43964,8 @@ function startRunCaseRecorder(opts) {
43964
43964
  });
43965
43965
  const ensureStream = () => {
43966
43966
  if (stream) return stream;
43967
- import_node_fs62.default.mkdirSync(dir, { recursive: true });
43968
- stream = import_node_fs62.default.createWriteStream(opts.recordPath, { flags: "a" });
43967
+ import_node_fs61.default.mkdirSync(dir, { recursive: true });
43968
+ stream = import_node_fs61.default.createWriteStream(opts.recordPath, { flags: "a" });
43969
43969
  stream.on("close", () => closedResolve());
43970
43970
  return stream;
43971
43971
  };
@@ -43990,12 +43990,12 @@ function startRunCaseRecorder(opts) {
43990
43990
  };
43991
43991
  return { tap, close, closed };
43992
43992
  }
43993
- var import_node_fs62, import_node_path81;
43993
+ var import_node_fs61, import_node_path79;
43994
43994
  var init_recorder = __esm({
43995
43995
  "src/run-case/recorder.ts"() {
43996
43996
  "use strict";
43997
- import_node_fs62 = __toESM(require("fs"), 1);
43998
- import_node_path81 = __toESM(require("path"), 1);
43997
+ import_node_fs61 = __toESM(require("fs"), 1);
43998
+ import_node_path79 = __toESM(require("path"), 1);
43999
43999
  }
44000
44000
  });
44001
44001
 
@@ -44038,7 +44038,7 @@ var init_wire = __esm({
44038
44038
  // src/run-case/controller.ts
44039
44039
  async function runController(opts) {
44040
44040
  const now = opts.now ?? Date.now;
44041
- const cwd = opts.cwd ?? (0, import_node_fs63.mkdtempSync)(import_node_path82.default.join(import_node_os29.default.tmpdir(), "clawd-runcase-"));
44041
+ const cwd = opts.cwd ?? (0, import_node_fs62.mkdtempSync)(import_node_path80.default.join(import_node_os29.default.tmpdir(), "clawd-runcase-"));
44042
44042
  const ownsCwd = opts.cwd === void 0;
44043
44043
  const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
44044
44044
  const spawnCtx = { cwd };
@@ -44199,19 +44199,19 @@ async function runController(opts) {
44199
44199
  if (sigintHandler) process.off("SIGINT", sigintHandler);
44200
44200
  if (ownsCwd) {
44201
44201
  try {
44202
- (0, import_node_fs63.rmSync)(cwd, { recursive: true, force: true });
44202
+ (0, import_node_fs62.rmSync)(cwd, { recursive: true, force: true });
44203
44203
  } catch {
44204
44204
  }
44205
44205
  }
44206
44206
  return exitCode ?? 0;
44207
44207
  }
44208
- var import_node_fs63, import_node_os29, import_node_path82;
44208
+ var import_node_fs62, import_node_os29, import_node_path80;
44209
44209
  var init_controller = __esm({
44210
44210
  "src/run-case/controller.ts"() {
44211
44211
  "use strict";
44212
- import_node_fs63 = require("fs");
44212
+ import_node_fs62 = require("fs");
44213
44213
  import_node_os29 = __toESM(require("os"), 1);
44214
- import_node_path82 = __toESM(require("path"), 1);
44214
+ import_node_path80 = __toESM(require("path"), 1);
44215
44215
  init_claude();
44216
44216
  init_stdout_splitter();
44217
44217
  init_permission_stdio();
@@ -44483,8 +44483,8 @@ Env (advanced):
44483
44483
  `;
44484
44484
 
44485
44485
  // src/index.ts
44486
- var import_node_path80 = __toESM(require("path"), 1);
44487
- var import_node_fs61 = __toESM(require("fs"), 1);
44486
+ var import_node_path78 = __toESM(require("path"), 1);
44487
+ var import_node_fs60 = __toESM(require("fs"), 1);
44488
44488
  var import_node_os28 = __toESM(require("os"), 1);
44489
44489
  var import_node_crypto22 = require("crypto");
44490
44490
  var import_node_url5 = require("url");
@@ -45796,10 +45796,9 @@ function buildSpawnContext(state, deps) {
45796
45796
  const personaId2 = file.ownerPersonaId;
45797
45797
  if (personaId2) env.CLAWD_PERSONA_ID = personaId2;
45798
45798
  const userWorkDir = state.subSessionMeta?.userWorkDir;
45799
- if (userWorkDir) env.CLAWD_APP_BUILDER_ROOT = userWorkDir;
45800
- const mcpConfigs = (deps.getMcpConfigs?.() ?? []).filter(
45801
- (c2) => !c2.personas || personaId2 != null && c2.personas.includes(personaId2)
45802
- );
45799
+ if (personaId2) env.CLAWD_PERSONA_DIR = file.cwd;
45800
+ if (personaId2 && userWorkDir) env.CLAWD_WORK_DIR = userWorkDir;
45801
+ const mcpConfigs = deps.getMcpConfigs?.() ?? [];
45803
45802
  const ctx = {
45804
45803
  cwd: file.cwd,
45805
45804
  toolSessionId: file.toolSessionId,
@@ -46642,9 +46641,13 @@ var import_node_fs7 = __toESM(require("fs"), 1);
46642
46641
  var import_node_path6 = __toESM(require("path"), 1);
46643
46642
  var PLACEHOLDER = /\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g;
46644
46643
  var PERSONA_SECRET_MCP_ID_PREFIX = "persona-secrets:";
46644
+ var PERSONA_DIR_PLACEHOLDER = "${CLAWD_PERSONA_DIR}";
46645
46645
  function hasPlaceholder(v3) {
46646
46646
  return typeof v3 === "string" && new RegExp(PLACEHOLDER).test(v3);
46647
46647
  }
46648
+ function renderPersonaDir(v3, personaDir) {
46649
+ return v3.split(PERSONA_DIR_PLACEHOLDER).join(personaDir);
46650
+ }
46648
46651
  function renderPersonaMcpSecrets(args) {
46649
46652
  const src = import_node_path6.default.join(args.personaDir, ".mcp.json");
46650
46653
  let parsed;
@@ -46664,13 +46667,17 @@ function renderPersonaMcpSecrets(args) {
46664
46667
  for (const [name, raw] of Object.entries(servers)) {
46665
46668
  const def = raw ?? {};
46666
46669
  const env = def.env && typeof def.env === "object" ? def.env : void 0;
46667
- if (Array.isArray(def.args) && def.args.some(hasPlaceholder)) {
46670
+ const command = typeof def.command === "string" ? renderPersonaDir(def.command, args.personaDir) : void 0;
46671
+ const rawArgs = Array.isArray(def.args) ? def.args : void 0;
46672
+ const argv = rawArgs?.map((a2) => typeof a2 === "string" ? renderPersonaDir(a2, args.personaDir) : a2);
46673
+ const argvHas = command !== void 0 && command !== def.command || argv !== void 0 && argv.some((a2, i2) => a2 !== rawArgs[i2]);
46674
+ if (argv?.some(hasPlaceholder)) {
46668
46675
  args.logger?.warn("persona.mcp-secret.placeholder-in-args", { persona: args.personaId, server: name });
46669
46676
  }
46670
46677
  const headers = def.headers && typeof def.headers === "object" ? def.headers : void 0;
46671
46678
  const envHas = !!env && Object.values(env).some(hasPlaceholder);
46672
46679
  const headersHas = !!headers && Object.values(headers).some(hasPlaceholder);
46673
- if (!envHas && !headersHas) continue;
46680
+ if (!envHas && !headersHas && !argvHas) continue;
46674
46681
  const renderTable = (table) => {
46675
46682
  const out = {};
46676
46683
  for (const [k3, v3] of Object.entries(table)) {
@@ -46683,7 +46690,13 @@ function renderPersonaMcpSecrets(args) {
46683
46690
  }
46684
46691
  return out;
46685
46692
  };
46686
- rendered[name] = { ...def, ...envHas ? { env: renderTable(env) } : {}, ...headersHas ? { headers: renderTable(headers) } : {} };
46693
+ rendered[name] = {
46694
+ ...def,
46695
+ ...command !== void 0 ? { command } : {},
46696
+ ...argv !== void 0 ? { args: argv } : {},
46697
+ ...envHas ? { env: renderTable(env) } : {},
46698
+ ...headersHas ? { headers: renderTable(headers) } : {}
46699
+ };
46687
46700
  }
46688
46701
  if (Object.keys(rendered).length === 0) return void 0;
46689
46702
  if (missing.size > 0) {
@@ -46695,7 +46708,7 @@ function renderPersonaMcpSecrets(args) {
46695
46708
  const outPath = import_node_path6.default.join(args.outDir, `${safeFileName(args.personaId)}.mcp.json`);
46696
46709
  import_node_fs7.default.mkdirSync(args.outDir, { recursive: true, mode: 448 });
46697
46710
  const content = {
46698
- _comment: "daemon \u6BCF\u6B21 spawn \u73B0\u6E32\uFF1B\u6765\u6E90\u662F persona \u76EE\u5F55\u7684 .mcp.json\uFF08\u53EA\u6709\u58F0\u660E\uFF09+ \u51ED\u636E\u8868\uFF08\u53EA\u6709\u503C\uFF09\u3002\u540C\u540D server \u538B\u8FC7 persona \u76EE\u5F55\u90A3\u4EFD\uFF0C\u503C\u56E0\u6B64\u4E0D\u843D persona \u76EE\u5F55\u3001\u4E0D\u8FDB agent \u4E3B\u8FDB\u7A0B env\u3002\u624B\u6539\u65E0\u6548\u3002",
46711
+ _comment: "daemon \u6BCF\u6B21 spawn \u73B0\u6E32\uFF1B\u6765\u6E90\u662F persona \u76EE\u5F55\u7684 .mcp.json\uFF08\u53EA\u6709\u58F0\u660E\uFF09+ \u51ED\u636E\u8868\uFF08\u53EA\u6709\u503C\uFF09+ persona \u76EE\u5F55\u8DEF\u5F84\uFF08args \u91CC\u7684 ${CLAWD_PERSONA_DIR}\uFF09\u3002\u540C\u540D server \u538B\u8FC7 persona \u76EE\u5F55\u90A3\u4EFD\uFF0C\u503C\u56E0\u6B64\u4E0D\u843D persona \u76EE\u5F55\u3001\u4E0D\u8FDB agent \u4E3B\u8FDB\u7A0B env\u3002\u624B\u6539\u65E0\u6548\u3002",
46699
46712
  mcpServers: rendered
46700
46713
  };
46701
46714
  const tmp = `${outPath}.tmp-${process.pid}-${Date.now()}`;
@@ -46703,8 +46716,7 @@ function renderPersonaMcpSecrets(args) {
46703
46716
  import_node_fs7.default.renameSync(tmp, outPath);
46704
46717
  return {
46705
46718
  id: `${PERSONA_SECRET_MCP_ID_PREFIX}${args.personaId}`,
46706
- path: outPath,
46707
- personas: [args.personaId]
46719
+ path: outPath
46708
46720
  };
46709
46721
  }
46710
46722
  function attachPersonaSecretMcp(ctx, resolve9) {
@@ -49814,7 +49826,7 @@ var PersonaStore = class {
49814
49826
  *
49815
49827
  * 位置不是随手挑的,两条既有约定叠出来的:`.clawd/` 是 daemon 声明「不动」的 persona 私有区
49816
49828
  * (不在 seed.ts 的 DAEMON_MANAGED_PATHS 里),`.local` 是仓内已成立的「本机个人 override
49817
- * 永不被 OTA 覆盖」后缀(见 seed.refreshDeployKit)。于是内置 persona 的 CLAUDE.md 继续被
49829
+ * 永不被 OTA 覆盖」后缀。于是内置 persona 的 CLAUDE.md 继续被
49818
49830
  * refresh 覆盖成 bundle 新版、用户写的这层原样活着。
49819
49831
  *
49820
49832
  * 同 sandbox-settings.json 的理由:放 `.clawd/` 而非 persona 根目录,让 CC 的 project
@@ -50229,12 +50241,12 @@ var DEFAULT_PERSONAS = [
50229
50241
  // 与 app-builder 对齐"调用阿里云的工作方式"(owner 2026-06-17 要求):开发型 profile —— 放开文件/web
50230
50242
  // 工具 + node/pnpm 工具链精确路径 + 出站 TLD 通配白名单。html-slides 需要联网(git clone frontend-slides
50231
50243
  // skill、调阿里云 CLI/SDK)。
50232
- // 阿里云凭证:**复用共享 deploy-kit 单源**($HOME/.clawd/deploy-kit/.secrets/aliyun.env.local,使用者自己写、
50233
- // 全 FC persona 共用;bundle 不再 ship AK,见 specs/2026-09-18-aliyun-ak-leak-rotate-design.md),不在 persona
50234
- // 目录另存一份。app-builder 的 FC 部署走 daemon 侧脚本(沙箱外)故其 profile 无需 carve 这个路径;html-slides
50235
- // 没有 daemon 侧流程、要在 cc 沙箱内直接 `set -a; . $HOME/.clawd/deploy-kit/.secrets/aliyun.env.local; set +a`
50236
- // 后调 aliyun CLI(env 凭证绕过沙箱外的 ~/.aliyun/),所以这里**额外**把这两个凭证文件加进 allowRead
50237
- // (denyRead '~/' 之上的精确凿洞,单文件、最小暴露,同 ~/.npmrc 先例;aliyun.env 是老机器上的遗留文件)。
50244
+ // 阿里云凭证:**凭据表单源**($HOME/.clawd/secrets/aliyun.env,使用者自己写;bundle 不 ship AK,见
50245
+ // specs/2026-09-18-aliyun-ak-leak-rotate-design.md;deploy-kit 下那份 .secrets/ 已随 design 2026-09-19-persona-mcp-single-source 删),
50246
+ // 不在 persona 目录另存一份。app-builder 的 FC 部署由 clawd-app-builder MCP server 起(沙箱外、AK 在它 env 里)故其 profile
50247
+ // 无需 carve 这个路径;html-slides 没有 daemon 侧流程、要在 cc 沙箱内直接 `set -a; . $HOME/.clawd/secrets/aliyun.env; set +a`
50248
+ // 后调 aliyun CLI(env 凭证绕过沙箱外的 ~/.aliyun/),所以这里**额外**把这个凭证文件加进 allowRead
50249
+ // (denyRead '~/' 之上的精确凿洞,单文件、最小暴露,同 ~/.npmrc 先例)。
50238
50250
  // excludedCommands: ['aliyun *'] —— 额外把 aliyun CLI 放沙箱外跑(逃出 seatbelt 直接用宿主凭证/网络),
50239
50251
  // 与上面沙箱内 env 凭证方案并存,按运行时实际命令前缀匹配生效。
50240
50252
  sandboxProfile: {
@@ -50244,7 +50256,7 @@ var DEFAULT_PERSONAS = [
50244
50256
  },
50245
50257
  sandbox: {
50246
50258
  filesystem: {
50247
- allowRead: ["~/.npmrc", "~/Library/Preferences/pnpm", "~/.nvm", "~/Library/pnpm", "~/.local/share/pnpm", "~/.local/state/pnpm", "~/.npm", "~/.pnpm-store", "~/.clawd/deploy-kit/.secrets/aliyun.env", "~/.clawd/deploy-kit/.secrets/aliyun.env.local"],
50259
+ allowRead: ["~/.npmrc", "~/Library/Preferences/pnpm", "~/.nvm", "~/Library/pnpm", "~/.local/share/pnpm", "~/.local/state/pnpm", "~/.npm", "~/.pnpm-store", "~/.clawd/secrets/aliyun.env"],
50248
50260
  allowWrite: ["~/Library/pnpm", "~/.local/share/pnpm", "~/.local/state/pnpm", "~/.npm", "~/.pnpm-store"]
50249
50261
  },
50250
50262
  network: {
@@ -50373,7 +50385,7 @@ function copyBundleExtras(srcDir, dstDir) {
50373
50385
  }
50374
50386
  }
50375
50387
  }
50376
- var DAEMON_MANAGED_PATHS = ["extension-kit", "CLAUDE.md", ".mcp.json", ".claude/skills", ".claude/agents"];
50388
+ var DAEMON_MANAGED_PATHS = ["extension-kit", "CLAUDE.md", ".mcp.json", ".claude/skills", ".claude/agents", "mcp"];
50377
50389
  function replaceManagedPath(src, dst) {
50378
50390
  if (!fs13.statSync(src).isDirectory()) {
50379
50391
  fs13.mkdirSync(path16.dirname(dst), { recursive: true });
@@ -50613,59 +50625,6 @@ function retirePersonaBuilder(args) {
50613
50625
  });
50614
50626
  }
50615
50627
  }
50616
- function findDeployKitRoot(logger) {
50617
- const candidates = [];
50618
- try {
50619
- const here = path16.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
50620
- candidates.push(path16.resolve(here, "..", "deploy-kit"));
50621
- } catch {
50622
- }
50623
- const fromArgv = bundleSiblingFromArgv(process.argv[1], "deploy-kit");
50624
- if (fromArgv) candidates.push(fromArgv);
50625
- for (const c2 of candidates) {
50626
- try {
50627
- if (fs13.statSync(c2).isDirectory()) {
50628
- logger?.info("persona.deploy-kit-root.resolved", { root: c2 });
50629
- return c2;
50630
- }
50631
- } catch {
50632
- }
50633
- }
50634
- logger?.warn("persona.deploy-kit-root.not-found", { argv1: process.argv[1], candidates });
50635
- return null;
50636
- }
50637
- function seedDeployKit(args) {
50638
- const dst = path16.join(args.dataDir, "deploy-kit");
50639
- fs13.cpSync(args.deployKitBundleRoot, dst, {
50640
- recursive: true,
50641
- dereference: true,
50642
- force: false,
50643
- errorOnExist: false
50644
- });
50645
- args.logger.info("deploy-kit.seed.done", { dst });
50646
- }
50647
- function refreshDeployKit(args) {
50648
- const dst = path16.join(args.dataDir, "deploy-kit");
50649
- if (!fs13.existsSync(dst)) {
50650
- seedDeployKit(args);
50651
- return;
50652
- }
50653
- for (const sub of ["scripts", "contract"]) {
50654
- const s2 = path16.join(args.deployKitBundleRoot, sub);
50655
- if (fs13.existsSync(s2)) {
50656
- fs13.cpSync(s2, path16.join(dst, sub), { recursive: true, force: true, dereference: true });
50657
- }
50658
- }
50659
- const secretsSrc = path16.join(args.deployKitBundleRoot, ".secrets");
50660
- if (fs13.existsSync(secretsSrc)) {
50661
- fs13.mkdirSync(path16.join(dst, ".secrets"), { recursive: true });
50662
- for (const f2 of fs13.readdirSync(secretsSrc)) {
50663
- if (f2.endsWith(".local")) continue;
50664
- fs13.copyFileSync(path16.join(secretsSrc, f2), path16.join(dst, ".secrets", f2));
50665
- }
50666
- }
50667
- args.logger.info("deploy-kit.refresh.done", { dst });
50668
- }
50669
50628
 
50670
50629
  // src/skills/scanner.ts
50671
50630
  var import_node_fs10 = __toESM(require("fs"), 1);
@@ -51834,8 +51793,8 @@ function turnStartInput(text, resolveImage) {
51834
51793
  const items = [];
51835
51794
  let leftover = text;
51836
51795
  for (const m3 of text.matchAll(SKILL_RE)) {
51837
- const [marker, name, path102] = m3;
51838
- items.push({ type: "skill", name, path: path102 });
51796
+ const [marker, name, path100] = m3;
51797
+ items.push({ type: "skill", name, path: path100 });
51839
51798
  leftover = leftover.replace(marker, "");
51840
51799
  }
51841
51800
  for (const m3 of text.matchAll(ATTACHMENT_RE2)) {
@@ -54741,44 +54700,6 @@ function readDir(dir, logger) {
54741
54700
  }
54742
54701
  return out;
54743
54702
  }
54744
- function collectKitPlaceholders(kitDir) {
54745
- const out = /* @__PURE__ */ new Set();
54746
- const scan = (file, re2) => {
54747
- let text;
54748
- try {
54749
- text = import_node_fs28.default.readFileSync(file, "utf8");
54750
- } catch {
54751
- return;
54752
- }
54753
- for (const m3 of text.matchAll(re2)) out.add(m3[1]);
54754
- };
54755
- const walk2 = (dir, depth) => {
54756
- if (depth > 6) return [];
54757
- let entries;
54758
- try {
54759
- entries = import_node_fs28.default.readdirSync(dir, { withFileTypes: true });
54760
- } catch {
54761
- return [];
54762
- }
54763
- return entries.flatMap((e) => {
54764
- if (e.name === "node_modules") return [];
54765
- const p3 = import_node_path29.default.join(dir, e.name);
54766
- return e.isDirectory() ? walk2(p3, depth + 1) : [p3];
54767
- });
54768
- };
54769
- for (const f2 of walk2(import_node_path29.default.join(kitDir, "contract"), 0)) {
54770
- if (f2.endsWith(".tmpl")) scan(f2, /__([A-Z0-9_]+)__/g);
54771
- }
54772
- for (const f2 of walk2(import_node_path29.default.join(kitDir, "examples"), 0)) {
54773
- if (f2.endsWith(".env.example")) scan(f2, /\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g);
54774
- }
54775
- return out;
54776
- }
54777
- function secretsForKit(table, kitDir) {
54778
- if (!table) return void 0;
54779
- const wanted = collectKitPlaceholders(kitDir);
54780
- return Object.fromEntries(Object.entries(table).filter(([k3]) => wanted.has(k3)));
54781
- }
54782
54703
  function upsertEnvFileVar(file, key, value) {
54783
54704
  if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) throw new Error(`invalid env name: ${key}`);
54784
54705
  import_node_fs28.default.mkdirSync(import_node_path29.default.dirname(file), { recursive: true, mode: 448 });
@@ -55426,6 +55347,8 @@ function sanitizeForQuote(def) {
55426
55347
  var stringRecord = (v3) => v3 && typeof v3 === "object" ? Object.fromEntries(Object.entries(v3).filter((kv) => typeof kv[1] === "string")) : {};
55427
55348
  var HTTP_TYPES2 = /* @__PURE__ */ new Set(["http", "sse", "streamable_http", "streamable-http"]);
55428
55349
  var PACKAGE_RUNNERS = /* @__PURE__ */ new Set(["npx", "uvx", "pnpx", "bunx"]);
55350
+ var SCRIPT_RUNNERS = /* @__PURE__ */ new Set(["node", "bun", "deno", "python", "python3"]);
55351
+ var HOST_ARG_PLACEHOLDER = "CLAWD_PERSONA_DIR";
55429
55352
  function scanMcpConnectors(personaDir) {
55430
55353
  const file = import_node_path32.default.join(personaDir, ".mcp.json");
55431
55354
  const out = { readable: true, connectors: [], evidence: [], warnings: [] };
@@ -55477,10 +55400,10 @@ function scanMcpConnectors(personaDir) {
55477
55400
  continue;
55478
55401
  }
55479
55402
  const args = Array.isArray(def.args) ? def.args.map(String) : [];
55480
- const pkg = PACKAGE_RUNNERS.has(command) ? args.find((a2) => !a2.startsWith("-")) : void 0;
55481
- const id = pkg ?? command;
55403
+ const target = PACKAGE_RUNNERS.has(command) || SCRIPT_RUNNERS.has(command) ? args.find((a2) => !a2.startsWith("-")) : void 0;
55404
+ const id = target ?? command;
55482
55405
  const fields = fieldsOf(name, "env", Object.values(stringRecord(def.env)).flatMap(placeholdersIn), out.warnings);
55483
- if (args.some((a2) => placeholdersIn(a2).length > 0)) {
55406
+ if (args.some((a2) => placeholdersIn(a2).some((p3) => p3 !== HOST_ARG_PLACEHOLDER))) {
55484
55407
  out.warnings.push(`MCP server\u300C${name}\u300D\u7684 args \u91CC\u6709 \${VAR} \u5360\u4F4D\u2014\u2014args \u4F1A\u8FDB ps\uFF0C\u4E91\u4E0A\u548C\u672C\u673A\u90FD\u53EA\u6E32 env\uFF0C\u8FD9\u4E9B\u5360\u4F4D\u4E0D\u4F1A\u88AB\u586B\uFF1B\u628A\u51ED\u636E\u6539\u5230 env \u91CC`);
55485
55408
  }
55486
55409
  out.connectors.push({ name, kind: "env", runner: "mcp", id, fields });
@@ -59079,10 +59002,10 @@ function createGithubApi(args) {
59079
59002
  const doFetch = args.fetch ?? fetch;
59080
59003
  const seal = args.seal ?? sealWithSodium;
59081
59004
  const timeoutMs = args.timeoutMs ?? TIMEOUT_MS;
59082
- async function request(method, path102, body) {
59005
+ async function request(method, path100, body) {
59083
59006
  let res;
59084
59007
  try {
59085
- res = await doFetch(`${API}${path102}`, {
59008
+ res = await doFetch(`${API}${path100}`, {
59086
59009
  method,
59087
59010
  headers: {
59088
59011
  Authorization: `Bearer ${args.token}`,
@@ -59107,8 +59030,8 @@ function createGithubApi(args) {
59107
59030
  }
59108
59031
  return { status: res.status, json };
59109
59032
  }
59110
- async function must(method, path102, what, body) {
59111
- const r2 = await request(method, path102, body);
59033
+ async function must(method, path100, what, body) {
59034
+ const r2 = await request(method, path100, body);
59112
59035
  if (r2.status < 200 || r2.status >= 300) throw new GithubApiError(r2.status, explain(r2.status, what, r2.json));
59113
59036
  return r2.json;
59114
59037
  }
@@ -59148,9 +59071,9 @@ function createGithubApi(args) {
59148
59071
  return { env: x2.name, ...Number.isFinite(at3) ? { setAt: at3 } : {} };
59149
59072
  });
59150
59073
  },
59151
- async getJson(path102) {
59074
+ async getJson(path100) {
59152
59075
  try {
59153
- const r2 = await request("GET", path102);
59076
+ const r2 = await request("GET", path100);
59154
59077
  return r2.status >= 200 && r2.status < 300 ? r2.json : void 0;
59155
59078
  } catch {
59156
59079
  return void 0;
@@ -59231,7 +59154,8 @@ var GITIGNORE_LINES = [
59231
59154
  ".attachments/",
59232
59155
  ".clawd/sessions/",
59233
59156
  ".clawd/deploy-scan.json",
59234
- "node_modules/"
59157
+ "node_modules/",
59158
+ ".s-home/"
59235
59159
  ];
59236
59160
  function mergeGitignore(existing) {
59237
59161
  const lines = (existing ?? "").split("\n");
@@ -59741,19 +59665,8 @@ async function rerunJob(api, slug, jobId) {
59741
59665
  }
59742
59666
 
59743
59667
  // src/deploy/scan-task.ts
59744
- var import_node_path35 = __toESM(require("path"), 1);
59745
59668
  var BUTLER_PERSONA_ID = "persona-clawd-butler";
59746
- var SCANNABLE_ASSETS = [
59747
- {
59748
- name: "deploy-kit",
59749
- path: (dataDir) => import_node_path35.default.join(dataDir, "deploy-kit"),
59750
- what: "FC \u90E8\u7F72\u80FD\u529B\uFF08publish.sh / new-extension.sh / \u5DE5\u5177\u94FE / \u51ED\u8BC1\u76EE\u5F55\uFF09\u3002persona \u7528\u7EDD\u5BF9\u8DEF\u5F84\u53BB\u8C03\u8FD9\u91CC\u7684\u811A\u672C\u65F6\uFF0C\u5C31\u8BE5\u62A5\u4E00\u6761 asset\u3002"
59751
- },
59752
- {
59753
- name: "app-builder-plugin",
59754
- what: "clawd-app-builder MCP server \u7684\u6784\u5EFA\u4EA7\u7269\uFF08daemon \u7684 tsup \u4EA7\u7269\uFF0C\u672C\u673A\u4E0D\u5728\u76D8\u4E0A\u5355\u72EC\u5B58\u4E00\u4EFD\uFF09\u3002**\u5224\u636E**\uFF1Apersona \u7684\u4E3B\u5E72\u52A8\u4F5C\u8D70 clawd-app-builder \u8FD9\u4E2A MCP \u65F6\uFF0C\u4E91\u4E0A\u5BB9\u5668\u91CC\u8DD1\u7684\u5C31\u662F\u8FD9\u4EFD\u4EA7\u7269\u2014\u2014\u7528\u5230\u5B83\u5C31\u62A5\u4E00\u6761 asset\uFF0C\u5426\u5219\u5B83\u8FDB\u4E0D\u4E86\u955C\u50CF\u3002"
59755
- }
59756
- ];
59669
+ var SCANNABLE_ASSETS = [];
59757
59670
  function staleScannerAssets(scan, known = SCANNABLE_ASSETS) {
59758
59671
  const knew = new Set(scan.scannedAssets ?? []);
59759
59672
  return known.filter((a2) => !knew.has(a2.name));
@@ -59813,6 +59726,7 @@ function mustBeScanning(scan, method) {
59813
59726
  return scan;
59814
59727
  }
59815
59728
  function buildDeployHandlers(deps) {
59729
+ const scannableAssets = deps.scannableAssets ?? SCANNABLE_ASSETS;
59816
59730
  const cacheMs = deps.secretsCacheMs ?? SECRETS_CACHE_MS;
59817
59731
  const secretsCache = /* @__PURE__ */ new Map();
59818
59732
  const runCache = /* @__PURE__ */ new Map();
@@ -59850,7 +59764,7 @@ function buildDeployHandlers(deps) {
59850
59764
  }
59851
59765
  let scan = await readScan(dir);
59852
59766
  if (scan && scan.status === "done") {
59853
- const stale = describeStaleAssets(staleScannerAssets(scan));
59767
+ const stale = describeStaleAssets(staleScannerAssets(scan, scannableAssets));
59854
59768
  const kept = scan.notes.filter((n2) => !n2.startsWith(STALE_ASSETS_NOTE_PREFIX));
59855
59769
  scan = { ...scan, notes: stale ? [...kept, stale] : kept };
59856
59770
  }
@@ -60013,7 +59927,7 @@ function buildDeployHandlers(deps) {
60013
59927
  notes: [...scan.notes.filter((n2) => n2.startsWith(MCP_SCAN_NOTE_PREFIX)), ...args.notes.map(redactSecretValues)],
60014
59928
  // 记下这次扫描**被告知有哪些共享资产**。以后资产表长出新条目时,只有扫的时候还不知道
60015
59929
  // 它的那些记录会被提示一次(见 staleScannerAssets)
60016
- scannedAssets: SCANNABLE_ASSETS.map((a2) => a2.name),
59930
+ scannedAssets: scannableAssets.map((a2) => a2.name),
60017
59931
  error: void 0
60018
59932
  });
60019
59933
  return view(args.personaId);
@@ -60643,9 +60557,9 @@ async function refreshTunnelUrlOnStartup(deps) {
60643
60557
 
60644
60558
  // src/lark-bot-connector/binding-store.ts
60645
60559
  var import_node_fs30 = __toESM(require("fs"), 1);
60646
- var import_node_path36 = __toESM(require("path"), 1);
60560
+ var import_node_path35 = __toESM(require("path"), 1);
60647
60561
  function createLarkBotBindingStore(personaRoot) {
60648
- const filePath = (personaId2) => import_node_path36.default.join(personaRoot, safeFileName(personaId2), ".clawd", "lark-bot.json");
60562
+ const filePath = (personaId2) => import_node_path35.default.join(personaRoot, safeFileName(personaId2), ".clawd", "lark-bot.json");
60649
60563
  const read = (personaId2) => {
60650
60564
  const file = filePath(personaId2);
60651
60565
  if (!import_node_fs30.default.existsSync(file)) return null;
@@ -60659,7 +60573,7 @@ function createLarkBotBindingStore(personaRoot) {
60659
60573
  };
60660
60574
  const write = (personaId2, meta) => {
60661
60575
  const file = filePath(personaId2);
60662
- import_node_fs30.default.mkdirSync(import_node_path36.default.dirname(file), { recursive: true });
60576
+ import_node_fs30.default.mkdirSync(import_node_path35.default.dirname(file), { recursive: true });
60663
60577
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
60664
60578
  import_node_fs30.default.writeFileSync(tmp, JSON.stringify(meta, null, 2), { mode: 384 });
60665
60579
  import_node_fs30.default.renameSync(tmp, file);
@@ -60821,7 +60735,7 @@ function createLarkBotCloudClient(opts) {
60821
60735
 
60822
60736
  // src/lark-bot-connector/chat-router.ts
60823
60737
  var import_node_fs31 = __toESM(require("fs"), 1);
60824
- var import_node_path37 = __toESM(require("path"), 1);
60738
+ var import_node_path36 = __toESM(require("path"), 1);
60825
60739
  init_protocol();
60826
60740
  var ERROR_REPLY_TEXT = "\u5904\u7406\u51FA\u9519\u4E86\uFF0C\u8BF7\u91CD\u8BD5";
60827
60741
  var LOCAL_TURN_RETRIES = 2;
@@ -60900,7 +60814,7 @@ function createLarkChatRouter(deps) {
60900
60814
  }
60901
60815
  const dir = deps.mediaRootFor(env.chatId);
60902
60816
  import_node_fs31.default.mkdirSync(dir, { recursive: true });
60903
- const p3 = import_node_path37.default.join(dir, `${safeMediaName(ownerMessageId)}-${i2}.${ext}`);
60817
+ const p3 = import_node_path36.default.join(dir, `${safeMediaName(ownerMessageId)}-${i2}.${ext}`);
60904
60818
  import_node_fs31.default.writeFileSync(p3, r2.data);
60905
60819
  lines.push(`[\u56FE\u7247: ${p3}]\uFF08\u7528 Read \u5DE5\u5177\u67E5\u770B\uFF09`);
60906
60820
  } catch (err) {
@@ -60923,7 +60837,7 @@ function createLarkChatRouter(deps) {
60923
60837
  }
60924
60838
  const dir = deps.mediaRootFor(env.chatId);
60925
60839
  import_node_fs31.default.mkdirSync(dir, { recursive: true });
60926
- const p3 = import_node_path37.default.join(dir, `${safeMediaName(ownerMessageId)}-${i2}-${safeAttachmentName(f2.name)}`);
60840
+ const p3 = import_node_path36.default.join(dir, `${safeMediaName(ownerMessageId)}-${i2}-${safeAttachmentName(f2.name)}`);
60927
60841
  import_node_fs31.default.writeFileSync(p3, r2.data);
60928
60842
  lines.push(`[\u6587\u4EF6: ${p3}]\uFF08\u7528 Read \u5DE5\u5177\u67E5\u770B\uFF09`);
60929
60843
  } catch (err) {
@@ -61749,11 +61663,11 @@ async function forwardPeerExecToPeer(args) {
61749
61663
 
61750
61664
  // src/tools/codex-history.ts
61751
61665
  var import_node_fs33 = __toESM(require("fs"), 1);
61752
- var import_node_path39 = __toESM(require("path"), 1);
61666
+ var import_node_path38 = __toESM(require("path"), 1);
61753
61667
 
61754
61668
  // src/tools/transcript-search.ts
61755
61669
  var import_node_fs32 = __toESM(require("fs"), 1);
61756
- var import_node_path38 = __toESM(require("path"), 1);
61670
+ var import_node_path37 = __toESM(require("path"), 1);
61757
61671
  var SNIPPET_PAD = 60;
61758
61672
  var INJECTED_ENVELOPE_RE = /^<(system-reminder|command-name|command-message|command-args|local-command-stdout|local-command-stderr|task-notification|user-prompt-submit-hook|environment_context|user_instructions)\b/;
61759
61673
  var CODEX_WRAPPER_RE = /<(related-dir|environment_context|user_instructions)>[\s\S]*?<\/\1>/g;
@@ -61846,7 +61760,7 @@ function createCodexRolloutLocator(roots) {
61846
61760
  return;
61847
61761
  }
61848
61762
  for (const entry of entries) {
61849
- const full = import_node_path38.default.join(dir, entry.name);
61763
+ const full = import_node_path37.default.join(dir, entry.name);
61850
61764
  if (entry.isDirectory()) {
61851
61765
  walk2(full, into);
61852
61766
  continue;
@@ -62126,7 +62040,7 @@ function readThreadNames(sharedHome) {
62126
62040
  if (!sharedHome) return names;
62127
62041
  let raw;
62128
62042
  try {
62129
- raw = import_node_fs33.default.readFileSync(import_node_path39.default.join(sharedHome, "session_index.jsonl"), "utf8");
62043
+ raw = import_node_fs33.default.readFileSync(import_node_path38.default.join(sharedHome, "session_index.jsonl"), "utf8");
62130
62044
  } catch {
62131
62045
  return names;
62132
62046
  }
@@ -62151,7 +62065,7 @@ function walkRollouts(dir, visit) {
62151
62065
  }
62152
62066
  entries.sort((a2, b3) => a2.name < b3.name ? 1 : a2.name > b3.name ? -1 : 0);
62153
62067
  for (const entry of entries) {
62154
- const full = import_node_path39.default.join(dir, entry.name);
62068
+ const full = import_node_path38.default.join(dir, entry.name);
62155
62069
  if (entry.isDirectory()) {
62156
62070
  if (!walkRollouts(full, visit)) return false;
62157
62071
  } else if (ROLLOUT_NAME_RE.test(entry.name)) {
@@ -62219,7 +62133,7 @@ var CodexHistoryReader = class {
62219
62133
  return [];
62220
62134
  }
62221
62135
  async listSessions(args) {
62222
- const want = import_node_path39.default.resolve(args.projectPath);
62136
+ const want = import_node_path38.default.resolve(args.projectPath);
62223
62137
  const names = readThreadNames(this.deps.sharedHome);
62224
62138
  const found = [];
62225
62139
  let scanned = 0;
@@ -62228,7 +62142,7 @@ var CodexHistoryReader = class {
62228
62142
  if (++scanned > CODEX_LIST_SESSIONS_SCAN_CAP) return false;
62229
62143
  const head = readHead(file, PEEK_BYTES);
62230
62144
  const cwd = head === null ? null : peekSessionCwd(head);
62231
- if (!cwd || import_node_path39.default.resolve(cwd) !== want) return;
62145
+ if (!cwd || import_node_path38.default.resolve(cwd) !== want) return;
62232
62146
  const first = readFirstLine(file);
62233
62147
  const meta = first === null ? null : parseCodexRolloutMeta(first);
62234
62148
  if (!meta) return;
@@ -62312,9 +62226,9 @@ var CentralClientError = class extends Error {
62312
62226
  code;
62313
62227
  cause;
62314
62228
  };
62315
- async function centralRequest(opts, path102, init) {
62229
+ async function centralRequest(opts, path100, init) {
62316
62230
  const f2 = opts.fetchImpl ?? globalThis.fetch;
62317
- const url = `${opts.api.replace(/\/+$/, "")}${path102}`;
62231
+ const url = `${opts.api.replace(/\/+$/, "")}${path100}`;
62318
62232
  const ctrl = new AbortController();
62319
62233
  const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
62320
62234
  let res;
@@ -62411,6 +62325,32 @@ async function centralGetApiKey(opts) {
62411
62325
  gatewayUrl: typeof body.gatewayUrl === "string" ? body.gatewayUrl : null
62412
62326
  };
62413
62327
  }
62328
+ async function centralGetThread(opts) {
62329
+ const f2 = opts.fetchImpl ?? globalThis.fetch;
62330
+ const url = `${opts.api.replace(/\/+$/, "")}/api/persona-cloud/threads/${encodeURIComponent(opts.threadId)}`;
62331
+ const ctrl = new AbortController();
62332
+ const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
62333
+ let res;
62334
+ try {
62335
+ res = await f2(url, { method: "GET", headers: { authorization: `Bearer ${opts.loginPass}` }, signal: ctrl.signal });
62336
+ } catch (err) {
62337
+ clearTimeout(timer);
62338
+ throw new CentralClientError("NETWORK", `central server request failed: ${err.message}`, err);
62339
+ }
62340
+ clearTimeout(timer);
62341
+ if (res.status === 404) return null;
62342
+ if (res.status === 401) throw new CentralClientError("UNAUTHORIZED", "login pass rejected by center");
62343
+ if (!res.ok) {
62344
+ let detail = "";
62345
+ try {
62346
+ const body = await res.json();
62347
+ if (typeof body?.message === "string" && body.message) detail = `: ${body.message}`;
62348
+ } catch {
62349
+ }
62350
+ throw new CentralClientError("API_ERROR", `central server HTTP ${res.status}${detail}`);
62351
+ }
62352
+ return await res.text();
62353
+ }
62414
62354
  async function centralIssueApiKey(opts) {
62415
62355
  const body = await centralRequest(opts, "/api/persona-cloud/api-key", {
62416
62356
  method: "POST",
@@ -62498,8 +62438,6 @@ var GATEWAY_ROUTES = {
62498
62438
  healthz: () => "/healthz",
62499
62439
  session: (personaId2) => `/p/${encodeURIComponent(personaId2)}/session`,
62500
62440
  sessionSend: (personaId2, sessionId) => `/p/${encodeURIComponent(personaId2)}/session/${encodeURIComponent(sessionId)}`,
62501
- // 历史文件不挂在 persona 下:使用者卷跨 persona 共用(design 2026-09-14-codex-native-memories §3.2f)
62502
- thread: (threadId) => `/threads/${encodeURIComponent(threadId)}`,
62503
62441
  // 调用方自己那块盘的用量(design 2026-09-19-cloud-volume-usage §3.3):同样按人、不挂 persona
62504
62442
  volume: () => "/me/volume"
62505
62443
  };
@@ -62614,16 +62552,6 @@ var CloudGatewayClient = class {
62614
62552
  if (body.volume == null) return null;
62615
62553
  return CloudVolumeUsageSchema.parse(body.volume);
62616
62554
  }
62617
- /** rollout 原文;404 = 没这条 thread(还没开过第一轮 / 卷被清)→ null */
62618
- async fetchRollout(threadId) {
62619
- const { apiKey, gatewayUrl } = await this.credentials();
62620
- const res = await this.fetchImpl(gatewayUrl + GATEWAY_ROUTES.thread(threadId), {
62621
- headers: { authorization: `Bearer ${apiKey}` }
62622
- });
62623
- if (res.status === 404) return null;
62624
- if (!res.ok) throw new Error(`gateway threads \u8DEF\u7531\u56DE ${res.status}`);
62625
- return await res.text();
62626
- }
62627
62555
  };
62628
62556
  function parseControlLine(line) {
62629
62557
  let o2;
@@ -63020,7 +62948,7 @@ var CloudCodexAdapter = class {
63020
62948
  this.client = opts.client;
63021
62949
  this.logger = opts.logger;
63022
62950
  this.getSignSecret = opts.getSignSecret;
63023
- this.historyReader = new CloudCodexHistoryReader(opts.client, opts.logger);
62951
+ this.historyReader = new CloudCodexHistoryReader(opts.history, opts.logger);
63024
62952
  }
63025
62953
  /** 可用 = 能拿到凭据(登了飞书、生成过 key、中心配了 gateway),与本机装没装 codex 无关 */
63026
62954
  async probe() {
@@ -63134,7 +63062,7 @@ var PiRpcClient = class {
63134
63062
  var import_node_child_process10 = require("child_process");
63135
63063
  var import_node_crypto9 = require("crypto");
63136
63064
  var import_node_fs35 = __toESM(require("fs"), 1);
63137
- var import_node_path40 = __toESM(require("path"), 1);
63065
+ var import_node_path39 = __toESM(require("path"), 1);
63138
63066
 
63139
63067
  // src/tools/pi-events.ts
63140
63068
  init_protocol();
@@ -63311,7 +63239,7 @@ ${dirs.map((d2) => `- ${d2}`).join("\n")}`;
63311
63239
  function createPiSession(ctx, sink, deps = {}) {
63312
63240
  const cmd = process.env.PI_BIN ?? "pi";
63313
63241
  const sessionId = ctx.toolSessionId ?? (0, import_node_crypto9.randomUUID)();
63314
- const skillsDir = import_node_path40.default.join(ctx.cwd, ".claude", "skills");
63242
+ const skillsDir = import_node_path39.default.join(ctx.cwd, ".claude", "skills");
63315
63243
  const exists = deps.skillsDirExists ?? ((d2) => import_node_fs35.default.existsSync(d2));
63316
63244
  const args = buildPiArgs(ctx, {
63317
63245
  sessionId,
@@ -63430,20 +63358,20 @@ function createPiSession(ctx, sink, deps = {}) {
63430
63358
  // src/tools/pi-history.ts
63431
63359
  var import_node_fs36 = __toESM(require("fs"), 1);
63432
63360
  var import_node_os10 = __toESM(require("os"), 1);
63433
- var import_node_path41 = __toESM(require("path"), 1);
63361
+ var import_node_path40 = __toESM(require("path"), 1);
63434
63362
  var PI_LIST_SESSIONS_LIMIT = 100;
63435
63363
  var PI_LIST_SESSIONS_SCAN_CAP = 4e3;
63436
63364
  function piAgentDir(env = process.env) {
63437
- return env.PI_CODING_AGENT_DIR || import_node_path41.default.join(import_node_os10.default.homedir(), ".pi", "agent");
63365
+ return env.PI_CODING_AGENT_DIR || import_node_path40.default.join(import_node_os10.default.homedir(), ".pi", "agent");
63438
63366
  }
63439
63367
  function piSessionsRoot(env = process.env) {
63440
- return import_node_path41.default.join(piAgentDir(env), "sessions");
63368
+ return import_node_path40.default.join(piAgentDir(env), "sessions");
63441
63369
  }
63442
63370
  function encodePiCwd(cwd) {
63443
63371
  return `--${cwd.replace(/^[\\/]+/, "").replace(/[\\/:]/g, "-")}--`;
63444
63372
  }
63445
63373
  function piProjectSessionDir(sessionsRoot, cwd) {
63446
- return import_node_path41.default.join(sessionsRoot, encodePiCwd(cwd));
63374
+ return import_node_path40.default.join(sessionsRoot, encodePiCwd(cwd));
63447
63375
  }
63448
63376
  function findInDir(dir, toolSessionId) {
63449
63377
  let names;
@@ -63454,7 +63382,7 @@ function findInDir(dir, toolSessionId) {
63454
63382
  }
63455
63383
  const suffix = `_${toolSessionId}.jsonl`;
63456
63384
  const hit = names.filter((n2) => n2.endsWith(suffix)).sort().at(-1);
63457
- return hit ? import_node_path41.default.join(dir, hit) : null;
63385
+ return hit ? import_node_path40.default.join(dir, hit) : null;
63458
63386
  }
63459
63387
  function locatePiSessionFile(sessionsRoot, cwd, toolSessionId) {
63460
63388
  const direct = findInDir(piProjectSessionDir(sessionsRoot, cwd), toolSessionId);
@@ -63466,7 +63394,7 @@ function locatePiSessionFile(sessionsRoot, cwd, toolSessionId) {
63466
63394
  return null;
63467
63395
  }
63468
63396
  for (const d2 of dirs) {
63469
- const hit = findInDir(import_node_path41.default.join(sessionsRoot, d2), toolSessionId);
63397
+ const hit = findInDir(import_node_path40.default.join(sessionsRoot, d2), toolSessionId);
63470
63398
  if (hit) return hit;
63471
63399
  }
63472
63400
  return null;
@@ -63565,7 +63493,7 @@ var PiHistoryReader = class {
63565
63493
  return [];
63566
63494
  }
63567
63495
  async listSessions(args) {
63568
- const want = import_node_path41.default.resolve(args.projectPath);
63496
+ const want = import_node_path40.default.resolve(args.projectPath);
63569
63497
  const dir = piProjectSessionDir(this.deps.sessionsRoot, want);
63570
63498
  let names;
63571
63499
  try {
@@ -63577,12 +63505,12 @@ var PiHistoryReader = class {
63577
63505
  let scanned = 0;
63578
63506
  for (const n2 of names) {
63579
63507
  if (++scanned > PI_LIST_SESSIONS_SCAN_CAP) break;
63580
- const file = import_node_path41.default.join(dir, n2);
63508
+ const file = import_node_path40.default.join(dir, n2);
63581
63509
  const head = parseLine2(readFirstLine(file) ?? "");
63582
63510
  if (!head || head.type !== "session") continue;
63583
63511
  const cwd = str3(head.cwd);
63584
63512
  const id = str3(head.id);
63585
- if (!cwd || !id || import_node_path41.default.resolve(cwd) !== want) continue;
63513
+ if (!cwd || !id || import_node_path40.default.resolve(cwd) !== want) continue;
63586
63514
  let mtimeMs;
63587
63515
  try {
63588
63516
  mtimeMs = import_node_fs36.default.statSync(file).mtimeMs;
@@ -63817,7 +63745,7 @@ var PiAdapter = class {
63817
63745
  init_protocol();
63818
63746
 
63819
63747
  // src/tools/codex-skills.ts
63820
- var import_node_path42 = __toESM(require("path"), 1);
63748
+ var import_node_path41 = __toESM(require("path"), 1);
63821
63749
  function str4(v3) {
63822
63750
  return typeof v3 === "string" ? v3 : void 0;
63823
63751
  }
@@ -63832,13 +63760,13 @@ function mapSkillsListResponse(res) {
63832
63760
  const r2 = s2 ?? {};
63833
63761
  const name = str4(r2.name);
63834
63762
  if (!name) continue;
63835
- const path102 = str4(r2.path);
63763
+ const path100 = str4(r2.path);
63836
63764
  const description = str4(r2.description);
63837
63765
  const isPlugin = name.includes(":");
63838
63766
  out.push({
63839
63767
  name,
63840
63768
  source: isPlugin ? "plugin" : "project",
63841
- ...path102 ? { path: path102 } : {},
63769
+ ...path100 ? { path: path100 } : {},
63842
63770
  ...description ? { description } : {},
63843
63771
  ...isPlugin ? { plugin: name.split(":")[0] } : {}
63844
63772
  });
@@ -63854,7 +63782,7 @@ async function listCodexSkills(cwd, deps = {}) {
63854
63782
  // 先写 extraRoots 再写 list(stdio 按写入顺序处理,fire-and-forget 不 await 回包;
63855
63783
  // codex-session.ts ready 序列同款,两处保持一致)。失败不阻塞 list。
63856
63784
  beforeRequest: (client) => {
63857
- void client.request("skills/extraRoots/set", { extraRoots: [import_node_path42.default.join(cwd, ".claude", "skills")] }).catch(() => void 0);
63785
+ void client.request("skills/extraRoots/set", { extraRoots: [import_node_path41.default.join(cwd, ".claude", "skills")] }).catch(() => void 0);
63858
63786
  }
63859
63787
  });
63860
63788
  return mapSkillsListResponse(res);
@@ -63930,14 +63858,14 @@ function rec4(v3) {
63930
63858
  // src/workspace/browser.ts
63931
63859
  var import_node_fs38 = __toESM(require("fs"), 1);
63932
63860
  var import_node_os11 = __toESM(require("os"), 1);
63933
- var import_node_path43 = __toESM(require("path"), 1);
63861
+ var import_node_path42 = __toESM(require("path"), 1);
63934
63862
  init_protocol();
63935
63863
  var MAX_FILE_BYTES2 = 2 * 1024 * 1024;
63936
63864
  function resolveInsideCwd(cwd, subpath) {
63937
- const absCwd = import_node_path43.default.resolve(cwd);
63938
- const joined = import_node_path43.default.resolve(absCwd, subpath ?? ".");
63939
- const rel = import_node_path43.default.relative(absCwd, joined);
63940
- if (rel.startsWith("..") || import_node_path43.default.isAbsolute(rel)) {
63865
+ const absCwd = import_node_path42.default.resolve(cwd);
63866
+ const joined = import_node_path42.default.resolve(absCwd, subpath ?? ".");
63867
+ const rel = import_node_path42.default.relative(absCwd, joined);
63868
+ if (rel.startsWith("..") || import_node_path42.default.isAbsolute(rel)) {
63941
63869
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
63942
63870
  }
63943
63871
  return joined;
@@ -63968,7 +63896,7 @@ var WorkspaceBrowser = class {
63968
63896
  mtime: ""
63969
63897
  };
63970
63898
  try {
63971
- const st2 = import_node_fs38.default.statSync(import_node_path43.default.join(full, d2.name));
63899
+ const st2 = import_node_fs38.default.statSync(import_node_path42.default.join(full, d2.name));
63972
63900
  entry.mtime = new Date(st2.mtimeMs).toISOString();
63973
63901
  if (d2.isFile()) entry.size = st2.size;
63974
63902
  } catch {
@@ -64015,7 +63943,7 @@ var WorkspaceBrowser = class {
64015
63943
  // src/skills/agents-scanner.ts
64016
63944
  var import_node_fs39 = __toESM(require("fs"), 1);
64017
63945
  var import_node_os12 = __toESM(require("os"), 1);
64018
- var import_node_path44 = __toESM(require("path"), 1);
63946
+ var import_node_path43 = __toESM(require("path"), 1);
64019
63947
  var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
64020
63948
  function isDirLikeSync2(p3) {
64021
63949
  try {
@@ -64053,10 +63981,10 @@ function scanAgentsDir(dir, source, seen, out) {
64053
63981
  }
64054
63982
  for (const ent of entries) {
64055
63983
  if (!ent.name.endsWith(".md")) continue;
64056
- if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path44.default.join(dir, ent.name)))) {
63984
+ if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path43.default.join(dir, ent.name)))) {
64057
63985
  continue;
64058
63986
  }
64059
- const filePath = import_node_path44.default.join(dir, ent.name);
63987
+ const filePath = import_node_path43.default.join(dir, ent.name);
64060
63988
  const baseName = ent.name.replace(/\.md$/, "");
64061
63989
  if (seen.has(baseName)) continue;
64062
63990
  seen.add(baseName);
@@ -64079,7 +64007,7 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
64079
64007
  return;
64080
64008
  }
64081
64009
  for (const ent of entries) {
64082
- const childPath = import_node_path44.default.join(dir, ent.name);
64010
+ const childPath = import_node_path43.default.join(dir, ent.name);
64083
64011
  if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
64084
64012
  walk2(childPath, [...namespaces, ent.name]);
64085
64013
  continue;
@@ -64104,9 +64032,9 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
64104
64032
  walk2(root, []);
64105
64033
  }
64106
64034
  function readInstalledPlugins2(home) {
64107
- const pluginsDir = import_node_path44.default.join(home, ".claude", "plugins");
64108
- const v22 = import_node_path44.default.join(pluginsDir, "installed_plugins_v2.json");
64109
- const v1 = import_node_path44.default.join(pluginsDir, "installed_plugins.json");
64035
+ const pluginsDir = import_node_path43.default.join(home, ".claude", "plugins");
64036
+ const v22 = import_node_path43.default.join(pluginsDir, "installed_plugins_v2.json");
64037
+ const v1 = import_node_path43.default.join(pluginsDir, "installed_plugins.json");
64110
64038
  let raw = null;
64111
64039
  for (const candidate of [v22, v1]) {
64112
64040
  try {
@@ -64135,19 +64063,19 @@ function readInstalledPlugins2(home) {
64135
64063
  return out;
64136
64064
  }
64137
64065
  function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
64138
- let cur = import_node_path44.default.resolve(startCwd);
64139
- const fsRoot = import_node_path44.default.parse(cur).root;
64066
+ let cur = import_node_path43.default.resolve(startCwd);
64067
+ const fsRoot = import_node_path43.default.parse(cur).root;
64140
64068
  while (true) {
64141
- scanAgentsDir(import_node_path44.default.join(cur, ".claude", "agents"), "project", seen, out);
64069
+ scanAgentsDir(import_node_path43.default.join(cur, ".claude", "agents"), "project", seen, out);
64142
64070
  let hasGit = false;
64143
64071
  try {
64144
- hasGit = import_node_fs39.default.existsSync(import_node_path44.default.join(cur, ".git"));
64072
+ hasGit = import_node_fs39.default.existsSync(import_node_path43.default.join(cur, ".git"));
64145
64073
  } catch {
64146
64074
  }
64147
64075
  if (hasGit) return;
64148
64076
  if (cur === home) return;
64149
64077
  if (cur === fsRoot) return;
64150
- const parent = import_node_path44.default.dirname(cur);
64078
+ const parent = import_node_path43.default.dirname(cur);
64151
64079
  if (parent === cur) return;
64152
64080
  cur = parent;
64153
64081
  }
@@ -64182,7 +64110,7 @@ var AgentsScanner = class {
64182
64110
  }
64183
64111
  const fsBlock = [];
64184
64112
  scanAgentsDir(
64185
- import_node_path44.default.join(this.home, ".claude", "agents"),
64113
+ import_node_path43.default.join(this.home, ".claude", "agents"),
64186
64114
  "global",
64187
64115
  seen,
64188
64116
  fsBlock
@@ -64196,7 +64124,7 @@ var AgentsScanner = class {
64196
64124
  ...this.extraPluginRoots
64197
64125
  ];
64198
64126
  for (const { name, root } of plugins) {
64199
- const agentsRoot = import_node_path44.default.join(root, "agents");
64127
+ const agentsRoot = import_node_path43.default.join(root, "agents");
64200
64128
  scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
64201
64129
  }
64202
64130
  return [...builtinBlock, ...fsBlock];
@@ -64206,13 +64134,13 @@ var AgentsScanner = class {
64206
64134
  // src/observer/session-observer.ts
64207
64135
  var import_node_fs41 = __toESM(require("fs"), 1);
64208
64136
  var import_node_os14 = __toESM(require("os"), 1);
64209
- var import_node_path46 = __toESM(require("path"), 1);
64137
+ var import_node_path45 = __toESM(require("path"), 1);
64210
64138
  init_claude_history();
64211
64139
 
64212
64140
  // src/observer/subagent-meta-observer.ts
64213
64141
  var import_node_fs40 = __toESM(require("fs"), 1);
64214
64142
  var import_node_os13 = __toESM(require("os"), 1);
64215
- var import_node_path45 = __toESM(require("path"), 1);
64143
+ var import_node_path44 = __toESM(require("path"), 1);
64216
64144
  init_claude_history();
64217
64145
  var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
64218
64146
  var SubagentMetaObserver = class {
@@ -64225,7 +64153,7 @@ var SubagentMetaObserver = class {
64225
64153
  watches = /* @__PURE__ */ new Map();
64226
64154
  // public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
64227
64155
  resolveSubagentDir(cwd, toolSessionId) {
64228
- return import_node_path45.default.join(
64156
+ return import_node_path44.default.join(
64229
64157
  this.home,
64230
64158
  ".claude",
64231
64159
  "projects",
@@ -64281,7 +64209,7 @@ var SubagentMetaObserver = class {
64281
64209
  if (!m3) return;
64282
64210
  const agentId = m3[1];
64283
64211
  if (w3.emitted.has(agentId)) return;
64284
- const file = import_node_path45.default.join(w3.dirPath, name);
64212
+ const file = import_node_path44.default.join(w3.dirPath, name);
64285
64213
  let raw;
64286
64214
  try {
64287
64215
  raw = import_node_fs40.default.readFileSync(file, "utf8");
@@ -64341,7 +64269,7 @@ var SessionObserver = class {
64341
64269
  metaObserver;
64342
64270
  resolveJsonlPath(cwd, toolSessionId, override) {
64343
64271
  if (override) return override;
64344
- return import_node_path46.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
64272
+ return import_node_path45.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
64345
64273
  }
64346
64274
  start(args) {
64347
64275
  this.stop(args.sessionId);
@@ -64367,10 +64295,10 @@ var SessionObserver = class {
64367
64295
  lastDeriveMs: 0
64368
64296
  };
64369
64297
  try {
64370
- import_node_fs41.default.mkdirSync(import_node_path46.default.dirname(filePath), { recursive: true });
64298
+ import_node_fs41.default.mkdirSync(import_node_path45.default.dirname(filePath), { recursive: true });
64371
64299
  } catch {
64372
64300
  }
64373
- w3.watcher = import_node_fs41.default.watch(import_node_path46.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
64301
+ w3.watcher = import_node_fs41.default.watch(import_node_path45.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
64374
64302
  if (!changedName || !w3.filePath.endsWith(changedName)) return;
64375
64303
  this.poll(w3);
64376
64304
  });
@@ -64467,7 +64395,7 @@ var SessionObserver = class {
64467
64395
  const now = Date.now();
64468
64396
  if (now - w3.lastRelocateScanMs < 1e3) return;
64469
64397
  w3.lastRelocateScanMs = now;
64470
- const projectsRoot = import_node_path46.default.join(this.home, ".claude", "projects");
64398
+ const projectsRoot = import_node_path45.default.join(this.home, ".claude", "projects");
64471
64399
  const found = findTranscriptByToolSessionId(projectsRoot, w3.toolSessionId);
64472
64400
  if (!found || found === w3.filePath) return;
64473
64401
  try {
@@ -64476,7 +64404,7 @@ var SessionObserver = class {
64476
64404
  }
64477
64405
  w3.filePath = found;
64478
64406
  try {
64479
- w3.watcher = import_node_fs41.default.watch(import_node_path46.default.dirname(found), { persistent: false }, (_event, changedName) => {
64407
+ w3.watcher = import_node_fs41.default.watch(import_node_path45.default.dirname(found), { persistent: false }, (_event, changedName) => {
64480
64408
  if (!changedName || !w3.filePath.endsWith(changedName)) return;
64481
64409
  this.poll(w3);
64482
64410
  });
@@ -64600,7 +64528,7 @@ var import_node_child_process12 = require("child_process");
64600
64528
  init_protocol();
64601
64529
  var import_node_fs42 = __toESM(require("fs"), 1);
64602
64530
  var import_node_os15 = __toESM(require("os"), 1);
64603
- var import_node_path47 = __toESM(require("path"), 1);
64531
+ var import_node_path46 = __toESM(require("path"), 1);
64604
64532
  var TITLE_GEN_DIR_PREFIX = "clawd-title-";
64605
64533
  var TITLE_MODEL_BY_TOOL = {
64606
64534
  claude: "haiku",
@@ -64671,7 +64599,7 @@ async function generateSessionTitle(tool, firstMessage, deps = {}) {
64671
64599
  if (!text) return null;
64672
64600
  let workDir;
64673
64601
  try {
64674
- workDir = import_node_fs42.default.mkdtempSync(import_node_path47.default.join(import_node_os15.default.tmpdir(), TITLE_GEN_DIR_PREFIX));
64602
+ workDir = import_node_fs42.default.mkdtempSync(import_node_path46.default.join(import_node_os15.default.tmpdir(), TITLE_GEN_DIR_PREFIX));
64675
64603
  } catch {
64676
64604
  return null;
64677
64605
  }
@@ -64681,8 +64609,8 @@ async function generateSessionTitle(tool, firstMessage, deps = {}) {
64681
64609
  } catch {
64682
64610
  }
64683
64611
  };
64684
- const outFile = import_node_path47.default.join(workDir, `codex-title-${process.pid}-${++outFileSeq}-${Date.now()}.txt`);
64685
- const schemaFile = import_node_path47.default.join(workDir, "title-schema.json");
64612
+ const outFile = import_node_path46.default.join(workDir, `codex-title-${process.pid}-${++outFileSeq}-${Date.now()}.txt`);
64613
+ const schemaFile = import_node_path46.default.join(workDir, "title-schema.json");
64686
64614
  if (isCodexFamily(tool)) {
64687
64615
  try {
64688
64616
  import_node_fs42.default.writeFileSync(schemaFile, CODEX_TITLE_SCHEMA);
@@ -65381,7 +65309,7 @@ async function authenticate(token, deps) {
65381
65309
 
65382
65310
  // src/legacy-cleanup.ts
65383
65311
  var fs53 = __toESM(require("fs/promises"), 1);
65384
- var path55 = __toESM(require("path"), 1);
65312
+ var path54 = __toESM(require("path"), 1);
65385
65313
  var LEGACY_FILES = [
65386
65314
  "personal-capability.json",
65387
65315
  "received-capabilities.json",
@@ -65390,7 +65318,7 @@ var LEGACY_FILES = [
65390
65318
  async function cleanupLegacyCapabilityFiles(dataDir, logger) {
65391
65319
  const removed = [];
65392
65320
  for (const name of LEGACY_FILES) {
65393
- const p3 = path55.join(dataDir, name);
65321
+ const p3 = path54.join(dataDir, name);
65394
65322
  try {
65395
65323
  await fs53.unlink(p3);
65396
65324
  removed.push(name);
@@ -65405,7 +65333,7 @@ async function cleanupLegacyCapabilityFiles(dataDir, logger) {
65405
65333
 
65406
65334
  // src/inbox/inbox-store.ts
65407
65335
  var fs54 = __toESM(require("fs"), 1);
65408
- var path56 = __toESM(require("path"), 1);
65336
+ var path55 = __toESM(require("path"), 1);
65409
65337
  var INBOX_SUBDIR = "inbox";
65410
65338
  var InboxStore = class {
65411
65339
  constructor(dataDir) {
@@ -65503,10 +65431,10 @@ var InboxStore = class {
65503
65431
  }
65504
65432
  }
65505
65433
  dirPath() {
65506
- return path56.join(this.dataDir, INBOX_SUBDIR);
65434
+ return path55.join(this.dataDir, INBOX_SUBDIR);
65507
65435
  }
65508
65436
  filePath(peerDeviceId) {
65509
- return path56.join(this.dirPath(), `${peerDeviceId}.jsonl`);
65437
+ return path55.join(this.dirPath(), `${peerDeviceId}.jsonl`);
65510
65438
  }
65511
65439
  };
65512
65440
  function parseAllLines(raw) {
@@ -65595,7 +65523,7 @@ var InboxManager = class {
65595
65523
 
65596
65524
  // src/state/contact-store.ts
65597
65525
  var fs55 = __toESM(require("fs"), 1);
65598
- var path57 = __toESM(require("path"), 1);
65526
+ var path56 = __toESM(require("path"), 1);
65599
65527
  var FILE_NAME = "contacts.json";
65600
65528
  var ContactStore = class {
65601
65529
  constructor(dataDir) {
@@ -65605,7 +65533,7 @@ var ContactStore = class {
65605
65533
  contacts = /* @__PURE__ */ new Map();
65606
65534
  load() {
65607
65535
  this.contacts.clear();
65608
- const file = path57.join(this.dataDir, FILE_NAME);
65536
+ const file = path56.join(this.dataDir, FILE_NAME);
65609
65537
  let raw;
65610
65538
  try {
65611
65539
  raw = fs55.readFileSync(file, "utf8");
@@ -65689,7 +65617,7 @@ var ContactStore = class {
65689
65617
  return true;
65690
65618
  }
65691
65619
  flush() {
65692
- const file = path57.join(this.dataDir, FILE_NAME);
65620
+ const file = path56.join(this.dataDir, FILE_NAME);
65693
65621
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
65694
65622
  const content = JSON.stringify(
65695
65623
  { contacts: Array.from(this.contacts.values()) },
@@ -65811,52 +65739,52 @@ async function connectRemote(args) {
65811
65739
 
65812
65740
  // src/migrations/2026-05-20-flatten-sessions.ts
65813
65741
  var fs56 = __toESM(require("fs"), 1);
65814
- var path58 = __toESM(require("path"), 1);
65742
+ var path57 = __toESM(require("path"), 1);
65815
65743
  var MIGRATION_FLAG_NAME = ".migration.v1.done";
65816
65744
  function migrateFlattenSessions(opts) {
65817
65745
  const dataDir = opts.dataDir;
65818
65746
  const now = opts.now ?? Date.now;
65819
- const sessionsDir = path58.join(dataDir, "sessions");
65820
- const flagPath = path58.join(sessionsDir, MIGRATION_FLAG_NAME);
65747
+ const sessionsDir = path57.join(dataDir, "sessions");
65748
+ const flagPath = path57.join(sessionsDir, MIGRATION_FLAG_NAME);
65821
65749
  if (existsSync3(flagPath)) {
65822
65750
  return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
65823
65751
  }
65824
65752
  let movedBare = 0;
65825
65753
  let movedVmOwner = 0;
65826
65754
  let archivedListener = 0;
65827
- const defaultDir = path58.join(sessionsDir, "default");
65755
+ const defaultDir = path57.join(sessionsDir, "default");
65828
65756
  if (existsSync3(defaultDir)) {
65829
65757
  for (const entry of readdirSafe(defaultDir)) {
65830
65758
  if (!entry.endsWith(".json")) continue;
65831
- const src = path58.join(defaultDir, entry);
65832
- const dst = path58.join(sessionsDir, entry);
65759
+ const src = path57.join(defaultDir, entry);
65760
+ const dst = path57.join(sessionsDir, entry);
65833
65761
  fs56.renameSync(src, dst);
65834
65762
  movedBare += 1;
65835
65763
  }
65836
65764
  rmdirIfEmpty(defaultDir);
65837
65765
  }
65838
65766
  for (const pid of readdirSafe(sessionsDir)) {
65839
- const personaDir = path58.join(sessionsDir, pid);
65767
+ const personaDir = path57.join(sessionsDir, pid);
65840
65768
  if (!isDir(personaDir)) continue;
65841
65769
  if (pid === "default") continue;
65842
- const ownerSrc = path58.join(personaDir, "owner");
65770
+ const ownerSrc = path57.join(personaDir, "owner");
65843
65771
  if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
65844
- const ownerDst = path58.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
65772
+ const ownerDst = path57.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
65845
65773
  fs56.mkdirSync(ownerDst, { recursive: true });
65846
65774
  for (const file of readdirSafe(ownerSrc)) {
65847
65775
  if (!file.endsWith(".json")) continue;
65848
- fs56.renameSync(path58.join(ownerSrc, file), path58.join(ownerDst, file));
65776
+ fs56.renameSync(path57.join(ownerSrc, file), path57.join(ownerDst, file));
65849
65777
  movedVmOwner += 1;
65850
65778
  }
65851
65779
  rmdirIfEmpty(ownerSrc);
65852
65780
  }
65853
- const listenerSrc = path58.join(personaDir, "listener");
65781
+ const listenerSrc = path57.join(personaDir, "listener");
65854
65782
  if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
65855
- const archiveDst = path58.join(dataDir, ".legacy", `listener-${pid}`);
65783
+ const archiveDst = path57.join(dataDir, ".legacy", `listener-${pid}`);
65856
65784
  fs56.mkdirSync(archiveDst, { recursive: true });
65857
65785
  for (const file of readdirSafe(listenerSrc)) {
65858
65786
  if (!file.endsWith(".json")) continue;
65859
- fs56.renameSync(path58.join(listenerSrc, file), path58.join(archiveDst, file));
65787
+ fs56.renameSync(path57.join(listenerSrc, file), path57.join(archiveDst, file));
65860
65788
  archivedListener += 1;
65861
65789
  }
65862
65790
  rmdirIfEmpty(listenerSrc);
@@ -65904,13 +65832,13 @@ function rmdirIfEmpty(p3) {
65904
65832
 
65905
65833
  // src/migrations/2026-08-18-drop-seeded-projects.ts
65906
65834
  var fs57 = __toESM(require("fs"), 1);
65907
- var path59 = __toESM(require("path"), 1);
65835
+ var path58 = __toESM(require("path"), 1);
65908
65836
  var DROP_SEEDED_PROJECTS_FLAG = ".projects-seed-dropped.v1.done";
65909
65837
  function dropSeededProjects(opts) {
65910
65838
  fs57.mkdirSync(opts.dataDir, { recursive: true });
65911
- const flag = path59.join(opts.dataDir, DROP_SEEDED_PROJECTS_FLAG);
65839
+ const flag = path58.join(opts.dataDir, DROP_SEEDED_PROJECTS_FLAG);
65912
65840
  if (fs57.existsSync(flag)) return { skipped: true, dropped: 0, backup: null };
65913
- const file = path59.join(opts.dataDir, "projects.json");
65841
+ const file = path58.join(opts.dataDir, "projects.json");
65914
65842
  let raw = null;
65915
65843
  let dropped = 0;
65916
65844
  try {
@@ -65920,9 +65848,9 @@ function dropSeededProjects(opts) {
65920
65848
  }
65921
65849
  let backup = null;
65922
65850
  if (raw != null && dropped > 0) {
65923
- const dir = path59.join(opts.dataDir, "backups");
65851
+ const dir = path58.join(opts.dataDir, "backups");
65924
65852
  fs57.mkdirSync(dir, { recursive: true });
65925
- backup = path59.join(dir, `projects.seed-dropped.${(opts.now ?? Date.now)()}.json`);
65853
+ backup = path58.join(dir, `projects.seed-dropped.${(opts.now ?? Date.now)()}.json`);
65926
65854
  fs57.writeFileSync(backup, raw);
65927
65855
  }
65928
65856
  if (raw != null || dropped > 0) {
@@ -65934,11 +65862,11 @@ function dropSeededProjects(opts) {
65934
65862
 
65935
65863
  // src/transport/http-router.ts
65936
65864
  var import_node_fs44 = __toESM(require("fs"), 1);
65937
- var import_node_path50 = __toESM(require("path"), 1);
65865
+ var import_node_path49 = __toESM(require("path"), 1);
65938
65866
 
65939
65867
  // src/attachment/upload.ts
65940
65868
  var import_node_fs43 = __toESM(require("fs"), 1);
65941
- var import_node_path48 = __toESM(require("path"), 1);
65869
+ var import_node_path47 = __toESM(require("path"), 1);
65942
65870
  var import_node_crypto11 = __toESM(require("crypto"), 1);
65943
65871
  var import_promises7 = require("stream/promises");
65944
65872
  var UploadError = class extends Error {
@@ -65950,14 +65878,14 @@ var UploadError = class extends Error {
65950
65878
  code;
65951
65879
  };
65952
65880
  function assertValidFileName(fileName) {
65953
- if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path48.default.basename(fileName)) {
65881
+ if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path47.default.basename(fileName)) {
65954
65882
  throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
65955
65883
  }
65956
65884
  }
65957
65885
  var HASH_PREFIX_LEN = 16;
65958
65886
  async function writeUploadedAttachment(args) {
65959
65887
  assertValidFileName(args.fileName);
65960
- const attachmentsRoot = import_node_path48.default.join(args.baseDir, ".attachments");
65888
+ const attachmentsRoot = import_node_path47.default.join(args.baseDir, ".attachments");
65961
65889
  try {
65962
65890
  import_node_fs43.default.mkdirSync(attachmentsRoot, { recursive: true });
65963
65891
  } catch (err) {
@@ -65965,7 +65893,7 @@ async function writeUploadedAttachment(args) {
65965
65893
  }
65966
65894
  const hasher = import_node_crypto11.default.createHash("sha256");
65967
65895
  let actualSize = 0;
65968
- const tmpPath = import_node_path48.default.join(
65896
+ const tmpPath = import_node_path47.default.join(
65969
65897
  attachmentsRoot,
65970
65898
  `.upload-${process.pid}-${Date.now()}-${import_node_crypto11.default.randomBytes(4).toString("hex")}`
65971
65899
  );
@@ -66000,7 +65928,7 @@ async function writeUploadedAttachment(args) {
66000
65928
  );
66001
65929
  }
66002
65930
  const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
66003
- const hashDir = import_node_path48.default.join(attachmentsRoot, attachmentId);
65931
+ const hashDir = import_node_path47.default.join(attachmentsRoot, attachmentId);
66004
65932
  let finalFileName;
66005
65933
  let hashDirExists = false;
66006
65934
  try {
@@ -66018,7 +65946,7 @@ async function writeUploadedAttachment(args) {
66018
65946
  try {
66019
65947
  import_node_fs43.default.mkdirSync(hashDir, { recursive: true });
66020
65948
  finalFileName = args.fileName;
66021
- import_node_fs43.default.renameSync(tmpPath, import_node_path48.default.join(hashDir, finalFileName));
65949
+ import_node_fs43.default.renameSync(tmpPath, import_node_path47.default.join(hashDir, finalFileName));
66022
65950
  } catch (err) {
66023
65951
  try {
66024
65952
  import_node_fs43.default.unlinkSync(tmpPath);
@@ -66027,7 +65955,7 @@ async function writeUploadedAttachment(args) {
66027
65955
  throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
66028
65956
  }
66029
65957
  }
66030
- const absPath = import_node_path48.default.join(hashDir, finalFileName);
65958
+ const absPath = import_node_path47.default.join(hashDir, finalFileName);
66031
65959
  const relPath = absPath;
66032
65960
  args.groupFileStore.upsert(args.scope, args.sessionId, {
66033
65961
  relPath: absPath,
@@ -66042,7 +65970,7 @@ async function writeUploadedAttachment(args) {
66042
65970
 
66043
65971
  // src/extension/import.ts
66044
65972
  var import_promises8 = __toESM(require("fs/promises"), 1);
66045
- var import_node_path49 = __toESM(require("path"), 1);
65973
+ var import_node_path48 = __toESM(require("path"), 1);
66046
65974
  var import_node_os16 = __toESM(require("os"), 1);
66047
65975
  var import_jszip = __toESM(require_lib3(), 1);
66048
65976
  var ImportError = class extends Error {
@@ -66060,7 +65988,7 @@ async function importZip(buf, root) {
66060
65988
  throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
66061
65989
  }
66062
65990
  for (const name of Object.keys(zip.files)) {
66063
- if (name.includes("..") || name.startsWith("/") || import_node_path49.default.isAbsolute(name)) {
65991
+ if (name.includes("..") || name.startsWith("/") || import_node_path48.default.isAbsolute(name)) {
66064
65992
  throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
66065
65993
  }
66066
65994
  }
@@ -66093,7 +66021,7 @@ async function importZip(buf, root) {
66093
66021
  );
66094
66022
  }
66095
66023
  }
66096
- const destDir = import_node_path49.default.join(root, manifest.id);
66024
+ const destDir = import_node_path48.default.join(root, manifest.id);
66097
66025
  let destExists = false;
66098
66026
  try {
66099
66027
  await import_promises8.default.access(destDir);
@@ -66103,15 +66031,15 @@ async function importZip(buf, root) {
66103
66031
  if (destExists) {
66104
66032
  throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
66105
66033
  }
66106
- const stage = await import_promises8.default.mkdtemp(import_node_path49.default.join(import_node_os16.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
66034
+ const stage = await import_promises8.default.mkdtemp(import_node_path48.default.join(import_node_os16.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
66107
66035
  try {
66108
66036
  for (const [name, entry] of Object.entries(zip.files)) {
66109
- const dest = import_node_path49.default.join(stage, name);
66037
+ const dest = import_node_path48.default.join(stage, name);
66110
66038
  if (entry.dir) {
66111
66039
  await import_promises8.default.mkdir(dest, { recursive: true });
66112
66040
  continue;
66113
66041
  }
66114
- await import_promises8.default.mkdir(import_node_path49.default.dirname(dest), { recursive: true });
66042
+ await import_promises8.default.mkdir(import_node_path48.default.dirname(dest), { recursive: true });
66115
66043
  const content = await entry.async("nodebuffer");
66116
66044
  await import_promises8.default.writeFile(dest, content);
66117
66045
  }
@@ -66165,7 +66093,7 @@ var SHARE_UI_ASSET_MIME = {
66165
66093
  ".wasm": "application/wasm"
66166
66094
  };
66167
66095
  function shareUiAssetMime(filePath) {
66168
- const ext = import_node_path50.default.extname(filePath).toLowerCase();
66096
+ const ext = import_node_path49.default.extname(filePath).toLowerCase();
66169
66097
  return SHARE_UI_ASSET_MIME[ext] ?? lookupMime(filePath);
66170
66098
  }
66171
66099
  var AUTHED_RPC_ROUTE_PREFIX = "/rpc/";
@@ -66264,7 +66192,7 @@ function isValidUploadFileName(fileName) {
66264
66192
  if (fileName === "." || fileName === "..") return false;
66265
66193
  if (fileName.startsWith(".")) return false;
66266
66194
  if (fileName.includes("/") || fileName.includes("\\")) return false;
66267
- return fileName === import_node_path50.default.basename(fileName);
66195
+ return fileName === import_node_path49.default.basename(fileName);
66268
66196
  }
66269
66197
  function createHttpRouter(deps) {
66270
66198
  return async (req, res) => {
@@ -66487,7 +66415,7 @@ function createHttpRouter(deps) {
66487
66415
  sendHtml(res, statusByCode[r2.code], loader.renderErrorHtml(r2.code, msgByCode[r2.code]));
66488
66416
  return true;
66489
66417
  }
66490
- sendHtml(res, 200, loader.renderViewerHtml(import_node_path50.default.basename(r2.absPath)));
66418
+ sendHtml(res, 200, loader.renderViewerHtml(import_node_path49.default.basename(r2.absPath)));
66491
66419
  return true;
66492
66420
  }
66493
66421
  const ctx = deps.authResolver.resolveFromHeader(
@@ -66608,7 +66536,7 @@ function createHttpRouter(deps) {
66608
66536
  return true;
66609
66537
  }
66610
66538
  let absPath;
66611
- if (import_node_path50.default.isAbsolute(pathParam)) {
66539
+ if (import_node_path49.default.isAbsolute(pathParam)) {
66612
66540
  absPath = pathParam;
66613
66541
  } else if (deps.sessionStore) {
66614
66542
  const file = deps.sessionStore.read(sid);
@@ -66616,7 +66544,7 @@ function createHttpRouter(deps) {
66616
66544
  sendJson(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
66617
66545
  return true;
66618
66546
  }
66619
- absPath = import_node_path50.default.join(file.cwd, pathParam);
66547
+ absPath = import_node_path49.default.join(file.cwd, pathParam);
66620
66548
  } else {
66621
66549
  sendJson(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
66622
66550
  return true;
@@ -66715,7 +66643,7 @@ function streamFile(res, absPath, logger) {
66715
66643
  return;
66716
66644
  }
66717
66645
  const mime = lookupMime(absPath);
66718
- const basename2 = import_node_path50.default.basename(absPath);
66646
+ const basename2 = import_node_path49.default.basename(absPath);
66719
66647
  res.writeHead(200, {
66720
66648
  "Content-Type": mime,
66721
66649
  "Content-Length": String(stat.size),
@@ -66733,7 +66661,7 @@ function streamFile(res, absPath, logger) {
66733
66661
 
66734
66662
  // src/attachment/gc.ts
66735
66663
  var import_node_fs45 = __toESM(require("fs"), 1);
66736
- var import_node_path51 = __toESM(require("path"), 1);
66664
+ var import_node_path50 = __toESM(require("path"), 1);
66737
66665
  var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
66738
66666
  function runAttachmentGc(args) {
66739
66667
  const now = (args.now ?? Date.now)();
@@ -66742,12 +66670,12 @@ function runAttachmentGc(args) {
66742
66670
  for (const { scope, sessionId } of args.sessionScopes) {
66743
66671
  for (const entry of args.groupFileStore.list(scope, sessionId)) {
66744
66672
  if (entry.stale) continue;
66745
- if (import_node_path51.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
66673
+ if (import_node_path50.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
66746
66674
  }
66747
66675
  }
66748
66676
  const visited = /* @__PURE__ */ new Set();
66749
66677
  for (const { scope, sessionId } of args.sessionScopes) {
66750
- const legacyDir = args.getSessionCwd?.(sessionId) ?? import_node_path51.default.join(
66678
+ const legacyDir = args.getSessionCwd?.(sessionId) ?? import_node_path50.default.join(
66751
66679
  args.dataDir,
66752
66680
  "sessions",
66753
66681
  ...scopeSubPath(scope).map(safeFileName),
@@ -66760,7 +66688,7 @@ function runAttachmentGc(args) {
66760
66688
  return true;
66761
66689
  });
66762
66690
  for (const rootDir of roots) {
66763
- const attRoot = import_node_path51.default.join(rootDir, ".attachments");
66691
+ const attRoot = import_node_path50.default.join(rootDir, ".attachments");
66764
66692
  let hashDirs;
66765
66693
  try {
66766
66694
  hashDirs = import_node_fs45.default.readdirSync(attRoot);
@@ -66770,7 +66698,7 @@ function runAttachmentGc(args) {
66770
66698
  continue;
66771
66699
  }
66772
66700
  for (const hashDir of hashDirs) {
66773
- const hashDirAbs = import_node_path51.default.join(attRoot, hashDir);
66701
+ const hashDirAbs = import_node_path50.default.join(attRoot, hashDir);
66774
66702
  let files;
66775
66703
  try {
66776
66704
  files = import_node_fs45.default.readdirSync(hashDirAbs);
@@ -66778,7 +66706,7 @@ function runAttachmentGc(args) {
66778
66706
  continue;
66779
66707
  }
66780
66708
  for (const name of files) {
66781
- const file = import_node_path51.default.join(hashDirAbs, name);
66709
+ const file = import_node_path50.default.join(hashDirAbs, name);
66782
66710
  let stat;
66783
66711
  try {
66784
66712
  stat = import_node_fs45.default.statSync(file);
@@ -66810,7 +66738,7 @@ function runAttachmentGc(args) {
66810
66738
 
66811
66739
  // src/attachment/group.ts
66812
66740
  var import_node_fs46 = __toESM(require("fs"), 1);
66813
- var import_node_path52 = __toESM(require("path"), 1);
66741
+ var import_node_path51 = __toESM(require("path"), 1);
66814
66742
  var import_node_crypto12 = __toESM(require("crypto"), 1);
66815
66743
  init_protocol();
66816
66744
  var GroupFileStore = class {
@@ -66822,11 +66750,11 @@ var GroupFileStore = class {
66822
66750
  this.logger = opts.logger;
66823
66751
  }
66824
66752
  rootForScope(scope) {
66825
- return import_node_path52.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
66753
+ return import_node_path51.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
66826
66754
  }
66827
66755
  /** 与 SessionStore.filePath 平级,扩展名 .group-files.json */
66828
66756
  filePath(scope, sessionId) {
66829
- return import_node_path52.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
66757
+ return import_node_path51.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
66830
66758
  }
66831
66759
  cacheKey(scope, sessionId) {
66832
66760
  return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
@@ -66861,7 +66789,7 @@ var GroupFileStore = class {
66861
66789
  }
66862
66790
  writeFile(scope, sessionId, entries) {
66863
66791
  const file = this.filePath(scope, sessionId);
66864
- import_node_fs46.default.mkdirSync(import_node_path52.default.dirname(file), { recursive: true });
66792
+ import_node_fs46.default.mkdirSync(import_node_path51.default.dirname(file), { recursive: true });
66865
66793
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
66866
66794
  import_node_fs46.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
66867
66795
  import_node_fs46.default.renameSync(tmp, file);
@@ -66969,7 +66897,7 @@ var GroupFileStore = class {
66969
66897
  * 不在 persona 目录里(见文件头的路径约定)。没树的 persona 是 noop。
66970
66898
  */
66971
66899
  deletePersona(personaId2) {
66972
- import_node_fs46.default.rmSync(import_node_path52.default.join(this.dataDir, "sessions", safeFileName(personaId2)), { recursive: true, force: true });
66900
+ import_node_fs46.default.rmSync(import_node_path51.default.join(this.dataDir, "sessions", safeFileName(personaId2)), { recursive: true, force: true });
66973
66901
  const prefix = `persona:${personaId2}:`;
66974
66902
  for (const key of this.cache.keys()) {
66975
66903
  if (key.startsWith(prefix)) this.cache.delete(key);
@@ -66979,9 +66907,9 @@ var GroupFileStore = class {
66979
66907
 
66980
66908
  // src/discovery/state-file.ts
66981
66909
  var import_node_fs47 = __toESM(require("fs"), 1);
66982
- var import_node_path53 = __toESM(require("path"), 1);
66910
+ var import_node_path52 = __toESM(require("path"), 1);
66983
66911
  function defaultStateFilePath(dataDir) {
66984
- return import_node_path53.default.join(dataDir, "state.json");
66912
+ return import_node_path52.default.join(dataDir, "state.json");
66985
66913
  }
66986
66914
  function isPidAlive(pid) {
66987
66915
  if (!Number.isFinite(pid) || pid <= 0) return false;
@@ -67017,7 +66945,7 @@ var StateFileManager = class {
67017
66945
  return { status: "stale", existing };
67018
66946
  }
67019
66947
  write(state) {
67020
- import_node_fs47.default.mkdirSync(import_node_path53.default.dirname(this.file), { recursive: true });
66948
+ import_node_fs47.default.mkdirSync(import_node_path52.default.dirname(this.file), { recursive: true });
67021
66949
  const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
67022
66950
  import_node_fs47.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
67023
66951
  import_node_fs47.default.renameSync(tmp, this.file);
@@ -67045,13 +66973,13 @@ function readSpawnedByDesktopFromEnv(env = process.env) {
67045
66973
 
67046
66974
  // src/tunnel/tunnel-manager.ts
67047
66975
  var import_node_fs51 = __toESM(require("fs"), 1);
67048
- var import_node_path57 = __toESM(require("path"), 1);
66976
+ var import_node_path56 = __toESM(require("path"), 1);
67049
66977
  var import_node_crypto13 = __toESM(require("crypto"), 1);
67050
66978
  var import_node_child_process15 = require("child_process");
67051
66979
 
67052
66980
  // src/tunnel/tunnel-store.ts
67053
66981
  var import_node_fs48 = __toESM(require("fs"), 1);
67054
- var import_node_path54 = __toESM(require("path"), 1);
66982
+ var import_node_path53 = __toESM(require("path"), 1);
67055
66983
  var TunnelStore = class {
67056
66984
  constructor(filePath) {
67057
66985
  this.filePath = filePath;
@@ -67070,7 +66998,7 @@ var TunnelStore = class {
67070
66998
  }
67071
66999
  }
67072
67000
  async set(v3) {
67073
- const dir = import_node_path54.default.dirname(this.filePath);
67001
+ const dir = import_node_path53.default.dirname(this.filePath);
67074
67002
  await import_node_fs48.default.promises.mkdir(dir, { recursive: true });
67075
67003
  const data = JSON.stringify(v3, null, 2);
67076
67004
  const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
@@ -67182,7 +67110,7 @@ function escape2(v3) {
67182
67110
  // src/tunnel/frpc-binary.ts
67183
67111
  var import_node_fs49 = __toESM(require("fs"), 1);
67184
67112
  var import_node_os17 = __toESM(require("os"), 1);
67185
- var import_node_path55 = __toESM(require("path"), 1);
67113
+ var import_node_path54 = __toESM(require("path"), 1);
67186
67114
  var import_node_child_process13 = require("child_process");
67187
67115
  var import_node_stream3 = require("stream");
67188
67116
  var import_promises9 = require("stream/promises");
@@ -67221,13 +67149,13 @@ async function ensureFrpcBinary(opts) {
67221
67149
  }
67222
67150
  const version2 = opts.version ?? FRPC_VERSION;
67223
67151
  const platform = opts.platform ?? detectPlatform();
67224
- const binDir = import_node_path55.default.join(opts.dataDir, "bin");
67152
+ const binDir = import_node_path54.default.join(opts.dataDir, "bin");
67225
67153
  import_node_fs49.default.mkdirSync(binDir, { recursive: true });
67226
67154
  cleanupStaleArtifacts(binDir);
67227
- const stableBin = import_node_path55.default.join(binDir, "frpc");
67155
+ const stableBin = import_node_path54.default.join(binDir, "frpc");
67228
67156
  if (import_node_fs49.default.existsSync(stableBin)) return stableBin;
67229
67157
  const partialBin = `${stableBin}.partial`;
67230
- const tarballPath = import_node_path55.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
67158
+ const tarballPath = import_node_path54.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
67231
67159
  try {
67232
67160
  const url = frpcDownloadUrl(version2, platform);
67233
67161
  await downloadToFile(url, tarballPath, opts.fetchImpl);
@@ -67253,7 +67181,7 @@ function cleanupStaleArtifacts(binDir) {
67253
67181
  }
67254
67182
  for (const name of entries) {
67255
67183
  if (name.endsWith(".partial") || name.startsWith("extract-")) {
67256
- const full = import_node_path55.default.join(binDir, name);
67184
+ const full = import_node_path54.default.join(binDir, name);
67257
67185
  try {
67258
67186
  import_node_fs49.default.rmSync(full, { recursive: true, force: true });
67259
67187
  } catch {
@@ -67279,7 +67207,7 @@ async function downloadToFile(url, dest, fetchImpl) {
67279
67207
  await (0, import_promises9.pipeline)(nodeStream, out);
67280
67208
  }
67281
67209
  async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
67282
- const work = import_node_path55.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
67210
+ const work = import_node_path54.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
67283
67211
  import_node_fs49.default.mkdirSync(work, { recursive: true });
67284
67212
  try {
67285
67213
  await new Promise((resolve9, reject) => {
@@ -67288,7 +67216,7 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
67288
67216
  proc.on("exit", (code) => code === 0 ? resolve9() : reject(new Error(`tar exited ${code}`)));
67289
67217
  });
67290
67218
  const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
67291
- const src = import_node_path55.default.join(work, dirName, "frpc");
67219
+ const src = import_node_path54.default.join(work, dirName, "frpc");
67292
67220
  if (!import_node_fs49.default.existsSync(src)) {
67293
67221
  throw new Error(`frpc not found inside tarball at ${src}`);
67294
67222
  }
@@ -67300,10 +67228,10 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
67300
67228
 
67301
67229
  // src/tunnel/frpc-process.ts
67302
67230
  var import_node_fs50 = __toESM(require("fs"), 1);
67303
- var import_node_path56 = __toESM(require("path"), 1);
67231
+ var import_node_path55 = __toESM(require("path"), 1);
67304
67232
  var import_node_child_process14 = require("child_process");
67305
67233
  function frpcPidFilePath(dataDir) {
67306
- return import_node_path56.default.join(dataDir, "frpc.pid");
67234
+ return import_node_path55.default.join(dataDir, "frpc.pid");
67307
67235
  }
67308
67236
  function writeFrpcPid(dataDir, pid) {
67309
67237
  try {
@@ -67345,7 +67273,7 @@ function defaultSleep2(ms) {
67345
67273
  }
67346
67274
  async function killStaleFrpc(deps) {
67347
67275
  const pidFile = frpcPidFilePath(deps.dataDir);
67348
- const tomlPath = import_node_path56.default.join(deps.dataDir, "frpc.toml");
67276
+ const tomlPath = import_node_path55.default.join(deps.dataDir, "frpc.toml");
67349
67277
  const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
67350
67278
  const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
67351
67279
  const killPid = deps.killPidImpl ?? defaultKillPid;
@@ -67417,7 +67345,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
67417
67345
  var TunnelManager = class {
67418
67346
  constructor(deps) {
67419
67347
  this.deps = deps;
67420
- this.store = deps.store ?? new TunnelStore(import_node_path57.default.join(deps.dataDir, "tunnel.json"));
67348
+ this.store = deps.store ?? new TunnelStore(import_node_path56.default.join(deps.dataDir, "tunnel.json"));
67421
67349
  this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
67422
67350
  this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
67423
67351
  }
@@ -67544,7 +67472,7 @@ var TunnelManager = class {
67544
67472
  dataDir: this.deps.dataDir,
67545
67473
  override: this.deps.frpcBinaryOverride ?? void 0
67546
67474
  });
67547
- const tomlPath = import_node_path57.default.join(this.deps.dataDir, "frpc.toml");
67475
+ const tomlPath = import_node_path56.default.join(this.deps.dataDir, "frpc.toml");
67548
67476
  const proxyName = `clawd-${t2.subdomain}-${localPort}-${import_node_crypto13.default.randomBytes(3).toString("hex")}`;
67549
67477
  const toml = buildFrpcToml({
67550
67478
  serverAddr: t2.frpsHost,
@@ -67559,9 +67487,9 @@ var TunnelManager = class {
67559
67487
  const proc = (this.deps.spawnImpl ?? import_node_child_process15.spawn)(frpcBin, ["-c", tomlPath], {
67560
67488
  stdio: ["ignore", "pipe", "pipe"]
67561
67489
  });
67562
- const logDir = import_node_path57.default.join(this.deps.dataDir, "log");
67490
+ const logDir = import_node_path56.default.join(this.deps.dataDir, "log");
67563
67491
  import_node_fs51.default.mkdirSync(logDir, { recursive: true });
67564
- const logFilePath = import_node_path57.default.join(logDir, "frpc.log");
67492
+ const logFilePath = import_node_path56.default.join(logDir, "frpc.log");
67565
67493
  const logStream = import_node_fs51.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
67566
67494
  logStream.on("error", () => {
67567
67495
  });
@@ -67645,15 +67573,15 @@ async function waitForFrpcReady(proc, timeoutMs) {
67645
67573
 
67646
67574
  // src/tunnel/device-key.ts
67647
67575
  var import_node_os18 = __toESM(require("os"), 1);
67648
- var import_node_path58 = __toESM(require("path"), 1);
67576
+ var import_node_path57 = __toESM(require("path"), 1);
67649
67577
  var import_node_crypto14 = __toESM(require("crypto"), 1);
67650
67578
  var DERIVE_SALT = "clawd-tunnel-device-v1";
67651
67579
  function deriveStableDeviceKey(opts = {}) {
67652
67580
  const hostname = opts.hostname ?? import_node_os18.default.hostname();
67653
67581
  const uid = opts.uid ?? (typeof import_node_os18.default.userInfo === "function" ? import_node_os18.default.userInfo().uid : 0);
67654
67582
  const home = opts.home ?? import_node_os18.default.homedir();
67655
- const defaultDataDir = import_node_path58.default.resolve(import_node_path58.default.join(home, ".clawd"));
67656
- const normalizedDataDir = opts.dataDir ? import_node_path58.default.resolve(opts.dataDir) : null;
67583
+ const defaultDataDir = import_node_path57.default.resolve(import_node_path57.default.join(home, ".clawd"));
67584
+ const normalizedDataDir = opts.dataDir ? import_node_path57.default.resolve(opts.dataDir) : null;
67657
67585
  const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
67658
67586
  const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
67659
67587
  return import_node_crypto14.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
@@ -67661,11 +67589,11 @@ function deriveStableDeviceKey(opts = {}) {
67661
67589
 
67662
67590
  // src/auth-store.ts
67663
67591
  var import_node_fs52 = __toESM(require("fs"), 1);
67664
- var import_node_path59 = __toESM(require("path"), 1);
67592
+ var import_node_path58 = __toESM(require("path"), 1);
67665
67593
  var import_node_crypto15 = __toESM(require("crypto"), 1);
67666
67594
  var AUTH_FILE_NAME = "auth.json";
67667
67595
  function authFilePath(dataDir) {
67668
- return import_node_path59.default.join(dataDir, AUTH_FILE_NAME);
67596
+ return import_node_path58.default.join(dataDir, AUTH_FILE_NAME);
67669
67597
  }
67670
67598
  function loadOrCreateAuthFile(opts) {
67671
67599
  const file = authFilePath(opts.dataDir);
@@ -67727,7 +67655,7 @@ function readAuthFile(file) {
67727
67655
  }
67728
67656
  }
67729
67657
  function writeAuthFile(file, content) {
67730
- import_node_fs52.default.mkdirSync(import_node_path59.default.dirname(file), { recursive: true });
67658
+ import_node_fs52.default.mkdirSync(import_node_path58.default.dirname(file), { recursive: true });
67731
67659
  import_node_fs52.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
67732
67660
  try {
67733
67661
  import_node_fs52.default.chmodSync(file, 384);
@@ -67738,10 +67666,10 @@ function writeAuthFile(file, content) {
67738
67666
  // src/owner-profile.ts
67739
67667
  var import_node_fs53 = __toESM(require("fs"), 1);
67740
67668
  var import_node_os19 = __toESM(require("os"), 1);
67741
- var import_node_path60 = __toESM(require("path"), 1);
67669
+ var import_node_path59 = __toESM(require("path"), 1);
67742
67670
  var PROFILE_FILENAME = "profile.json";
67743
67671
  function profilePath(dataDir) {
67744
- return import_node_path60.default.join(dataDir, PROFILE_FILENAME);
67672
+ return import_node_path59.default.join(dataDir, PROFILE_FILENAME);
67745
67673
  }
67746
67674
  function loadOwnerProfile(dataDir) {
67747
67675
  let raw;
@@ -67779,12 +67707,12 @@ function loadOwnerDisplayName(dataDir) {
67779
67707
 
67780
67708
  // src/feishu-auth/owner-identity-store.ts
67781
67709
  var import_node_fs54 = __toESM(require("fs"), 1);
67782
- var import_node_path61 = __toESM(require("path"), 1);
67710
+ var import_node_path60 = __toESM(require("path"), 1);
67783
67711
  var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
67784
67712
  var OwnerIdentityStore = class {
67785
67713
  file;
67786
67714
  constructor(dataDir) {
67787
- this.file = import_node_path61.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
67715
+ this.file = import_node_path60.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
67788
67716
  }
67789
67717
  read() {
67790
67718
  let raw;
@@ -67816,7 +67744,7 @@ var OwnerIdentityStore = class {
67816
67744
  };
67817
67745
  }
67818
67746
  write(record4) {
67819
- import_node_fs54.default.mkdirSync(import_node_path61.default.dirname(this.file), { recursive: true });
67747
+ import_node_fs54.default.mkdirSync(import_node_path60.default.dirname(this.file), { recursive: true });
67820
67748
  import_node_fs54.default.writeFileSync(this.file, JSON.stringify(record4, null, 2), { mode: 384 });
67821
67749
  try {
67822
67750
  import_node_fs54.default.chmodSync(this.file, 384);
@@ -68322,7 +68250,7 @@ function verifyConnectToken(args) {
68322
68250
 
68323
68251
  // src/feishu-auth/server-key.ts
68324
68252
  var fs71 = __toESM(require("fs"), 1);
68325
- var path74 = __toESM(require("path"), 1);
68253
+ var path73 = __toESM(require("path"), 1);
68326
68254
  var FILE_NAME2 = "server-signing-key.json";
68327
68255
  var ServerKeyStore = class {
68328
68256
  constructor(dataDir) {
@@ -68330,7 +68258,7 @@ var ServerKeyStore = class {
68330
68258
  }
68331
68259
  dataDir;
68332
68260
  filePath() {
68333
- return path74.join(this.dataDir, FILE_NAME2);
68261
+ return path73.join(this.dataDir, FILE_NAME2);
68334
68262
  }
68335
68263
  /** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
68336
68264
  read() {
@@ -68365,7 +68293,7 @@ var ServerKeyStore = class {
68365
68293
  init_protocol();
68366
68294
 
68367
68295
  // src/handlers/index.ts
68368
- var import_node_path75 = __toESM(require("path"), 1);
68296
+ var import_node_path74 = __toESM(require("path"), 1);
68369
68297
 
68370
68298
  // src/handlers/session.ts
68371
68299
  init_protocol();
@@ -68373,7 +68301,7 @@ init_protocol();
68373
68301
  // src/session/fork.ts
68374
68302
  var import_node_fs55 = __toESM(require("fs"), 1);
68375
68303
  var import_node_os20 = __toESM(require("os"), 1);
68376
- var import_node_path62 = __toESM(require("path"), 1);
68304
+ var import_node_path61 = __toESM(require("path"), 1);
68377
68305
  var import_node_crypto17 = require("crypto");
68378
68306
  init_claude_history();
68379
68307
  function readJsonlEntries(file) {
@@ -68390,19 +68318,19 @@ function readJsonlEntries(file) {
68390
68318
  return out;
68391
68319
  }
68392
68320
  function forkSession(input) {
68393
- const baseDir = input.baseDir ?? import_node_path62.default.join(import_node_os20.default.homedir(), ".claude");
68394
- let projectDir = import_node_path62.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
68395
- let sourceFile = import_node_path62.default.join(projectDir, `${input.toolSessionId}.jsonl`);
68321
+ const baseDir = input.baseDir ?? import_node_path61.default.join(import_node_os20.default.homedir(), ".claude");
68322
+ let projectDir = import_node_path61.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
68323
+ let sourceFile = import_node_path61.default.join(projectDir, `${input.toolSessionId}.jsonl`);
68396
68324
  if (!import_node_fs55.default.existsSync(sourceFile)) {
68397
68325
  const found = findTranscriptByToolSessionId(
68398
- import_node_path62.default.join(baseDir, "projects"),
68326
+ import_node_path61.default.join(baseDir, "projects"),
68399
68327
  input.toolSessionId
68400
68328
  );
68401
68329
  if (!found) {
68402
68330
  throw new Error(`fork: source transcript not found: ${sourceFile}`);
68403
68331
  }
68404
68332
  sourceFile = found;
68405
- projectDir = import_node_path62.default.dirname(found);
68333
+ projectDir = import_node_path61.default.dirname(found);
68406
68334
  }
68407
68335
  const entries = readJsonlEntries(sourceFile);
68408
68336
  const mainEntries = entries.filter((e) => e.isSidechain !== true);
@@ -68431,8 +68359,8 @@ function forkSession(input) {
68431
68359
  }
68432
68360
  forkedLines.push(JSON.stringify(forked));
68433
68361
  }
68434
- const outDir = input.targetCwd ? import_node_path62.default.join(baseDir, "projects", cwdToHashDir(input.targetCwd)) : projectDir;
68435
- const forkedFilePath = import_node_path62.default.join(outDir, `${forkedToolSessionId}.jsonl`);
68362
+ const outDir = input.targetCwd ? import_node_path61.default.join(baseDir, "projects", cwdToHashDir(input.targetCwd)) : projectDir;
68363
+ const forkedFilePath = import_node_path61.default.join(outDir, `${forkedToolSessionId}.jsonl`);
68436
68364
  import_node_fs55.default.mkdirSync(outDir, { recursive: true });
68437
68365
  import_node_fs55.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
68438
68366
  return { forkedToolSessionId, forkedFilePath };
@@ -68442,16 +68370,16 @@ function forkSession(input) {
68442
68370
  var import_node_fs56 = __toESM(require("fs"), 1);
68443
68371
  var import_promises10 = __toESM(require("fs/promises"), 1);
68444
68372
  var import_node_os21 = __toESM(require("os"), 1);
68445
- var import_node_path63 = __toESM(require("path"), 1);
68373
+ var import_node_path62 = __toESM(require("path"), 1);
68446
68374
  var import_node_module = require("module");
68447
68375
  var import_node_child_process16 = require("child_process");
68448
68376
  var import_meta6 = {};
68449
68377
  function defaultRoots() {
68450
68378
  const home = import_node_os21.default.homedir();
68451
68379
  return {
68452
- claudeProjectsDir: import_node_path63.default.join(home, ".claude", "projects"),
68453
- codexDir: import_node_path63.default.join(home, ".codex"),
68454
- clawdDir: import_node_path63.default.join(home, ".clawd")
68380
+ claudeProjectsDir: import_node_path62.default.join(home, ".claude", "projects"),
68381
+ codexDir: import_node_path62.default.join(home, ".codex"),
68382
+ clawdDir: import_node_path62.default.join(home, ".clawd")
68455
68383
  };
68456
68384
  }
68457
68385
  function width(s2) {
@@ -68519,13 +68447,13 @@ async function scanClaude(roots) {
68519
68447
  if (!d2.isDirectory()) continue;
68520
68448
  let files;
68521
68449
  try {
68522
- files = import_node_fs56.default.readdirSync(import_node_path63.default.join(roots.claudeProjectsDir, d2.name));
68450
+ files = import_node_fs56.default.readdirSync(import_node_path62.default.join(roots.claudeProjectsDir, d2.name));
68523
68451
  } catch {
68524
68452
  continue;
68525
68453
  }
68526
68454
  for (const name of files) {
68527
68455
  if (!name.endsWith(".jsonl")) continue;
68528
- const file = import_node_path63.default.join(roots.claudeProjectsDir, d2.name, name);
68456
+ const file = import_node_path62.default.join(roots.claudeProjectsDir, d2.name, name);
68529
68457
  let st2;
68530
68458
  try {
68531
68459
  st2 = import_node_fs56.default.statSync(file);
@@ -68655,7 +68583,7 @@ async function codexFromRows(rows) {
68655
68583
  async function scanCodex(roots) {
68656
68584
  let dbs = [];
68657
68585
  try {
68658
- dbs = import_node_fs56.default.readdirSync(roots.codexDir).filter((n2) => /^state_.*\.sqlite$/.test(n2)).sort().map((n2) => import_node_path63.default.join(roots.codexDir, n2));
68586
+ dbs = import_node_fs56.default.readdirSync(roots.codexDir).filter((n2) => /^state_.*\.sqlite$/.test(n2)).sort().map((n2) => import_node_path62.default.join(roots.codexDir, n2));
68659
68587
  } catch {
68660
68588
  }
68661
68589
  if (!dbs.length) return [];
@@ -68664,14 +68592,14 @@ async function scanCodex(roots) {
68664
68592
  }
68665
68593
  async function scanExternalSessions(rootsIn) {
68666
68594
  const roots = { ...defaultRoots(), ...rootsIn };
68667
- const personaRoot = import_node_path63.default.join(roots.clawdDir, "personas");
68595
+ const personaRoot = import_node_path62.default.join(roots.clawdDir, "personas");
68668
68596
  const all = [...await scanClaude(roots), ...await scanCodex(roots)];
68669
68597
  const out = [];
68670
68598
  for (const c2 of all) {
68671
68599
  if (c2.skip) continue;
68672
68600
  if (c2.turns < 1) continue;
68673
68601
  if (!c2.cwd || !isDir2(c2.cwd)) continue;
68674
- if (c2.cwd === roots.clawdDir || c2.cwd === personaRoot || c2.cwd.startsWith(personaRoot + import_node_path63.default.sep) || c2.cwd.startsWith(roots.clawdDir + import_node_path63.default.sep)) {
68602
+ if (c2.cwd === roots.clawdDir || c2.cwd === personaRoot || c2.cwd.startsWith(personaRoot + import_node_path62.default.sep) || c2.cwd.startsWith(roots.clawdDir + import_node_path62.default.sep)) {
68675
68603
  continue;
68676
68604
  }
68677
68605
  out.push({
@@ -68689,12 +68617,12 @@ async function scanExternalSessions(rootsIn) {
68689
68617
 
68690
68618
  // src/session/import-ledger.ts
68691
68619
  var import_node_fs57 = __toESM(require("fs"), 1);
68692
- var import_node_path64 = __toESM(require("path"), 1);
68620
+ var import_node_path63 = __toESM(require("path"), 1);
68693
68621
  var LEDGER_FILENAME = "session-import-ledger.json";
68694
68622
  function readImportLedger(dataDir) {
68695
68623
  try {
68696
68624
  const parsed = JSON.parse(
68697
- import_node_fs57.default.readFileSync(import_node_path64.default.join(dataDir, LEDGER_FILENAME), "utf8")
68625
+ import_node_fs57.default.readFileSync(import_node_path63.default.join(dataDir, LEDGER_FILENAME), "utf8")
68698
68626
  );
68699
68627
  return Array.isArray(parsed) ? parsed : [];
68700
68628
  } catch {
@@ -68702,7 +68630,7 @@ function readImportLedger(dataDir) {
68702
68630
  }
68703
68631
  }
68704
68632
  function appendImportLedger(dataDir, entry) {
68705
- const file = import_node_path64.default.join(dataDir, LEDGER_FILENAME);
68633
+ const file = import_node_path63.default.join(dataDir, LEDGER_FILENAME);
68706
68634
  const entries = readImportLedger(dataDir);
68707
68635
  entries.push(entry);
68708
68636
  import_node_fs57.default.writeFileSync(file, JSON.stringify(entries, null, 2), { encoding: "utf8", mode: 384 });
@@ -69238,7 +69166,7 @@ function buildPermissionHandlers(deps) {
69238
69166
  }
69239
69167
 
69240
69168
  // src/handlers/history.ts
69241
- var path79 = __toESM(require("path"), 1);
69169
+ var path78 = __toESM(require("path"), 1);
69242
69170
  init_protocol();
69243
69171
 
69244
69172
  // src/session/recent-dirs.ts
@@ -69256,7 +69184,7 @@ function listRecentDirs(store, limit = 50) {
69256
69184
  }
69257
69185
 
69258
69186
  // src/permission/persona-paths.ts
69259
- var path78 = __toESM(require("path"), 1);
69187
+ var path77 = __toESM(require("path"), 1);
69260
69188
  function getAllowedPersonaIds(grants, action) {
69261
69189
  const ids = /* @__PURE__ */ new Set();
69262
69190
  for (const g3 of grants) {
@@ -69269,42 +69197,42 @@ function getAllowedPersonaIds(grants, action) {
69269
69197
  return ids;
69270
69198
  }
69271
69199
  function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
69272
- const target = path78.resolve(absPath);
69200
+ const target = path77.resolve(absPath);
69273
69201
  if (userWorkDir) {
69274
- const u2 = path78.resolve(userWorkDir);
69275
- const usep = u2.endsWith(path78.sep) ? "" : path78.sep;
69202
+ const u2 = path77.resolve(userWorkDir);
69203
+ const usep = u2.endsWith(path77.sep) ? "" : path77.sep;
69276
69204
  if (target === u2 || target.startsWith(u2 + usep)) return true;
69277
69205
  }
69278
- const root = path78.resolve(personaRoot);
69279
- const sep4 = root.endsWith(path78.sep) ? "" : path78.sep;
69206
+ const root = path77.resolve(personaRoot);
69207
+ const sep4 = root.endsWith(path77.sep) ? "" : path77.sep;
69280
69208
  if (!target.startsWith(root + sep4)) return false;
69281
- const rel = path78.relative(root, target);
69209
+ const rel = path77.relative(root, target);
69282
69210
  if (!rel || rel.startsWith("..")) return false;
69283
- const personaId2 = rel.split(path78.sep)[0];
69211
+ const personaId2 = rel.split(path77.sep)[0];
69284
69212
  if (!personaId2) return false;
69285
69213
  const allowed = getAllowedPersonaIds(grants, action);
69286
69214
  if (allowed === "*") return true;
69287
69215
  return allowed.has(personaId2);
69288
69216
  }
69289
69217
  function personaIdFromPath(absPath, personaRoot) {
69290
- const root = path78.resolve(personaRoot);
69291
- const target = path78.resolve(absPath);
69292
- const sep4 = root.endsWith(path78.sep) ? "" : path78.sep;
69218
+ const root = path77.resolve(personaRoot);
69219
+ const target = path77.resolve(absPath);
69220
+ const sep4 = root.endsWith(path77.sep) ? "" : path77.sep;
69293
69221
  if (!target.startsWith(root + sep4)) return null;
69294
- const rel = path78.relative(root, target);
69222
+ const rel = path77.relative(root, target);
69295
69223
  if (!rel || rel.startsWith("..")) return null;
69296
- const id = rel.split(path78.sep)[0];
69224
+ const id = rel.split(path77.sep)[0];
69297
69225
  return id || null;
69298
69226
  }
69299
69227
  function isPathWithin(dir, absPath) {
69300
- const d2 = path78.resolve(dir);
69301
- const t2 = path78.resolve(absPath);
69302
- const sep4 = d2.endsWith(path78.sep) ? "" : path78.sep;
69228
+ const d2 = path77.resolve(dir);
69229
+ const t2 = path77.resolve(absPath);
69230
+ const sep4 = d2.endsWith(path77.sep) ? "" : path77.sep;
69303
69231
  return t2 === d2 || t2.startsWith(d2 + sep4);
69304
69232
  }
69305
69233
  function isPathInGuestBoundary(personaRoot, personaId2, userWorkDir, absPath) {
69306
69234
  if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
69307
- return personaIdFromPath(path78.resolve(absPath), personaRoot) === personaId2;
69235
+ return personaIdFromPath(path77.resolve(absPath), personaRoot) === personaId2;
69308
69236
  }
69309
69237
 
69310
69238
  // src/handlers/history.ts
@@ -69357,7 +69285,7 @@ function buildHistoryHandlers(deps) {
69357
69285
  if (!pid) return false;
69358
69286
  return isGuestPathAllowed(
69359
69287
  ctx.grants,
69360
- path79.join(personaRoot, pid),
69288
+ path78.join(personaRoot, pid),
69361
69289
  personaRoot,
69362
69290
  "read",
69363
69291
  userWorkDir
@@ -69369,7 +69297,7 @@ function buildHistoryHandlers(deps) {
69369
69297
  };
69370
69298
  const list = async (frame, _client, ctx) => {
69371
69299
  const args = HistoryListArgs.parse(frame);
69372
- assertGuestPath(ctx, path79.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
69300
+ assertGuestPath(ctx, path78.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
69373
69301
  const sessions = await history.listSessions(args);
69374
69302
  return { response: { type: "history:list", sessions } };
69375
69303
  };
@@ -69417,14 +69345,14 @@ function buildHistoryHandlers(deps) {
69417
69345
  };
69418
69346
  const subagents = async (frame, _client, ctx) => {
69419
69347
  const args = HistorySubagentsArgs.parse(frame);
69420
- assertGuestPath(ctx, path79.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
69348
+ assertGuestPath(ctx, path78.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
69421
69349
  assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagents");
69422
69350
  const subs = await historyReaderForToolSession(args.toolSessionId).listSubagents(args);
69423
69351
  return { response: { type: "history:subagents", subagents: subs } };
69424
69352
  };
69425
69353
  const subagentRead = async (frame, _client, ctx) => {
69426
69354
  const args = HistorySubagentReadArgs.parse(frame);
69427
- assertGuestPath(ctx, path79.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
69355
+ assertGuestPath(ctx, path78.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
69428
69356
  assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagent-read");
69429
69357
  const res = await historyReaderForToolSession(args.toolSessionId).readSubagent(args);
69430
69358
  return { response: { type: "history:subagent-read", ...res } };
@@ -69434,7 +69362,7 @@ function buildHistoryHandlers(deps) {
69434
69362
  if (ctx?.principal.kind === "guest" && personaRoot) {
69435
69363
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
69436
69364
  const filtered = dirs.filter(
69437
- (d2) => isGuestPathAllowed(ctx.grants, path79.resolve(d2.cwd), personaRoot, "read", userWorkDir)
69365
+ (d2) => isGuestPathAllowed(ctx.grants, path78.resolve(d2.cwd), personaRoot, "read", userWorkDir)
69438
69366
  );
69439
69367
  return { response: { type: "history:recentDirs", dirs: filtered } };
69440
69368
  }
@@ -69453,15 +69381,15 @@ function buildHistoryHandlers(deps) {
69453
69381
  // src/handlers/projects.ts
69454
69382
  var fs75 = __toESM(require("fs"), 1);
69455
69383
  var os23 = __toESM(require("os"), 1);
69456
- var path80 = __toESM(require("path"), 1);
69384
+ var path79 = __toESM(require("path"), 1);
69457
69385
  var import_node_child_process17 = require("child_process");
69458
69386
  init_protocol();
69459
- var DEFAULT_PROJECTS_ROOT = path80.join(os23.homedir(), "Documents", "ChatGPT");
69387
+ var DEFAULT_PROJECTS_ROOT = path79.join(os23.homedir(), "Documents", "ChatGPT");
69460
69388
  function allocateDir(root, name) {
69461
- let candidate = path80.join(root, name);
69389
+ let candidate = path79.join(root, name);
69462
69390
  let n2 = 2;
69463
69391
  while (fs75.existsSync(candidate)) {
69464
- candidate = path80.join(root, `${name} ${n2}`);
69392
+ candidate = path79.join(root, `${name} ${n2}`);
69465
69393
  n2 += 1;
69466
69394
  }
69467
69395
  return candidate;
@@ -69546,7 +69474,7 @@ function buildProjectHandlers(deps) {
69546
69474
  }
69547
69475
 
69548
69476
  // src/handlers/workspace.ts
69549
- var path81 = __toESM(require("path"), 1);
69477
+ var path80 = __toESM(require("path"), 1);
69550
69478
  init_protocol();
69551
69479
  var os24 = __toESM(require("os"), 1);
69552
69480
  init_protocol();
@@ -69589,22 +69517,22 @@ function buildWorkspaceHandlers(deps) {
69589
69517
  const args = WorkspaceListArgs.parse(frame);
69590
69518
  const isGuest = ctx?.principal.kind === "guest";
69591
69519
  const fallbackCwd = isGuest && personaRoot ? personaRoot : os24.homedir();
69592
- const resolvedCwd = path81.resolve(args.cwd ?? fallbackCwd);
69593
- const target = args.path ? path81.resolve(resolvedCwd, args.path) : resolvedCwd;
69520
+ const resolvedCwd = path80.resolve(args.cwd ?? fallbackCwd);
69521
+ const target = args.path ? path80.resolve(resolvedCwd, args.path) : resolvedCwd;
69594
69522
  assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
69595
69523
  const res = workspace.list({ ...args, cwd: resolvedCwd });
69596
69524
  return { response: { type: "workspace:list", ...res } };
69597
69525
  };
69598
69526
  const read = async (frame, _client, ctx) => {
69599
69527
  const args = WorkspaceReadArgs.parse(frame);
69600
- const target = path81.isAbsolute(args.path) ? path81.resolve(args.path) : path81.resolve(args.cwd, args.path);
69528
+ const target = path80.isAbsolute(args.path) ? path80.resolve(args.path) : path80.resolve(args.cwd, args.path);
69601
69529
  assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
69602
69530
  const res = workspace.read(args);
69603
69531
  return { response: { type: "workspace:read", ...res } };
69604
69532
  };
69605
69533
  const skillsList = async (frame, _client, ctx) => {
69606
69534
  const args = SkillsListArgs.parse(frame);
69607
- const cwdAbs = path81.resolve(args.cwd);
69535
+ const cwdAbs = path80.resolve(args.cwd);
69608
69536
  assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
69609
69537
  const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
69610
69538
  if (ctx?.principal.kind === "guest" && personaRoot) {
@@ -69616,7 +69544,7 @@ function buildWorkspaceHandlers(deps) {
69616
69544
  };
69617
69545
  const agentsList = async (frame, _client, ctx) => {
69618
69546
  const args = AgentsListArgs.parse(frame);
69619
- const cwdAbs = path81.resolve(args.cwd);
69547
+ const cwdAbs = path80.resolve(args.cwd);
69620
69548
  assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
69621
69549
  if (isCodexFamily(args.tool) || args.tool === PI_TOOL_ID) {
69622
69550
  return { response: { type: "agents:list", agents: [] } };
@@ -69638,18 +69566,18 @@ function buildWorkspaceHandlers(deps) {
69638
69566
  }
69639
69567
 
69640
69568
  // src/handlers/git.ts
69641
- var path83 = __toESM(require("path"), 1);
69569
+ var path82 = __toESM(require("path"), 1);
69642
69570
  init_protocol();
69643
69571
  init_protocol();
69644
69572
 
69645
69573
  // src/workspace/git.ts
69646
69574
  var import_node_child_process18 = require("child_process");
69647
69575
  var import_node_fs58 = __toESM(require("fs"), 1);
69648
- var import_node_path65 = __toESM(require("path"), 1);
69576
+ var import_node_path64 = __toESM(require("path"), 1);
69649
69577
  var import_node_util2 = require("util");
69650
69578
  var pexec = (0, import_node_util2.promisify)(import_node_child_process18.execFile);
69651
69579
  function normalizePath(p3) {
69652
- const resolved = import_node_path65.default.resolve(p3);
69580
+ const resolved = import_node_path64.default.resolve(p3);
69653
69581
  try {
69654
69582
  return import_node_fs58.default.realpathSync(resolved);
69655
69583
  } catch {
@@ -69725,7 +69653,7 @@ async function listGitBranches(cwd) {
69725
69653
  function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
69726
69654
  if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
69727
69655
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
69728
- if (!isGuestPathAllowed(ctx.grants, path83.resolve(cwd), personaRoot, "read", userWorkDir)) {
69656
+ if (!isGuestPathAllowed(ctx.grants, path82.resolve(cwd), personaRoot, "read", userWorkDir)) {
69729
69657
  throw new ClawdError(
69730
69658
  ERROR_CODES.UNAUTHORIZED,
69731
69659
  `guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
@@ -69793,8 +69721,8 @@ function refreshPathFromLoginShell() {
69793
69721
  timeout: 3e3,
69794
69722
  stdio: ["ignore", "pipe", "ignore"]
69795
69723
  });
69796
- const path102 = out.trim();
69797
- if (path102) process.env.PATH = path102;
69724
+ const path100 = out.trim();
69725
+ if (path100) process.env.PATH = path100;
69798
69726
  } catch {
69799
69727
  }
69800
69728
  }
@@ -70003,11 +69931,11 @@ async function queryCodexAccount(deps = {}) {
70003
69931
 
70004
69932
  // src/tools/pi-account.ts
70005
69933
  var import_node_fs59 = __toESM(require("fs"), 1);
70006
- var import_node_path66 = __toESM(require("path"), 1);
69934
+ var import_node_path65 = __toESM(require("path"), 1);
70007
69935
  function readPiCredentials(agentDir) {
70008
69936
  let raw;
70009
69937
  try {
70010
- raw = JSON.parse(import_node_fs59.default.readFileSync(import_node_path66.default.join(agentDir, "auth.json"), "utf8"));
69938
+ raw = JSON.parse(import_node_fs59.default.readFileSync(import_node_path65.default.join(agentDir, "auth.json"), "utf8"));
70011
69939
  } catch {
70012
69940
  return {};
70013
69941
  }
@@ -70997,21 +70925,21 @@ function computeMethodAccess(args) {
70997
70925
  }
70998
70926
 
70999
70927
  // src/version.ts
71000
- var version = "0.2.546".length > 0 ? "0.2.546" : "dev";
70928
+ var version = "0.2.548".length > 0 ? "0.2.548" : "dev";
71001
70929
 
71002
70930
  // src/cli-probe/probe.ts
71003
70931
  var fs78 = __toESM(require("fs"), 1);
71004
- var path85 = __toESM(require("path"), 1);
70932
+ var path84 = __toESM(require("path"), 1);
71005
70933
  var PKG_NAME = "@clawos-dev/clawd";
71006
70934
  var BIN_NAME = "clawd";
71007
70935
  var MAX_PARENT_HOPS = 5;
71008
70936
  function probeGlobalCli(pathEnv) {
71009
70937
  if (!pathEnv) return null;
71010
- for (const dir of pathEnv.split(path85.delimiter)) {
70938
+ for (const dir of pathEnv.split(path84.delimiter)) {
71011
70939
  if (!dir) continue;
71012
70940
  let real;
71013
70941
  try {
71014
- real = fs78.realpathSync(path85.join(dir, BIN_NAME));
70942
+ real = fs78.realpathSync(path84.join(dir, BIN_NAME));
71015
70943
  } catch {
71016
70944
  continue;
71017
70945
  }
@@ -71021,15 +70949,15 @@ function probeGlobalCli(pathEnv) {
71021
70949
  return null;
71022
70950
  }
71023
70951
  function readOwnPackageVersion(entryPath) {
71024
- let dir = path85.dirname(entryPath);
70952
+ let dir = path84.dirname(entryPath);
71025
70953
  for (let i2 = 0; i2 < MAX_PARENT_HOPS; i2++) {
71026
70954
  try {
71027
- const raw = fs78.readFileSync(path85.join(dir, "package.json"), "utf8");
70955
+ const raw = fs78.readFileSync(path84.join(dir, "package.json"), "utf8");
71028
70956
  const pkg = JSON.parse(raw);
71029
70957
  if (pkg.name !== PKG_NAME) return null;
71030
70958
  return typeof pkg.version === "string" && pkg.version ? pkg.version : null;
71031
70959
  } catch {
71032
- const parent = path85.dirname(dir);
70960
+ const parent = path84.dirname(dir);
71033
70961
  if (parent === dir) return null;
71034
70962
  dir = parent;
71035
70963
  }
@@ -71205,7 +71133,7 @@ function buildPersonaHandlers(deps) {
71205
71133
  }
71206
71134
 
71207
71135
  // src/handlers/attachment.ts
71208
- var import_node_path67 = __toESM(require("path"), 1);
71136
+ var import_node_path66 = __toESM(require("path"), 1);
71209
71137
  init_protocol();
71210
71138
  init_protocol();
71211
71139
  function assertGuestAttachmentPath(ctx, absPath, personaRoot, method, usersRoot) {
@@ -71284,12 +71212,12 @@ function buildAttachmentHandlers(deps) {
71284
71212
  `session ${args.sessionId} scope unresolved`
71285
71213
  );
71286
71214
  }
71287
- const cwdAbs = import_node_path67.default.resolve(sessionFile.cwd);
71288
- const candidateAbs = import_node_path67.default.isAbsolute(args.relPath) ? import_node_path67.default.resolve(args.relPath) : import_node_path67.default.resolve(cwdAbs, args.relPath);
71215
+ const cwdAbs = import_node_path66.default.resolve(sessionFile.cwd);
71216
+ const candidateAbs = import_node_path66.default.isAbsolute(args.relPath) ? import_node_path66.default.resolve(args.relPath) : import_node_path66.default.resolve(cwdAbs, args.relPath);
71289
71217
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
71290
71218
  const entries = deps.groupFileStore.list(scope, args.sessionId);
71291
71219
  const entry = entries.find((e) => {
71292
- const storedAbs = import_node_path67.default.isAbsolute(e.relPath) ? import_node_path67.default.resolve(e.relPath) : import_node_path67.default.resolve(cwdAbs, e.relPath);
71220
+ const storedAbs = import_node_path66.default.isAbsolute(e.relPath) ? import_node_path66.default.resolve(e.relPath) : import_node_path66.default.resolve(cwdAbs, e.relPath);
71293
71221
  return storedAbs === candidateAbs && !e.stale;
71294
71222
  });
71295
71223
  if (!entry) {
@@ -71313,7 +71241,7 @@ function buildAttachmentHandlers(deps) {
71313
71241
  if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
71314
71242
  const f2 = deps.sessionStore.read(sessionId);
71315
71243
  if (!f2) return;
71316
- assertGuestAttachmentPath(ctx, import_node_path67.default.resolve(f2.cwd), deps.personaRoot, method, deps.usersRoot);
71244
+ assertGuestAttachmentPath(ctx, import_node_path66.default.resolve(f2.cwd), deps.personaRoot, method, deps.usersRoot);
71317
71245
  }
71318
71246
  const groupAdd = async (frame, _client, ctx) => {
71319
71247
  if (!deps.groupFileStore || !deps.getSessionScope) {
@@ -71328,8 +71256,8 @@ function buildAttachmentHandlers(deps) {
71328
71256
  if (!scope) {
71329
71257
  throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
71330
71258
  }
71331
- const cwdAbs = import_node_path67.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
71332
- const candidateAbs = import_node_path67.default.isAbsolute(args.relPath) ? import_node_path67.default.resolve(args.relPath) : import_node_path67.default.resolve(cwdAbs, args.relPath);
71259
+ const cwdAbs = import_node_path66.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
71260
+ const candidateAbs = import_node_path66.default.isAbsolute(args.relPath) ? import_node_path66.default.resolve(args.relPath) : import_node_path66.default.resolve(cwdAbs, args.relPath);
71333
71261
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
71334
71262
  const from = args.origin === "agent" ? "agent" : ctx?.principal.kind === "owner" ? "owner" : "agent";
71335
71263
  const size = 0;
@@ -71388,19 +71316,19 @@ function buildAttachmentHandlers(deps) {
71388
71316
 
71389
71317
  // src/handlers/extension.ts
71390
71318
  var import_promises14 = __toESM(require("fs/promises"), 1);
71391
- var import_node_path72 = __toESM(require("path"), 1);
71319
+ var import_node_path71 = __toESM(require("path"), 1);
71392
71320
  init_protocol();
71393
71321
 
71394
71322
  // src/extension/bundle-zip.ts
71395
71323
  var import_promises11 = __toESM(require("fs/promises"), 1);
71396
- var import_node_path68 = __toESM(require("path"), 1);
71324
+ var import_node_path67 = __toESM(require("path"), 1);
71397
71325
  var import_node_crypto18 = __toESM(require("crypto"), 1);
71398
71326
  var import_jszip2 = __toESM(require_lib3(), 1);
71399
71327
  async function bundleExtensionDir(dir) {
71400
71328
  const entries = await listFilesSorted(dir);
71401
71329
  const zip = new import_jszip2.default();
71402
71330
  for (const rel of entries) {
71403
- const abs = import_node_path68.default.join(dir, rel);
71331
+ const abs = import_node_path67.default.join(dir, rel);
71404
71332
  const content = await import_promises11.default.readFile(abs);
71405
71333
  zip.file(rel, content, { date: FIXED_DATE });
71406
71334
  }
@@ -71421,7 +71349,7 @@ async function listFilesSorted(rootDir) {
71421
71349
  return out;
71422
71350
  }
71423
71351
  async function walk(absRoot, relPrefix, out) {
71424
- const dirAbs = import_node_path68.default.join(absRoot, relPrefix);
71352
+ const dirAbs = import_node_path67.default.join(absRoot, relPrefix);
71425
71353
  const entries = await import_promises11.default.readdir(dirAbs, { withFileTypes: true });
71426
71354
  for (const e of entries) {
71427
71355
  if (IGNORE_BASENAMES.has(e.name)) continue;
@@ -71475,25 +71403,25 @@ function computePublishCheck(args) {
71475
71403
 
71476
71404
  // src/extension/install-flow.ts
71477
71405
  var import_promises12 = __toESM(require("fs/promises"), 1);
71478
- var import_node_path70 = __toESM(require("path"), 1);
71406
+ var import_node_path69 = __toESM(require("path"), 1);
71479
71407
  var import_node_os25 = __toESM(require("os"), 1);
71480
71408
  var import_node_crypto19 = __toESM(require("crypto"), 1);
71481
71409
  var import_jszip3 = __toESM(require_lib3(), 1);
71482
71410
 
71483
71411
  // src/extension/paths.ts
71484
71412
  var import_node_os24 = __toESM(require("os"), 1);
71485
- var import_node_path69 = __toESM(require("path"), 1);
71413
+ var import_node_path68 = __toESM(require("path"), 1);
71486
71414
  function clawdHomeRoot(override) {
71487
- return override ?? process.env.CLAWD_HOME ?? import_node_path69.default.join(import_node_os24.default.homedir(), ".clawd");
71415
+ return override ?? process.env.CLAWD_HOME ?? import_node_path68.default.join(import_node_os24.default.homedir(), ".clawd");
71488
71416
  }
71489
71417
  function extensionsRoot(override) {
71490
- return import_node_path69.default.join(clawdHomeRoot(override), "extensions");
71418
+ return import_node_path68.default.join(clawdHomeRoot(override), "extensions");
71491
71419
  }
71492
71420
  function publishedChannelsFile(override) {
71493
- return import_node_path69.default.join(clawdHomeRoot(override), "extensions-published.json");
71421
+ return import_node_path68.default.join(clawdHomeRoot(override), "extensions-published.json");
71494
71422
  }
71495
71423
  function bundleCacheRoot(override) {
71496
- return import_node_path69.default.join(clawdHomeRoot(override), "extension-bundles");
71424
+ return import_node_path68.default.join(clawdHomeRoot(override), "extension-bundles");
71497
71425
  }
71498
71426
 
71499
71427
  // src/extension/install-flow.ts
@@ -71520,7 +71448,7 @@ async function installFromChannel(args, deps) {
71520
71448
  throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
71521
71449
  }
71522
71450
  for (const name of Object.keys(zip.files)) {
71523
- if (name.includes("..") || name.startsWith("/") || import_node_path70.default.isAbsolute(name)) {
71451
+ if (name.includes("..") || name.startsWith("/") || import_node_path69.default.isAbsolute(name)) {
71524
71452
  throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
71525
71453
  }
71526
71454
  }
@@ -71552,7 +71480,7 @@ async function installFromChannel(args, deps) {
71552
71480
  );
71553
71481
  }
71554
71482
  const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
71555
- const destDir = import_node_path70.default.join(deps.extensionsRoot, localExtId);
71483
+ const destDir = import_node_path69.default.join(deps.extensionsRoot, localExtId);
71556
71484
  let destExists = false;
71557
71485
  try {
71558
71486
  await import_promises12.default.access(destDir);
@@ -71566,16 +71494,16 @@ async function installFromChannel(args, deps) {
71566
71494
  );
71567
71495
  }
71568
71496
  const stage = await import_promises12.default.mkdtemp(
71569
- import_node_path70.default.join(import_node_os25.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
71497
+ import_node_path69.default.join(import_node_os25.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
71570
71498
  );
71571
71499
  try {
71572
71500
  for (const [name, entry] of Object.entries(zip.files)) {
71573
- const dest = import_node_path70.default.join(stage, name);
71501
+ const dest = import_node_path69.default.join(stage, name);
71574
71502
  if (entry.dir) {
71575
71503
  await import_promises12.default.mkdir(dest, { recursive: true });
71576
71504
  continue;
71577
71505
  }
71578
- await import_promises12.default.mkdir(import_node_path70.default.dirname(dest), { recursive: true });
71506
+ await import_promises12.default.mkdir(import_node_path69.default.dirname(dest), { recursive: true });
71579
71507
  if (name === "manifest.json") {
71580
71508
  const rewritten = { ...parsed.data, id: localExtId };
71581
71509
  await import_promises12.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -71596,7 +71524,7 @@ async function installFromChannel(args, deps) {
71596
71524
 
71597
71525
  // src/extension/update-flow.ts
71598
71526
  var import_promises13 = __toESM(require("fs/promises"), 1);
71599
- var import_node_path71 = __toESM(require("path"), 1);
71527
+ var import_node_path70 = __toESM(require("path"), 1);
71600
71528
  var import_node_os26 = __toESM(require("os"), 1);
71601
71529
  var import_node_crypto20 = __toESM(require("crypto"), 1);
71602
71530
  var import_jszip4 = __toESM(require_lib3(), 1);
@@ -71613,11 +71541,11 @@ async function updateFromChannel(args, deps) {
71613
71541
  channelRef.extId,
71614
71542
  channelRef.ownerPrincipalId
71615
71543
  );
71616
- const liveDir = import_node_path71.default.join(deps.extensionsRoot, localExtId);
71544
+ const liveDir = import_node_path70.default.join(deps.extensionsRoot, localExtId);
71617
71545
  const prevDir = `${liveDir}.prev`;
71618
71546
  let existingVersion;
71619
71547
  try {
71620
- const raw = await import_promises13.default.readFile(import_node_path71.default.join(liveDir, "manifest.json"), "utf8");
71548
+ const raw = await import_promises13.default.readFile(import_node_path70.default.join(liveDir, "manifest.json"), "utf8");
71621
71549
  const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
71622
71550
  if (!parsed2.success) {
71623
71551
  throw new UpdateError(
@@ -71650,7 +71578,7 @@ async function updateFromChannel(args, deps) {
71650
71578
  throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
71651
71579
  }
71652
71580
  for (const name of Object.keys(zip.files)) {
71653
- if (name.includes("..") || name.startsWith("/") || import_node_path71.default.isAbsolute(name)) {
71581
+ if (name.includes("..") || name.startsWith("/") || import_node_path70.default.isAbsolute(name)) {
71654
71582
  throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
71655
71583
  }
71656
71584
  }
@@ -71685,16 +71613,16 @@ async function updateFromChannel(args, deps) {
71685
71613
  await import_promises13.default.rm(prevDir, { recursive: true, force: true });
71686
71614
  await import_promises13.default.rename(liveDir, prevDir);
71687
71615
  const stage = await import_promises13.default.mkdtemp(
71688
- import_node_path71.default.join(import_node_os26.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
71616
+ import_node_path70.default.join(import_node_os26.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
71689
71617
  );
71690
71618
  try {
71691
71619
  for (const [name, entry] of Object.entries(zip.files)) {
71692
- const dest = import_node_path71.default.join(stage, name);
71620
+ const dest = import_node_path70.default.join(stage, name);
71693
71621
  if (entry.dir) {
71694
71622
  await import_promises13.default.mkdir(dest, { recursive: true });
71695
71623
  continue;
71696
71624
  }
71697
- await import_promises13.default.mkdir(import_node_path71.default.dirname(dest), { recursive: true });
71625
+ await import_promises13.default.mkdir(import_node_path70.default.dirname(dest), { recursive: true });
71698
71626
  if (name === "manifest.json") {
71699
71627
  const rewritten = { ...parsed.data, id: localExtId };
71700
71628
  await import_promises13.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -71761,7 +71689,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
71761
71689
  );
71762
71690
  }
71763
71691
  }
71764
- const manifestPath = import_node_path72.default.join(root, extId, "manifest.json");
71692
+ const manifestPath = import_node_path71.default.join(root, extId, "manifest.json");
71765
71693
  const manifest = await readManifest(root, extId);
71766
71694
  const next = { ...manifest, version: newVersion };
71767
71695
  const tmp = `${manifestPath}.tmp`;
@@ -71769,7 +71697,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
71769
71697
  await import_promises14.default.rename(tmp, manifestPath);
71770
71698
  }
71771
71699
  async function readManifest(root, extId) {
71772
- const file = import_node_path72.default.join(root, extId, "manifest.json");
71700
+ const file = import_node_path71.default.join(root, extId, "manifest.json");
71773
71701
  let raw;
71774
71702
  try {
71775
71703
  raw = await import_promises14.default.readFile(file, "utf8");
@@ -71853,7 +71781,7 @@ function buildExtensionHandlers(deps) {
71853
71781
  };
71854
71782
  async function buildSnapshotMeta(extId) {
71855
71783
  const manifest = await readManifest(deps.root, extId);
71856
- const { sha256, buffer } = await bundleExtensionDir(import_node_path72.default.join(deps.root, extId));
71784
+ const { sha256, buffer } = await bundleExtensionDir(import_node_path71.default.join(deps.root, extId));
71857
71785
  return { manifest, contentHash: sha256, buffer };
71858
71786
  }
71859
71787
  const publish = async (frame, _client, ctx) => {
@@ -72681,7 +72609,7 @@ function buildVisitorHandlers(deps) {
72681
72609
 
72682
72610
  // src/extension/registry.ts
72683
72611
  var import_promises16 = __toESM(require("fs/promises"), 1);
72684
- var import_node_path73 = __toESM(require("path"), 1);
72612
+ var import_node_path72 = __toESM(require("path"), 1);
72685
72613
  async function loadAll(root) {
72686
72614
  let entries;
72687
72615
  try {
@@ -72694,13 +72622,13 @@ async function loadAll(root) {
72694
72622
  for (const ent of entries) {
72695
72623
  if (!ent.isDirectory()) continue;
72696
72624
  if (ent.name.startsWith(".")) continue;
72697
- records.push(await loadOne(import_node_path73.default.join(root, ent.name), ent.name));
72625
+ records.push(await loadOne(import_node_path72.default.join(root, ent.name), ent.name));
72698
72626
  }
72699
72627
  records.sort((a2, b3) => a2.extId < b3.extId ? -1 : a2.extId > b3.extId ? 1 : 0);
72700
72628
  return records;
72701
72629
  }
72702
72630
  async function loadOne(dir, dirName) {
72703
- const manifestPath = import_node_path73.default.join(dir, "manifest.json");
72631
+ const manifestPath = import_node_path72.default.join(dir, "manifest.json");
72704
72632
  let raw;
72705
72633
  try {
72706
72634
  raw = await import_promises16.default.readFile(manifestPath, "utf8");
@@ -72745,7 +72673,7 @@ async function loadOne(dir, dirName) {
72745
72673
 
72746
72674
  // src/extension/uninstall.ts
72747
72675
  var import_promises17 = __toESM(require("fs/promises"), 1);
72748
- var import_node_path74 = __toESM(require("path"), 1);
72676
+ var import_node_path73 = __toESM(require("path"), 1);
72749
72677
  var UninstallError = class extends Error {
72750
72678
  constructor(code, message) {
72751
72679
  super(message);
@@ -72754,7 +72682,7 @@ var UninstallError = class extends Error {
72754
72682
  code;
72755
72683
  };
72756
72684
  async function uninstall(deps) {
72757
- const dir = import_node_path74.default.join(deps.root, deps.extId);
72685
+ const dir = import_node_path73.default.join(deps.root, deps.extId);
72758
72686
  try {
72759
72687
  await import_promises17.default.access(dir);
72760
72688
  } catch {
@@ -72969,7 +72897,7 @@ function buildMethodHandlers(deps) {
72969
72897
  broadcast: deps.broadcastToOwners
72970
72898
  }),
72971
72899
  ...buildMasterHandlers({
72972
- authorityTablePath: import_node_path75.default.join(deps.masterDataDir, "master-authority.json")
72900
+ authorityTablePath: import_node_path74.default.join(deps.masterDataDir, "master-authority.json")
72973
72901
  }),
72974
72902
  ...buildTopicHandlers({
72975
72903
  topicStore: deps.topicStore,
@@ -73069,45 +72997,6 @@ function buildOnboardingHandlers(deps) {
73069
72997
  return { "onboarding:complete": complete, "tools:probe": toolsProbe, "onboarding:iosInterest": iosInterest };
73070
72998
  }
73071
72999
 
73072
- // src/app-builder-plugin/mcp-config.ts
73073
- var import_node_fs60 = __toESM(require("fs"), 1);
73074
- var import_node_path76 = __toESM(require("path"), 1);
73075
- function appBuilderMcpConfigPath(outDir, personaId2) {
73076
- return import_node_path76.default.join(outDir, `${personaId2}.app-builder.mcp.json`);
73077
- }
73078
- function writeAppBuilderMcpConfig(args) {
73079
- const cfgPath = appBuilderMcpConfigPath(args.outDir, args.personaId);
73080
- const cfg = {
73081
- _comment: `daemon \u81EA\u52A8\u751F\u6210\uFF08${args.personaId} \u7684\u4F1A\u8BDD spawn \u524D\u91CD\u6E32\uFF09\uFF1Bagent spawn \u901A\u8FC7 --mcp-config \u6CE8\u5165\u3002app-builder-plugin/mcp-server.cjs \u662F clawd-app-builder \u63D2\u4EF6\uFF1A\u9879\u76EE\u76EE\u5F55 / scaffold / \u53D1\u5E03 / \u62C6\u9664\u90FD\u5728\u5B83\u8FDB\u7A0B\u91CC\u505A\uFF0C\u51ED\u636E\u53EA\u5728\u8FD9\u4EFD per-server env \u91CC\uFF08GitHub \u5EFA\u4ED3 / \u63D0\u4EA4\u4E0D\u5728\u8FD9\u91CC\uFF0Cagent \u6309 skill \u8D70 GitHub MCP\uFF09\u3002\u975E app-builder \u7CFB persona \u7684\u4F1A\u8BDD\u4E0D\u6302\u672C server\u3002`,
73082
- mcpServers: {
73083
- "clawd-app-builder": {
73084
- type: "stdio",
73085
- command: "node",
73086
- args: [args.serverScriptPath],
73087
- env: {
73088
- // 凭据排前面:固定键在后,凭据表里若混进同名条目也顶不掉路径
73089
- ...args.secrets ?? {},
73090
- CLAWD_APP_BUILDER_PERSONA_ROOT: args.personaRoot,
73091
- CLAWD_APP_BUILDER_TEMPLATE_DIR: args.templateDir,
73092
- CLAWD_APP_BUILDER_SCAFFOLD_SCRIPT: import_node_path76.default.join(args.deployKitScriptsDir, "new-extension.sh"),
73093
- CLAWD_APP_BUILDER_PUBLISH_SCRIPT: import_node_path76.default.join(args.deployKitScriptsDir, "publish.sh"),
73094
- CLAWD_APP_BUILDER_REMOVE_SCRIPT: import_node_path76.default.join(args.deployKitScriptsDir, "remove-extension.sh"),
73095
- ...args.logPath ? { CLAWD_APP_BUILDER_LOG: args.logPath } : {}
73096
- }
73097
- }
73098
- }
73099
- };
73100
- import_node_fs60.default.mkdirSync(args.outDir, { recursive: true, mode: 448 });
73101
- const tmp = `${cfgPath}.${process.pid}.tmp`;
73102
- import_node_fs60.default.writeFileSync(tmp, JSON.stringify(cfg, null, 2), { encoding: "utf8", mode: 384 });
73103
- import_node_fs60.default.renameSync(tmp, cfgPath);
73104
- return cfgPath;
73105
- }
73106
-
73107
- // src/app-builder-plugin/personas.ts
73108
- var APP_BUILDER_PERSONAS = ["persona-app-builder", "persona-dataclaw-builder"];
73109
- var APP_BUILDER_TEMPLATE = "nestjs-react";
73110
-
73111
73000
  // src/handlers/dispatch-rpc.ts
73112
73001
  init_zod();
73113
73002
  init_protocol();
@@ -73151,7 +73040,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
73151
73040
 
73152
73041
  // src/extension/runtime.ts
73153
73042
  var import_node_child_process24 = require("child_process");
73154
- var import_node_path77 = __toESM(require("path"), 1);
73043
+ var import_node_path75 = __toESM(require("path"), 1);
73155
73044
  var import_promises18 = require("timers/promises");
73156
73045
 
73157
73046
  // src/extension/port-allocator.ts
@@ -73252,7 +73141,7 @@ var Runtime = class {
73252
73141
  /\$CLAWOS_EXT_PORT/g,
73253
73142
  String(port)
73254
73143
  );
73255
- const dir = import_node_path77.default.join(this.root, extId);
73144
+ const dir = import_node_path75.default.join(this.root, extId);
73256
73145
  const env = {
73257
73146
  ...process.env,
73258
73147
  CLAWOS_EXT_PORT: String(port),
@@ -73364,7 +73253,7 @@ ${handle.stderrTail}`
73364
73253
 
73365
73254
  // src/extension/published-channels.ts
73366
73255
  var import_promises19 = __toESM(require("fs/promises"), 1);
73367
- var import_node_path78 = __toESM(require("path"), 1);
73256
+ var import_node_path76 = __toESM(require("path"), 1);
73368
73257
  init_zod();
73369
73258
  var PublishedChannelsError = class extends Error {
73370
73259
  constructor(code, message) {
@@ -73463,7 +73352,7 @@ var PublishedChannelStore = class {
73463
73352
  )
73464
73353
  };
73465
73354
  const tmp = `${this.filePath}.tmp`;
73466
- await import_promises19.default.mkdir(import_node_path78.default.dirname(this.filePath), { recursive: true });
73355
+ await import_promises19.default.mkdir(import_node_path76.default.dirname(this.filePath), { recursive: true });
73467
73356
  await import_promises19.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
73468
73357
  await import_promises19.default.rename(tmp, this.filePath);
73469
73358
  }
@@ -73471,7 +73360,7 @@ var PublishedChannelStore = class {
73471
73360
 
73472
73361
  // src/extension/bundle-cache.ts
73473
73362
  var import_promises20 = __toESM(require("fs/promises"), 1);
73474
- var import_node_path79 = __toESM(require("path"), 1);
73363
+ var import_node_path77 = __toESM(require("path"), 1);
73475
73364
  var BundleCache = class {
73476
73365
  constructor(rootDir) {
73477
73366
  this.rootDir = rootDir;
@@ -73480,14 +73369,14 @@ var BundleCache = class {
73480
73369
  /** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
73481
73370
  async write(snapshotHash, buffer) {
73482
73371
  await import_promises20.default.mkdir(this.rootDir, { recursive: true });
73483
- const file = import_node_path79.default.join(this.rootDir, `${snapshotHash}.zip`);
73372
+ const file = import_node_path77.default.join(this.rootDir, `${snapshotHash}.zip`);
73484
73373
  const tmp = `${file}.tmp`;
73485
73374
  await import_promises20.default.writeFile(tmp, buffer, { mode: 384 });
73486
73375
  await import_promises20.default.rename(tmp, file);
73487
73376
  }
73488
73377
  /** Returns the bundle bytes, or null when the file doesn't exist. */
73489
73378
  async read(snapshotHash) {
73490
- const file = import_node_path79.default.join(this.rootDir, `${snapshotHash}.zip`);
73379
+ const file = import_node_path77.default.join(this.rootDir, `${snapshotHash}.zip`);
73491
73380
  try {
73492
73381
  return await import_promises20.default.readFile(file);
73493
73382
  } catch (e) {
@@ -73497,7 +73386,7 @@ var BundleCache = class {
73497
73386
  }
73498
73387
  /** Idempotent — missing file is not an error. */
73499
73388
  async delete(snapshotHash) {
73500
- const file = import_node_path79.default.join(this.rootDir, `${snapshotHash}.zip`);
73389
+ const file = import_node_path77.default.join(this.rootDir, `${snapshotHash}.zip`);
73501
73390
  await import_promises20.default.rm(file, { force: true });
73502
73391
  }
73503
73392
  };
@@ -73520,24 +73409,24 @@ async function startDaemon(config) {
73520
73409
  sampling: logShippingCfg.sampling,
73521
73410
  homeDir: import_node_os28.default.homedir()
73522
73411
  });
73523
- const logDir = import_node_path80.default.join(config.dataDir, "log");
73524
- import_node_fs61.default.mkdirSync(logDir, { recursive: true });
73412
+ const logDir = import_node_path78.default.join(config.dataDir, "log");
73413
+ import_node_fs60.default.mkdirSync(logDir, { recursive: true });
73525
73414
  const logger = createLogger({
73526
73415
  level: config.logLevel,
73527
- file: import_node_path80.default.join(logDir, "clawd.log"),
73416
+ file: import_node_path78.default.join(logDir, "clawd.log"),
73528
73417
  logClient
73529
73418
  });
73530
73419
  logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
73531
73420
  const screenIdleProbeLogger = createFileOnlyLogger({
73532
- file: import_node_path80.default.join(logDir, "screen-idle-probe.log"),
73421
+ file: import_node_path78.default.join(logDir, "screen-idle-probe.log"),
73533
73422
  level: "debug"
73534
73423
  });
73535
73424
  logger.info("screen-idle probe logger enabled", {
73536
- file: import_node_path80.default.join(logDir, "screen-idle-probe.log")
73425
+ file: import_node_path78.default.join(logDir, "screen-idle-probe.log")
73537
73426
  });
73538
73427
  const CAP_TARGETS = [
73539
- import_node_path80.default.join(logDir, "clawd.log"),
73540
- import_node_path80.default.join(logDir, "screen-idle-probe.log")
73428
+ import_node_path78.default.join(logDir, "clawd.log"),
73429
+ import_node_path78.default.join(logDir, "screen-idle-probe.log")
73541
73430
  ];
73542
73431
  const LOG_CAP_MAX_BYTES = 10 * 1024 * 1024;
73543
73432
  const LOG_CAP_KEEP_BYTES = 5 * 1024 * 1024;
@@ -73659,8 +73548,8 @@ async function startDaemon(config) {
73659
73548
  const agents = new AgentsScanner();
73660
73549
  const history = new ClaudeHistoryReader();
73661
73550
  let transport = null;
73662
- const personaStore = new PersonaStore(import_node_path80.default.join(config.dataDir, "personas"));
73663
- const usersRoot = import_node_path80.default.join(config.dataDir, "users");
73551
+ const personaStore = new PersonaStore(import_node_path78.default.join(config.dataDir, "personas"));
73552
+ const usersRoot = import_node_path78.default.join(config.dataDir, "users");
73664
73553
  const defaultsRoot = findDefaultsRoot(logger);
73665
73554
  if (defaultsRoot) {
73666
73555
  seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
@@ -73669,13 +73558,6 @@ async function startDaemon(config) {
73669
73558
  } else {
73670
73559
  logger.warn("persona.seed.skip", { reason: "defaults-root-not-found" });
73671
73560
  }
73672
- const deployKitBundleRoot = findDeployKitRoot(logger);
73673
- if (deployKitBundleRoot) {
73674
- seedDeployKit({ deployKitBundleRoot, dataDir: config.dataDir, logger });
73675
- refreshDeployKit({ deployKitBundleRoot, dataDir: config.dataDir, logger });
73676
- } else {
73677
- logger.warn("deploy-kit.bundle-missing", {});
73678
- }
73679
73561
  refreshSandboxSettings({ store: personaStore, logger });
73680
73562
  migrateAgentsMirror({ store: personaStore, logger });
73681
73563
  migrateCodexSandbox({ store: personaStore, logger });
@@ -73684,7 +73566,7 @@ async function startDaemon(config) {
73684
73566
  retirePersonaBuilder({ store: personaStore, logger });
73685
73567
  const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
73686
73568
  const dispatchStore = createDispatchStore({
73687
- filePath: import_node_path80.default.join(config.dataDir, "dispatch.json"),
73569
+ filePath: import_node_path78.default.join(config.dataDir, "dispatch.json"),
73688
73570
  now: () => Date.now(),
73689
73571
  onFlushError: (err) => logger.error("dispatch store flush failed", {
73690
73572
  reason: err instanceof Error ? err.message : String(err)
@@ -73693,7 +73575,7 @@ async function startDaemon(config) {
73693
73575
  await dispatchStore.load();
73694
73576
  dispatchStore.markInterruptedAsFailed((/* @__PURE__ */ new Date()).toISOString());
73695
73577
  const channelStore = createChannelStore({
73696
- filePath: import_node_path80.default.join(config.dataDir, "channels.json"),
73578
+ filePath: import_node_path78.default.join(config.dataDir, "channels.json"),
73697
73579
  now: () => Date.now(),
73698
73580
  genId: () => `ch-${(0, import_node_crypto22.randomUUID)().slice(0, 8)}`,
73699
73581
  onFlushError: (err) => logger.error("channel store flush failed", {
@@ -73702,7 +73584,7 @@ async function startDaemon(config) {
73702
73584
  });
73703
73585
  await channelStore.load();
73704
73586
  const topicStore = createTopicStore({
73705
- filePath: import_node_path80.default.join(config.dataDir, "topics.json"),
73587
+ filePath: import_node_path78.default.join(config.dataDir, "topics.json"),
73706
73588
  now: () => Date.now(),
73707
73589
  genId: () => `tp-${(0, import_node_crypto22.randomUUID)().slice(0, 8)}`,
73708
73590
  onFlushError: (err) => logger.error("topic store flush failed", {
@@ -73729,12 +73611,12 @@ async function startDaemon(config) {
73729
73611
  });
73730
73612
  }
73731
73613
  });
73732
- const here = typeof __dirname === "string" ? __dirname : import_node_path80.default.dirname((0, import_node_url5.fileURLToPath)(import_meta9.url));
73614
+ const here = typeof __dirname === "string" ? __dirname : import_node_path78.default.dirname((0, import_node_url5.fileURLToPath)(import_meta9.url));
73733
73615
  const mcpConfigs = [];
73734
73616
  const secretsBundleRoot = findSecretsBundleRoot(logger);
73735
- const localSecretsDir = import_node_path80.default.join(config.dataDir, LOCAL_SECRETS_DIRNAME);
73617
+ const localSecretsDir = import_node_path78.default.join(config.dataDir, LOCAL_SECRETS_DIRNAME);
73736
73618
  const readSecrets = () => readSecretTable({ bundleRoot: secretsBundleRoot, overrideDir: localSecretsDir, logger });
73737
- const githubTokenFile = import_node_path80.default.join(localSecretsDir, GITHUB_TOKEN_FILE);
73619
+ const githubTokenFile = import_node_path78.default.join(localSecretsDir, GITHUB_TOKEN_FILE);
73738
73620
  const githubIdentity = createGithubIdentity({
73739
73621
  resolve: () => resolveGithubAuth({ exec: runCommand, fileToken: () => readEnvFileVar(githubTokenFile, GITHUB_TOKEN_VAR) }),
73740
73622
  store: (token) => storeGithubAuth({
@@ -73767,29 +73649,27 @@ async function startDaemon(config) {
73767
73649
  logger
73768
73650
  });
73769
73651
  void githubIdentity.refresh();
73770
- let refreshAppBuilderMcpConfig;
73771
73652
  const resolvePersonaMcpConfig = (personaId2) => {
73772
- refreshAppBuilderMcpConfig?.(personaId2);
73773
73653
  const secrets = secretsWithGithubIdentity(readSecrets(), githubIdentity.cached());
73774
73654
  void githubIdentity.refresh();
73775
73655
  return renderPersonaMcpSecrets({
73776
73656
  personaId: personaId2,
73777
- personaDir: import_node_path80.default.join(config.dataDir, "personas", personaId2),
73657
+ personaDir: import_node_path78.default.join(config.dataDir, "personas", personaId2),
73778
73658
  secrets,
73779
- outDir: import_node_path80.default.join(config.dataDir, "persona-mcp"),
73659
+ outDir: import_node_path78.default.join(config.dataDir, "persona-mcp"),
73780
73660
  logger
73781
73661
  });
73782
73662
  };
73783
73663
  const mcpDaemonUrl = `http://127.0.0.1:${config.port}`;
73784
73664
  const dispatchServerCandidates = [
73785
- import_node_path80.default.join(here, "dispatch", "mcp-server.cjs"),
73665
+ import_node_path78.default.join(here, "dispatch", "mcp-server.cjs"),
73786
73666
  // 生产 dist/index → dist/dispatch/mcp-server.cjs
73787
- import_node_path80.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
73667
+ import_node_path78.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
73788
73668
  // dev tsx src/index → ../dist/dispatch/mcp-server.cjs
73789
73669
  ];
73790
- const dispatchServerScriptPath = dispatchServerCandidates.find((p3) => import_node_fs61.default.existsSync(p3));
73670
+ const dispatchServerScriptPath = dispatchServerCandidates.find((p3) => import_node_fs60.default.existsSync(p3));
73791
73671
  if (dispatchServerScriptPath) {
73792
- const dispatchLogPath = import_node_path80.default.join(logDir, "dispatch-mcp-server.log");
73672
+ const dispatchLogPath = import_node_path78.default.join(logDir, "dispatch-mcp-server.log");
73793
73673
  const dispatchCfgPath = writeDispatchMcpConfig({
73794
73674
  dataDir: config.dataDir,
73795
73675
  serverScriptPath: dispatchServerScriptPath,
@@ -73809,12 +73689,12 @@ async function startDaemon(config) {
73809
73689
  });
73810
73690
  }
73811
73691
  const ticketServerCandidates = [
73812
- import_node_path80.default.join(here, "ticket", "mcp-server.cjs"),
73813
- import_node_path80.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
73692
+ import_node_path78.default.join(here, "ticket", "mcp-server.cjs"),
73693
+ import_node_path78.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
73814
73694
  ];
73815
- const ticketServerScriptPath = ticketServerCandidates.find((p3) => import_node_fs61.default.existsSync(p3));
73695
+ const ticketServerScriptPath = ticketServerCandidates.find((p3) => import_node_fs60.default.existsSync(p3));
73816
73696
  if (ticketServerScriptPath) {
73817
- const ticketLogPath = import_node_path80.default.join(logDir, "ticket-mcp-server.log");
73697
+ const ticketLogPath = import_node_path78.default.join(logDir, "ticket-mcp-server.log");
73818
73698
  const ticketCfgPath = writeTicketMcpConfig({
73819
73699
  dataDir: config.dataDir,
73820
73700
  serverScriptPath: ticketServerScriptPath,
@@ -73836,12 +73716,12 @@ async function startDaemon(config) {
73836
73716
  });
73837
73717
  }
73838
73718
  const shiftServerCandidates = [
73839
- import_node_path80.default.join(here, "shift", "mcp-server.cjs"),
73840
- import_node_path80.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
73719
+ import_node_path78.default.join(here, "shift", "mcp-server.cjs"),
73720
+ import_node_path78.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
73841
73721
  ];
73842
- const shiftServerScriptPath = shiftServerCandidates.find((p3) => import_node_fs61.default.existsSync(p3));
73722
+ const shiftServerScriptPath = shiftServerCandidates.find((p3) => import_node_fs60.default.existsSync(p3));
73843
73723
  if (shiftServerScriptPath) {
73844
- const shiftLogPath = import_node_path80.default.join(logDir, "shift-mcp-server.log");
73724
+ const shiftLogPath = import_node_path78.default.join(logDir, "shift-mcp-server.log");
73845
73725
  const shiftCfgPath = await writeShiftMcpConfig({
73846
73726
  dataDir: config.dataDir,
73847
73727
  serverScriptPath: shiftServerScriptPath,
@@ -73862,12 +73742,12 @@ async function startDaemon(config) {
73862
73742
  );
73863
73743
  }
73864
73744
  const inboxServerCandidates = [
73865
- import_node_path80.default.join(here, "inbox", "mcp-server.cjs"),
73866
- import_node_path80.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
73745
+ import_node_path78.default.join(here, "inbox", "mcp-server.cjs"),
73746
+ import_node_path78.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
73867
73747
  ];
73868
- const inboxServerScriptPath = inboxServerCandidates.find((p3) => import_node_fs61.default.existsSync(p3));
73748
+ const inboxServerScriptPath = inboxServerCandidates.find((p3) => import_node_fs60.default.existsSync(p3));
73869
73749
  if (inboxServerScriptPath) {
73870
- const inboxLogPath = import_node_path80.default.join(logDir, "inbox-mcp-server.log");
73750
+ const inboxLogPath = import_node_path78.default.join(logDir, "inbox-mcp-server.log");
73871
73751
  const inboxCfgPath = await writeInboxMcpConfig({
73872
73752
  dataDir: config.dataDir,
73873
73753
  serverScriptPath: inboxServerScriptPath,
@@ -73888,10 +73768,10 @@ async function startDaemon(config) {
73888
73768
  );
73889
73769
  }
73890
73770
  const peerOpsServerCandidates = [
73891
- import_node_path80.default.join(here, "peer-ops", "mcp-server.cjs"),
73892
- import_node_path80.default.join(here, "..", "dist", "peer-ops", "mcp-server.cjs")
73771
+ import_node_path78.default.join(here, "peer-ops", "mcp-server.cjs"),
73772
+ import_node_path78.default.join(here, "..", "dist", "peer-ops", "mcp-server.cjs")
73893
73773
  ];
73894
- const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) => import_node_fs61.default.existsSync(p3));
73774
+ const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) => import_node_fs60.default.existsSync(p3));
73895
73775
  if (peerOpsServerScriptPath) {
73896
73776
  const peerOpsCfgPath = writePeerOpsMcpConfig({
73897
73777
  dataDir: config.dataDir,
@@ -73911,12 +73791,12 @@ async function startDaemon(config) {
73911
73791
  );
73912
73792
  }
73913
73793
  const rpcToolServerCandidates = [
73914
- import_node_path80.default.join(here, "rpc-tool", "mcp-server.cjs"),
73915
- import_node_path80.default.join(here, "..", "dist", "rpc-tool", "mcp-server.cjs")
73794
+ import_node_path78.default.join(here, "rpc-tool", "mcp-server.cjs"),
73795
+ import_node_path78.default.join(here, "..", "dist", "rpc-tool", "mcp-server.cjs")
73916
73796
  ];
73917
- const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) => import_node_fs61.default.existsSync(p3));
73797
+ const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) => import_node_fs60.default.existsSync(p3));
73918
73798
  if (rpcToolServerScriptPath) {
73919
- const rpcToolLogPath = import_node_path80.default.join(logDir, "rpc-tool-mcp-server.log");
73799
+ const rpcToolLogPath = import_node_path78.default.join(logDir, "rpc-tool-mcp-server.log");
73920
73800
  const rpcToolCfgPath = writeRpcToolMcpConfig({
73921
73801
  dataDir: config.dataDir,
73922
73802
  serverScriptPath: rpcToolServerScriptPath,
@@ -73936,48 +73816,8 @@ async function startDaemon(config) {
73936
73816
  { tried: rpcToolServerCandidates }
73937
73817
  );
73938
73818
  }
73939
- const appBuilderServerCandidates = [
73940
- import_node_path80.default.join(here, "app-builder-plugin", "mcp-server.cjs"),
73941
- import_node_path80.default.join(here, "..", "dist", "app-builder-plugin", "mcp-server.cjs")
73942
- ];
73943
- const appBuilderServerScriptPath = appBuilderServerCandidates.find((p3) => import_node_fs61.default.existsSync(p3));
73944
- if (appBuilderServerScriptPath) {
73945
- const appBuilderLogPath = import_node_path80.default.join(logDir, "app-builder-mcp-server.log");
73946
- const writeAppBuilderConfigFor = (personaId2) => {
73947
- const personaRoot = import_node_path80.default.join(config.dataDir, "personas", personaId2);
73948
- const secrets = secretsForKit(readSecrets(), import_node_path80.default.join(personaRoot, "extension-kit"));
73949
- return writeAppBuilderMcpConfig({
73950
- outDir: import_node_path80.default.join(config.dataDir, "persona-mcp"),
73951
- personaId: personaId2,
73952
- serverScriptPath: appBuilderServerScriptPath,
73953
- personaRoot,
73954
- templateDir: import_node_path80.default.join(personaRoot, "extension-kit", "examples", APP_BUILDER_TEMPLATE),
73955
- deployKitScriptsDir: import_node_path80.default.join(config.dataDir, "deploy-kit", "scripts"),
73956
- ...secrets ? { secrets } : {},
73957
- logPath: appBuilderLogPath
73958
- });
73959
- };
73960
- for (const personaId2 of APP_BUILDER_PERSONAS) {
73961
- const cfgPath = writeAppBuilderConfigFor(personaId2);
73962
- mcpConfigs.push({ id: `app-builder:${personaId2}`, path: cfgPath, personas: [personaId2] });
73963
- logger.info("app-builder.mcp.json written", { personaId: personaId2, path: cfgPath, server: appBuilderServerScriptPath });
73964
- }
73965
- refreshAppBuilderMcpConfig = (personaId2) => {
73966
- if (!APP_BUILDER_PERSONAS.includes(personaId2)) return;
73967
- try {
73968
- writeAppBuilderConfigFor(personaId2);
73969
- } catch (err) {
73970
- logger.warn("app-builder.mcp.json refresh failed", { personaId: personaId2, error: err instanceof Error ? err.message : String(err) });
73971
- }
73972
- };
73973
- } else {
73974
- logger.warn(
73975
- "app-builder-plugin/mcp-server.cjs not found; clawd-app-builder tools disabled (dev tsx \u6A21\u5F0F\u4E0B\u9700\u5148\u8DD1\u8FC7 build)",
73976
- { tried: appBuilderServerCandidates }
73977
- );
73978
- }
73979
73819
  const shiftStore = createShiftStore({
73980
- filePath: import_node_path80.default.join(config.dataDir, "shift.json"),
73820
+ filePath: import_node_path78.default.join(config.dataDir, "shift.json"),
73981
73821
  ownerIdProvider: () => ownerPrincipalId,
73982
73822
  now: () => Date.now()
73983
73823
  });
@@ -73999,7 +73839,7 @@ async function startDaemon(config) {
73999
73839
  getAdapter,
74000
73840
  historyReader: history,
74001
73841
  dataDir: config.dataDir,
74002
- personaRoot: import_node_path80.default.join(config.dataDir, "personas"),
73842
+ personaRoot: import_node_path78.default.join(config.dataDir, "personas"),
74003
73843
  // dispatch / shift 自动化 spawn 按 persona 绑定 tool 起 B session(codex persona 用 codex)。
74004
73844
  // personaRegistry 声明在 manager 之后(同作用域 const,调用时机在启动完成后,无 TDZ 风险)。
74005
73845
  getPersonaDefaults: (personaId2) => personaRegistry.get(personaId2),
@@ -74056,10 +73896,10 @@ async function startDaemon(config) {
74056
73896
  // 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
74057
73897
  attachmentGroup: {
74058
73898
  onFileEdit: (input) => {
74059
- const absPath = import_node_path80.default.isAbsolute(input.relPath) ? input.relPath : import_node_path80.default.join(input.cwd, input.relPath);
73899
+ const absPath = import_node_path78.default.isAbsolute(input.relPath) ? input.relPath : import_node_path78.default.join(input.cwd, input.relPath);
74060
73900
  let size = 0;
74061
73901
  try {
74062
- size = import_node_fs61.default.statSync(absPath).size;
73902
+ size = import_node_fs60.default.statSync(absPath).size;
74063
73903
  } catch (err) {
74064
73904
  logger.warn("attachment.onFileEdit stat failed", {
74065
73905
  sessionId: input.sessionId,
@@ -74100,9 +73940,9 @@ async function startDaemon(config) {
74100
73940
  logger.info("projects.seed-dropped", { dropped: droppedSeed.dropped, backup: droppedSeed.backup });
74101
73941
  }
74102
73942
  const projectsStore = new ProjectsStore({
74103
- file: import_node_path80.default.join(config.dataDir, "projects.json"),
73943
+ file: import_node_path78.default.join(config.dataDir, "projects.json"),
74104
73944
  clawdDir: config.dataDir,
74105
- codexStateFile: import_node_path80.default.join(import_node_os28.default.homedir(), ".codex", ".codex-global-state.json"),
73945
+ codexStateFile: import_node_path78.default.join(import_node_os28.default.homedir(), ".codex", ".codex-global-state.json"),
74106
73946
  logger
74107
73947
  });
74108
73948
  const observer = new SessionObserver({
@@ -74167,13 +74007,13 @@ async function startDaemon(config) {
74167
74007
  logger
74168
74008
  });
74169
74009
  registerAdapter("claude", claudeAdapter);
74170
- const codexIsolatedHome = import_node_path80.default.join(config.dataDir, "codex-home");
74010
+ const codexIsolatedHome = import_node_path78.default.join(config.dataDir, "codex-home");
74171
74011
  try {
74172
- import_node_fs61.default.mkdirSync(codexIsolatedHome, { recursive: true });
74012
+ import_node_fs60.default.mkdirSync(codexIsolatedHome, { recursive: true });
74173
74013
  for (const f2 of ["auth.json", "config.toml"]) {
74174
- const link = import_node_path80.default.join(codexIsolatedHome, f2);
74175
- const target = import_node_path80.default.join(import_node_os28.default.homedir(), ".codex", f2);
74176
- if (!import_node_fs61.default.existsSync(link) && import_node_fs61.default.existsSync(target)) import_node_fs61.default.symlinkSync(target, link);
74014
+ const link = import_node_path78.default.join(codexIsolatedHome, f2);
74015
+ const target = import_node_path78.default.join(import_node_os28.default.homedir(), ".codex", f2);
74016
+ if (!import_node_fs60.default.existsSync(link) && import_node_fs60.default.existsSync(target)) import_node_fs60.default.symlinkSync(target, link);
74177
74017
  }
74178
74018
  } catch (err) {
74179
74019
  logger.warn("codex isolated home setup failed", { err: String(err) });
@@ -74184,29 +74024,44 @@ async function startDaemon(config) {
74184
74024
  logger,
74185
74025
  historyReader: new CodexHistoryReader({
74186
74026
  roots: codexRolloutRoots(config.dataDir),
74187
- sharedHome: import_node_path80.default.join(import_node_os28.default.homedir(), ".codex"),
74027
+ sharedHome: import_node_path78.default.join(import_node_os28.default.homedir(), ".codex"),
74188
74028
  logger
74189
74029
  }),
74190
74030
  // projectPaths 每次调用现取 —— 用户新建 project 后立即生效,不用重启 daemon
74191
74031
  codexHomeFor: (cwd) => resolveCodexHome({
74192
74032
  cwd,
74193
- personaRoot: import_node_path80.default.join(config.dataDir, "personas"),
74033
+ personaRoot: import_node_path78.default.join(config.dataDir, "personas"),
74194
74034
  // 必须用 listMerged(Codex registry ∪ 叠加层):只用本地 list() 的话,用户在
74195
74035
  // Codex 里建的 project 不在表里,在它下面开的会话会被误判成隔离 → Codex 侧看不到
74196
74036
  projectPaths: projectsStore.listMerged().map((x2) => x2.path),
74197
- sharedHome: import_node_path80.default.join(import_node_os28.default.homedir(), ".codex"),
74037
+ sharedHome: import_node_path78.default.join(import_node_os28.default.homedir(), ".codex"),
74198
74038
  isolatedHome: codexIsolatedHome
74199
74039
  }),
74200
74040
  // 附件图片验签:与 http-router /files 路由同一把 secret
74201
74041
  getSignSecret: () => authFile.token
74202
74042
  })
74203
74043
  );
74204
- registerAdapter(CODEX_CLOUD_TOOL_ID, new CloudCodexAdapter({ client: cloudGateway, logger, getSignSecret: () => authFile.token }));
74044
+ registerAdapter(
74045
+ CODEX_CLOUD_TOOL_ID,
74046
+ new CloudCodexAdapter({
74047
+ client: cloudGateway,
74048
+ // 历史副本从中心拉(design 2026-09-19-cloud-session-oss §3.4):没登录就没有历史,不抛
74049
+ history: {
74050
+ fetchRollout: (threadId) => {
74051
+ const loginPass = ownerIdentityStore.read()?.loginPass;
74052
+ if (!loginPass) return Promise.resolve(null);
74053
+ return centralGetThread({ api: config.clawosApi ?? DEFAULT_CLAWOS_API, loginPass, threadId });
74054
+ }
74055
+ },
74056
+ logger,
74057
+ getSignSecret: () => authFile.token
74058
+ })
74059
+ );
74205
74060
  const piMcpBridgeCandidates = [
74206
- import_node_path80.default.join(here, "pi-mcp-bridge", "extension.cjs"),
74207
- import_node_path80.default.join(here, "..", "dist", "pi-mcp-bridge", "extension.cjs")
74061
+ import_node_path78.default.join(here, "pi-mcp-bridge", "extension.cjs"),
74062
+ import_node_path78.default.join(here, "..", "dist", "pi-mcp-bridge", "extension.cjs")
74208
74063
  ];
74209
- const piMcpBridgePath = piMcpBridgeCandidates.find((p3) => import_node_fs61.default.existsSync(p3));
74064
+ const piMcpBridgePath = piMcpBridgeCandidates.find((p3) => import_node_fs60.default.existsSync(p3));
74210
74065
  if (piMcpBridgePath) {
74211
74066
  logger.info("pi-mcp-bridge extension resolved", { path: piMcpBridgePath });
74212
74067
  } else {
@@ -74501,11 +74356,11 @@ async function startDaemon(config) {
74501
74356
  // 'persona/<pid>/owner',default 走 'default'。
74502
74357
  getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
74503
74358
  // guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
74504
- personaRoot: import_node_path80.default.join(config.dataDir, "personas"),
74359
+ personaRoot: import_node_path78.default.join(config.dataDir, "personas"),
74505
74360
  usersRoot
74506
74361
  },
74507
74362
  // workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
74508
- personaRoot: import_node_path80.default.join(config.dataDir, "personas"),
74363
+ personaRoot: import_node_path78.default.join(config.dataDir, "personas"),
74509
74364
  // v2 多人 persona 隔离:handler 派生 guest user-dir 放行
74510
74365
  usersRoot,
74511
74366
  // v2 Phase 6: whoami handler 装在 owner principal.displayName + persona 解析
@@ -74786,7 +74641,7 @@ async function startDaemon(config) {
74786
74641
  });
74787
74642
  shiftScheduler.start();
74788
74643
  logger.info("shift scheduler started", { shiftCount: shiftStore.list().length });
74789
- const larkBotStore = createLarkBotBindingStore(import_node_path80.default.join(config.dataDir, "personas"));
74644
+ const larkBotStore = createLarkBotBindingStore(import_node_path78.default.join(config.dataDir, "personas"));
74790
74645
  const larkBotCloud = createLarkBotCloudClient({
74791
74646
  api: config.clawosApi ?? DEFAULT_CLAWOS_API,
74792
74647
  getLoginPass: () => ownerIdentityStore.read()?.loginPass ?? null
@@ -74798,7 +74653,7 @@ async function startDaemon(config) {
74798
74653
  store: larkBotStore,
74799
74654
  fetchResource: (appId, messageId, fileKey, maxBytes, type) => larkBotCloud.fetchResource(appId, messageId, fileKey, maxBytes, type),
74800
74655
  // 图片落 guest userWorkDir 下(capId = lark-<chat_id>):CC 经 --add-dir + allowRead carve 可 Read
74801
- mediaRootFor: (chatId) => import_node_path80.default.join(deriveUserWorkDir(`lark-${chatId}`, usersRoot), "lark-media"),
74656
+ mediaRootFor: (chatId) => import_node_path78.default.join(deriveUserWorkDir(`lark-${chatId}`, usersRoot), "lark-media"),
74802
74657
  isShuttingDown: () => larkDraining,
74803
74658
  logger: {
74804
74659
  warn: (msg) => logger.warn(msg),
@@ -75082,8 +74937,8 @@ async function startDaemon(config) {
75082
74937
  const lines = [
75083
74938
  `Tunnel: ${r2.url}`,
75084
74939
  ...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
75085
- `Frpc config: ${import_node_path80.default.join(config.dataDir, "frpc.toml")}`,
75086
- `Frpc log: ${import_node_path80.default.join(logDir, "frpc.log")}`
74940
+ `Frpc config: ${import_node_path78.default.join(config.dataDir, "frpc.toml")}`,
74941
+ `Frpc log: ${import_node_path78.default.join(logDir, "frpc.log")}`
75087
74942
  ];
75088
74943
  const width2 = Math.max(...lines.map((l2) => l2.length));
75089
74944
  const bar = "\u2550".repeat(width2 + 4);
@@ -75096,8 +74951,8 @@ ${bar}
75096
74951
 
75097
74952
  `);
75098
74953
  try {
75099
- const connectPath = import_node_path80.default.join(config.dataDir, "connect.txt");
75100
- import_node_fs61.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
74954
+ const connectPath = import_node_path78.default.join(config.dataDir, "connect.txt");
74955
+ import_node_fs60.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
75101
74956
  } catch {
75102
74957
  }
75103
74958
  } catch (err) {
@@ -75195,9 +75050,9 @@ ${bar}
75195
75050
  };
75196
75051
  }
75197
75052
  function migrateDropPersonsDir(dataDir) {
75198
- const dir = import_node_path80.default.join(dataDir, "persons");
75053
+ const dir = import_node_path78.default.join(dataDir, "persons");
75199
75054
  try {
75200
- import_node_fs61.default.rmSync(dir, { recursive: true, force: true });
75055
+ import_node_fs60.default.rmSync(dir, { recursive: true, force: true });
75201
75056
  } catch {
75202
75057
  }
75203
75058
  }