@clawos-dev/clawd 0.2.547 → 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 +475 -649
  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;
@@ -63148,7 +63062,7 @@ var PiRpcClient = class {
63148
63062
  var import_node_child_process10 = require("child_process");
63149
63063
  var import_node_crypto9 = require("crypto");
63150
63064
  var import_node_fs35 = __toESM(require("fs"), 1);
63151
- var import_node_path40 = __toESM(require("path"), 1);
63065
+ var import_node_path39 = __toESM(require("path"), 1);
63152
63066
 
63153
63067
  // src/tools/pi-events.ts
63154
63068
  init_protocol();
@@ -63325,7 +63239,7 @@ ${dirs.map((d2) => `- ${d2}`).join("\n")}`;
63325
63239
  function createPiSession(ctx, sink, deps = {}) {
63326
63240
  const cmd = process.env.PI_BIN ?? "pi";
63327
63241
  const sessionId = ctx.toolSessionId ?? (0, import_node_crypto9.randomUUID)();
63328
- const skillsDir = import_node_path40.default.join(ctx.cwd, ".claude", "skills");
63242
+ const skillsDir = import_node_path39.default.join(ctx.cwd, ".claude", "skills");
63329
63243
  const exists = deps.skillsDirExists ?? ((d2) => import_node_fs35.default.existsSync(d2));
63330
63244
  const args = buildPiArgs(ctx, {
63331
63245
  sessionId,
@@ -63444,20 +63358,20 @@ function createPiSession(ctx, sink, deps = {}) {
63444
63358
  // src/tools/pi-history.ts
63445
63359
  var import_node_fs36 = __toESM(require("fs"), 1);
63446
63360
  var import_node_os10 = __toESM(require("os"), 1);
63447
- var import_node_path41 = __toESM(require("path"), 1);
63361
+ var import_node_path40 = __toESM(require("path"), 1);
63448
63362
  var PI_LIST_SESSIONS_LIMIT = 100;
63449
63363
  var PI_LIST_SESSIONS_SCAN_CAP = 4e3;
63450
63364
  function piAgentDir(env = process.env) {
63451
- 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");
63452
63366
  }
63453
63367
  function piSessionsRoot(env = process.env) {
63454
- return import_node_path41.default.join(piAgentDir(env), "sessions");
63368
+ return import_node_path40.default.join(piAgentDir(env), "sessions");
63455
63369
  }
63456
63370
  function encodePiCwd(cwd) {
63457
63371
  return `--${cwd.replace(/^[\\/]+/, "").replace(/[\\/:]/g, "-")}--`;
63458
63372
  }
63459
63373
  function piProjectSessionDir(sessionsRoot, cwd) {
63460
- return import_node_path41.default.join(sessionsRoot, encodePiCwd(cwd));
63374
+ return import_node_path40.default.join(sessionsRoot, encodePiCwd(cwd));
63461
63375
  }
63462
63376
  function findInDir(dir, toolSessionId) {
63463
63377
  let names;
@@ -63468,7 +63382,7 @@ function findInDir(dir, toolSessionId) {
63468
63382
  }
63469
63383
  const suffix = `_${toolSessionId}.jsonl`;
63470
63384
  const hit = names.filter((n2) => n2.endsWith(suffix)).sort().at(-1);
63471
- return hit ? import_node_path41.default.join(dir, hit) : null;
63385
+ return hit ? import_node_path40.default.join(dir, hit) : null;
63472
63386
  }
63473
63387
  function locatePiSessionFile(sessionsRoot, cwd, toolSessionId) {
63474
63388
  const direct = findInDir(piProjectSessionDir(sessionsRoot, cwd), toolSessionId);
@@ -63480,7 +63394,7 @@ function locatePiSessionFile(sessionsRoot, cwd, toolSessionId) {
63480
63394
  return null;
63481
63395
  }
63482
63396
  for (const d2 of dirs) {
63483
- const hit = findInDir(import_node_path41.default.join(sessionsRoot, d2), toolSessionId);
63397
+ const hit = findInDir(import_node_path40.default.join(sessionsRoot, d2), toolSessionId);
63484
63398
  if (hit) return hit;
63485
63399
  }
63486
63400
  return null;
@@ -63579,7 +63493,7 @@ var PiHistoryReader = class {
63579
63493
  return [];
63580
63494
  }
63581
63495
  async listSessions(args) {
63582
- const want = import_node_path41.default.resolve(args.projectPath);
63496
+ const want = import_node_path40.default.resolve(args.projectPath);
63583
63497
  const dir = piProjectSessionDir(this.deps.sessionsRoot, want);
63584
63498
  let names;
63585
63499
  try {
@@ -63591,12 +63505,12 @@ var PiHistoryReader = class {
63591
63505
  let scanned = 0;
63592
63506
  for (const n2 of names) {
63593
63507
  if (++scanned > PI_LIST_SESSIONS_SCAN_CAP) break;
63594
- const file = import_node_path41.default.join(dir, n2);
63508
+ const file = import_node_path40.default.join(dir, n2);
63595
63509
  const head = parseLine2(readFirstLine(file) ?? "");
63596
63510
  if (!head || head.type !== "session") continue;
63597
63511
  const cwd = str3(head.cwd);
63598
63512
  const id = str3(head.id);
63599
- if (!cwd || !id || import_node_path41.default.resolve(cwd) !== want) continue;
63513
+ if (!cwd || !id || import_node_path40.default.resolve(cwd) !== want) continue;
63600
63514
  let mtimeMs;
63601
63515
  try {
63602
63516
  mtimeMs = import_node_fs36.default.statSync(file).mtimeMs;
@@ -63831,7 +63745,7 @@ var PiAdapter = class {
63831
63745
  init_protocol();
63832
63746
 
63833
63747
  // src/tools/codex-skills.ts
63834
- var import_node_path42 = __toESM(require("path"), 1);
63748
+ var import_node_path41 = __toESM(require("path"), 1);
63835
63749
  function str4(v3) {
63836
63750
  return typeof v3 === "string" ? v3 : void 0;
63837
63751
  }
@@ -63846,13 +63760,13 @@ function mapSkillsListResponse(res) {
63846
63760
  const r2 = s2 ?? {};
63847
63761
  const name = str4(r2.name);
63848
63762
  if (!name) continue;
63849
- const path102 = str4(r2.path);
63763
+ const path100 = str4(r2.path);
63850
63764
  const description = str4(r2.description);
63851
63765
  const isPlugin = name.includes(":");
63852
63766
  out.push({
63853
63767
  name,
63854
63768
  source: isPlugin ? "plugin" : "project",
63855
- ...path102 ? { path: path102 } : {},
63769
+ ...path100 ? { path: path100 } : {},
63856
63770
  ...description ? { description } : {},
63857
63771
  ...isPlugin ? { plugin: name.split(":")[0] } : {}
63858
63772
  });
@@ -63868,7 +63782,7 @@ async function listCodexSkills(cwd, deps = {}) {
63868
63782
  // 先写 extraRoots 再写 list(stdio 按写入顺序处理,fire-and-forget 不 await 回包;
63869
63783
  // codex-session.ts ready 序列同款,两处保持一致)。失败不阻塞 list。
63870
63784
  beforeRequest: (client) => {
63871
- 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);
63872
63786
  }
63873
63787
  });
63874
63788
  return mapSkillsListResponse(res);
@@ -63944,14 +63858,14 @@ function rec4(v3) {
63944
63858
  // src/workspace/browser.ts
63945
63859
  var import_node_fs38 = __toESM(require("fs"), 1);
63946
63860
  var import_node_os11 = __toESM(require("os"), 1);
63947
- var import_node_path43 = __toESM(require("path"), 1);
63861
+ var import_node_path42 = __toESM(require("path"), 1);
63948
63862
  init_protocol();
63949
63863
  var MAX_FILE_BYTES2 = 2 * 1024 * 1024;
63950
63864
  function resolveInsideCwd(cwd, subpath) {
63951
- const absCwd = import_node_path43.default.resolve(cwd);
63952
- const joined = import_node_path43.default.resolve(absCwd, subpath ?? ".");
63953
- const rel = import_node_path43.default.relative(absCwd, joined);
63954
- 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)) {
63955
63869
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
63956
63870
  }
63957
63871
  return joined;
@@ -63982,7 +63896,7 @@ var WorkspaceBrowser = class {
63982
63896
  mtime: ""
63983
63897
  };
63984
63898
  try {
63985
- 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));
63986
63900
  entry.mtime = new Date(st2.mtimeMs).toISOString();
63987
63901
  if (d2.isFile()) entry.size = st2.size;
63988
63902
  } catch {
@@ -64029,7 +63943,7 @@ var WorkspaceBrowser = class {
64029
63943
  // src/skills/agents-scanner.ts
64030
63944
  var import_node_fs39 = __toESM(require("fs"), 1);
64031
63945
  var import_node_os12 = __toESM(require("os"), 1);
64032
- var import_node_path44 = __toESM(require("path"), 1);
63946
+ var import_node_path43 = __toESM(require("path"), 1);
64033
63947
  var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
64034
63948
  function isDirLikeSync2(p3) {
64035
63949
  try {
@@ -64067,10 +63981,10 @@ function scanAgentsDir(dir, source, seen, out) {
64067
63981
  }
64068
63982
  for (const ent of entries) {
64069
63983
  if (!ent.name.endsWith(".md")) continue;
64070
- 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)))) {
64071
63985
  continue;
64072
63986
  }
64073
- const filePath = import_node_path44.default.join(dir, ent.name);
63987
+ const filePath = import_node_path43.default.join(dir, ent.name);
64074
63988
  const baseName = ent.name.replace(/\.md$/, "");
64075
63989
  if (seen.has(baseName)) continue;
64076
63990
  seen.add(baseName);
@@ -64093,7 +64007,7 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
64093
64007
  return;
64094
64008
  }
64095
64009
  for (const ent of entries) {
64096
- const childPath = import_node_path44.default.join(dir, ent.name);
64010
+ const childPath = import_node_path43.default.join(dir, ent.name);
64097
64011
  if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
64098
64012
  walk2(childPath, [...namespaces, ent.name]);
64099
64013
  continue;
@@ -64118,9 +64032,9 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
64118
64032
  walk2(root, []);
64119
64033
  }
64120
64034
  function readInstalledPlugins2(home) {
64121
- const pluginsDir = import_node_path44.default.join(home, ".claude", "plugins");
64122
- const v22 = import_node_path44.default.join(pluginsDir, "installed_plugins_v2.json");
64123
- 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");
64124
64038
  let raw = null;
64125
64039
  for (const candidate of [v22, v1]) {
64126
64040
  try {
@@ -64149,19 +64063,19 @@ function readInstalledPlugins2(home) {
64149
64063
  return out;
64150
64064
  }
64151
64065
  function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
64152
- let cur = import_node_path44.default.resolve(startCwd);
64153
- 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;
64154
64068
  while (true) {
64155
- 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);
64156
64070
  let hasGit = false;
64157
64071
  try {
64158
- 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"));
64159
64073
  } catch {
64160
64074
  }
64161
64075
  if (hasGit) return;
64162
64076
  if (cur === home) return;
64163
64077
  if (cur === fsRoot) return;
64164
- const parent = import_node_path44.default.dirname(cur);
64078
+ const parent = import_node_path43.default.dirname(cur);
64165
64079
  if (parent === cur) return;
64166
64080
  cur = parent;
64167
64081
  }
@@ -64196,7 +64110,7 @@ var AgentsScanner = class {
64196
64110
  }
64197
64111
  const fsBlock = [];
64198
64112
  scanAgentsDir(
64199
- import_node_path44.default.join(this.home, ".claude", "agents"),
64113
+ import_node_path43.default.join(this.home, ".claude", "agents"),
64200
64114
  "global",
64201
64115
  seen,
64202
64116
  fsBlock
@@ -64210,7 +64124,7 @@ var AgentsScanner = class {
64210
64124
  ...this.extraPluginRoots
64211
64125
  ];
64212
64126
  for (const { name, root } of plugins) {
64213
- const agentsRoot = import_node_path44.default.join(root, "agents");
64127
+ const agentsRoot = import_node_path43.default.join(root, "agents");
64214
64128
  scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
64215
64129
  }
64216
64130
  return [...builtinBlock, ...fsBlock];
@@ -64220,13 +64134,13 @@ var AgentsScanner = class {
64220
64134
  // src/observer/session-observer.ts
64221
64135
  var import_node_fs41 = __toESM(require("fs"), 1);
64222
64136
  var import_node_os14 = __toESM(require("os"), 1);
64223
- var import_node_path46 = __toESM(require("path"), 1);
64137
+ var import_node_path45 = __toESM(require("path"), 1);
64224
64138
  init_claude_history();
64225
64139
 
64226
64140
  // src/observer/subagent-meta-observer.ts
64227
64141
  var import_node_fs40 = __toESM(require("fs"), 1);
64228
64142
  var import_node_os13 = __toESM(require("os"), 1);
64229
- var import_node_path45 = __toESM(require("path"), 1);
64143
+ var import_node_path44 = __toESM(require("path"), 1);
64230
64144
  init_claude_history();
64231
64145
  var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
64232
64146
  var SubagentMetaObserver = class {
@@ -64239,7 +64153,7 @@ var SubagentMetaObserver = class {
64239
64153
  watches = /* @__PURE__ */ new Map();
64240
64154
  // public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
64241
64155
  resolveSubagentDir(cwd, toolSessionId) {
64242
- return import_node_path45.default.join(
64156
+ return import_node_path44.default.join(
64243
64157
  this.home,
64244
64158
  ".claude",
64245
64159
  "projects",
@@ -64295,7 +64209,7 @@ var SubagentMetaObserver = class {
64295
64209
  if (!m3) return;
64296
64210
  const agentId = m3[1];
64297
64211
  if (w3.emitted.has(agentId)) return;
64298
- const file = import_node_path45.default.join(w3.dirPath, name);
64212
+ const file = import_node_path44.default.join(w3.dirPath, name);
64299
64213
  let raw;
64300
64214
  try {
64301
64215
  raw = import_node_fs40.default.readFileSync(file, "utf8");
@@ -64355,7 +64269,7 @@ var SessionObserver = class {
64355
64269
  metaObserver;
64356
64270
  resolveJsonlPath(cwd, toolSessionId, override) {
64357
64271
  if (override) return override;
64358
- 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`);
64359
64273
  }
64360
64274
  start(args) {
64361
64275
  this.stop(args.sessionId);
@@ -64381,10 +64295,10 @@ var SessionObserver = class {
64381
64295
  lastDeriveMs: 0
64382
64296
  };
64383
64297
  try {
64384
- 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 });
64385
64299
  } catch {
64386
64300
  }
64387
- 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) => {
64388
64302
  if (!changedName || !w3.filePath.endsWith(changedName)) return;
64389
64303
  this.poll(w3);
64390
64304
  });
@@ -64481,7 +64395,7 @@ var SessionObserver = class {
64481
64395
  const now = Date.now();
64482
64396
  if (now - w3.lastRelocateScanMs < 1e3) return;
64483
64397
  w3.lastRelocateScanMs = now;
64484
- const projectsRoot = import_node_path46.default.join(this.home, ".claude", "projects");
64398
+ const projectsRoot = import_node_path45.default.join(this.home, ".claude", "projects");
64485
64399
  const found = findTranscriptByToolSessionId(projectsRoot, w3.toolSessionId);
64486
64400
  if (!found || found === w3.filePath) return;
64487
64401
  try {
@@ -64490,7 +64404,7 @@ var SessionObserver = class {
64490
64404
  }
64491
64405
  w3.filePath = found;
64492
64406
  try {
64493
- 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) => {
64494
64408
  if (!changedName || !w3.filePath.endsWith(changedName)) return;
64495
64409
  this.poll(w3);
64496
64410
  });
@@ -64614,7 +64528,7 @@ var import_node_child_process12 = require("child_process");
64614
64528
  init_protocol();
64615
64529
  var import_node_fs42 = __toESM(require("fs"), 1);
64616
64530
  var import_node_os15 = __toESM(require("os"), 1);
64617
- var import_node_path47 = __toESM(require("path"), 1);
64531
+ var import_node_path46 = __toESM(require("path"), 1);
64618
64532
  var TITLE_GEN_DIR_PREFIX = "clawd-title-";
64619
64533
  var TITLE_MODEL_BY_TOOL = {
64620
64534
  claude: "haiku",
@@ -64685,7 +64599,7 @@ async function generateSessionTitle(tool, firstMessage, deps = {}) {
64685
64599
  if (!text) return null;
64686
64600
  let workDir;
64687
64601
  try {
64688
- 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));
64689
64603
  } catch {
64690
64604
  return null;
64691
64605
  }
@@ -64695,8 +64609,8 @@ async function generateSessionTitle(tool, firstMessage, deps = {}) {
64695
64609
  } catch {
64696
64610
  }
64697
64611
  };
64698
- const outFile = import_node_path47.default.join(workDir, `codex-title-${process.pid}-${++outFileSeq}-${Date.now()}.txt`);
64699
- 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");
64700
64614
  if (isCodexFamily(tool)) {
64701
64615
  try {
64702
64616
  import_node_fs42.default.writeFileSync(schemaFile, CODEX_TITLE_SCHEMA);
@@ -65395,7 +65309,7 @@ async function authenticate(token, deps) {
65395
65309
 
65396
65310
  // src/legacy-cleanup.ts
65397
65311
  var fs53 = __toESM(require("fs/promises"), 1);
65398
- var path55 = __toESM(require("path"), 1);
65312
+ var path54 = __toESM(require("path"), 1);
65399
65313
  var LEGACY_FILES = [
65400
65314
  "personal-capability.json",
65401
65315
  "received-capabilities.json",
@@ -65404,7 +65318,7 @@ var LEGACY_FILES = [
65404
65318
  async function cleanupLegacyCapabilityFiles(dataDir, logger) {
65405
65319
  const removed = [];
65406
65320
  for (const name of LEGACY_FILES) {
65407
- const p3 = path55.join(dataDir, name);
65321
+ const p3 = path54.join(dataDir, name);
65408
65322
  try {
65409
65323
  await fs53.unlink(p3);
65410
65324
  removed.push(name);
@@ -65419,7 +65333,7 @@ async function cleanupLegacyCapabilityFiles(dataDir, logger) {
65419
65333
 
65420
65334
  // src/inbox/inbox-store.ts
65421
65335
  var fs54 = __toESM(require("fs"), 1);
65422
- var path56 = __toESM(require("path"), 1);
65336
+ var path55 = __toESM(require("path"), 1);
65423
65337
  var INBOX_SUBDIR = "inbox";
65424
65338
  var InboxStore = class {
65425
65339
  constructor(dataDir) {
@@ -65517,10 +65431,10 @@ var InboxStore = class {
65517
65431
  }
65518
65432
  }
65519
65433
  dirPath() {
65520
- return path56.join(this.dataDir, INBOX_SUBDIR);
65434
+ return path55.join(this.dataDir, INBOX_SUBDIR);
65521
65435
  }
65522
65436
  filePath(peerDeviceId) {
65523
- return path56.join(this.dirPath(), `${peerDeviceId}.jsonl`);
65437
+ return path55.join(this.dirPath(), `${peerDeviceId}.jsonl`);
65524
65438
  }
65525
65439
  };
65526
65440
  function parseAllLines(raw) {
@@ -65609,7 +65523,7 @@ var InboxManager = class {
65609
65523
 
65610
65524
  // src/state/contact-store.ts
65611
65525
  var fs55 = __toESM(require("fs"), 1);
65612
- var path57 = __toESM(require("path"), 1);
65526
+ var path56 = __toESM(require("path"), 1);
65613
65527
  var FILE_NAME = "contacts.json";
65614
65528
  var ContactStore = class {
65615
65529
  constructor(dataDir) {
@@ -65619,7 +65533,7 @@ var ContactStore = class {
65619
65533
  contacts = /* @__PURE__ */ new Map();
65620
65534
  load() {
65621
65535
  this.contacts.clear();
65622
- const file = path57.join(this.dataDir, FILE_NAME);
65536
+ const file = path56.join(this.dataDir, FILE_NAME);
65623
65537
  let raw;
65624
65538
  try {
65625
65539
  raw = fs55.readFileSync(file, "utf8");
@@ -65703,7 +65617,7 @@ var ContactStore = class {
65703
65617
  return true;
65704
65618
  }
65705
65619
  flush() {
65706
- const file = path57.join(this.dataDir, FILE_NAME);
65620
+ const file = path56.join(this.dataDir, FILE_NAME);
65707
65621
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
65708
65622
  const content = JSON.stringify(
65709
65623
  { contacts: Array.from(this.contacts.values()) },
@@ -65825,52 +65739,52 @@ async function connectRemote(args) {
65825
65739
 
65826
65740
  // src/migrations/2026-05-20-flatten-sessions.ts
65827
65741
  var fs56 = __toESM(require("fs"), 1);
65828
- var path58 = __toESM(require("path"), 1);
65742
+ var path57 = __toESM(require("path"), 1);
65829
65743
  var MIGRATION_FLAG_NAME = ".migration.v1.done";
65830
65744
  function migrateFlattenSessions(opts) {
65831
65745
  const dataDir = opts.dataDir;
65832
65746
  const now = opts.now ?? Date.now;
65833
- const sessionsDir = path58.join(dataDir, "sessions");
65834
- const flagPath = path58.join(sessionsDir, MIGRATION_FLAG_NAME);
65747
+ const sessionsDir = path57.join(dataDir, "sessions");
65748
+ const flagPath = path57.join(sessionsDir, MIGRATION_FLAG_NAME);
65835
65749
  if (existsSync3(flagPath)) {
65836
65750
  return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
65837
65751
  }
65838
65752
  let movedBare = 0;
65839
65753
  let movedVmOwner = 0;
65840
65754
  let archivedListener = 0;
65841
- const defaultDir = path58.join(sessionsDir, "default");
65755
+ const defaultDir = path57.join(sessionsDir, "default");
65842
65756
  if (existsSync3(defaultDir)) {
65843
65757
  for (const entry of readdirSafe(defaultDir)) {
65844
65758
  if (!entry.endsWith(".json")) continue;
65845
- const src = path58.join(defaultDir, entry);
65846
- const dst = path58.join(sessionsDir, entry);
65759
+ const src = path57.join(defaultDir, entry);
65760
+ const dst = path57.join(sessionsDir, entry);
65847
65761
  fs56.renameSync(src, dst);
65848
65762
  movedBare += 1;
65849
65763
  }
65850
65764
  rmdirIfEmpty(defaultDir);
65851
65765
  }
65852
65766
  for (const pid of readdirSafe(sessionsDir)) {
65853
- const personaDir = path58.join(sessionsDir, pid);
65767
+ const personaDir = path57.join(sessionsDir, pid);
65854
65768
  if (!isDir(personaDir)) continue;
65855
65769
  if (pid === "default") continue;
65856
- const ownerSrc = path58.join(personaDir, "owner");
65770
+ const ownerSrc = path57.join(personaDir, "owner");
65857
65771
  if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
65858
- const ownerDst = path58.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
65772
+ const ownerDst = path57.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
65859
65773
  fs56.mkdirSync(ownerDst, { recursive: true });
65860
65774
  for (const file of readdirSafe(ownerSrc)) {
65861
65775
  if (!file.endsWith(".json")) continue;
65862
- fs56.renameSync(path58.join(ownerSrc, file), path58.join(ownerDst, file));
65776
+ fs56.renameSync(path57.join(ownerSrc, file), path57.join(ownerDst, file));
65863
65777
  movedVmOwner += 1;
65864
65778
  }
65865
65779
  rmdirIfEmpty(ownerSrc);
65866
65780
  }
65867
- const listenerSrc = path58.join(personaDir, "listener");
65781
+ const listenerSrc = path57.join(personaDir, "listener");
65868
65782
  if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
65869
- const archiveDst = path58.join(dataDir, ".legacy", `listener-${pid}`);
65783
+ const archiveDst = path57.join(dataDir, ".legacy", `listener-${pid}`);
65870
65784
  fs56.mkdirSync(archiveDst, { recursive: true });
65871
65785
  for (const file of readdirSafe(listenerSrc)) {
65872
65786
  if (!file.endsWith(".json")) continue;
65873
- fs56.renameSync(path58.join(listenerSrc, file), path58.join(archiveDst, file));
65787
+ fs56.renameSync(path57.join(listenerSrc, file), path57.join(archiveDst, file));
65874
65788
  archivedListener += 1;
65875
65789
  }
65876
65790
  rmdirIfEmpty(listenerSrc);
@@ -65918,13 +65832,13 @@ function rmdirIfEmpty(p3) {
65918
65832
 
65919
65833
  // src/migrations/2026-08-18-drop-seeded-projects.ts
65920
65834
  var fs57 = __toESM(require("fs"), 1);
65921
- var path59 = __toESM(require("path"), 1);
65835
+ var path58 = __toESM(require("path"), 1);
65922
65836
  var DROP_SEEDED_PROJECTS_FLAG = ".projects-seed-dropped.v1.done";
65923
65837
  function dropSeededProjects(opts) {
65924
65838
  fs57.mkdirSync(opts.dataDir, { recursive: true });
65925
- const flag = path59.join(opts.dataDir, DROP_SEEDED_PROJECTS_FLAG);
65839
+ const flag = path58.join(opts.dataDir, DROP_SEEDED_PROJECTS_FLAG);
65926
65840
  if (fs57.existsSync(flag)) return { skipped: true, dropped: 0, backup: null };
65927
- const file = path59.join(opts.dataDir, "projects.json");
65841
+ const file = path58.join(opts.dataDir, "projects.json");
65928
65842
  let raw = null;
65929
65843
  let dropped = 0;
65930
65844
  try {
@@ -65934,9 +65848,9 @@ function dropSeededProjects(opts) {
65934
65848
  }
65935
65849
  let backup = null;
65936
65850
  if (raw != null && dropped > 0) {
65937
- const dir = path59.join(opts.dataDir, "backups");
65851
+ const dir = path58.join(opts.dataDir, "backups");
65938
65852
  fs57.mkdirSync(dir, { recursive: true });
65939
- 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`);
65940
65854
  fs57.writeFileSync(backup, raw);
65941
65855
  }
65942
65856
  if (raw != null || dropped > 0) {
@@ -65948,11 +65862,11 @@ function dropSeededProjects(opts) {
65948
65862
 
65949
65863
  // src/transport/http-router.ts
65950
65864
  var import_node_fs44 = __toESM(require("fs"), 1);
65951
- var import_node_path50 = __toESM(require("path"), 1);
65865
+ var import_node_path49 = __toESM(require("path"), 1);
65952
65866
 
65953
65867
  // src/attachment/upload.ts
65954
65868
  var import_node_fs43 = __toESM(require("fs"), 1);
65955
- var import_node_path48 = __toESM(require("path"), 1);
65869
+ var import_node_path47 = __toESM(require("path"), 1);
65956
65870
  var import_node_crypto11 = __toESM(require("crypto"), 1);
65957
65871
  var import_promises7 = require("stream/promises");
65958
65872
  var UploadError = class extends Error {
@@ -65964,14 +65878,14 @@ var UploadError = class extends Error {
65964
65878
  code;
65965
65879
  };
65966
65880
  function assertValidFileName(fileName) {
65967
- 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)) {
65968
65882
  throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
65969
65883
  }
65970
65884
  }
65971
65885
  var HASH_PREFIX_LEN = 16;
65972
65886
  async function writeUploadedAttachment(args) {
65973
65887
  assertValidFileName(args.fileName);
65974
- const attachmentsRoot = import_node_path48.default.join(args.baseDir, ".attachments");
65888
+ const attachmentsRoot = import_node_path47.default.join(args.baseDir, ".attachments");
65975
65889
  try {
65976
65890
  import_node_fs43.default.mkdirSync(attachmentsRoot, { recursive: true });
65977
65891
  } catch (err) {
@@ -65979,7 +65893,7 @@ async function writeUploadedAttachment(args) {
65979
65893
  }
65980
65894
  const hasher = import_node_crypto11.default.createHash("sha256");
65981
65895
  let actualSize = 0;
65982
- const tmpPath = import_node_path48.default.join(
65896
+ const tmpPath = import_node_path47.default.join(
65983
65897
  attachmentsRoot,
65984
65898
  `.upload-${process.pid}-${Date.now()}-${import_node_crypto11.default.randomBytes(4).toString("hex")}`
65985
65899
  );
@@ -66014,7 +65928,7 @@ async function writeUploadedAttachment(args) {
66014
65928
  );
66015
65929
  }
66016
65930
  const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
66017
- const hashDir = import_node_path48.default.join(attachmentsRoot, attachmentId);
65931
+ const hashDir = import_node_path47.default.join(attachmentsRoot, attachmentId);
66018
65932
  let finalFileName;
66019
65933
  let hashDirExists = false;
66020
65934
  try {
@@ -66032,7 +65946,7 @@ async function writeUploadedAttachment(args) {
66032
65946
  try {
66033
65947
  import_node_fs43.default.mkdirSync(hashDir, { recursive: true });
66034
65948
  finalFileName = args.fileName;
66035
- 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));
66036
65950
  } catch (err) {
66037
65951
  try {
66038
65952
  import_node_fs43.default.unlinkSync(tmpPath);
@@ -66041,7 +65955,7 @@ async function writeUploadedAttachment(args) {
66041
65955
  throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
66042
65956
  }
66043
65957
  }
66044
- const absPath = import_node_path48.default.join(hashDir, finalFileName);
65958
+ const absPath = import_node_path47.default.join(hashDir, finalFileName);
66045
65959
  const relPath = absPath;
66046
65960
  args.groupFileStore.upsert(args.scope, args.sessionId, {
66047
65961
  relPath: absPath,
@@ -66056,7 +65970,7 @@ async function writeUploadedAttachment(args) {
66056
65970
 
66057
65971
  // src/extension/import.ts
66058
65972
  var import_promises8 = __toESM(require("fs/promises"), 1);
66059
- var import_node_path49 = __toESM(require("path"), 1);
65973
+ var import_node_path48 = __toESM(require("path"), 1);
66060
65974
  var import_node_os16 = __toESM(require("os"), 1);
66061
65975
  var import_jszip = __toESM(require_lib3(), 1);
66062
65976
  var ImportError = class extends Error {
@@ -66074,7 +65988,7 @@ async function importZip(buf, root) {
66074
65988
  throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
66075
65989
  }
66076
65990
  for (const name of Object.keys(zip.files)) {
66077
- if (name.includes("..") || name.startsWith("/") || import_node_path49.default.isAbsolute(name)) {
65991
+ if (name.includes("..") || name.startsWith("/") || import_node_path48.default.isAbsolute(name)) {
66078
65992
  throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
66079
65993
  }
66080
65994
  }
@@ -66107,7 +66021,7 @@ async function importZip(buf, root) {
66107
66021
  );
66108
66022
  }
66109
66023
  }
66110
- const destDir = import_node_path49.default.join(root, manifest.id);
66024
+ const destDir = import_node_path48.default.join(root, manifest.id);
66111
66025
  let destExists = false;
66112
66026
  try {
66113
66027
  await import_promises8.default.access(destDir);
@@ -66117,15 +66031,15 @@ async function importZip(buf, root) {
66117
66031
  if (destExists) {
66118
66032
  throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
66119
66033
  }
66120
- 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}-`));
66121
66035
  try {
66122
66036
  for (const [name, entry] of Object.entries(zip.files)) {
66123
- const dest = import_node_path49.default.join(stage, name);
66037
+ const dest = import_node_path48.default.join(stage, name);
66124
66038
  if (entry.dir) {
66125
66039
  await import_promises8.default.mkdir(dest, { recursive: true });
66126
66040
  continue;
66127
66041
  }
66128
- 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 });
66129
66043
  const content = await entry.async("nodebuffer");
66130
66044
  await import_promises8.default.writeFile(dest, content);
66131
66045
  }
@@ -66179,7 +66093,7 @@ var SHARE_UI_ASSET_MIME = {
66179
66093
  ".wasm": "application/wasm"
66180
66094
  };
66181
66095
  function shareUiAssetMime(filePath) {
66182
- const ext = import_node_path50.default.extname(filePath).toLowerCase();
66096
+ const ext = import_node_path49.default.extname(filePath).toLowerCase();
66183
66097
  return SHARE_UI_ASSET_MIME[ext] ?? lookupMime(filePath);
66184
66098
  }
66185
66099
  var AUTHED_RPC_ROUTE_PREFIX = "/rpc/";
@@ -66278,7 +66192,7 @@ function isValidUploadFileName(fileName) {
66278
66192
  if (fileName === "." || fileName === "..") return false;
66279
66193
  if (fileName.startsWith(".")) return false;
66280
66194
  if (fileName.includes("/") || fileName.includes("\\")) return false;
66281
- return fileName === import_node_path50.default.basename(fileName);
66195
+ return fileName === import_node_path49.default.basename(fileName);
66282
66196
  }
66283
66197
  function createHttpRouter(deps) {
66284
66198
  return async (req, res) => {
@@ -66501,7 +66415,7 @@ function createHttpRouter(deps) {
66501
66415
  sendHtml(res, statusByCode[r2.code], loader.renderErrorHtml(r2.code, msgByCode[r2.code]));
66502
66416
  return true;
66503
66417
  }
66504
- 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)));
66505
66419
  return true;
66506
66420
  }
66507
66421
  const ctx = deps.authResolver.resolveFromHeader(
@@ -66622,7 +66536,7 @@ function createHttpRouter(deps) {
66622
66536
  return true;
66623
66537
  }
66624
66538
  let absPath;
66625
- if (import_node_path50.default.isAbsolute(pathParam)) {
66539
+ if (import_node_path49.default.isAbsolute(pathParam)) {
66626
66540
  absPath = pathParam;
66627
66541
  } else if (deps.sessionStore) {
66628
66542
  const file = deps.sessionStore.read(sid);
@@ -66630,7 +66544,7 @@ function createHttpRouter(deps) {
66630
66544
  sendJson(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
66631
66545
  return true;
66632
66546
  }
66633
- absPath = import_node_path50.default.join(file.cwd, pathParam);
66547
+ absPath = import_node_path49.default.join(file.cwd, pathParam);
66634
66548
  } else {
66635
66549
  sendJson(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
66636
66550
  return true;
@@ -66729,7 +66643,7 @@ function streamFile(res, absPath, logger) {
66729
66643
  return;
66730
66644
  }
66731
66645
  const mime = lookupMime(absPath);
66732
- const basename2 = import_node_path50.default.basename(absPath);
66646
+ const basename2 = import_node_path49.default.basename(absPath);
66733
66647
  res.writeHead(200, {
66734
66648
  "Content-Type": mime,
66735
66649
  "Content-Length": String(stat.size),
@@ -66747,7 +66661,7 @@ function streamFile(res, absPath, logger) {
66747
66661
 
66748
66662
  // src/attachment/gc.ts
66749
66663
  var import_node_fs45 = __toESM(require("fs"), 1);
66750
- var import_node_path51 = __toESM(require("path"), 1);
66664
+ var import_node_path50 = __toESM(require("path"), 1);
66751
66665
  var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
66752
66666
  function runAttachmentGc(args) {
66753
66667
  const now = (args.now ?? Date.now)();
@@ -66756,12 +66670,12 @@ function runAttachmentGc(args) {
66756
66670
  for (const { scope, sessionId } of args.sessionScopes) {
66757
66671
  for (const entry of args.groupFileStore.list(scope, sessionId)) {
66758
66672
  if (entry.stale) continue;
66759
- 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);
66760
66674
  }
66761
66675
  }
66762
66676
  const visited = /* @__PURE__ */ new Set();
66763
66677
  for (const { scope, sessionId } of args.sessionScopes) {
66764
- const legacyDir = args.getSessionCwd?.(sessionId) ?? import_node_path51.default.join(
66678
+ const legacyDir = args.getSessionCwd?.(sessionId) ?? import_node_path50.default.join(
66765
66679
  args.dataDir,
66766
66680
  "sessions",
66767
66681
  ...scopeSubPath(scope).map(safeFileName),
@@ -66774,7 +66688,7 @@ function runAttachmentGc(args) {
66774
66688
  return true;
66775
66689
  });
66776
66690
  for (const rootDir of roots) {
66777
- const attRoot = import_node_path51.default.join(rootDir, ".attachments");
66691
+ const attRoot = import_node_path50.default.join(rootDir, ".attachments");
66778
66692
  let hashDirs;
66779
66693
  try {
66780
66694
  hashDirs = import_node_fs45.default.readdirSync(attRoot);
@@ -66784,7 +66698,7 @@ function runAttachmentGc(args) {
66784
66698
  continue;
66785
66699
  }
66786
66700
  for (const hashDir of hashDirs) {
66787
- const hashDirAbs = import_node_path51.default.join(attRoot, hashDir);
66701
+ const hashDirAbs = import_node_path50.default.join(attRoot, hashDir);
66788
66702
  let files;
66789
66703
  try {
66790
66704
  files = import_node_fs45.default.readdirSync(hashDirAbs);
@@ -66792,7 +66706,7 @@ function runAttachmentGc(args) {
66792
66706
  continue;
66793
66707
  }
66794
66708
  for (const name of files) {
66795
- const file = import_node_path51.default.join(hashDirAbs, name);
66709
+ const file = import_node_path50.default.join(hashDirAbs, name);
66796
66710
  let stat;
66797
66711
  try {
66798
66712
  stat = import_node_fs45.default.statSync(file);
@@ -66824,7 +66738,7 @@ function runAttachmentGc(args) {
66824
66738
 
66825
66739
  // src/attachment/group.ts
66826
66740
  var import_node_fs46 = __toESM(require("fs"), 1);
66827
- var import_node_path52 = __toESM(require("path"), 1);
66741
+ var import_node_path51 = __toESM(require("path"), 1);
66828
66742
  var import_node_crypto12 = __toESM(require("crypto"), 1);
66829
66743
  init_protocol();
66830
66744
  var GroupFileStore = class {
@@ -66836,11 +66750,11 @@ var GroupFileStore = class {
66836
66750
  this.logger = opts.logger;
66837
66751
  }
66838
66752
  rootForScope(scope) {
66839
- 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));
66840
66754
  }
66841
66755
  /** 与 SessionStore.filePath 平级,扩展名 .group-files.json */
66842
66756
  filePath(scope, sessionId) {
66843
- 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`);
66844
66758
  }
66845
66759
  cacheKey(scope, sessionId) {
66846
66760
  return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
@@ -66875,7 +66789,7 @@ var GroupFileStore = class {
66875
66789
  }
66876
66790
  writeFile(scope, sessionId, entries) {
66877
66791
  const file = this.filePath(scope, sessionId);
66878
- 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 });
66879
66793
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
66880
66794
  import_node_fs46.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
66881
66795
  import_node_fs46.default.renameSync(tmp, file);
@@ -66983,7 +66897,7 @@ var GroupFileStore = class {
66983
66897
  * 不在 persona 目录里(见文件头的路径约定)。没树的 persona 是 noop。
66984
66898
  */
66985
66899
  deletePersona(personaId2) {
66986
- 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 });
66987
66901
  const prefix = `persona:${personaId2}:`;
66988
66902
  for (const key of this.cache.keys()) {
66989
66903
  if (key.startsWith(prefix)) this.cache.delete(key);
@@ -66993,9 +66907,9 @@ var GroupFileStore = class {
66993
66907
 
66994
66908
  // src/discovery/state-file.ts
66995
66909
  var import_node_fs47 = __toESM(require("fs"), 1);
66996
- var import_node_path53 = __toESM(require("path"), 1);
66910
+ var import_node_path52 = __toESM(require("path"), 1);
66997
66911
  function defaultStateFilePath(dataDir) {
66998
- return import_node_path53.default.join(dataDir, "state.json");
66912
+ return import_node_path52.default.join(dataDir, "state.json");
66999
66913
  }
67000
66914
  function isPidAlive(pid) {
67001
66915
  if (!Number.isFinite(pid) || pid <= 0) return false;
@@ -67031,7 +66945,7 @@ var StateFileManager = class {
67031
66945
  return { status: "stale", existing };
67032
66946
  }
67033
66947
  write(state) {
67034
- 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 });
67035
66949
  const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
67036
66950
  import_node_fs47.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
67037
66951
  import_node_fs47.default.renameSync(tmp, this.file);
@@ -67059,13 +66973,13 @@ function readSpawnedByDesktopFromEnv(env = process.env) {
67059
66973
 
67060
66974
  // src/tunnel/tunnel-manager.ts
67061
66975
  var import_node_fs51 = __toESM(require("fs"), 1);
67062
- var import_node_path57 = __toESM(require("path"), 1);
66976
+ var import_node_path56 = __toESM(require("path"), 1);
67063
66977
  var import_node_crypto13 = __toESM(require("crypto"), 1);
67064
66978
  var import_node_child_process15 = require("child_process");
67065
66979
 
67066
66980
  // src/tunnel/tunnel-store.ts
67067
66981
  var import_node_fs48 = __toESM(require("fs"), 1);
67068
- var import_node_path54 = __toESM(require("path"), 1);
66982
+ var import_node_path53 = __toESM(require("path"), 1);
67069
66983
  var TunnelStore = class {
67070
66984
  constructor(filePath) {
67071
66985
  this.filePath = filePath;
@@ -67084,7 +66998,7 @@ var TunnelStore = class {
67084
66998
  }
67085
66999
  }
67086
67000
  async set(v3) {
67087
- const dir = import_node_path54.default.dirname(this.filePath);
67001
+ const dir = import_node_path53.default.dirname(this.filePath);
67088
67002
  await import_node_fs48.default.promises.mkdir(dir, { recursive: true });
67089
67003
  const data = JSON.stringify(v3, null, 2);
67090
67004
  const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
@@ -67196,7 +67110,7 @@ function escape2(v3) {
67196
67110
  // src/tunnel/frpc-binary.ts
67197
67111
  var import_node_fs49 = __toESM(require("fs"), 1);
67198
67112
  var import_node_os17 = __toESM(require("os"), 1);
67199
- var import_node_path55 = __toESM(require("path"), 1);
67113
+ var import_node_path54 = __toESM(require("path"), 1);
67200
67114
  var import_node_child_process13 = require("child_process");
67201
67115
  var import_node_stream3 = require("stream");
67202
67116
  var import_promises9 = require("stream/promises");
@@ -67235,13 +67149,13 @@ async function ensureFrpcBinary(opts) {
67235
67149
  }
67236
67150
  const version2 = opts.version ?? FRPC_VERSION;
67237
67151
  const platform = opts.platform ?? detectPlatform();
67238
- const binDir = import_node_path55.default.join(opts.dataDir, "bin");
67152
+ const binDir = import_node_path54.default.join(opts.dataDir, "bin");
67239
67153
  import_node_fs49.default.mkdirSync(binDir, { recursive: true });
67240
67154
  cleanupStaleArtifacts(binDir);
67241
- const stableBin = import_node_path55.default.join(binDir, "frpc");
67155
+ const stableBin = import_node_path54.default.join(binDir, "frpc");
67242
67156
  if (import_node_fs49.default.existsSync(stableBin)) return stableBin;
67243
67157
  const partialBin = `${stableBin}.partial`;
67244
- 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`);
67245
67159
  try {
67246
67160
  const url = frpcDownloadUrl(version2, platform);
67247
67161
  await downloadToFile(url, tarballPath, opts.fetchImpl);
@@ -67267,7 +67181,7 @@ function cleanupStaleArtifacts(binDir) {
67267
67181
  }
67268
67182
  for (const name of entries) {
67269
67183
  if (name.endsWith(".partial") || name.startsWith("extract-")) {
67270
- const full = import_node_path55.default.join(binDir, name);
67184
+ const full = import_node_path54.default.join(binDir, name);
67271
67185
  try {
67272
67186
  import_node_fs49.default.rmSync(full, { recursive: true, force: true });
67273
67187
  } catch {
@@ -67293,7 +67207,7 @@ async function downloadToFile(url, dest, fetchImpl) {
67293
67207
  await (0, import_promises9.pipeline)(nodeStream, out);
67294
67208
  }
67295
67209
  async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
67296
- 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()}`);
67297
67211
  import_node_fs49.default.mkdirSync(work, { recursive: true });
67298
67212
  try {
67299
67213
  await new Promise((resolve9, reject) => {
@@ -67302,7 +67216,7 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
67302
67216
  proc.on("exit", (code) => code === 0 ? resolve9() : reject(new Error(`tar exited ${code}`)));
67303
67217
  });
67304
67218
  const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
67305
- const src = import_node_path55.default.join(work, dirName, "frpc");
67219
+ const src = import_node_path54.default.join(work, dirName, "frpc");
67306
67220
  if (!import_node_fs49.default.existsSync(src)) {
67307
67221
  throw new Error(`frpc not found inside tarball at ${src}`);
67308
67222
  }
@@ -67314,10 +67228,10 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
67314
67228
 
67315
67229
  // src/tunnel/frpc-process.ts
67316
67230
  var import_node_fs50 = __toESM(require("fs"), 1);
67317
- var import_node_path56 = __toESM(require("path"), 1);
67231
+ var import_node_path55 = __toESM(require("path"), 1);
67318
67232
  var import_node_child_process14 = require("child_process");
67319
67233
  function frpcPidFilePath(dataDir) {
67320
- return import_node_path56.default.join(dataDir, "frpc.pid");
67234
+ return import_node_path55.default.join(dataDir, "frpc.pid");
67321
67235
  }
67322
67236
  function writeFrpcPid(dataDir, pid) {
67323
67237
  try {
@@ -67359,7 +67273,7 @@ function defaultSleep2(ms) {
67359
67273
  }
67360
67274
  async function killStaleFrpc(deps) {
67361
67275
  const pidFile = frpcPidFilePath(deps.dataDir);
67362
- const tomlPath = import_node_path56.default.join(deps.dataDir, "frpc.toml");
67276
+ const tomlPath = import_node_path55.default.join(deps.dataDir, "frpc.toml");
67363
67277
  const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
67364
67278
  const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
67365
67279
  const killPid = deps.killPidImpl ?? defaultKillPid;
@@ -67431,7 +67345,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
67431
67345
  var TunnelManager = class {
67432
67346
  constructor(deps) {
67433
67347
  this.deps = deps;
67434
- 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"));
67435
67349
  this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
67436
67350
  this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
67437
67351
  }
@@ -67558,7 +67472,7 @@ var TunnelManager = class {
67558
67472
  dataDir: this.deps.dataDir,
67559
67473
  override: this.deps.frpcBinaryOverride ?? void 0
67560
67474
  });
67561
- 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");
67562
67476
  const proxyName = `clawd-${t2.subdomain}-${localPort}-${import_node_crypto13.default.randomBytes(3).toString("hex")}`;
67563
67477
  const toml = buildFrpcToml({
67564
67478
  serverAddr: t2.frpsHost,
@@ -67573,9 +67487,9 @@ var TunnelManager = class {
67573
67487
  const proc = (this.deps.spawnImpl ?? import_node_child_process15.spawn)(frpcBin, ["-c", tomlPath], {
67574
67488
  stdio: ["ignore", "pipe", "pipe"]
67575
67489
  });
67576
- const logDir = import_node_path57.default.join(this.deps.dataDir, "log");
67490
+ const logDir = import_node_path56.default.join(this.deps.dataDir, "log");
67577
67491
  import_node_fs51.default.mkdirSync(logDir, { recursive: true });
67578
- const logFilePath = import_node_path57.default.join(logDir, "frpc.log");
67492
+ const logFilePath = import_node_path56.default.join(logDir, "frpc.log");
67579
67493
  const logStream = import_node_fs51.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
67580
67494
  logStream.on("error", () => {
67581
67495
  });
@@ -67659,15 +67573,15 @@ async function waitForFrpcReady(proc, timeoutMs) {
67659
67573
 
67660
67574
  // src/tunnel/device-key.ts
67661
67575
  var import_node_os18 = __toESM(require("os"), 1);
67662
- var import_node_path58 = __toESM(require("path"), 1);
67576
+ var import_node_path57 = __toESM(require("path"), 1);
67663
67577
  var import_node_crypto14 = __toESM(require("crypto"), 1);
67664
67578
  var DERIVE_SALT = "clawd-tunnel-device-v1";
67665
67579
  function deriveStableDeviceKey(opts = {}) {
67666
67580
  const hostname = opts.hostname ?? import_node_os18.default.hostname();
67667
67581
  const uid = opts.uid ?? (typeof import_node_os18.default.userInfo === "function" ? import_node_os18.default.userInfo().uid : 0);
67668
67582
  const home = opts.home ?? import_node_os18.default.homedir();
67669
- const defaultDataDir = import_node_path58.default.resolve(import_node_path58.default.join(home, ".clawd"));
67670
- 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;
67671
67585
  const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
67672
67586
  const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
67673
67587
  return import_node_crypto14.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
@@ -67675,11 +67589,11 @@ function deriveStableDeviceKey(opts = {}) {
67675
67589
 
67676
67590
  // src/auth-store.ts
67677
67591
  var import_node_fs52 = __toESM(require("fs"), 1);
67678
- var import_node_path59 = __toESM(require("path"), 1);
67592
+ var import_node_path58 = __toESM(require("path"), 1);
67679
67593
  var import_node_crypto15 = __toESM(require("crypto"), 1);
67680
67594
  var AUTH_FILE_NAME = "auth.json";
67681
67595
  function authFilePath(dataDir) {
67682
- return import_node_path59.default.join(dataDir, AUTH_FILE_NAME);
67596
+ return import_node_path58.default.join(dataDir, AUTH_FILE_NAME);
67683
67597
  }
67684
67598
  function loadOrCreateAuthFile(opts) {
67685
67599
  const file = authFilePath(opts.dataDir);
@@ -67741,7 +67655,7 @@ function readAuthFile(file) {
67741
67655
  }
67742
67656
  }
67743
67657
  function writeAuthFile(file, content) {
67744
- 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 });
67745
67659
  import_node_fs52.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
67746
67660
  try {
67747
67661
  import_node_fs52.default.chmodSync(file, 384);
@@ -67752,10 +67666,10 @@ function writeAuthFile(file, content) {
67752
67666
  // src/owner-profile.ts
67753
67667
  var import_node_fs53 = __toESM(require("fs"), 1);
67754
67668
  var import_node_os19 = __toESM(require("os"), 1);
67755
- var import_node_path60 = __toESM(require("path"), 1);
67669
+ var import_node_path59 = __toESM(require("path"), 1);
67756
67670
  var PROFILE_FILENAME = "profile.json";
67757
67671
  function profilePath(dataDir) {
67758
- return import_node_path60.default.join(dataDir, PROFILE_FILENAME);
67672
+ return import_node_path59.default.join(dataDir, PROFILE_FILENAME);
67759
67673
  }
67760
67674
  function loadOwnerProfile(dataDir) {
67761
67675
  let raw;
@@ -67793,12 +67707,12 @@ function loadOwnerDisplayName(dataDir) {
67793
67707
 
67794
67708
  // src/feishu-auth/owner-identity-store.ts
67795
67709
  var import_node_fs54 = __toESM(require("fs"), 1);
67796
- var import_node_path61 = __toESM(require("path"), 1);
67710
+ var import_node_path60 = __toESM(require("path"), 1);
67797
67711
  var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
67798
67712
  var OwnerIdentityStore = class {
67799
67713
  file;
67800
67714
  constructor(dataDir) {
67801
- 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);
67802
67716
  }
67803
67717
  read() {
67804
67718
  let raw;
@@ -67830,7 +67744,7 @@ var OwnerIdentityStore = class {
67830
67744
  };
67831
67745
  }
67832
67746
  write(record4) {
67833
- 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 });
67834
67748
  import_node_fs54.default.writeFileSync(this.file, JSON.stringify(record4, null, 2), { mode: 384 });
67835
67749
  try {
67836
67750
  import_node_fs54.default.chmodSync(this.file, 384);
@@ -68336,7 +68250,7 @@ function verifyConnectToken(args) {
68336
68250
 
68337
68251
  // src/feishu-auth/server-key.ts
68338
68252
  var fs71 = __toESM(require("fs"), 1);
68339
- var path74 = __toESM(require("path"), 1);
68253
+ var path73 = __toESM(require("path"), 1);
68340
68254
  var FILE_NAME2 = "server-signing-key.json";
68341
68255
  var ServerKeyStore = class {
68342
68256
  constructor(dataDir) {
@@ -68344,7 +68258,7 @@ var ServerKeyStore = class {
68344
68258
  }
68345
68259
  dataDir;
68346
68260
  filePath() {
68347
- return path74.join(this.dataDir, FILE_NAME2);
68261
+ return path73.join(this.dataDir, FILE_NAME2);
68348
68262
  }
68349
68263
  /** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
68350
68264
  read() {
@@ -68379,7 +68293,7 @@ var ServerKeyStore = class {
68379
68293
  init_protocol();
68380
68294
 
68381
68295
  // src/handlers/index.ts
68382
- var import_node_path75 = __toESM(require("path"), 1);
68296
+ var import_node_path74 = __toESM(require("path"), 1);
68383
68297
 
68384
68298
  // src/handlers/session.ts
68385
68299
  init_protocol();
@@ -68387,7 +68301,7 @@ init_protocol();
68387
68301
  // src/session/fork.ts
68388
68302
  var import_node_fs55 = __toESM(require("fs"), 1);
68389
68303
  var import_node_os20 = __toESM(require("os"), 1);
68390
- var import_node_path62 = __toESM(require("path"), 1);
68304
+ var import_node_path61 = __toESM(require("path"), 1);
68391
68305
  var import_node_crypto17 = require("crypto");
68392
68306
  init_claude_history();
68393
68307
  function readJsonlEntries(file) {
@@ -68404,19 +68318,19 @@ function readJsonlEntries(file) {
68404
68318
  return out;
68405
68319
  }
68406
68320
  function forkSession(input) {
68407
- const baseDir = input.baseDir ?? import_node_path62.default.join(import_node_os20.default.homedir(), ".claude");
68408
- let projectDir = import_node_path62.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
68409
- 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`);
68410
68324
  if (!import_node_fs55.default.existsSync(sourceFile)) {
68411
68325
  const found = findTranscriptByToolSessionId(
68412
- import_node_path62.default.join(baseDir, "projects"),
68326
+ import_node_path61.default.join(baseDir, "projects"),
68413
68327
  input.toolSessionId
68414
68328
  );
68415
68329
  if (!found) {
68416
68330
  throw new Error(`fork: source transcript not found: ${sourceFile}`);
68417
68331
  }
68418
68332
  sourceFile = found;
68419
- projectDir = import_node_path62.default.dirname(found);
68333
+ projectDir = import_node_path61.default.dirname(found);
68420
68334
  }
68421
68335
  const entries = readJsonlEntries(sourceFile);
68422
68336
  const mainEntries = entries.filter((e) => e.isSidechain !== true);
@@ -68445,8 +68359,8 @@ function forkSession(input) {
68445
68359
  }
68446
68360
  forkedLines.push(JSON.stringify(forked));
68447
68361
  }
68448
- const outDir = input.targetCwd ? import_node_path62.default.join(baseDir, "projects", cwdToHashDir(input.targetCwd)) : projectDir;
68449
- 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`);
68450
68364
  import_node_fs55.default.mkdirSync(outDir, { recursive: true });
68451
68365
  import_node_fs55.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
68452
68366
  return { forkedToolSessionId, forkedFilePath };
@@ -68456,16 +68370,16 @@ function forkSession(input) {
68456
68370
  var import_node_fs56 = __toESM(require("fs"), 1);
68457
68371
  var import_promises10 = __toESM(require("fs/promises"), 1);
68458
68372
  var import_node_os21 = __toESM(require("os"), 1);
68459
- var import_node_path63 = __toESM(require("path"), 1);
68373
+ var import_node_path62 = __toESM(require("path"), 1);
68460
68374
  var import_node_module = require("module");
68461
68375
  var import_node_child_process16 = require("child_process");
68462
68376
  var import_meta6 = {};
68463
68377
  function defaultRoots() {
68464
68378
  const home = import_node_os21.default.homedir();
68465
68379
  return {
68466
- claudeProjectsDir: import_node_path63.default.join(home, ".claude", "projects"),
68467
- codexDir: import_node_path63.default.join(home, ".codex"),
68468
- 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")
68469
68383
  };
68470
68384
  }
68471
68385
  function width(s2) {
@@ -68533,13 +68447,13 @@ async function scanClaude(roots) {
68533
68447
  if (!d2.isDirectory()) continue;
68534
68448
  let files;
68535
68449
  try {
68536
- 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));
68537
68451
  } catch {
68538
68452
  continue;
68539
68453
  }
68540
68454
  for (const name of files) {
68541
68455
  if (!name.endsWith(".jsonl")) continue;
68542
- 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);
68543
68457
  let st2;
68544
68458
  try {
68545
68459
  st2 = import_node_fs56.default.statSync(file);
@@ -68669,7 +68583,7 @@ async function codexFromRows(rows) {
68669
68583
  async function scanCodex(roots) {
68670
68584
  let dbs = [];
68671
68585
  try {
68672
- 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));
68673
68587
  } catch {
68674
68588
  }
68675
68589
  if (!dbs.length) return [];
@@ -68678,14 +68592,14 @@ async function scanCodex(roots) {
68678
68592
  }
68679
68593
  async function scanExternalSessions(rootsIn) {
68680
68594
  const roots = { ...defaultRoots(), ...rootsIn };
68681
- const personaRoot = import_node_path63.default.join(roots.clawdDir, "personas");
68595
+ const personaRoot = import_node_path62.default.join(roots.clawdDir, "personas");
68682
68596
  const all = [...await scanClaude(roots), ...await scanCodex(roots)];
68683
68597
  const out = [];
68684
68598
  for (const c2 of all) {
68685
68599
  if (c2.skip) continue;
68686
68600
  if (c2.turns < 1) continue;
68687
68601
  if (!c2.cwd || !isDir2(c2.cwd)) continue;
68688
- 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)) {
68689
68603
  continue;
68690
68604
  }
68691
68605
  out.push({
@@ -68703,12 +68617,12 @@ async function scanExternalSessions(rootsIn) {
68703
68617
 
68704
68618
  // src/session/import-ledger.ts
68705
68619
  var import_node_fs57 = __toESM(require("fs"), 1);
68706
- var import_node_path64 = __toESM(require("path"), 1);
68620
+ var import_node_path63 = __toESM(require("path"), 1);
68707
68621
  var LEDGER_FILENAME = "session-import-ledger.json";
68708
68622
  function readImportLedger(dataDir) {
68709
68623
  try {
68710
68624
  const parsed = JSON.parse(
68711
- 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")
68712
68626
  );
68713
68627
  return Array.isArray(parsed) ? parsed : [];
68714
68628
  } catch {
@@ -68716,7 +68630,7 @@ function readImportLedger(dataDir) {
68716
68630
  }
68717
68631
  }
68718
68632
  function appendImportLedger(dataDir, entry) {
68719
- const file = import_node_path64.default.join(dataDir, LEDGER_FILENAME);
68633
+ const file = import_node_path63.default.join(dataDir, LEDGER_FILENAME);
68720
68634
  const entries = readImportLedger(dataDir);
68721
68635
  entries.push(entry);
68722
68636
  import_node_fs57.default.writeFileSync(file, JSON.stringify(entries, null, 2), { encoding: "utf8", mode: 384 });
@@ -69252,7 +69166,7 @@ function buildPermissionHandlers(deps) {
69252
69166
  }
69253
69167
 
69254
69168
  // src/handlers/history.ts
69255
- var path79 = __toESM(require("path"), 1);
69169
+ var path78 = __toESM(require("path"), 1);
69256
69170
  init_protocol();
69257
69171
 
69258
69172
  // src/session/recent-dirs.ts
@@ -69270,7 +69184,7 @@ function listRecentDirs(store, limit = 50) {
69270
69184
  }
69271
69185
 
69272
69186
  // src/permission/persona-paths.ts
69273
- var path78 = __toESM(require("path"), 1);
69187
+ var path77 = __toESM(require("path"), 1);
69274
69188
  function getAllowedPersonaIds(grants, action) {
69275
69189
  const ids = /* @__PURE__ */ new Set();
69276
69190
  for (const g3 of grants) {
@@ -69283,42 +69197,42 @@ function getAllowedPersonaIds(grants, action) {
69283
69197
  return ids;
69284
69198
  }
69285
69199
  function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
69286
- const target = path78.resolve(absPath);
69200
+ const target = path77.resolve(absPath);
69287
69201
  if (userWorkDir) {
69288
- const u2 = path78.resolve(userWorkDir);
69289
- const usep = u2.endsWith(path78.sep) ? "" : path78.sep;
69202
+ const u2 = path77.resolve(userWorkDir);
69203
+ const usep = u2.endsWith(path77.sep) ? "" : path77.sep;
69290
69204
  if (target === u2 || target.startsWith(u2 + usep)) return true;
69291
69205
  }
69292
- const root = path78.resolve(personaRoot);
69293
- const sep4 = root.endsWith(path78.sep) ? "" : path78.sep;
69206
+ const root = path77.resolve(personaRoot);
69207
+ const sep4 = root.endsWith(path77.sep) ? "" : path77.sep;
69294
69208
  if (!target.startsWith(root + sep4)) return false;
69295
- const rel = path78.relative(root, target);
69209
+ const rel = path77.relative(root, target);
69296
69210
  if (!rel || rel.startsWith("..")) return false;
69297
- const personaId2 = rel.split(path78.sep)[0];
69211
+ const personaId2 = rel.split(path77.sep)[0];
69298
69212
  if (!personaId2) return false;
69299
69213
  const allowed = getAllowedPersonaIds(grants, action);
69300
69214
  if (allowed === "*") return true;
69301
69215
  return allowed.has(personaId2);
69302
69216
  }
69303
69217
  function personaIdFromPath(absPath, personaRoot) {
69304
- const root = path78.resolve(personaRoot);
69305
- const target = path78.resolve(absPath);
69306
- 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;
69307
69221
  if (!target.startsWith(root + sep4)) return null;
69308
- const rel = path78.relative(root, target);
69222
+ const rel = path77.relative(root, target);
69309
69223
  if (!rel || rel.startsWith("..")) return null;
69310
- const id = rel.split(path78.sep)[0];
69224
+ const id = rel.split(path77.sep)[0];
69311
69225
  return id || null;
69312
69226
  }
69313
69227
  function isPathWithin(dir, absPath) {
69314
- const d2 = path78.resolve(dir);
69315
- const t2 = path78.resolve(absPath);
69316
- 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;
69317
69231
  return t2 === d2 || t2.startsWith(d2 + sep4);
69318
69232
  }
69319
69233
  function isPathInGuestBoundary(personaRoot, personaId2, userWorkDir, absPath) {
69320
69234
  if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
69321
- return personaIdFromPath(path78.resolve(absPath), personaRoot) === personaId2;
69235
+ return personaIdFromPath(path77.resolve(absPath), personaRoot) === personaId2;
69322
69236
  }
69323
69237
 
69324
69238
  // src/handlers/history.ts
@@ -69371,7 +69285,7 @@ function buildHistoryHandlers(deps) {
69371
69285
  if (!pid) return false;
69372
69286
  return isGuestPathAllowed(
69373
69287
  ctx.grants,
69374
- path79.join(personaRoot, pid),
69288
+ path78.join(personaRoot, pid),
69375
69289
  personaRoot,
69376
69290
  "read",
69377
69291
  userWorkDir
@@ -69383,7 +69297,7 @@ function buildHistoryHandlers(deps) {
69383
69297
  };
69384
69298
  const list = async (frame, _client, ctx) => {
69385
69299
  const args = HistoryListArgs.parse(frame);
69386
- assertGuestPath(ctx, path79.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
69300
+ assertGuestPath(ctx, path78.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
69387
69301
  const sessions = await history.listSessions(args);
69388
69302
  return { response: { type: "history:list", sessions } };
69389
69303
  };
@@ -69431,14 +69345,14 @@ function buildHistoryHandlers(deps) {
69431
69345
  };
69432
69346
  const subagents = async (frame, _client, ctx) => {
69433
69347
  const args = HistorySubagentsArgs.parse(frame);
69434
- assertGuestPath(ctx, path79.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
69348
+ assertGuestPath(ctx, path78.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
69435
69349
  assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagents");
69436
69350
  const subs = await historyReaderForToolSession(args.toolSessionId).listSubagents(args);
69437
69351
  return { response: { type: "history:subagents", subagents: subs } };
69438
69352
  };
69439
69353
  const subagentRead = async (frame, _client, ctx) => {
69440
69354
  const args = HistorySubagentReadArgs.parse(frame);
69441
- assertGuestPath(ctx, path79.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
69355
+ assertGuestPath(ctx, path78.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
69442
69356
  assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagent-read");
69443
69357
  const res = await historyReaderForToolSession(args.toolSessionId).readSubagent(args);
69444
69358
  return { response: { type: "history:subagent-read", ...res } };
@@ -69448,7 +69362,7 @@ function buildHistoryHandlers(deps) {
69448
69362
  if (ctx?.principal.kind === "guest" && personaRoot) {
69449
69363
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
69450
69364
  const filtered = dirs.filter(
69451
- (d2) => isGuestPathAllowed(ctx.grants, path79.resolve(d2.cwd), personaRoot, "read", userWorkDir)
69365
+ (d2) => isGuestPathAllowed(ctx.grants, path78.resolve(d2.cwd), personaRoot, "read", userWorkDir)
69452
69366
  );
69453
69367
  return { response: { type: "history:recentDirs", dirs: filtered } };
69454
69368
  }
@@ -69467,15 +69381,15 @@ function buildHistoryHandlers(deps) {
69467
69381
  // src/handlers/projects.ts
69468
69382
  var fs75 = __toESM(require("fs"), 1);
69469
69383
  var os23 = __toESM(require("os"), 1);
69470
- var path80 = __toESM(require("path"), 1);
69384
+ var path79 = __toESM(require("path"), 1);
69471
69385
  var import_node_child_process17 = require("child_process");
69472
69386
  init_protocol();
69473
- var DEFAULT_PROJECTS_ROOT = path80.join(os23.homedir(), "Documents", "ChatGPT");
69387
+ var DEFAULT_PROJECTS_ROOT = path79.join(os23.homedir(), "Documents", "ChatGPT");
69474
69388
  function allocateDir(root, name) {
69475
- let candidate = path80.join(root, name);
69389
+ let candidate = path79.join(root, name);
69476
69390
  let n2 = 2;
69477
69391
  while (fs75.existsSync(candidate)) {
69478
- candidate = path80.join(root, `${name} ${n2}`);
69392
+ candidate = path79.join(root, `${name} ${n2}`);
69479
69393
  n2 += 1;
69480
69394
  }
69481
69395
  return candidate;
@@ -69560,7 +69474,7 @@ function buildProjectHandlers(deps) {
69560
69474
  }
69561
69475
 
69562
69476
  // src/handlers/workspace.ts
69563
- var path81 = __toESM(require("path"), 1);
69477
+ var path80 = __toESM(require("path"), 1);
69564
69478
  init_protocol();
69565
69479
  var os24 = __toESM(require("os"), 1);
69566
69480
  init_protocol();
@@ -69603,22 +69517,22 @@ function buildWorkspaceHandlers(deps) {
69603
69517
  const args = WorkspaceListArgs.parse(frame);
69604
69518
  const isGuest = ctx?.principal.kind === "guest";
69605
69519
  const fallbackCwd = isGuest && personaRoot ? personaRoot : os24.homedir();
69606
- const resolvedCwd = path81.resolve(args.cwd ?? fallbackCwd);
69607
- 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;
69608
69522
  assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
69609
69523
  const res = workspace.list({ ...args, cwd: resolvedCwd });
69610
69524
  return { response: { type: "workspace:list", ...res } };
69611
69525
  };
69612
69526
  const read = async (frame, _client, ctx) => {
69613
69527
  const args = WorkspaceReadArgs.parse(frame);
69614
- 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);
69615
69529
  assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
69616
69530
  const res = workspace.read(args);
69617
69531
  return { response: { type: "workspace:read", ...res } };
69618
69532
  };
69619
69533
  const skillsList = async (frame, _client, ctx) => {
69620
69534
  const args = SkillsListArgs.parse(frame);
69621
- const cwdAbs = path81.resolve(args.cwd);
69535
+ const cwdAbs = path80.resolve(args.cwd);
69622
69536
  assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
69623
69537
  const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
69624
69538
  if (ctx?.principal.kind === "guest" && personaRoot) {
@@ -69630,7 +69544,7 @@ function buildWorkspaceHandlers(deps) {
69630
69544
  };
69631
69545
  const agentsList = async (frame, _client, ctx) => {
69632
69546
  const args = AgentsListArgs.parse(frame);
69633
- const cwdAbs = path81.resolve(args.cwd);
69547
+ const cwdAbs = path80.resolve(args.cwd);
69634
69548
  assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
69635
69549
  if (isCodexFamily(args.tool) || args.tool === PI_TOOL_ID) {
69636
69550
  return { response: { type: "agents:list", agents: [] } };
@@ -69652,18 +69566,18 @@ function buildWorkspaceHandlers(deps) {
69652
69566
  }
69653
69567
 
69654
69568
  // src/handlers/git.ts
69655
- var path83 = __toESM(require("path"), 1);
69569
+ var path82 = __toESM(require("path"), 1);
69656
69570
  init_protocol();
69657
69571
  init_protocol();
69658
69572
 
69659
69573
  // src/workspace/git.ts
69660
69574
  var import_node_child_process18 = require("child_process");
69661
69575
  var import_node_fs58 = __toESM(require("fs"), 1);
69662
- var import_node_path65 = __toESM(require("path"), 1);
69576
+ var import_node_path64 = __toESM(require("path"), 1);
69663
69577
  var import_node_util2 = require("util");
69664
69578
  var pexec = (0, import_node_util2.promisify)(import_node_child_process18.execFile);
69665
69579
  function normalizePath(p3) {
69666
- const resolved = import_node_path65.default.resolve(p3);
69580
+ const resolved = import_node_path64.default.resolve(p3);
69667
69581
  try {
69668
69582
  return import_node_fs58.default.realpathSync(resolved);
69669
69583
  } catch {
@@ -69739,7 +69653,7 @@ async function listGitBranches(cwd) {
69739
69653
  function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
69740
69654
  if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
69741
69655
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
69742
- if (!isGuestPathAllowed(ctx.grants, path83.resolve(cwd), personaRoot, "read", userWorkDir)) {
69656
+ if (!isGuestPathAllowed(ctx.grants, path82.resolve(cwd), personaRoot, "read", userWorkDir)) {
69743
69657
  throw new ClawdError(
69744
69658
  ERROR_CODES.UNAUTHORIZED,
69745
69659
  `guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
@@ -69807,8 +69721,8 @@ function refreshPathFromLoginShell() {
69807
69721
  timeout: 3e3,
69808
69722
  stdio: ["ignore", "pipe", "ignore"]
69809
69723
  });
69810
- const path102 = out.trim();
69811
- if (path102) process.env.PATH = path102;
69724
+ const path100 = out.trim();
69725
+ if (path100) process.env.PATH = path100;
69812
69726
  } catch {
69813
69727
  }
69814
69728
  }
@@ -70017,11 +69931,11 @@ async function queryCodexAccount(deps = {}) {
70017
69931
 
70018
69932
  // src/tools/pi-account.ts
70019
69933
  var import_node_fs59 = __toESM(require("fs"), 1);
70020
- var import_node_path66 = __toESM(require("path"), 1);
69934
+ var import_node_path65 = __toESM(require("path"), 1);
70021
69935
  function readPiCredentials(agentDir) {
70022
69936
  let raw;
70023
69937
  try {
70024
- 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"));
70025
69939
  } catch {
70026
69940
  return {};
70027
69941
  }
@@ -71011,21 +70925,21 @@ function computeMethodAccess(args) {
71011
70925
  }
71012
70926
 
71013
70927
  // src/version.ts
71014
- var version = "0.2.547".length > 0 ? "0.2.547" : "dev";
70928
+ var version = "0.2.548".length > 0 ? "0.2.548" : "dev";
71015
70929
 
71016
70930
  // src/cli-probe/probe.ts
71017
70931
  var fs78 = __toESM(require("fs"), 1);
71018
- var path85 = __toESM(require("path"), 1);
70932
+ var path84 = __toESM(require("path"), 1);
71019
70933
  var PKG_NAME = "@clawos-dev/clawd";
71020
70934
  var BIN_NAME = "clawd";
71021
70935
  var MAX_PARENT_HOPS = 5;
71022
70936
  function probeGlobalCli(pathEnv) {
71023
70937
  if (!pathEnv) return null;
71024
- for (const dir of pathEnv.split(path85.delimiter)) {
70938
+ for (const dir of pathEnv.split(path84.delimiter)) {
71025
70939
  if (!dir) continue;
71026
70940
  let real;
71027
70941
  try {
71028
- real = fs78.realpathSync(path85.join(dir, BIN_NAME));
70942
+ real = fs78.realpathSync(path84.join(dir, BIN_NAME));
71029
70943
  } catch {
71030
70944
  continue;
71031
70945
  }
@@ -71035,15 +70949,15 @@ function probeGlobalCli(pathEnv) {
71035
70949
  return null;
71036
70950
  }
71037
70951
  function readOwnPackageVersion(entryPath) {
71038
- let dir = path85.dirname(entryPath);
70952
+ let dir = path84.dirname(entryPath);
71039
70953
  for (let i2 = 0; i2 < MAX_PARENT_HOPS; i2++) {
71040
70954
  try {
71041
- const raw = fs78.readFileSync(path85.join(dir, "package.json"), "utf8");
70955
+ const raw = fs78.readFileSync(path84.join(dir, "package.json"), "utf8");
71042
70956
  const pkg = JSON.parse(raw);
71043
70957
  if (pkg.name !== PKG_NAME) return null;
71044
70958
  return typeof pkg.version === "string" && pkg.version ? pkg.version : null;
71045
70959
  } catch {
71046
- const parent = path85.dirname(dir);
70960
+ const parent = path84.dirname(dir);
71047
70961
  if (parent === dir) return null;
71048
70962
  dir = parent;
71049
70963
  }
@@ -71219,7 +71133,7 @@ function buildPersonaHandlers(deps) {
71219
71133
  }
71220
71134
 
71221
71135
  // src/handlers/attachment.ts
71222
- var import_node_path67 = __toESM(require("path"), 1);
71136
+ var import_node_path66 = __toESM(require("path"), 1);
71223
71137
  init_protocol();
71224
71138
  init_protocol();
71225
71139
  function assertGuestAttachmentPath(ctx, absPath, personaRoot, method, usersRoot) {
@@ -71298,12 +71212,12 @@ function buildAttachmentHandlers(deps) {
71298
71212
  `session ${args.sessionId} scope unresolved`
71299
71213
  );
71300
71214
  }
71301
- const cwdAbs = import_node_path67.default.resolve(sessionFile.cwd);
71302
- 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);
71303
71217
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
71304
71218
  const entries = deps.groupFileStore.list(scope, args.sessionId);
71305
71219
  const entry = entries.find((e) => {
71306
- 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);
71307
71221
  return storedAbs === candidateAbs && !e.stale;
71308
71222
  });
71309
71223
  if (!entry) {
@@ -71327,7 +71241,7 @@ function buildAttachmentHandlers(deps) {
71327
71241
  if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
71328
71242
  const f2 = deps.sessionStore.read(sessionId);
71329
71243
  if (!f2) return;
71330
- 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);
71331
71245
  }
71332
71246
  const groupAdd = async (frame, _client, ctx) => {
71333
71247
  if (!deps.groupFileStore || !deps.getSessionScope) {
@@ -71342,8 +71256,8 @@ function buildAttachmentHandlers(deps) {
71342
71256
  if (!scope) {
71343
71257
  throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
71344
71258
  }
71345
- const cwdAbs = import_node_path67.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
71346
- 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);
71347
71261
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
71348
71262
  const from = args.origin === "agent" ? "agent" : ctx?.principal.kind === "owner" ? "owner" : "agent";
71349
71263
  const size = 0;
@@ -71402,19 +71316,19 @@ function buildAttachmentHandlers(deps) {
71402
71316
 
71403
71317
  // src/handlers/extension.ts
71404
71318
  var import_promises14 = __toESM(require("fs/promises"), 1);
71405
- var import_node_path72 = __toESM(require("path"), 1);
71319
+ var import_node_path71 = __toESM(require("path"), 1);
71406
71320
  init_protocol();
71407
71321
 
71408
71322
  // src/extension/bundle-zip.ts
71409
71323
  var import_promises11 = __toESM(require("fs/promises"), 1);
71410
- var import_node_path68 = __toESM(require("path"), 1);
71324
+ var import_node_path67 = __toESM(require("path"), 1);
71411
71325
  var import_node_crypto18 = __toESM(require("crypto"), 1);
71412
71326
  var import_jszip2 = __toESM(require_lib3(), 1);
71413
71327
  async function bundleExtensionDir(dir) {
71414
71328
  const entries = await listFilesSorted(dir);
71415
71329
  const zip = new import_jszip2.default();
71416
71330
  for (const rel of entries) {
71417
- const abs = import_node_path68.default.join(dir, rel);
71331
+ const abs = import_node_path67.default.join(dir, rel);
71418
71332
  const content = await import_promises11.default.readFile(abs);
71419
71333
  zip.file(rel, content, { date: FIXED_DATE });
71420
71334
  }
@@ -71435,7 +71349,7 @@ async function listFilesSorted(rootDir) {
71435
71349
  return out;
71436
71350
  }
71437
71351
  async function walk(absRoot, relPrefix, out) {
71438
- const dirAbs = import_node_path68.default.join(absRoot, relPrefix);
71352
+ const dirAbs = import_node_path67.default.join(absRoot, relPrefix);
71439
71353
  const entries = await import_promises11.default.readdir(dirAbs, { withFileTypes: true });
71440
71354
  for (const e of entries) {
71441
71355
  if (IGNORE_BASENAMES.has(e.name)) continue;
@@ -71489,25 +71403,25 @@ function computePublishCheck(args) {
71489
71403
 
71490
71404
  // src/extension/install-flow.ts
71491
71405
  var import_promises12 = __toESM(require("fs/promises"), 1);
71492
- var import_node_path70 = __toESM(require("path"), 1);
71406
+ var import_node_path69 = __toESM(require("path"), 1);
71493
71407
  var import_node_os25 = __toESM(require("os"), 1);
71494
71408
  var import_node_crypto19 = __toESM(require("crypto"), 1);
71495
71409
  var import_jszip3 = __toESM(require_lib3(), 1);
71496
71410
 
71497
71411
  // src/extension/paths.ts
71498
71412
  var import_node_os24 = __toESM(require("os"), 1);
71499
- var import_node_path69 = __toESM(require("path"), 1);
71413
+ var import_node_path68 = __toESM(require("path"), 1);
71500
71414
  function clawdHomeRoot(override) {
71501
- 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");
71502
71416
  }
71503
71417
  function extensionsRoot(override) {
71504
- return import_node_path69.default.join(clawdHomeRoot(override), "extensions");
71418
+ return import_node_path68.default.join(clawdHomeRoot(override), "extensions");
71505
71419
  }
71506
71420
  function publishedChannelsFile(override) {
71507
- return import_node_path69.default.join(clawdHomeRoot(override), "extensions-published.json");
71421
+ return import_node_path68.default.join(clawdHomeRoot(override), "extensions-published.json");
71508
71422
  }
71509
71423
  function bundleCacheRoot(override) {
71510
- return import_node_path69.default.join(clawdHomeRoot(override), "extension-bundles");
71424
+ return import_node_path68.default.join(clawdHomeRoot(override), "extension-bundles");
71511
71425
  }
71512
71426
 
71513
71427
  // src/extension/install-flow.ts
@@ -71534,7 +71448,7 @@ async function installFromChannel(args, deps) {
71534
71448
  throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
71535
71449
  }
71536
71450
  for (const name of Object.keys(zip.files)) {
71537
- if (name.includes("..") || name.startsWith("/") || import_node_path70.default.isAbsolute(name)) {
71451
+ if (name.includes("..") || name.startsWith("/") || import_node_path69.default.isAbsolute(name)) {
71538
71452
  throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
71539
71453
  }
71540
71454
  }
@@ -71566,7 +71480,7 @@ async function installFromChannel(args, deps) {
71566
71480
  );
71567
71481
  }
71568
71482
  const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
71569
- const destDir = import_node_path70.default.join(deps.extensionsRoot, localExtId);
71483
+ const destDir = import_node_path69.default.join(deps.extensionsRoot, localExtId);
71570
71484
  let destExists = false;
71571
71485
  try {
71572
71486
  await import_promises12.default.access(destDir);
@@ -71580,16 +71494,16 @@ async function installFromChannel(args, deps) {
71580
71494
  );
71581
71495
  }
71582
71496
  const stage = await import_promises12.default.mkdtemp(
71583
- 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}-`)
71584
71498
  );
71585
71499
  try {
71586
71500
  for (const [name, entry] of Object.entries(zip.files)) {
71587
- const dest = import_node_path70.default.join(stage, name);
71501
+ const dest = import_node_path69.default.join(stage, name);
71588
71502
  if (entry.dir) {
71589
71503
  await import_promises12.default.mkdir(dest, { recursive: true });
71590
71504
  continue;
71591
71505
  }
71592
- 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 });
71593
71507
  if (name === "manifest.json") {
71594
71508
  const rewritten = { ...parsed.data, id: localExtId };
71595
71509
  await import_promises12.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -71610,7 +71524,7 @@ async function installFromChannel(args, deps) {
71610
71524
 
71611
71525
  // src/extension/update-flow.ts
71612
71526
  var import_promises13 = __toESM(require("fs/promises"), 1);
71613
- var import_node_path71 = __toESM(require("path"), 1);
71527
+ var import_node_path70 = __toESM(require("path"), 1);
71614
71528
  var import_node_os26 = __toESM(require("os"), 1);
71615
71529
  var import_node_crypto20 = __toESM(require("crypto"), 1);
71616
71530
  var import_jszip4 = __toESM(require_lib3(), 1);
@@ -71627,11 +71541,11 @@ async function updateFromChannel(args, deps) {
71627
71541
  channelRef.extId,
71628
71542
  channelRef.ownerPrincipalId
71629
71543
  );
71630
- const liveDir = import_node_path71.default.join(deps.extensionsRoot, localExtId);
71544
+ const liveDir = import_node_path70.default.join(deps.extensionsRoot, localExtId);
71631
71545
  const prevDir = `${liveDir}.prev`;
71632
71546
  let existingVersion;
71633
71547
  try {
71634
- 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");
71635
71549
  const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
71636
71550
  if (!parsed2.success) {
71637
71551
  throw new UpdateError(
@@ -71664,7 +71578,7 @@ async function updateFromChannel(args, deps) {
71664
71578
  throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
71665
71579
  }
71666
71580
  for (const name of Object.keys(zip.files)) {
71667
- if (name.includes("..") || name.startsWith("/") || import_node_path71.default.isAbsolute(name)) {
71581
+ if (name.includes("..") || name.startsWith("/") || import_node_path70.default.isAbsolute(name)) {
71668
71582
  throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
71669
71583
  }
71670
71584
  }
@@ -71699,16 +71613,16 @@ async function updateFromChannel(args, deps) {
71699
71613
  await import_promises13.default.rm(prevDir, { recursive: true, force: true });
71700
71614
  await import_promises13.default.rename(liveDir, prevDir);
71701
71615
  const stage = await import_promises13.default.mkdtemp(
71702
- 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}-`)
71703
71617
  );
71704
71618
  try {
71705
71619
  for (const [name, entry] of Object.entries(zip.files)) {
71706
- const dest = import_node_path71.default.join(stage, name);
71620
+ const dest = import_node_path70.default.join(stage, name);
71707
71621
  if (entry.dir) {
71708
71622
  await import_promises13.default.mkdir(dest, { recursive: true });
71709
71623
  continue;
71710
71624
  }
71711
- 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 });
71712
71626
  if (name === "manifest.json") {
71713
71627
  const rewritten = { ...parsed.data, id: localExtId };
71714
71628
  await import_promises13.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -71775,7 +71689,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
71775
71689
  );
71776
71690
  }
71777
71691
  }
71778
- const manifestPath = import_node_path72.default.join(root, extId, "manifest.json");
71692
+ const manifestPath = import_node_path71.default.join(root, extId, "manifest.json");
71779
71693
  const manifest = await readManifest(root, extId);
71780
71694
  const next = { ...manifest, version: newVersion };
71781
71695
  const tmp = `${manifestPath}.tmp`;
@@ -71783,7 +71697,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
71783
71697
  await import_promises14.default.rename(tmp, manifestPath);
71784
71698
  }
71785
71699
  async function readManifest(root, extId) {
71786
- const file = import_node_path72.default.join(root, extId, "manifest.json");
71700
+ const file = import_node_path71.default.join(root, extId, "manifest.json");
71787
71701
  let raw;
71788
71702
  try {
71789
71703
  raw = await import_promises14.default.readFile(file, "utf8");
@@ -71867,7 +71781,7 @@ function buildExtensionHandlers(deps) {
71867
71781
  };
71868
71782
  async function buildSnapshotMeta(extId) {
71869
71783
  const manifest = await readManifest(deps.root, extId);
71870
- 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));
71871
71785
  return { manifest, contentHash: sha256, buffer };
71872
71786
  }
71873
71787
  const publish = async (frame, _client, ctx) => {
@@ -72695,7 +72609,7 @@ function buildVisitorHandlers(deps) {
72695
72609
 
72696
72610
  // src/extension/registry.ts
72697
72611
  var import_promises16 = __toESM(require("fs/promises"), 1);
72698
- var import_node_path73 = __toESM(require("path"), 1);
72612
+ var import_node_path72 = __toESM(require("path"), 1);
72699
72613
  async function loadAll(root) {
72700
72614
  let entries;
72701
72615
  try {
@@ -72708,13 +72622,13 @@ async function loadAll(root) {
72708
72622
  for (const ent of entries) {
72709
72623
  if (!ent.isDirectory()) continue;
72710
72624
  if (ent.name.startsWith(".")) continue;
72711
- 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));
72712
72626
  }
72713
72627
  records.sort((a2, b3) => a2.extId < b3.extId ? -1 : a2.extId > b3.extId ? 1 : 0);
72714
72628
  return records;
72715
72629
  }
72716
72630
  async function loadOne(dir, dirName) {
72717
- const manifestPath = import_node_path73.default.join(dir, "manifest.json");
72631
+ const manifestPath = import_node_path72.default.join(dir, "manifest.json");
72718
72632
  let raw;
72719
72633
  try {
72720
72634
  raw = await import_promises16.default.readFile(manifestPath, "utf8");
@@ -72759,7 +72673,7 @@ async function loadOne(dir, dirName) {
72759
72673
 
72760
72674
  // src/extension/uninstall.ts
72761
72675
  var import_promises17 = __toESM(require("fs/promises"), 1);
72762
- var import_node_path74 = __toESM(require("path"), 1);
72676
+ var import_node_path73 = __toESM(require("path"), 1);
72763
72677
  var UninstallError = class extends Error {
72764
72678
  constructor(code, message) {
72765
72679
  super(message);
@@ -72768,7 +72682,7 @@ var UninstallError = class extends Error {
72768
72682
  code;
72769
72683
  };
72770
72684
  async function uninstall(deps) {
72771
- const dir = import_node_path74.default.join(deps.root, deps.extId);
72685
+ const dir = import_node_path73.default.join(deps.root, deps.extId);
72772
72686
  try {
72773
72687
  await import_promises17.default.access(dir);
72774
72688
  } catch {
@@ -72983,7 +72897,7 @@ function buildMethodHandlers(deps) {
72983
72897
  broadcast: deps.broadcastToOwners
72984
72898
  }),
72985
72899
  ...buildMasterHandlers({
72986
- authorityTablePath: import_node_path75.default.join(deps.masterDataDir, "master-authority.json")
72900
+ authorityTablePath: import_node_path74.default.join(deps.masterDataDir, "master-authority.json")
72987
72901
  }),
72988
72902
  ...buildTopicHandlers({
72989
72903
  topicStore: deps.topicStore,
@@ -73083,45 +72997,6 @@ function buildOnboardingHandlers(deps) {
73083
72997
  return { "onboarding:complete": complete, "tools:probe": toolsProbe, "onboarding:iosInterest": iosInterest };
73084
72998
  }
73085
72999
 
73086
- // src/app-builder-plugin/mcp-config.ts
73087
- var import_node_fs60 = __toESM(require("fs"), 1);
73088
- var import_node_path76 = __toESM(require("path"), 1);
73089
- function appBuilderMcpConfigPath(outDir, personaId2) {
73090
- return import_node_path76.default.join(outDir, `${personaId2}.app-builder.mcp.json`);
73091
- }
73092
- function writeAppBuilderMcpConfig(args) {
73093
- const cfgPath = appBuilderMcpConfigPath(args.outDir, args.personaId);
73094
- const cfg = {
73095
- _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`,
73096
- mcpServers: {
73097
- "clawd-app-builder": {
73098
- type: "stdio",
73099
- command: "node",
73100
- args: [args.serverScriptPath],
73101
- env: {
73102
- // 凭据排前面:固定键在后,凭据表里若混进同名条目也顶不掉路径
73103
- ...args.secrets ?? {},
73104
- CLAWD_APP_BUILDER_PERSONA_ROOT: args.personaRoot,
73105
- CLAWD_APP_BUILDER_TEMPLATE_DIR: args.templateDir,
73106
- CLAWD_APP_BUILDER_SCAFFOLD_SCRIPT: import_node_path76.default.join(args.deployKitScriptsDir, "new-extension.sh"),
73107
- CLAWD_APP_BUILDER_PUBLISH_SCRIPT: import_node_path76.default.join(args.deployKitScriptsDir, "publish.sh"),
73108
- CLAWD_APP_BUILDER_REMOVE_SCRIPT: import_node_path76.default.join(args.deployKitScriptsDir, "remove-extension.sh"),
73109
- ...args.logPath ? { CLAWD_APP_BUILDER_LOG: args.logPath } : {}
73110
- }
73111
- }
73112
- }
73113
- };
73114
- import_node_fs60.default.mkdirSync(args.outDir, { recursive: true, mode: 448 });
73115
- const tmp = `${cfgPath}.${process.pid}.tmp`;
73116
- import_node_fs60.default.writeFileSync(tmp, JSON.stringify(cfg, null, 2), { encoding: "utf8", mode: 384 });
73117
- import_node_fs60.default.renameSync(tmp, cfgPath);
73118
- return cfgPath;
73119
- }
73120
-
73121
- // src/app-builder-plugin/personas.ts
73122
- var APP_BUILDER_PERSONAS = ["persona-app-builder", "persona-dataclaw-builder"];
73123
- var APP_BUILDER_TEMPLATE = "nestjs-react";
73124
-
73125
73000
  // src/handlers/dispatch-rpc.ts
73126
73001
  init_zod();
73127
73002
  init_protocol();
@@ -73165,7 +73040,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
73165
73040
 
73166
73041
  // src/extension/runtime.ts
73167
73042
  var import_node_child_process24 = require("child_process");
73168
- var import_node_path77 = __toESM(require("path"), 1);
73043
+ var import_node_path75 = __toESM(require("path"), 1);
73169
73044
  var import_promises18 = require("timers/promises");
73170
73045
 
73171
73046
  // src/extension/port-allocator.ts
@@ -73266,7 +73141,7 @@ var Runtime = class {
73266
73141
  /\$CLAWOS_EXT_PORT/g,
73267
73142
  String(port)
73268
73143
  );
73269
- const dir = import_node_path77.default.join(this.root, extId);
73144
+ const dir = import_node_path75.default.join(this.root, extId);
73270
73145
  const env = {
73271
73146
  ...process.env,
73272
73147
  CLAWOS_EXT_PORT: String(port),
@@ -73378,7 +73253,7 @@ ${handle.stderrTail}`
73378
73253
 
73379
73254
  // src/extension/published-channels.ts
73380
73255
  var import_promises19 = __toESM(require("fs/promises"), 1);
73381
- var import_node_path78 = __toESM(require("path"), 1);
73256
+ var import_node_path76 = __toESM(require("path"), 1);
73382
73257
  init_zod();
73383
73258
  var PublishedChannelsError = class extends Error {
73384
73259
  constructor(code, message) {
@@ -73477,7 +73352,7 @@ var PublishedChannelStore = class {
73477
73352
  )
73478
73353
  };
73479
73354
  const tmp = `${this.filePath}.tmp`;
73480
- 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 });
73481
73356
  await import_promises19.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
73482
73357
  await import_promises19.default.rename(tmp, this.filePath);
73483
73358
  }
@@ -73485,7 +73360,7 @@ var PublishedChannelStore = class {
73485
73360
 
73486
73361
  // src/extension/bundle-cache.ts
73487
73362
  var import_promises20 = __toESM(require("fs/promises"), 1);
73488
- var import_node_path79 = __toESM(require("path"), 1);
73363
+ var import_node_path77 = __toESM(require("path"), 1);
73489
73364
  var BundleCache = class {
73490
73365
  constructor(rootDir) {
73491
73366
  this.rootDir = rootDir;
@@ -73494,14 +73369,14 @@ var BundleCache = class {
73494
73369
  /** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
73495
73370
  async write(snapshotHash, buffer) {
73496
73371
  await import_promises20.default.mkdir(this.rootDir, { recursive: true });
73497
- const file = import_node_path79.default.join(this.rootDir, `${snapshotHash}.zip`);
73372
+ const file = import_node_path77.default.join(this.rootDir, `${snapshotHash}.zip`);
73498
73373
  const tmp = `${file}.tmp`;
73499
73374
  await import_promises20.default.writeFile(tmp, buffer, { mode: 384 });
73500
73375
  await import_promises20.default.rename(tmp, file);
73501
73376
  }
73502
73377
  /** Returns the bundle bytes, or null when the file doesn't exist. */
73503
73378
  async read(snapshotHash) {
73504
- const file = import_node_path79.default.join(this.rootDir, `${snapshotHash}.zip`);
73379
+ const file = import_node_path77.default.join(this.rootDir, `${snapshotHash}.zip`);
73505
73380
  try {
73506
73381
  return await import_promises20.default.readFile(file);
73507
73382
  } catch (e) {
@@ -73511,7 +73386,7 @@ var BundleCache = class {
73511
73386
  }
73512
73387
  /** Idempotent — missing file is not an error. */
73513
73388
  async delete(snapshotHash) {
73514
- const file = import_node_path79.default.join(this.rootDir, `${snapshotHash}.zip`);
73389
+ const file = import_node_path77.default.join(this.rootDir, `${snapshotHash}.zip`);
73515
73390
  await import_promises20.default.rm(file, { force: true });
73516
73391
  }
73517
73392
  };
@@ -73534,24 +73409,24 @@ async function startDaemon(config) {
73534
73409
  sampling: logShippingCfg.sampling,
73535
73410
  homeDir: import_node_os28.default.homedir()
73536
73411
  });
73537
- const logDir = import_node_path80.default.join(config.dataDir, "log");
73538
- 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 });
73539
73414
  const logger = createLogger({
73540
73415
  level: config.logLevel,
73541
- file: import_node_path80.default.join(logDir, "clawd.log"),
73416
+ file: import_node_path78.default.join(logDir, "clawd.log"),
73542
73417
  logClient
73543
73418
  });
73544
73419
  logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
73545
73420
  const screenIdleProbeLogger = createFileOnlyLogger({
73546
- file: import_node_path80.default.join(logDir, "screen-idle-probe.log"),
73421
+ file: import_node_path78.default.join(logDir, "screen-idle-probe.log"),
73547
73422
  level: "debug"
73548
73423
  });
73549
73424
  logger.info("screen-idle probe logger enabled", {
73550
- file: import_node_path80.default.join(logDir, "screen-idle-probe.log")
73425
+ file: import_node_path78.default.join(logDir, "screen-idle-probe.log")
73551
73426
  });
73552
73427
  const CAP_TARGETS = [
73553
- import_node_path80.default.join(logDir, "clawd.log"),
73554
- 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")
73555
73430
  ];
73556
73431
  const LOG_CAP_MAX_BYTES = 10 * 1024 * 1024;
73557
73432
  const LOG_CAP_KEEP_BYTES = 5 * 1024 * 1024;
@@ -73673,8 +73548,8 @@ async function startDaemon(config) {
73673
73548
  const agents = new AgentsScanner();
73674
73549
  const history = new ClaudeHistoryReader();
73675
73550
  let transport = null;
73676
- const personaStore = new PersonaStore(import_node_path80.default.join(config.dataDir, "personas"));
73677
- 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");
73678
73553
  const defaultsRoot = findDefaultsRoot(logger);
73679
73554
  if (defaultsRoot) {
73680
73555
  seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
@@ -73683,13 +73558,6 @@ async function startDaemon(config) {
73683
73558
  } else {
73684
73559
  logger.warn("persona.seed.skip", { reason: "defaults-root-not-found" });
73685
73560
  }
73686
- const deployKitBundleRoot = findDeployKitRoot(logger);
73687
- if (deployKitBundleRoot) {
73688
- seedDeployKit({ deployKitBundleRoot, dataDir: config.dataDir, logger });
73689
- refreshDeployKit({ deployKitBundleRoot, dataDir: config.dataDir, logger });
73690
- } else {
73691
- logger.warn("deploy-kit.bundle-missing", {});
73692
- }
73693
73561
  refreshSandboxSettings({ store: personaStore, logger });
73694
73562
  migrateAgentsMirror({ store: personaStore, logger });
73695
73563
  migrateCodexSandbox({ store: personaStore, logger });
@@ -73698,7 +73566,7 @@ async function startDaemon(config) {
73698
73566
  retirePersonaBuilder({ store: personaStore, logger });
73699
73567
  const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
73700
73568
  const dispatchStore = createDispatchStore({
73701
- filePath: import_node_path80.default.join(config.dataDir, "dispatch.json"),
73569
+ filePath: import_node_path78.default.join(config.dataDir, "dispatch.json"),
73702
73570
  now: () => Date.now(),
73703
73571
  onFlushError: (err) => logger.error("dispatch store flush failed", {
73704
73572
  reason: err instanceof Error ? err.message : String(err)
@@ -73707,7 +73575,7 @@ async function startDaemon(config) {
73707
73575
  await dispatchStore.load();
73708
73576
  dispatchStore.markInterruptedAsFailed((/* @__PURE__ */ new Date()).toISOString());
73709
73577
  const channelStore = createChannelStore({
73710
- filePath: import_node_path80.default.join(config.dataDir, "channels.json"),
73578
+ filePath: import_node_path78.default.join(config.dataDir, "channels.json"),
73711
73579
  now: () => Date.now(),
73712
73580
  genId: () => `ch-${(0, import_node_crypto22.randomUUID)().slice(0, 8)}`,
73713
73581
  onFlushError: (err) => logger.error("channel store flush failed", {
@@ -73716,7 +73584,7 @@ async function startDaemon(config) {
73716
73584
  });
73717
73585
  await channelStore.load();
73718
73586
  const topicStore = createTopicStore({
73719
- filePath: import_node_path80.default.join(config.dataDir, "topics.json"),
73587
+ filePath: import_node_path78.default.join(config.dataDir, "topics.json"),
73720
73588
  now: () => Date.now(),
73721
73589
  genId: () => `tp-${(0, import_node_crypto22.randomUUID)().slice(0, 8)}`,
73722
73590
  onFlushError: (err) => logger.error("topic store flush failed", {
@@ -73743,12 +73611,12 @@ async function startDaemon(config) {
73743
73611
  });
73744
73612
  }
73745
73613
  });
73746
- 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));
73747
73615
  const mcpConfigs = [];
73748
73616
  const secretsBundleRoot = findSecretsBundleRoot(logger);
73749
- 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);
73750
73618
  const readSecrets = () => readSecretTable({ bundleRoot: secretsBundleRoot, overrideDir: localSecretsDir, logger });
73751
- const githubTokenFile = import_node_path80.default.join(localSecretsDir, GITHUB_TOKEN_FILE);
73619
+ const githubTokenFile = import_node_path78.default.join(localSecretsDir, GITHUB_TOKEN_FILE);
73752
73620
  const githubIdentity = createGithubIdentity({
73753
73621
  resolve: () => resolveGithubAuth({ exec: runCommand, fileToken: () => readEnvFileVar(githubTokenFile, GITHUB_TOKEN_VAR) }),
73754
73622
  store: (token) => storeGithubAuth({
@@ -73781,29 +73649,27 @@ async function startDaemon(config) {
73781
73649
  logger
73782
73650
  });
73783
73651
  void githubIdentity.refresh();
73784
- let refreshAppBuilderMcpConfig;
73785
73652
  const resolvePersonaMcpConfig = (personaId2) => {
73786
- refreshAppBuilderMcpConfig?.(personaId2);
73787
73653
  const secrets = secretsWithGithubIdentity(readSecrets(), githubIdentity.cached());
73788
73654
  void githubIdentity.refresh();
73789
73655
  return renderPersonaMcpSecrets({
73790
73656
  personaId: personaId2,
73791
- personaDir: import_node_path80.default.join(config.dataDir, "personas", personaId2),
73657
+ personaDir: import_node_path78.default.join(config.dataDir, "personas", personaId2),
73792
73658
  secrets,
73793
- outDir: import_node_path80.default.join(config.dataDir, "persona-mcp"),
73659
+ outDir: import_node_path78.default.join(config.dataDir, "persona-mcp"),
73794
73660
  logger
73795
73661
  });
73796
73662
  };
73797
73663
  const mcpDaemonUrl = `http://127.0.0.1:${config.port}`;
73798
73664
  const dispatchServerCandidates = [
73799
- import_node_path80.default.join(here, "dispatch", "mcp-server.cjs"),
73665
+ import_node_path78.default.join(here, "dispatch", "mcp-server.cjs"),
73800
73666
  // 生产 dist/index → dist/dispatch/mcp-server.cjs
73801
- import_node_path80.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
73667
+ import_node_path78.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
73802
73668
  // dev tsx src/index → ../dist/dispatch/mcp-server.cjs
73803
73669
  ];
73804
- const dispatchServerScriptPath = dispatchServerCandidates.find((p3) => import_node_fs61.default.existsSync(p3));
73670
+ const dispatchServerScriptPath = dispatchServerCandidates.find((p3) => import_node_fs60.default.existsSync(p3));
73805
73671
  if (dispatchServerScriptPath) {
73806
- 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");
73807
73673
  const dispatchCfgPath = writeDispatchMcpConfig({
73808
73674
  dataDir: config.dataDir,
73809
73675
  serverScriptPath: dispatchServerScriptPath,
@@ -73823,12 +73689,12 @@ async function startDaemon(config) {
73823
73689
  });
73824
73690
  }
73825
73691
  const ticketServerCandidates = [
73826
- import_node_path80.default.join(here, "ticket", "mcp-server.cjs"),
73827
- 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")
73828
73694
  ];
73829
- const ticketServerScriptPath = ticketServerCandidates.find((p3) => import_node_fs61.default.existsSync(p3));
73695
+ const ticketServerScriptPath = ticketServerCandidates.find((p3) => import_node_fs60.default.existsSync(p3));
73830
73696
  if (ticketServerScriptPath) {
73831
- 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");
73832
73698
  const ticketCfgPath = writeTicketMcpConfig({
73833
73699
  dataDir: config.dataDir,
73834
73700
  serverScriptPath: ticketServerScriptPath,
@@ -73850,12 +73716,12 @@ async function startDaemon(config) {
73850
73716
  });
73851
73717
  }
73852
73718
  const shiftServerCandidates = [
73853
- import_node_path80.default.join(here, "shift", "mcp-server.cjs"),
73854
- 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")
73855
73721
  ];
73856
- const shiftServerScriptPath = shiftServerCandidates.find((p3) => import_node_fs61.default.existsSync(p3));
73722
+ const shiftServerScriptPath = shiftServerCandidates.find((p3) => import_node_fs60.default.existsSync(p3));
73857
73723
  if (shiftServerScriptPath) {
73858
- 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");
73859
73725
  const shiftCfgPath = await writeShiftMcpConfig({
73860
73726
  dataDir: config.dataDir,
73861
73727
  serverScriptPath: shiftServerScriptPath,
@@ -73876,12 +73742,12 @@ async function startDaemon(config) {
73876
73742
  );
73877
73743
  }
73878
73744
  const inboxServerCandidates = [
73879
- import_node_path80.default.join(here, "inbox", "mcp-server.cjs"),
73880
- 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")
73881
73747
  ];
73882
- const inboxServerScriptPath = inboxServerCandidates.find((p3) => import_node_fs61.default.existsSync(p3));
73748
+ const inboxServerScriptPath = inboxServerCandidates.find((p3) => import_node_fs60.default.existsSync(p3));
73883
73749
  if (inboxServerScriptPath) {
73884
- 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");
73885
73751
  const inboxCfgPath = await writeInboxMcpConfig({
73886
73752
  dataDir: config.dataDir,
73887
73753
  serverScriptPath: inboxServerScriptPath,
@@ -73902,10 +73768,10 @@ async function startDaemon(config) {
73902
73768
  );
73903
73769
  }
73904
73770
  const peerOpsServerCandidates = [
73905
- import_node_path80.default.join(here, "peer-ops", "mcp-server.cjs"),
73906
- 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")
73907
73773
  ];
73908
- const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) => import_node_fs61.default.existsSync(p3));
73774
+ const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) => import_node_fs60.default.existsSync(p3));
73909
73775
  if (peerOpsServerScriptPath) {
73910
73776
  const peerOpsCfgPath = writePeerOpsMcpConfig({
73911
73777
  dataDir: config.dataDir,
@@ -73925,12 +73791,12 @@ async function startDaemon(config) {
73925
73791
  );
73926
73792
  }
73927
73793
  const rpcToolServerCandidates = [
73928
- import_node_path80.default.join(here, "rpc-tool", "mcp-server.cjs"),
73929
- 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")
73930
73796
  ];
73931
- const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) => import_node_fs61.default.existsSync(p3));
73797
+ const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) => import_node_fs60.default.existsSync(p3));
73932
73798
  if (rpcToolServerScriptPath) {
73933
- 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");
73934
73800
  const rpcToolCfgPath = writeRpcToolMcpConfig({
73935
73801
  dataDir: config.dataDir,
73936
73802
  serverScriptPath: rpcToolServerScriptPath,
@@ -73950,48 +73816,8 @@ async function startDaemon(config) {
73950
73816
  { tried: rpcToolServerCandidates }
73951
73817
  );
73952
73818
  }
73953
- const appBuilderServerCandidates = [
73954
- import_node_path80.default.join(here, "app-builder-plugin", "mcp-server.cjs"),
73955
- import_node_path80.default.join(here, "..", "dist", "app-builder-plugin", "mcp-server.cjs")
73956
- ];
73957
- const appBuilderServerScriptPath = appBuilderServerCandidates.find((p3) => import_node_fs61.default.existsSync(p3));
73958
- if (appBuilderServerScriptPath) {
73959
- const appBuilderLogPath = import_node_path80.default.join(logDir, "app-builder-mcp-server.log");
73960
- const writeAppBuilderConfigFor = (personaId2) => {
73961
- const personaRoot = import_node_path80.default.join(config.dataDir, "personas", personaId2);
73962
- const secrets = secretsForKit(readSecrets(), import_node_path80.default.join(personaRoot, "extension-kit"));
73963
- return writeAppBuilderMcpConfig({
73964
- outDir: import_node_path80.default.join(config.dataDir, "persona-mcp"),
73965
- personaId: personaId2,
73966
- serverScriptPath: appBuilderServerScriptPath,
73967
- personaRoot,
73968
- templateDir: import_node_path80.default.join(personaRoot, "extension-kit", "examples", APP_BUILDER_TEMPLATE),
73969
- deployKitScriptsDir: import_node_path80.default.join(config.dataDir, "deploy-kit", "scripts"),
73970
- ...secrets ? { secrets } : {},
73971
- logPath: appBuilderLogPath
73972
- });
73973
- };
73974
- for (const personaId2 of APP_BUILDER_PERSONAS) {
73975
- const cfgPath = writeAppBuilderConfigFor(personaId2);
73976
- mcpConfigs.push({ id: `app-builder:${personaId2}`, path: cfgPath, personas: [personaId2] });
73977
- logger.info("app-builder.mcp.json written", { personaId: personaId2, path: cfgPath, server: appBuilderServerScriptPath });
73978
- }
73979
- refreshAppBuilderMcpConfig = (personaId2) => {
73980
- if (!APP_BUILDER_PERSONAS.includes(personaId2)) return;
73981
- try {
73982
- writeAppBuilderConfigFor(personaId2);
73983
- } catch (err) {
73984
- logger.warn("app-builder.mcp.json refresh failed", { personaId: personaId2, error: err instanceof Error ? err.message : String(err) });
73985
- }
73986
- };
73987
- } else {
73988
- logger.warn(
73989
- "app-builder-plugin/mcp-server.cjs not found; clawd-app-builder tools disabled (dev tsx \u6A21\u5F0F\u4E0B\u9700\u5148\u8DD1\u8FC7 build)",
73990
- { tried: appBuilderServerCandidates }
73991
- );
73992
- }
73993
73819
  const shiftStore = createShiftStore({
73994
- filePath: import_node_path80.default.join(config.dataDir, "shift.json"),
73820
+ filePath: import_node_path78.default.join(config.dataDir, "shift.json"),
73995
73821
  ownerIdProvider: () => ownerPrincipalId,
73996
73822
  now: () => Date.now()
73997
73823
  });
@@ -74013,7 +73839,7 @@ async function startDaemon(config) {
74013
73839
  getAdapter,
74014
73840
  historyReader: history,
74015
73841
  dataDir: config.dataDir,
74016
- personaRoot: import_node_path80.default.join(config.dataDir, "personas"),
73842
+ personaRoot: import_node_path78.default.join(config.dataDir, "personas"),
74017
73843
  // dispatch / shift 自动化 spawn 按 persona 绑定 tool 起 B session(codex persona 用 codex)。
74018
73844
  // personaRegistry 声明在 manager 之后(同作用域 const,调用时机在启动完成后,无 TDZ 风险)。
74019
73845
  getPersonaDefaults: (personaId2) => personaRegistry.get(personaId2),
@@ -74070,10 +73896,10 @@ async function startDaemon(config) {
74070
73896
  // 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
74071
73897
  attachmentGroup: {
74072
73898
  onFileEdit: (input) => {
74073
- 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);
74074
73900
  let size = 0;
74075
73901
  try {
74076
- size = import_node_fs61.default.statSync(absPath).size;
73902
+ size = import_node_fs60.default.statSync(absPath).size;
74077
73903
  } catch (err) {
74078
73904
  logger.warn("attachment.onFileEdit stat failed", {
74079
73905
  sessionId: input.sessionId,
@@ -74114,9 +73940,9 @@ async function startDaemon(config) {
74114
73940
  logger.info("projects.seed-dropped", { dropped: droppedSeed.dropped, backup: droppedSeed.backup });
74115
73941
  }
74116
73942
  const projectsStore = new ProjectsStore({
74117
- file: import_node_path80.default.join(config.dataDir, "projects.json"),
73943
+ file: import_node_path78.default.join(config.dataDir, "projects.json"),
74118
73944
  clawdDir: config.dataDir,
74119
- 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"),
74120
73946
  logger
74121
73947
  });
74122
73948
  const observer = new SessionObserver({
@@ -74181,13 +74007,13 @@ async function startDaemon(config) {
74181
74007
  logger
74182
74008
  });
74183
74009
  registerAdapter("claude", claudeAdapter);
74184
- const codexIsolatedHome = import_node_path80.default.join(config.dataDir, "codex-home");
74010
+ const codexIsolatedHome = import_node_path78.default.join(config.dataDir, "codex-home");
74185
74011
  try {
74186
- import_node_fs61.default.mkdirSync(codexIsolatedHome, { recursive: true });
74012
+ import_node_fs60.default.mkdirSync(codexIsolatedHome, { recursive: true });
74187
74013
  for (const f2 of ["auth.json", "config.toml"]) {
74188
- const link = import_node_path80.default.join(codexIsolatedHome, f2);
74189
- const target = import_node_path80.default.join(import_node_os28.default.homedir(), ".codex", f2);
74190
- 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);
74191
74017
  }
74192
74018
  } catch (err) {
74193
74019
  logger.warn("codex isolated home setup failed", { err: String(err) });
@@ -74198,17 +74024,17 @@ async function startDaemon(config) {
74198
74024
  logger,
74199
74025
  historyReader: new CodexHistoryReader({
74200
74026
  roots: codexRolloutRoots(config.dataDir),
74201
- 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"),
74202
74028
  logger
74203
74029
  }),
74204
74030
  // projectPaths 每次调用现取 —— 用户新建 project 后立即生效,不用重启 daemon
74205
74031
  codexHomeFor: (cwd) => resolveCodexHome({
74206
74032
  cwd,
74207
- personaRoot: import_node_path80.default.join(config.dataDir, "personas"),
74033
+ personaRoot: import_node_path78.default.join(config.dataDir, "personas"),
74208
74034
  // 必须用 listMerged(Codex registry ∪ 叠加层):只用本地 list() 的话,用户在
74209
74035
  // Codex 里建的 project 不在表里,在它下面开的会话会被误判成隔离 → Codex 侧看不到
74210
74036
  projectPaths: projectsStore.listMerged().map((x2) => x2.path),
74211
- 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"),
74212
74038
  isolatedHome: codexIsolatedHome
74213
74039
  }),
74214
74040
  // 附件图片验签:与 http-router /files 路由同一把 secret
@@ -74232,10 +74058,10 @@ async function startDaemon(config) {
74232
74058
  })
74233
74059
  );
74234
74060
  const piMcpBridgeCandidates = [
74235
- import_node_path80.default.join(here, "pi-mcp-bridge", "extension.cjs"),
74236
- 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")
74237
74063
  ];
74238
- const piMcpBridgePath = piMcpBridgeCandidates.find((p3) => import_node_fs61.default.existsSync(p3));
74064
+ const piMcpBridgePath = piMcpBridgeCandidates.find((p3) => import_node_fs60.default.existsSync(p3));
74239
74065
  if (piMcpBridgePath) {
74240
74066
  logger.info("pi-mcp-bridge extension resolved", { path: piMcpBridgePath });
74241
74067
  } else {
@@ -74530,11 +74356,11 @@ async function startDaemon(config) {
74530
74356
  // 'persona/<pid>/owner',default 走 'default'。
74531
74357
  getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
74532
74358
  // guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
74533
- personaRoot: import_node_path80.default.join(config.dataDir, "personas"),
74359
+ personaRoot: import_node_path78.default.join(config.dataDir, "personas"),
74534
74360
  usersRoot
74535
74361
  },
74536
74362
  // workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
74537
- personaRoot: import_node_path80.default.join(config.dataDir, "personas"),
74363
+ personaRoot: import_node_path78.default.join(config.dataDir, "personas"),
74538
74364
  // v2 多人 persona 隔离:handler 派生 guest user-dir 放行
74539
74365
  usersRoot,
74540
74366
  // v2 Phase 6: whoami handler 装在 owner principal.displayName + persona 解析
@@ -74815,7 +74641,7 @@ async function startDaemon(config) {
74815
74641
  });
74816
74642
  shiftScheduler.start();
74817
74643
  logger.info("shift scheduler started", { shiftCount: shiftStore.list().length });
74818
- const larkBotStore = createLarkBotBindingStore(import_node_path80.default.join(config.dataDir, "personas"));
74644
+ const larkBotStore = createLarkBotBindingStore(import_node_path78.default.join(config.dataDir, "personas"));
74819
74645
  const larkBotCloud = createLarkBotCloudClient({
74820
74646
  api: config.clawosApi ?? DEFAULT_CLAWOS_API,
74821
74647
  getLoginPass: () => ownerIdentityStore.read()?.loginPass ?? null
@@ -74827,7 +74653,7 @@ async function startDaemon(config) {
74827
74653
  store: larkBotStore,
74828
74654
  fetchResource: (appId, messageId, fileKey, maxBytes, type) => larkBotCloud.fetchResource(appId, messageId, fileKey, maxBytes, type),
74829
74655
  // 图片落 guest userWorkDir 下(capId = lark-<chat_id>):CC 经 --add-dir + allowRead carve 可 Read
74830
- 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"),
74831
74657
  isShuttingDown: () => larkDraining,
74832
74658
  logger: {
74833
74659
  warn: (msg) => logger.warn(msg),
@@ -75111,8 +74937,8 @@ async function startDaemon(config) {
75111
74937
  const lines = [
75112
74938
  `Tunnel: ${r2.url}`,
75113
74939
  ...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
75114
- `Frpc config: ${import_node_path80.default.join(config.dataDir, "frpc.toml")}`,
75115
- `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")}`
75116
74942
  ];
75117
74943
  const width2 = Math.max(...lines.map((l2) => l2.length));
75118
74944
  const bar = "\u2550".repeat(width2 + 4);
@@ -75125,8 +74951,8 @@ ${bar}
75125
74951
 
75126
74952
  `);
75127
74953
  try {
75128
- const connectPath = import_node_path80.default.join(config.dataDir, "connect.txt");
75129
- 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 });
75130
74956
  } catch {
75131
74957
  }
75132
74958
  } catch (err) {
@@ -75224,9 +75050,9 @@ ${bar}
75224
75050
  };
75225
75051
  }
75226
75052
  function migrateDropPersonsDir(dataDir) {
75227
- const dir = import_node_path80.default.join(dataDir, "persons");
75053
+ const dir = import_node_path78.default.join(dataDir, "persons");
75228
75054
  try {
75229
- import_node_fs61.default.rmSync(dir, { recursive: true, force: true });
75055
+ import_node_fs60.default.rmSync(dir, { recursive: true, force: true });
75230
75056
  } catch {
75231
75057
  }
75232
75058
  }