@clawos-dev/clawd 0.2.547 → 0.2.549

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 (40) hide show
  1. package/dist/app-builder-plugin/mcp-server.cjs +40 -37
  2. package/dist/cli.cjs +488 -657
  3. package/dist/dispatch/mcp-server.cjs +5 -2
  4. package/dist/persona-defaults/persona-app-builder/.mcp.json +17 -2
  5. package/dist/persona-defaults/persona-app-builder/CLAUDE.md +8 -9
  6. package/dist/persona-defaults/persona-app-builder/extension-kit/README.md +6 -7
  7. package/dist/persona-defaults/persona-app-builder/extension-kit/contract/s.yaml.tmpl +3 -2
  8. package/dist/persona-defaults/persona-app-builder/mcp/clawd-app-builder/deploy-kit/scripts/ensure-credentials.sh +96 -0
  9. package/dist/{deploy-kit → persona-defaults/persona-app-builder/mcp/clawd-app-builder/deploy-kit}/scripts/publish.sh +3 -3
  10. package/dist/{deploy-kit → persona-defaults/persona-app-builder/mcp/clawd-app-builder/deploy-kit}/scripts/remove-extension.sh +2 -2
  11. package/dist/persona-defaults/persona-app-builder/mcp/clawd-app-builder/mcp-server.cjs +25400 -0
  12. package/dist/persona-defaults/persona-dataclaw-builder/.mcp.json +14 -1
  13. package/dist/persona-defaults/persona-dataclaw-builder/CLAUDE.md +1 -1
  14. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/README.md +6 -7
  15. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/config.env +1 -1
  16. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/contract/s.yaml.tmpl +3 -2
  17. package/dist/persona-defaults/persona-dataclaw-builder/mcp/clawd-app-builder/deploy-kit/contract/bootstrap +22 -0
  18. package/dist/persona-defaults/persona-dataclaw-builder/mcp/clawd-app-builder/deploy-kit/scripts/ensure-credentials.sh +96 -0
  19. package/dist/persona-defaults/persona-dataclaw-builder/mcp/clawd-app-builder/deploy-kit/scripts/ensure-toolchain.sh +65 -0
  20. package/dist/persona-defaults/persona-dataclaw-builder/mcp/clawd-app-builder/deploy-kit/scripts/new-extension.sh +71 -0
  21. package/dist/persona-defaults/persona-dataclaw-builder/mcp/clawd-app-builder/deploy-kit/scripts/publish.sh +205 -0
  22. package/dist/persona-defaults/persona-dataclaw-builder/mcp/clawd-app-builder/deploy-kit/scripts/remove-extension.sh +89 -0
  23. package/dist/persona-defaults/persona-dataclaw-builder/mcp/clawd-app-builder/deploy-kit/scripts/verify.sh +49 -0
  24. package/dist/persona-defaults/persona-dataclaw-builder/mcp/clawd-app-builder/mcp-server.cjs +25400 -0
  25. package/dist/share-md-viewer-error.html +1 -1
  26. package/dist/share-md-viewer.html +1 -1
  27. package/dist/share-ui/assets/{guest-LyTPPmtK.js → guest-BG2kYWjt.js} +132 -132
  28. package/dist/share-ui/assets/guest-BHSs9s97.css +32 -0
  29. package/dist/share-ui/guest.html +2 -2
  30. package/package.json +1 -1
  31. package/dist/deploy-kit/.secrets/aliyun.env.example +0 -7
  32. package/dist/deploy-kit/.secrets/aliyun.env.local.example +0 -12
  33. package/dist/deploy-kit/scripts/ensure-credentials.sh +0 -111
  34. package/dist/deploy-kit/scripts/ensure-credentials.spec.ts +0 -438
  35. package/dist/deploy-kit/scripts/publish.spec.ts +0 -278
  36. package/dist/share-ui/assets/guest-DVW7Ohf0.css +0 -32
  37. /package/dist/{deploy-kit → persona-defaults/persona-app-builder/mcp/clawd-app-builder/deploy-kit}/contract/bootstrap +0 -0
  38. /package/dist/{deploy-kit → persona-defaults/persona-app-builder/mcp/clawd-app-builder/deploy-kit}/scripts/ensure-toolchain.sh +0 -0
  39. /package/dist/{deploy-kit → persona-defaults/persona-app-builder/mcp/clawd-app-builder/deploy-kit}/scripts/new-extension.sh +0 -0
  40. /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() {
@@ -6098,7 +6098,7 @@ function cloudEngineOk(tool) {
6098
6098
  function repoSlug(url) {
6099
6099
  return url.trim().replace(/^git@[^:]+:/, "").replace(/^https?:\/\/[^/]+\//, "").replace(/\.git$/, "");
6100
6100
  }
6101
- var DeployFileSchema, SCAN_BASE_KINDS, ScanBaseKindSchema, DeployScanStatusSchema, DeployScanSchema, DeployRepoSchema, DeploySecretPresenceSchema, DEPLOY_STAGE_STATUSES, DeployStageStatusSchema, DEPLOY_STAGE_KEYS, DeployStageKeySchema, DeployJobSchema, DeployRunSchema, DeployStateSchema, DeployReleaseResultSchema, DeployPersonaArgsSchema, DeployPatchArgsSchema, DeployPutSecretArgsSchema, DeployRerunJobArgsSchema, DeployReportFindingArgsSchema, DeployFinishScanArgsSchema, PERSONA_REPO_ORG;
6101
+ var DeployFileSchema, SCAN_BASE_KINDS, ScanBaseKindSchema, DeployScanStatusSchema, DeployScanSchema, DeployRepoSchema, DeploySecretPresenceSchema, DEPLOY_STAGE_STATUSES, DeployStageStatusSchema, DEPLOY_STAGE_KEYS, DeployStageKeySchema, DeployJobSchema, DeployRunSchema, DeployStateSchema, DeployReleaseResultSchema, DeployPersonaArgsSchema, DeployReleaseArgsSchema, DeployPatchArgsSchema, DeployPutSecretArgsSchema, DeployRerunJobArgsSchema, DeployReportFindingArgsSchema, DeployFinishScanArgsSchema, PERSONA_REPO_ORG;
6102
6102
  var init_deploy_schemas = __esm({
6103
6103
  "../protocol/src/deploy-schemas.ts"() {
6104
6104
  "use strict";
@@ -6228,6 +6228,9 @@ var init_deploy_schemas = __esm({
6228
6228
  DeployPersonaArgsSchema = external_exports.object({
6229
6229
  personaId: external_exports.string().min(1)
6230
6230
  }).strict();
6231
+ DeployReleaseArgsSchema = DeployPersonaArgsSchema.extend({
6232
+ scanBase: ScanBaseKindSchema.optional()
6233
+ }).strict();
6231
6234
  DeployPatchArgsSchema = external_exports.object({
6232
6235
  personaId: external_exports.string().min(1),
6233
6236
  patch: external_exports.object({
@@ -8999,8 +9002,8 @@ var init_methods = __esm({
8999
9002
  args: DeployFinishScanArgsSchema
9000
9003
  },
9001
9004
  "deploy:release": {
9002
- summary: "\u53D1\u5E03\u2014\u2014\u4E0A\u4E91\u552F\u4E00\u7684\u52A8\u4F5C\uFF0C\u626B\u63CF\u662F\u5B83\u7684\u7B2C\u4E00\u6BB5\u3002**\u6CA1\u4ED3\u5E93\u5148\u5EFA\u4ED3**\uFF08GitHub REST \u5EFA\u5728\u7EC4\u7EC7\u4E0B\u3001\u79C1\u6709\uFF0Cgit \u63A8\u9996\u4E2A\u63D0\u4EA4\uFF1Btoken \u6765\u81EA\u672C\u673A git \u7684\u8EAB\u4EFD\uFF0C\u6CA1\u6388\u6743\u5148\u62D2\uFF09\u3002\u6E05\u5355\u8FC7\u65F6\uFF08persona \u6539\u8FC7 / \u6CA1\u626B\u8FC7 / \u4E0A\u6B21\u626B\u5931\u8D25\uFF09\uFF1A\u5148\u628A persona \u76EE\u5F55\u63D0\u4EA4\u5230\u672C\u5730\uFF08\u4E0D\u63A8\uFF09\uFF0C\u8D77 persona-butler \u7684\u626B\u63CF\u4F1A\u8BDD\uFF0C\u56DE outcome=scanning\u2014\u2014\u7ED3\u679C\u5199\u8FDB .clawd/deploy.json\uFF08\u6E05\u5355\uFF0C\u8FDB\u4ED3\u5E93\uFF09\u4E0E .clawd/deploy-scan.json\uFF08\u8BC1\u636E\uFF0C\u4E0D\u8FDB\u4ED3\u5E93\uFF09\uFF0C\u6B63\u5728\u626B\u7684\u8BDD\u539F\u6837\u8FD4\u56DE\u4E0D\u8D77\u7B2C\u4E8C\u4E2A\u4F1A\u8BDD\u3002\u6E05\u5355\u65B0\u9C9C\uFF1A\u8FC7\u95F8\uFF08\u6BCF\u4E2A\u53D8\u91CF\u540D\u90FD\u5728 Secrets \u91CC\u3001\u8FDE\u63A5\u5668\u6765\u6E90\u70B9\u8FC7\u3001\u9009\u4E86\u6A21\u578B\uFF09\u2192 \u91CD\u5199 workflow \u6A21\u677F \u2192 git add -A \u2192 \u7A7A\u63D0\u4EA4\u4E5F\u5141\u8BB8 \u2192 push\uFF0C\u56DE outcome=pushed \u5E26 commit \u4E0E Actions \u5730\u5740\uFF1B\u4ED3\u5E93\u91CC\u7684\u6D41\u6C34\u7EBF\u63A5\u7740\u6784\u955C\u50CF\u3001\u8BD5\u8DD1\u3001\u767B\u8BB0\u3002owner-only",
9003
- args: DeployPersonaArgsSchema
9005
+ summary: "\u53D1\u5E03\u2014\u2014\u4E0A\u4E91\u552F\u4E00\u7684\u52A8\u4F5C\uFF0C\u626B\u63CF\u662F\u5B83\u7684\u7B2C\u4E00\u6BB5\u3002**\u6CA1\u4ED3\u5E93\u5148\u5EFA\u4ED3**\uFF08GitHub REST \u5EFA\u5728\u7EC4\u7EC7\u4E0B\u3001\u79C1\u6709\uFF0Cgit \u63A8\u9996\u4E2A\u63D0\u4EA4\uFF1Btoken \u6765\u81EA\u672C\u673A git \u7684\u8EAB\u4EFD\uFF0C\u6CA1\u6388\u6743\u5148\u62D2\uFF09\u3002\u6E05\u5355\u8FC7\u65F6\uFF08persona \u6539\u8FC7 / \u6CA1\u626B\u8FC7 / \u4E0A\u6B21\u626B\u5931\u8D25\uFF09\uFF1A\u5148\u628A persona \u76EE\u5F55\u63D0\u4EA4\u5230\u672C\u5730\uFF08\u4E0D\u63A8\uFF09\uFF0C\u8D77 persona-butler \u7684\u626B\u63CF\u4F1A\u8BDD\uFF0C\u56DE outcome=scanning\u2014\u2014\u7ED3\u679C\u5199\u8FDB .clawd/deploy.json\uFF08\u6E05\u5355\uFF0C\u8FDB\u4ED3\u5E93\uFF09\u4E0E .clawd/deploy-scan.json\uFF08\u8BC1\u636E\uFF0C\u4E0D\u8FDB\u4ED3\u5E93\uFF09\uFF0C\u6B63\u5728\u626B\u7684\u8BDD\u539F\u6837\u8FD4\u56DE\u4E0D\u8D77\u7B2C\u4E8C\u4E2A\u4F1A\u8BDD\u3002\u6E05\u5355\u65B0\u9C9C\uFF1A\u8FC7\u95F8\uFF08\u6BCF\u4E2A\u53D8\u91CF\u540D\u90FD\u5728 Secrets \u91CC\u3001\u8FDE\u63A5\u5668\u6765\u6E90\u70B9\u8FC7\u3001\u9009\u4E86\u6A21\u578B\uFF09\u2192 \u91CD\u5199 workflow \u6A21\u677F \u2192 git add -A \u2192 \u7A7A\u63D0\u4EA4\u4E5F\u5141\u8BB8 \u2192 push\uFF0C\u56DE outcome=pushed \u5E26 commit \u4E0E Actions \u5730\u5740\uFF1B\u4ED3\u5E93\u91CC\u7684\u6D41\u6C34\u7EBF\u63A5\u7740\u6784\u955C\u50CF\u3001\u8BD5\u8DD1\u3001\u767B\u8BB0\u3002\u5E26 scanBase\uFF08hard / soft\uFF09= \u8FD9\u6B21\u4E00\u5B9A\u5148\u626B\u3001\u6309\u8BE5\u6863\u4F4D\u626B\uFF08soft \u4E0D\u6210\u7ACB\u81EA\u52A8\u9000 hard\uFF09\uFF0C\u6E05\u5355\u65B0\u9C9C\u4E5F\u56DE scanning\uFF1Bowner-only",
9006
+ args: DeployReleaseArgsSchema
9004
9007
  },
9005
9008
  "deploy:rerunJob": {
9006
9009
  summary: "\u539F\u6837\u91CD\u8DD1\u6700\u65B0\u90A3\u6761\u6D41\u6C34\u7EBF\u91CC\u5931\u8D25\u7684\u67D0\u4E00\u6BB5\uFF08GitHub REST rerun job\uFF09\u3002**\u540C\u4E00\u4E2A commit\u3001\u540C\u4E00\u4EFD\u8F93\u5165**\uFF0C\u4E0D\u4EA7\u751F\u65B0\u63D0\u4EA4\u2014\u2014\u6539\u4E86 persona \u5185\u5BB9\u6216\u51ED\u636E\u8981\u8D70 deploy:release\u3002jobId \u5FC5\u987B\u5C5E\u4E8E\u6700\u65B0\u90A3\u6761 run\uFF1Bowner-only",
@@ -10033,8 +10036,8 @@ var require_req = __commonJS({
10033
10036
  if (req.originalUrl) {
10034
10037
  _req.url = req.originalUrl;
10035
10038
  } else {
10036
- const path102 = req.path;
10037
- _req.url = typeof path102 === "string" ? path102 : req.url ? req.url.path || req.url : void 0;
10039
+ const path100 = req.path;
10040
+ _req.url = typeof path100 === "string" ? path100 : req.url ? req.url.path || req.url : void 0;
10038
10041
  }
10039
10042
  if (req.query) {
10040
10043
  _req.query = req.query;
@@ -10199,14 +10202,14 @@ var require_redact = __commonJS({
10199
10202
  }
10200
10203
  return obj;
10201
10204
  }
10202
- function parsePath(path102) {
10205
+ function parsePath(path100) {
10203
10206
  const parts = [];
10204
10207
  let current = "";
10205
10208
  let inBrackets = false;
10206
10209
  let inQuotes = false;
10207
10210
  let quoteChar = "";
10208
- for (let i2 = 0; i2 < path102.length; i2++) {
10209
- const char = path102[i2];
10211
+ for (let i2 = 0; i2 < path100.length; i2++) {
10212
+ const char = path100[i2];
10210
10213
  if (!inBrackets && char === ".") {
10211
10214
  if (current) {
10212
10215
  parts.push(current);
@@ -10337,10 +10340,10 @@ var require_redact = __commonJS({
10337
10340
  return current;
10338
10341
  }
10339
10342
  function redactPaths(obj, paths, censor, remove = false) {
10340
- for (const path102 of paths) {
10341
- const parts = parsePath(path102);
10343
+ for (const path100 of paths) {
10344
+ const parts = parsePath(path100);
10342
10345
  if (parts.includes("*")) {
10343
- redactWildcardPath(obj, parts, censor, path102, remove);
10346
+ redactWildcardPath(obj, parts, censor, path100, remove);
10344
10347
  } else {
10345
10348
  if (remove) {
10346
10349
  removeKey(obj, parts);
@@ -10425,8 +10428,8 @@ var require_redact = __commonJS({
10425
10428
  }
10426
10429
  } else {
10427
10430
  if (afterWildcard.includes("*")) {
10428
- const wrappedCensor = typeof censor === "function" ? (value, path102) => {
10429
- const fullPath = [...pathArray.slice(0, pathLength), ...path102];
10431
+ const wrappedCensor = typeof censor === "function" ? (value, path100) => {
10432
+ const fullPath = [...pathArray.slice(0, pathLength), ...path100];
10430
10433
  return censor(value, fullPath);
10431
10434
  } : censor;
10432
10435
  redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
@@ -10461,8 +10464,8 @@ var require_redact = __commonJS({
10461
10464
  return null;
10462
10465
  }
10463
10466
  const pathStructure = /* @__PURE__ */ new Map();
10464
- for (const path102 of pathsToClone) {
10465
- const parts = parsePath(path102);
10467
+ for (const path100 of pathsToClone) {
10468
+ const parts = parsePath(path100);
10466
10469
  let current = pathStructure;
10467
10470
  for (let i2 = 0; i2 < parts.length; i2++) {
10468
10471
  const part = parts[i2];
@@ -10514,24 +10517,24 @@ var require_redact = __commonJS({
10514
10517
  }
10515
10518
  return cloneSelectively(obj, pathStructure);
10516
10519
  }
10517
- function validatePath(path102) {
10518
- if (typeof path102 !== "string") {
10520
+ function validatePath(path100) {
10521
+ if (typeof path100 !== "string") {
10519
10522
  throw new Error("Paths must be (non-empty) strings");
10520
10523
  }
10521
- if (path102 === "") {
10524
+ if (path100 === "") {
10522
10525
  throw new Error("Invalid redaction path ()");
10523
10526
  }
10524
- if (path102.includes("..")) {
10525
- throw new Error(`Invalid redaction path (${path102})`);
10527
+ if (path100.includes("..")) {
10528
+ throw new Error(`Invalid redaction path (${path100})`);
10526
10529
  }
10527
- if (path102.includes(",")) {
10528
- throw new Error(`Invalid redaction path (${path102})`);
10530
+ if (path100.includes(",")) {
10531
+ throw new Error(`Invalid redaction path (${path100})`);
10529
10532
  }
10530
10533
  let bracketCount = 0;
10531
10534
  let inQuotes = false;
10532
10535
  let quoteChar = "";
10533
- for (let i2 = 0; i2 < path102.length; i2++) {
10534
- const char = path102[i2];
10536
+ for (let i2 = 0; i2 < path100.length; i2++) {
10537
+ const char = path100[i2];
10535
10538
  if ((char === '"' || char === "'") && bracketCount > 0) {
10536
10539
  if (!inQuotes) {
10537
10540
  inQuotes = true;
@@ -10545,20 +10548,20 @@ var require_redact = __commonJS({
10545
10548
  } else if (char === "]" && !inQuotes) {
10546
10549
  bracketCount--;
10547
10550
  if (bracketCount < 0) {
10548
- throw new Error(`Invalid redaction path (${path102})`);
10551
+ throw new Error(`Invalid redaction path (${path100})`);
10549
10552
  }
10550
10553
  }
10551
10554
  }
10552
10555
  if (bracketCount !== 0) {
10553
- throw new Error(`Invalid redaction path (${path102})`);
10556
+ throw new Error(`Invalid redaction path (${path100})`);
10554
10557
  }
10555
10558
  }
10556
10559
  function validatePaths(paths) {
10557
10560
  if (!Array.isArray(paths)) {
10558
10561
  throw new TypeError("paths must be an array");
10559
10562
  }
10560
- for (const path102 of paths) {
10561
- validatePath(path102);
10563
+ for (const path100 of paths) {
10564
+ validatePath(path100);
10562
10565
  }
10563
10566
  }
10564
10567
  function slowRedact(options = {}) {
@@ -10726,8 +10729,8 @@ var require_redaction = __commonJS({
10726
10729
  if (shape[k3] === null) {
10727
10730
  o2[k3] = (value) => topCensor(value, [k3]);
10728
10731
  } else {
10729
- const wrappedCensor = typeof censor === "function" ? (value, path102) => {
10730
- return censor(value, [k3, ...path102]);
10732
+ const wrappedCensor = typeof censor === "function" ? (value, path100) => {
10733
+ return censor(value, [k3, ...path100]);
10731
10734
  } : censor;
10732
10735
  o2[k3] = Redact({
10733
10736
  paths: shape[k3],
@@ -10945,10 +10948,10 @@ var require_atomic_sleep = __commonJS({
10945
10948
  var require_sonic_boom = __commonJS({
10946
10949
  "../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
10947
10950
  "use strict";
10948
- var fs91 = require("fs");
10951
+ var fs90 = require("fs");
10949
10952
  var EventEmitter2 = require("events");
10950
10953
  var inherits = require("util").inherits;
10951
- var path102 = require("path");
10954
+ var path100 = require("path");
10952
10955
  var sleep2 = require_atomic_sleep();
10953
10956
  var assert = require("assert");
10954
10957
  var BUSY_WRITE_TIMEOUT = 100;
@@ -11002,20 +11005,20 @@ var require_sonic_boom = __commonJS({
11002
11005
  const mode = sonic.mode;
11003
11006
  if (sonic.sync) {
11004
11007
  try {
11005
- if (sonic.mkdir) fs91.mkdirSync(path102.dirname(file), { recursive: true });
11006
- const fd = fs91.openSync(file, flags, mode);
11008
+ if (sonic.mkdir) fs90.mkdirSync(path100.dirname(file), { recursive: true });
11009
+ const fd = fs90.openSync(file, flags, mode);
11007
11010
  fileOpened(null, fd);
11008
11011
  } catch (err) {
11009
11012
  fileOpened(err);
11010
11013
  throw err;
11011
11014
  }
11012
11015
  } else if (sonic.mkdir) {
11013
- fs91.mkdir(path102.dirname(file), { recursive: true }, (err) => {
11016
+ fs90.mkdir(path100.dirname(file), { recursive: true }, (err) => {
11014
11017
  if (err) return fileOpened(err);
11015
- fs91.open(file, flags, mode, fileOpened);
11018
+ fs90.open(file, flags, mode, fileOpened);
11016
11019
  });
11017
11020
  } else {
11018
- fs91.open(file, flags, mode, fileOpened);
11021
+ fs90.open(file, flags, mode, fileOpened);
11019
11022
  }
11020
11023
  }
11021
11024
  function SonicBoom(opts) {
@@ -11056,8 +11059,8 @@ var require_sonic_boom = __commonJS({
11056
11059
  this.flush = flushBuffer;
11057
11060
  this.flushSync = flushBufferSync;
11058
11061
  this._actualWrite = actualWriteBuffer;
11059
- fsWriteSync = () => fs91.writeSync(this.fd, this._writingBuf);
11060
- fsWrite = () => fs91.write(this.fd, this._writingBuf, this.release);
11062
+ fsWriteSync = () => fs90.writeSync(this.fd, this._writingBuf);
11063
+ fsWrite = () => fs90.write(this.fd, this._writingBuf, this.release);
11061
11064
  } else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
11062
11065
  this._writingBuf = "";
11063
11066
  this.write = write;
@@ -11066,15 +11069,15 @@ var require_sonic_boom = __commonJS({
11066
11069
  this._actualWrite = actualWrite;
11067
11070
  fsWriteSync = () => {
11068
11071
  if (Buffer.isBuffer(this._writingBuf)) {
11069
- return fs91.writeSync(this.fd, this._writingBuf);
11072
+ return fs90.writeSync(this.fd, this._writingBuf);
11070
11073
  }
11071
- return fs91.writeSync(this.fd, this._writingBuf, "utf8");
11074
+ return fs90.writeSync(this.fd, this._writingBuf, "utf8");
11072
11075
  };
11073
11076
  fsWrite = () => {
11074
11077
  if (Buffer.isBuffer(this._writingBuf)) {
11075
- return fs91.write(this.fd, this._writingBuf, this.release);
11078
+ return fs90.write(this.fd, this._writingBuf, this.release);
11076
11079
  }
11077
- return fs91.write(this.fd, this._writingBuf, "utf8", this.release);
11080
+ return fs90.write(this.fd, this._writingBuf, "utf8", this.release);
11078
11081
  };
11079
11082
  } else {
11080
11083
  throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
@@ -11131,7 +11134,7 @@ var require_sonic_boom = __commonJS({
11131
11134
  }
11132
11135
  }
11133
11136
  if (this._fsync) {
11134
- fs91.fsyncSync(this.fd);
11137
+ fs90.fsyncSync(this.fd);
11135
11138
  }
11136
11139
  const len = this._len;
11137
11140
  if (this._reopening) {
@@ -11245,7 +11248,7 @@ var require_sonic_boom = __commonJS({
11245
11248
  const onDrain = () => {
11246
11249
  if (!this._fsync) {
11247
11250
  try {
11248
- fs91.fsync(this.fd, (err) => {
11251
+ fs90.fsync(this.fd, (err) => {
11249
11252
  this._flushPending = false;
11250
11253
  cb(err);
11251
11254
  });
@@ -11347,7 +11350,7 @@ var require_sonic_boom = __commonJS({
11347
11350
  const fd = this.fd;
11348
11351
  this.once("ready", () => {
11349
11352
  if (fd !== this.fd) {
11350
- fs91.close(fd, (err) => {
11353
+ fs90.close(fd, (err) => {
11351
11354
  if (err) {
11352
11355
  return this.emit("error", err);
11353
11356
  }
@@ -11396,7 +11399,7 @@ var require_sonic_boom = __commonJS({
11396
11399
  buf = this._bufs[0];
11397
11400
  }
11398
11401
  try {
11399
- const n2 = Buffer.isBuffer(buf) ? fs91.writeSync(this.fd, buf) : fs91.writeSync(this.fd, buf, "utf8");
11402
+ const n2 = Buffer.isBuffer(buf) ? fs90.writeSync(this.fd, buf) : fs90.writeSync(this.fd, buf, "utf8");
11400
11403
  const releasedBufObj = releaseWritingBuf(buf, this._len, n2);
11401
11404
  buf = releasedBufObj.writingBuf;
11402
11405
  this._len = releasedBufObj.len;
@@ -11412,7 +11415,7 @@ var require_sonic_boom = __commonJS({
11412
11415
  }
11413
11416
  }
11414
11417
  try {
11415
- fs91.fsyncSync(this.fd);
11418
+ fs90.fsyncSync(this.fd);
11416
11419
  } catch {
11417
11420
  }
11418
11421
  }
@@ -11433,7 +11436,7 @@ var require_sonic_boom = __commonJS({
11433
11436
  buf = mergeBuf(this._bufs[0], this._lens[0]);
11434
11437
  }
11435
11438
  try {
11436
- const n2 = fs91.writeSync(this.fd, buf);
11439
+ const n2 = fs90.writeSync(this.fd, buf);
11437
11440
  buf = buf.subarray(n2);
11438
11441
  this._len = Math.max(this._len - n2, 0);
11439
11442
  if (buf.length <= 0) {
@@ -11461,13 +11464,13 @@ var require_sonic_boom = __commonJS({
11461
11464
  this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
11462
11465
  if (this.sync) {
11463
11466
  try {
11464
- const written = Buffer.isBuffer(this._writingBuf) ? fs91.writeSync(this.fd, this._writingBuf) : fs91.writeSync(this.fd, this._writingBuf, "utf8");
11467
+ const written = Buffer.isBuffer(this._writingBuf) ? fs90.writeSync(this.fd, this._writingBuf) : fs90.writeSync(this.fd, this._writingBuf, "utf8");
11465
11468
  release2(null, written);
11466
11469
  } catch (err) {
11467
11470
  release2(err);
11468
11471
  }
11469
11472
  } else {
11470
- fs91.write(this.fd, this._writingBuf, release2);
11473
+ fs90.write(this.fd, this._writingBuf, release2);
11471
11474
  }
11472
11475
  }
11473
11476
  function actualWriteBuffer() {
@@ -11476,7 +11479,7 @@ var require_sonic_boom = __commonJS({
11476
11479
  this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
11477
11480
  if (this.sync) {
11478
11481
  try {
11479
- const written = fs91.writeSync(this.fd, this._writingBuf);
11482
+ const written = fs90.writeSync(this.fd, this._writingBuf);
11480
11483
  release2(null, written);
11481
11484
  } catch (err) {
11482
11485
  release2(err);
@@ -11485,7 +11488,7 @@ var require_sonic_boom = __commonJS({
11485
11488
  if (kCopyBuffer) {
11486
11489
  this._writingBuf = Buffer.from(this._writingBuf);
11487
11490
  }
11488
- fs91.write(this.fd, this._writingBuf, release2);
11491
+ fs90.write(this.fd, this._writingBuf, release2);
11489
11492
  }
11490
11493
  }
11491
11494
  function actualClose(sonic) {
@@ -11501,12 +11504,12 @@ var require_sonic_boom = __commonJS({
11501
11504
  sonic._lens = [];
11502
11505
  assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
11503
11506
  try {
11504
- fs91.fsync(sonic.fd, closeWrapped);
11507
+ fs90.fsync(sonic.fd, closeWrapped);
11505
11508
  } catch {
11506
11509
  }
11507
11510
  function closeWrapped() {
11508
11511
  if (sonic.fd !== 1 && sonic.fd !== 2) {
11509
- fs91.close(sonic.fd, done);
11512
+ fs90.close(sonic.fd, done);
11510
11513
  } else {
11511
11514
  done();
11512
11515
  }
@@ -14641,11 +14644,11 @@ var init_lib = __esm({
14641
14644
  }
14642
14645
  }
14643
14646
  },
14644
- addToPath: function addToPath(path102, added, removed, oldPosInc, options) {
14645
- var last = path102.lastComponent;
14647
+ addToPath: function addToPath(path100, added, removed, oldPosInc, options) {
14648
+ var last = path100.lastComponent;
14646
14649
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
14647
14650
  return {
14648
- oldPos: path102.oldPos + oldPosInc,
14651
+ oldPos: path100.oldPos + oldPosInc,
14649
14652
  lastComponent: {
14650
14653
  count: last.count + 1,
14651
14654
  added,
@@ -14655,7 +14658,7 @@ var init_lib = __esm({
14655
14658
  };
14656
14659
  } else {
14657
14660
  return {
14658
- oldPos: path102.oldPos + oldPosInc,
14661
+ oldPos: path100.oldPos + oldPosInc,
14659
14662
  lastComponent: {
14660
14663
  count: 1,
14661
14664
  added,
@@ -15237,10 +15240,10 @@ function attachmentToHistoryMessage(o2, ts) {
15237
15240
  const memories = raw.map((m3) => {
15238
15241
  if (!m3 || typeof m3 !== "object") return null;
15239
15242
  const rec6 = m3;
15240
- const path102 = typeof rec6.path === "string" ? rec6.path : null;
15243
+ const path100 = typeof rec6.path === "string" ? rec6.path : null;
15241
15244
  const content = typeof rec6.content === "string" ? rec6.content : null;
15242
- if (!path102 || content == null) return null;
15243
- const entry = { path: path102, content };
15245
+ if (!path100 || content == null) return null;
15246
+ const entry = { path: path100, content };
15244
15247
  if (typeof rec6.mtimeMs === "number") entry.mtimeMs = rec6.mtimeMs;
15245
15248
  return entry;
15246
15249
  }).filter((m3) => m3 !== null);
@@ -16106,10 +16109,10 @@ function parseAttachment(obj) {
16106
16109
  const memories = raw.map((m3) => {
16107
16110
  if (!m3 || typeof m3 !== "object") return null;
16108
16111
  const rec6 = m3;
16109
- const path102 = typeof rec6.path === "string" ? rec6.path : null;
16112
+ const path100 = typeof rec6.path === "string" ? rec6.path : null;
16110
16113
  const content = typeof rec6.content === "string" ? rec6.content : null;
16111
- if (!path102 || content == null) return null;
16112
- const out = { path: path102, content };
16114
+ if (!path100 || content == null) return null;
16115
+ const out = { path: path100, content };
16113
16116
  if (typeof rec6.mtimeMs === "number") out.mtimeMs = rec6.mtimeMs;
16114
16117
  return out;
16115
16118
  }).filter((m3) => m3 !== null);
@@ -37083,8 +37086,8 @@ var require_utils = __commonJS({
37083
37086
  var result = transform[inputType][outputType](input);
37084
37087
  return result;
37085
37088
  };
37086
- exports2.resolve = function(path102) {
37087
- var parts = path102.split("/");
37089
+ exports2.resolve = function(path100) {
37090
+ var parts = path100.split("/");
37088
37091
  var result = [];
37089
37092
  for (var index = 0; index < parts.length; index++) {
37090
37093
  var part = parts[index];
@@ -42937,18 +42940,18 @@ var require_object = __commonJS({
42937
42940
  var object = new ZipObject(name, zipObjectContent, o2);
42938
42941
  this.files[name] = object;
42939
42942
  };
42940
- var parentFolder = function(path102) {
42941
- if (path102.slice(-1) === "/") {
42942
- path102 = path102.substring(0, path102.length - 1);
42943
+ var parentFolder = function(path100) {
42944
+ if (path100.slice(-1) === "/") {
42945
+ path100 = path100.substring(0, path100.length - 1);
42943
42946
  }
42944
- var lastSlash = path102.lastIndexOf("/");
42945
- return lastSlash > 0 ? path102.substring(0, lastSlash) : "";
42947
+ var lastSlash = path100.lastIndexOf("/");
42948
+ return lastSlash > 0 ? path100.substring(0, lastSlash) : "";
42946
42949
  };
42947
- var forceTrailingSlash = function(path102) {
42948
- if (path102.slice(-1) !== "/") {
42949
- path102 += "/";
42950
+ var forceTrailingSlash = function(path100) {
42951
+ if (path100.slice(-1) !== "/") {
42952
+ path100 += "/";
42950
42953
  }
42951
- return path102;
42954
+ return path100;
42952
42955
  };
42953
42956
  var folderAdd = function(name, createFolders) {
42954
42957
  createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
@@ -43950,7 +43953,7 @@ var require_lib3 = __commonJS({
43950
43953
  // src/run-case/recorder.ts
43951
43954
  function startRunCaseRecorder(opts) {
43952
43955
  const now = opts.now ?? Date.now;
43953
- const dir = import_node_path81.default.dirname(opts.recordPath);
43956
+ const dir = import_node_path79.default.dirname(opts.recordPath);
43954
43957
  let stream = null;
43955
43958
  let closing = false;
43956
43959
  let closedSettled = false;
@@ -43964,8 +43967,8 @@ function startRunCaseRecorder(opts) {
43964
43967
  });
43965
43968
  const ensureStream = () => {
43966
43969
  if (stream) return stream;
43967
- import_node_fs62.default.mkdirSync(dir, { recursive: true });
43968
- stream = import_node_fs62.default.createWriteStream(opts.recordPath, { flags: "a" });
43970
+ import_node_fs61.default.mkdirSync(dir, { recursive: true });
43971
+ stream = import_node_fs61.default.createWriteStream(opts.recordPath, { flags: "a" });
43969
43972
  stream.on("close", () => closedResolve());
43970
43973
  return stream;
43971
43974
  };
@@ -43990,12 +43993,12 @@ function startRunCaseRecorder(opts) {
43990
43993
  };
43991
43994
  return { tap, close, closed };
43992
43995
  }
43993
- var import_node_fs62, import_node_path81;
43996
+ var import_node_fs61, import_node_path79;
43994
43997
  var init_recorder = __esm({
43995
43998
  "src/run-case/recorder.ts"() {
43996
43999
  "use strict";
43997
- import_node_fs62 = __toESM(require("fs"), 1);
43998
- import_node_path81 = __toESM(require("path"), 1);
44000
+ import_node_fs61 = __toESM(require("fs"), 1);
44001
+ import_node_path79 = __toESM(require("path"), 1);
43999
44002
  }
44000
44003
  });
44001
44004
 
@@ -44038,7 +44041,7 @@ var init_wire = __esm({
44038
44041
  // src/run-case/controller.ts
44039
44042
  async function runController(opts) {
44040
44043
  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-"));
44044
+ const cwd = opts.cwd ?? (0, import_node_fs62.mkdtempSync)(import_node_path80.default.join(import_node_os29.default.tmpdir(), "clawd-runcase-"));
44042
44045
  const ownsCwd = opts.cwd === void 0;
44043
44046
  const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
44044
44047
  const spawnCtx = { cwd };
@@ -44199,19 +44202,19 @@ async function runController(opts) {
44199
44202
  if (sigintHandler) process.off("SIGINT", sigintHandler);
44200
44203
  if (ownsCwd) {
44201
44204
  try {
44202
- (0, import_node_fs63.rmSync)(cwd, { recursive: true, force: true });
44205
+ (0, import_node_fs62.rmSync)(cwd, { recursive: true, force: true });
44203
44206
  } catch {
44204
44207
  }
44205
44208
  }
44206
44209
  return exitCode ?? 0;
44207
44210
  }
44208
- var import_node_fs63, import_node_os29, import_node_path82;
44211
+ var import_node_fs62, import_node_os29, import_node_path80;
44209
44212
  var init_controller = __esm({
44210
44213
  "src/run-case/controller.ts"() {
44211
44214
  "use strict";
44212
- import_node_fs63 = require("fs");
44215
+ import_node_fs62 = require("fs");
44213
44216
  import_node_os29 = __toESM(require("os"), 1);
44214
- import_node_path82 = __toESM(require("path"), 1);
44217
+ import_node_path80 = __toESM(require("path"), 1);
44215
44218
  init_claude();
44216
44219
  init_stdout_splitter();
44217
44220
  init_permission_stdio();
@@ -44483,8 +44486,8 @@ Env (advanced):
44483
44486
  `;
44484
44487
 
44485
44488
  // src/index.ts
44486
- var import_node_path80 = __toESM(require("path"), 1);
44487
- var import_node_fs61 = __toESM(require("fs"), 1);
44489
+ var import_node_path78 = __toESM(require("path"), 1);
44490
+ var import_node_fs60 = __toESM(require("fs"), 1);
44488
44491
  var import_node_os28 = __toESM(require("os"), 1);
44489
44492
  var import_node_crypto22 = require("crypto");
44490
44493
  var import_node_url5 = require("url");
@@ -45796,10 +45799,9 @@ function buildSpawnContext(state, deps) {
45796
45799
  const personaId2 = file.ownerPersonaId;
45797
45800
  if (personaId2) env.CLAWD_PERSONA_ID = personaId2;
45798
45801
  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
- );
45802
+ if (personaId2) env.CLAWD_PERSONA_DIR = file.cwd;
45803
+ if (personaId2 && userWorkDir) env.CLAWD_WORK_DIR = userWorkDir;
45804
+ const mcpConfigs = deps.getMcpConfigs?.() ?? [];
45803
45805
  const ctx = {
45804
45806
  cwd: file.cwd,
45805
45807
  toolSessionId: file.toolSessionId,
@@ -46642,9 +46644,13 @@ var import_node_fs7 = __toESM(require("fs"), 1);
46642
46644
  var import_node_path6 = __toESM(require("path"), 1);
46643
46645
  var PLACEHOLDER = /\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g;
46644
46646
  var PERSONA_SECRET_MCP_ID_PREFIX = "persona-secrets:";
46647
+ var PERSONA_DIR_PLACEHOLDER = "${CLAWD_PERSONA_DIR}";
46645
46648
  function hasPlaceholder(v3) {
46646
46649
  return typeof v3 === "string" && new RegExp(PLACEHOLDER).test(v3);
46647
46650
  }
46651
+ function renderPersonaDir(v3, personaDir) {
46652
+ return v3.split(PERSONA_DIR_PLACEHOLDER).join(personaDir);
46653
+ }
46648
46654
  function renderPersonaMcpSecrets(args) {
46649
46655
  const src = import_node_path6.default.join(args.personaDir, ".mcp.json");
46650
46656
  let parsed;
@@ -46664,13 +46670,17 @@ function renderPersonaMcpSecrets(args) {
46664
46670
  for (const [name, raw] of Object.entries(servers)) {
46665
46671
  const def = raw ?? {};
46666
46672
  const env = def.env && typeof def.env === "object" ? def.env : void 0;
46667
- if (Array.isArray(def.args) && def.args.some(hasPlaceholder)) {
46673
+ const command = typeof def.command === "string" ? renderPersonaDir(def.command, args.personaDir) : void 0;
46674
+ const rawArgs = Array.isArray(def.args) ? def.args : void 0;
46675
+ const argv = rawArgs?.map((a2) => typeof a2 === "string" ? renderPersonaDir(a2, args.personaDir) : a2);
46676
+ const argvHas = command !== void 0 && command !== def.command || argv !== void 0 && argv.some((a2, i2) => a2 !== rawArgs[i2]);
46677
+ if (argv?.some(hasPlaceholder)) {
46668
46678
  args.logger?.warn("persona.mcp-secret.placeholder-in-args", { persona: args.personaId, server: name });
46669
46679
  }
46670
46680
  const headers = def.headers && typeof def.headers === "object" ? def.headers : void 0;
46671
46681
  const envHas = !!env && Object.values(env).some(hasPlaceholder);
46672
46682
  const headersHas = !!headers && Object.values(headers).some(hasPlaceholder);
46673
- if (!envHas && !headersHas) continue;
46683
+ if (!envHas && !headersHas && !argvHas) continue;
46674
46684
  const renderTable = (table) => {
46675
46685
  const out = {};
46676
46686
  for (const [k3, v3] of Object.entries(table)) {
@@ -46683,7 +46693,13 @@ function renderPersonaMcpSecrets(args) {
46683
46693
  }
46684
46694
  return out;
46685
46695
  };
46686
- rendered[name] = { ...def, ...envHas ? { env: renderTable(env) } : {}, ...headersHas ? { headers: renderTable(headers) } : {} };
46696
+ rendered[name] = {
46697
+ ...def,
46698
+ ...command !== void 0 ? { command } : {},
46699
+ ...argv !== void 0 ? { args: argv } : {},
46700
+ ...envHas ? { env: renderTable(env) } : {},
46701
+ ...headersHas ? { headers: renderTable(headers) } : {}
46702
+ };
46687
46703
  }
46688
46704
  if (Object.keys(rendered).length === 0) return void 0;
46689
46705
  if (missing.size > 0) {
@@ -46695,7 +46711,7 @@ function renderPersonaMcpSecrets(args) {
46695
46711
  const outPath = import_node_path6.default.join(args.outDir, `${safeFileName(args.personaId)}.mcp.json`);
46696
46712
  import_node_fs7.default.mkdirSync(args.outDir, { recursive: true, mode: 448 });
46697
46713
  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",
46714
+ _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
46715
  mcpServers: rendered
46700
46716
  };
46701
46717
  const tmp = `${outPath}.tmp-${process.pid}-${Date.now()}`;
@@ -46703,8 +46719,7 @@ function renderPersonaMcpSecrets(args) {
46703
46719
  import_node_fs7.default.renameSync(tmp, outPath);
46704
46720
  return {
46705
46721
  id: `${PERSONA_SECRET_MCP_ID_PREFIX}${args.personaId}`,
46706
- path: outPath,
46707
- personas: [args.personaId]
46722
+ path: outPath
46708
46723
  };
46709
46724
  }
46710
46725
  function attachPersonaSecretMcp(ctx, resolve9) {
@@ -49814,7 +49829,7 @@ var PersonaStore = class {
49814
49829
  *
49815
49830
  * 位置不是随手挑的,两条既有约定叠出来的:`.clawd/` 是 daemon 声明「不动」的 persona 私有区
49816
49831
  * (不在 seed.ts 的 DAEMON_MANAGED_PATHS 里),`.local` 是仓内已成立的「本机个人 override
49817
- * 永不被 OTA 覆盖」后缀(见 seed.refreshDeployKit)。于是内置 persona 的 CLAUDE.md 继续被
49832
+ * 永不被 OTA 覆盖」后缀。于是内置 persona 的 CLAUDE.md 继续被
49818
49833
  * refresh 覆盖成 bundle 新版、用户写的这层原样活着。
49819
49834
  *
49820
49835
  * 同 sandbox-settings.json 的理由:放 `.clawd/` 而非 persona 根目录,让 CC 的 project
@@ -50229,12 +50244,12 @@ var DEFAULT_PERSONAS = [
50229
50244
  // 与 app-builder 对齐"调用阿里云的工作方式"(owner 2026-06-17 要求):开发型 profile —— 放开文件/web
50230
50245
  // 工具 + node/pnpm 工具链精确路径 + 出站 TLD 通配白名单。html-slides 需要联网(git clone frontend-slides
50231
50246
  // 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 是老机器上的遗留文件)。
50247
+ // 阿里云凭证:**凭据表单源**($HOME/.clawd/secrets/aliyun.env,使用者自己写;bundle 不 ship AK,见
50248
+ // specs/2026-09-18-aliyun-ak-leak-rotate-design.md;deploy-kit 下那份 .secrets/ 已随 design 2026-09-19-persona-mcp-single-source 删),
50249
+ // 不在 persona 目录另存一份。app-builder 的 FC 部署由 clawd-app-builder MCP server 起(沙箱外、AK 在它 env 里)故其 profile
50250
+ // 无需 carve 这个路径;html-slides 没有 daemon 侧流程、要在 cc 沙箱内直接 `set -a; . $HOME/.clawd/secrets/aliyun.env; set +a`
50251
+ // 后调 aliyun CLI(env 凭证绕过沙箱外的 ~/.aliyun/),所以这里**额外**把这个凭证文件加进 allowRead
50252
+ // (denyRead '~/' 之上的精确凿洞,单文件、最小暴露,同 ~/.npmrc 先例)。
50238
50253
  // excludedCommands: ['aliyun *'] —— 额外把 aliyun CLI 放沙箱外跑(逃出 seatbelt 直接用宿主凭证/网络),
50239
50254
  // 与上面沙箱内 env 凭证方案并存,按运行时实际命令前缀匹配生效。
50240
50255
  sandboxProfile: {
@@ -50244,7 +50259,7 @@ var DEFAULT_PERSONAS = [
50244
50259
  },
50245
50260
  sandbox: {
50246
50261
  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"],
50262
+ allowRead: ["~/.npmrc", "~/Library/Preferences/pnpm", "~/.nvm", "~/Library/pnpm", "~/.local/share/pnpm", "~/.local/state/pnpm", "~/.npm", "~/.pnpm-store", "~/.clawd/secrets/aliyun.env"],
50248
50263
  allowWrite: ["~/Library/pnpm", "~/.local/share/pnpm", "~/.local/state/pnpm", "~/.npm", "~/.pnpm-store"]
50249
50264
  },
50250
50265
  network: {
@@ -50373,7 +50388,7 @@ function copyBundleExtras(srcDir, dstDir) {
50373
50388
  }
50374
50389
  }
50375
50390
  }
50376
- var DAEMON_MANAGED_PATHS = ["extension-kit", "CLAUDE.md", ".mcp.json", ".claude/skills", ".claude/agents"];
50391
+ var DAEMON_MANAGED_PATHS = ["extension-kit", "CLAUDE.md", ".mcp.json", ".claude/skills", ".claude/agents", "mcp"];
50377
50392
  function replaceManagedPath(src, dst) {
50378
50393
  if (!fs13.statSync(src).isDirectory()) {
50379
50394
  fs13.mkdirSync(path16.dirname(dst), { recursive: true });
@@ -50613,59 +50628,6 @@ function retirePersonaBuilder(args) {
50613
50628
  });
50614
50629
  }
50615
50630
  }
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
50631
 
50670
50632
  // src/skills/scanner.ts
50671
50633
  var import_node_fs10 = __toESM(require("fs"), 1);
@@ -51834,8 +51796,8 @@ function turnStartInput(text, resolveImage) {
51834
51796
  const items = [];
51835
51797
  let leftover = text;
51836
51798
  for (const m3 of text.matchAll(SKILL_RE)) {
51837
- const [marker, name, path102] = m3;
51838
- items.push({ type: "skill", name, path: path102 });
51799
+ const [marker, name, path100] = m3;
51800
+ items.push({ type: "skill", name, path: path100 });
51839
51801
  leftover = leftover.replace(marker, "");
51840
51802
  }
51841
51803
  for (const m3 of text.matchAll(ATTACHMENT_RE2)) {
@@ -54741,44 +54703,6 @@ function readDir(dir, logger) {
54741
54703
  }
54742
54704
  return out;
54743
54705
  }
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
54706
  function upsertEnvFileVar(file, key, value) {
54783
54707
  if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) throw new Error(`invalid env name: ${key}`);
54784
54708
  import_node_fs28.default.mkdirSync(import_node_path29.default.dirname(file), { recursive: true, mode: 448 });
@@ -55426,6 +55350,8 @@ function sanitizeForQuote(def) {
55426
55350
  var stringRecord = (v3) => v3 && typeof v3 === "object" ? Object.fromEntries(Object.entries(v3).filter((kv) => typeof kv[1] === "string")) : {};
55427
55351
  var HTTP_TYPES2 = /* @__PURE__ */ new Set(["http", "sse", "streamable_http", "streamable-http"]);
55428
55352
  var PACKAGE_RUNNERS = /* @__PURE__ */ new Set(["npx", "uvx", "pnpx", "bunx"]);
55353
+ var SCRIPT_RUNNERS = /* @__PURE__ */ new Set(["node", "bun", "deno", "python", "python3"]);
55354
+ var HOST_ARG_PLACEHOLDER = "CLAWD_PERSONA_DIR";
55429
55355
  function scanMcpConnectors(personaDir) {
55430
55356
  const file = import_node_path32.default.join(personaDir, ".mcp.json");
55431
55357
  const out = { readable: true, connectors: [], evidence: [], warnings: [] };
@@ -55477,10 +55403,10 @@ function scanMcpConnectors(personaDir) {
55477
55403
  continue;
55478
55404
  }
55479
55405
  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;
55406
+ const target = PACKAGE_RUNNERS.has(command) || SCRIPT_RUNNERS.has(command) ? args.find((a2) => !a2.startsWith("-")) : void 0;
55407
+ const id = target ?? command;
55482
55408
  const fields = fieldsOf(name, "env", Object.values(stringRecord(def.env)).flatMap(placeholdersIn), out.warnings);
55483
- if (args.some((a2) => placeholdersIn(a2).length > 0)) {
55409
+ if (args.some((a2) => placeholdersIn(a2).some((p3) => p3 !== HOST_ARG_PLACEHOLDER))) {
55484
55410
  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
55411
  }
55486
55412
  out.connectors.push({ name, kind: "env", runner: "mcp", id, fields });
@@ -59079,10 +59005,10 @@ function createGithubApi(args) {
59079
59005
  const doFetch = args.fetch ?? fetch;
59080
59006
  const seal = args.seal ?? sealWithSodium;
59081
59007
  const timeoutMs = args.timeoutMs ?? TIMEOUT_MS;
59082
- async function request(method, path102, body) {
59008
+ async function request(method, path100, body) {
59083
59009
  let res;
59084
59010
  try {
59085
- res = await doFetch(`${API}${path102}`, {
59011
+ res = await doFetch(`${API}${path100}`, {
59086
59012
  method,
59087
59013
  headers: {
59088
59014
  Authorization: `Bearer ${args.token}`,
@@ -59107,8 +59033,8 @@ function createGithubApi(args) {
59107
59033
  }
59108
59034
  return { status: res.status, json };
59109
59035
  }
59110
- async function must(method, path102, what, body) {
59111
- const r2 = await request(method, path102, body);
59036
+ async function must(method, path100, what, body) {
59037
+ const r2 = await request(method, path100, body);
59112
59038
  if (r2.status < 200 || r2.status >= 300) throw new GithubApiError(r2.status, explain(r2.status, what, r2.json));
59113
59039
  return r2.json;
59114
59040
  }
@@ -59148,9 +59074,9 @@ function createGithubApi(args) {
59148
59074
  return { env: x2.name, ...Number.isFinite(at3) ? { setAt: at3 } : {} };
59149
59075
  });
59150
59076
  },
59151
- async getJson(path102) {
59077
+ async getJson(path100) {
59152
59078
  try {
59153
- const r2 = await request("GET", path102);
59079
+ const r2 = await request("GET", path100);
59154
59080
  return r2.status >= 200 && r2.status < 300 ? r2.json : void 0;
59155
59081
  } catch {
59156
59082
  return void 0;
@@ -59231,7 +59157,8 @@ var GITIGNORE_LINES = [
59231
59157
  ".attachments/",
59232
59158
  ".clawd/sessions/",
59233
59159
  ".clawd/deploy-scan.json",
59234
- "node_modules/"
59160
+ "node_modules/",
59161
+ ".s-home/"
59235
59162
  ];
59236
59163
  function mergeGitignore(existing) {
59237
59164
  const lines = (existing ?? "").split("\n");
@@ -59669,6 +59596,7 @@ async function release(exec, api, args) {
59669
59596
 
59670
59597
  // src/deploy/scan-base.ts
59671
59598
  function pickScanBase(args) {
59599
+ if (args.want === "hard") return { kind: "hard" };
59672
59600
  if (!args.hasUsableManifest || !args.releasedHead) return { kind: "hard" };
59673
59601
  return { kind: "soft", base: args.releasedHead };
59674
59602
  }
@@ -59741,19 +59669,8 @@ async function rerunJob(api, slug, jobId) {
59741
59669
  }
59742
59670
 
59743
59671
  // src/deploy/scan-task.ts
59744
- var import_node_path35 = __toESM(require("path"), 1);
59745
59672
  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
- ];
59673
+ var SCANNABLE_ASSETS = [];
59757
59674
  function staleScannerAssets(scan, known = SCANNABLE_ASSETS) {
59758
59675
  const knew = new Set(scan.scannedAssets ?? []);
59759
59676
  return known.filter((a2) => !knew.has(a2.name));
@@ -59813,6 +59730,7 @@ function mustBeScanning(scan, method) {
59813
59730
  return scan;
59814
59731
  }
59815
59732
  function buildDeployHandlers(deps) {
59733
+ const scannableAssets = deps.scannableAssets ?? SCANNABLE_ASSETS;
59816
59734
  const cacheMs = deps.secretsCacheMs ?? SECRETS_CACHE_MS;
59817
59735
  const secretsCache = /* @__PURE__ */ new Map();
59818
59736
  const runCache = /* @__PURE__ */ new Map();
@@ -59850,7 +59768,7 @@ function buildDeployHandlers(deps) {
59850
59768
  }
59851
59769
  let scan = await readScan(dir);
59852
59770
  if (scan && scan.status === "done") {
59853
- const stale = describeStaleAssets(staleScannerAssets(scan));
59771
+ const stale = describeStaleAssets(staleScannerAssets(scan, scannableAssets));
59854
59772
  const kept = scan.notes.filter((n2) => !n2.startsWith(STALE_ASSETS_NOTE_PREFIX));
59855
59773
  scan = { ...scan, notes: stale ? [...kept, stale] : kept };
59856
59774
  }
@@ -59884,13 +59802,14 @@ function buildDeployHandlers(deps) {
59884
59802
  const view = async (personaId2) => ({
59885
59803
  response: { type: "deploy:state", ...await stateOf(personaId2) }
59886
59804
  });
59887
- async function beginScan(personaId2, dir, current, head) {
59805
+ async function beginScan(personaId2, dir, current, head, want) {
59888
59806
  const prevManifest = await readDeployFile(dir).catch(() => void 0);
59889
59807
  const scanBase = pickScanBase({
59890
59808
  // **文件在 ≠ 清单能用**:硬扫一开头就写了一份空清单,那一轮没跑完(OTA 重启 / butler 崩,
59891
59809
  // 见 scan-task.ts 的收尾判定)的话文件在、内容是空的。所以判据连上「上一轮扫完了」。
59892
59810
  hasUsableManifest: prevManifest !== void 0 && current?.status === "done",
59893
- releasedHead: await hasCommit(deps.exec, dir, current?.releasedHead) ? current?.releasedHead : void 0
59811
+ releasedHead: await hasCommit(deps.exec, dir, current?.releasedHead) ? current?.releasedHead : void 0,
59812
+ ...want ? { want } : {}
59894
59813
  });
59895
59814
  const startedAt = deps.now();
59896
59815
  const base = {
@@ -60013,14 +59932,14 @@ function buildDeployHandlers(deps) {
60013
59932
  notes: [...scan.notes.filter((n2) => n2.startsWith(MCP_SCAN_NOTE_PREFIX)), ...args.notes.map(redactSecretValues)],
60014
59933
  // 记下这次扫描**被告知有哪些共享资产**。以后资产表长出新条目时,只有扫的时候还不知道
60015
59934
  // 它的那些记录会被提示一次(见 staleScannerAssets)
60016
- scannedAssets: SCANNABLE_ASSETS.map((a2) => a2.name),
59935
+ scannedAssets: scannableAssets.map((a2) => a2.name),
60017
59936
  error: void 0
60018
59937
  });
60019
59938
  return view(args.personaId);
60020
59939
  };
60021
59940
  const releaseHandler = async (frame, _client, ctx) => {
60022
59941
  ensureOwner(ctx);
60023
- const { personaId: personaId2 } = parseArgs2(DeployPersonaArgsSchema, frame, "deploy:release");
59942
+ const { personaId: personaId2, scanBase } = parseArgs2(DeployReleaseArgsSchema, frame, "deploy:release");
60024
59943
  const dir = mustPersona(personaId2);
60025
59944
  const wrong = wrongEngine(deps.personaEngine(personaId2)?.tool);
60026
59945
  if (wrong) throw invalid(wrong);
@@ -60040,7 +59959,7 @@ function buildDeployHandlers(deps) {
60040
59959
  const current = await readScan(dir);
60041
59960
  if (current?.status === "scanning") return { response: { type: "deploy:release", outcome: "scanning" } };
60042
59961
  const fileUsable = await readDeployFile(dir).then((f2) => f2 !== void 0).catch(() => false);
60043
- if (!fileUsable || !isScanFresh(current, repo2)) {
59962
+ if (scanBase !== void 0 || !fileUsable || !isScanFresh(current, repo2)) {
60044
59963
  let head;
60045
59964
  try {
60046
59965
  head = await commitAll(deps.exec, { dir, message: `clawd: \u626B\u63CF\u524D\u843D\u5B58 ${new Date(deps.now()).toISOString()}` });
@@ -60048,7 +59967,7 @@ function buildDeployHandlers(deps) {
60048
59967
  throw toClawdError(err);
60049
59968
  }
60050
59969
  runCache.delete(personaId2);
60051
- await beginScan(personaId2, dir, current, head);
59970
+ await beginScan(personaId2, dir, current, head, scanBase);
60052
59971
  return { response: { type: "deploy:release", outcome: "scanning" } };
60053
59972
  }
60054
59973
  const file = await readDeployFile(dir);
@@ -60643,9 +60562,9 @@ async function refreshTunnelUrlOnStartup(deps) {
60643
60562
 
60644
60563
  // src/lark-bot-connector/binding-store.ts
60645
60564
  var import_node_fs30 = __toESM(require("fs"), 1);
60646
- var import_node_path36 = __toESM(require("path"), 1);
60565
+ var import_node_path35 = __toESM(require("path"), 1);
60647
60566
  function createLarkBotBindingStore(personaRoot) {
60648
- const filePath = (personaId2) => import_node_path36.default.join(personaRoot, safeFileName(personaId2), ".clawd", "lark-bot.json");
60567
+ const filePath = (personaId2) => import_node_path35.default.join(personaRoot, safeFileName(personaId2), ".clawd", "lark-bot.json");
60649
60568
  const read = (personaId2) => {
60650
60569
  const file = filePath(personaId2);
60651
60570
  if (!import_node_fs30.default.existsSync(file)) return null;
@@ -60659,7 +60578,7 @@ function createLarkBotBindingStore(personaRoot) {
60659
60578
  };
60660
60579
  const write = (personaId2, meta) => {
60661
60580
  const file = filePath(personaId2);
60662
- import_node_fs30.default.mkdirSync(import_node_path36.default.dirname(file), { recursive: true });
60581
+ import_node_fs30.default.mkdirSync(import_node_path35.default.dirname(file), { recursive: true });
60663
60582
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
60664
60583
  import_node_fs30.default.writeFileSync(tmp, JSON.stringify(meta, null, 2), { mode: 384 });
60665
60584
  import_node_fs30.default.renameSync(tmp, file);
@@ -60821,7 +60740,7 @@ function createLarkBotCloudClient(opts) {
60821
60740
 
60822
60741
  // src/lark-bot-connector/chat-router.ts
60823
60742
  var import_node_fs31 = __toESM(require("fs"), 1);
60824
- var import_node_path37 = __toESM(require("path"), 1);
60743
+ var import_node_path36 = __toESM(require("path"), 1);
60825
60744
  init_protocol();
60826
60745
  var ERROR_REPLY_TEXT = "\u5904\u7406\u51FA\u9519\u4E86\uFF0C\u8BF7\u91CD\u8BD5";
60827
60746
  var LOCAL_TURN_RETRIES = 2;
@@ -60900,7 +60819,7 @@ function createLarkChatRouter(deps) {
60900
60819
  }
60901
60820
  const dir = deps.mediaRootFor(env.chatId);
60902
60821
  import_node_fs31.default.mkdirSync(dir, { recursive: true });
60903
- const p3 = import_node_path37.default.join(dir, `${safeMediaName(ownerMessageId)}-${i2}.${ext}`);
60822
+ const p3 = import_node_path36.default.join(dir, `${safeMediaName(ownerMessageId)}-${i2}.${ext}`);
60904
60823
  import_node_fs31.default.writeFileSync(p3, r2.data);
60905
60824
  lines.push(`[\u56FE\u7247: ${p3}]\uFF08\u7528 Read \u5DE5\u5177\u67E5\u770B\uFF09`);
60906
60825
  } catch (err) {
@@ -60923,7 +60842,7 @@ function createLarkChatRouter(deps) {
60923
60842
  }
60924
60843
  const dir = deps.mediaRootFor(env.chatId);
60925
60844
  import_node_fs31.default.mkdirSync(dir, { recursive: true });
60926
- const p3 = import_node_path37.default.join(dir, `${safeMediaName(ownerMessageId)}-${i2}-${safeAttachmentName(f2.name)}`);
60845
+ const p3 = import_node_path36.default.join(dir, `${safeMediaName(ownerMessageId)}-${i2}-${safeAttachmentName(f2.name)}`);
60927
60846
  import_node_fs31.default.writeFileSync(p3, r2.data);
60928
60847
  lines.push(`[\u6587\u4EF6: ${p3}]\uFF08\u7528 Read \u5DE5\u5177\u67E5\u770B\uFF09`);
60929
60848
  } catch (err) {
@@ -61749,11 +61668,11 @@ async function forwardPeerExecToPeer(args) {
61749
61668
 
61750
61669
  // src/tools/codex-history.ts
61751
61670
  var import_node_fs33 = __toESM(require("fs"), 1);
61752
- var import_node_path39 = __toESM(require("path"), 1);
61671
+ var import_node_path38 = __toESM(require("path"), 1);
61753
61672
 
61754
61673
  // src/tools/transcript-search.ts
61755
61674
  var import_node_fs32 = __toESM(require("fs"), 1);
61756
- var import_node_path38 = __toESM(require("path"), 1);
61675
+ var import_node_path37 = __toESM(require("path"), 1);
61757
61676
  var SNIPPET_PAD = 60;
61758
61677
  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
61678
  var CODEX_WRAPPER_RE = /<(related-dir|environment_context|user_instructions)>[\s\S]*?<\/\1>/g;
@@ -61846,7 +61765,7 @@ function createCodexRolloutLocator(roots) {
61846
61765
  return;
61847
61766
  }
61848
61767
  for (const entry of entries) {
61849
- const full = import_node_path38.default.join(dir, entry.name);
61768
+ const full = import_node_path37.default.join(dir, entry.name);
61850
61769
  if (entry.isDirectory()) {
61851
61770
  walk2(full, into);
61852
61771
  continue;
@@ -62126,7 +62045,7 @@ function readThreadNames(sharedHome) {
62126
62045
  if (!sharedHome) return names;
62127
62046
  let raw;
62128
62047
  try {
62129
- raw = import_node_fs33.default.readFileSync(import_node_path39.default.join(sharedHome, "session_index.jsonl"), "utf8");
62048
+ raw = import_node_fs33.default.readFileSync(import_node_path38.default.join(sharedHome, "session_index.jsonl"), "utf8");
62130
62049
  } catch {
62131
62050
  return names;
62132
62051
  }
@@ -62151,7 +62070,7 @@ function walkRollouts(dir, visit) {
62151
62070
  }
62152
62071
  entries.sort((a2, b3) => a2.name < b3.name ? 1 : a2.name > b3.name ? -1 : 0);
62153
62072
  for (const entry of entries) {
62154
- const full = import_node_path39.default.join(dir, entry.name);
62073
+ const full = import_node_path38.default.join(dir, entry.name);
62155
62074
  if (entry.isDirectory()) {
62156
62075
  if (!walkRollouts(full, visit)) return false;
62157
62076
  } else if (ROLLOUT_NAME_RE.test(entry.name)) {
@@ -62219,7 +62138,7 @@ var CodexHistoryReader = class {
62219
62138
  return [];
62220
62139
  }
62221
62140
  async listSessions(args) {
62222
- const want = import_node_path39.default.resolve(args.projectPath);
62141
+ const want = import_node_path38.default.resolve(args.projectPath);
62223
62142
  const names = readThreadNames(this.deps.sharedHome);
62224
62143
  const found = [];
62225
62144
  let scanned = 0;
@@ -62228,7 +62147,7 @@ var CodexHistoryReader = class {
62228
62147
  if (++scanned > CODEX_LIST_SESSIONS_SCAN_CAP) return false;
62229
62148
  const head = readHead(file, PEEK_BYTES);
62230
62149
  const cwd = head === null ? null : peekSessionCwd(head);
62231
- if (!cwd || import_node_path39.default.resolve(cwd) !== want) return;
62150
+ if (!cwd || import_node_path38.default.resolve(cwd) !== want) return;
62232
62151
  const first = readFirstLine(file);
62233
62152
  const meta = first === null ? null : parseCodexRolloutMeta(first);
62234
62153
  if (!meta) return;
@@ -62312,9 +62231,9 @@ var CentralClientError = class extends Error {
62312
62231
  code;
62313
62232
  cause;
62314
62233
  };
62315
- async function centralRequest(opts, path102, init) {
62234
+ async function centralRequest(opts, path100, init) {
62316
62235
  const f2 = opts.fetchImpl ?? globalThis.fetch;
62317
- const url = `${opts.api.replace(/\/+$/, "")}${path102}`;
62236
+ const url = `${opts.api.replace(/\/+$/, "")}${path100}`;
62318
62237
  const ctrl = new AbortController();
62319
62238
  const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
62320
62239
  let res;
@@ -63148,7 +63067,7 @@ var PiRpcClient = class {
63148
63067
  var import_node_child_process10 = require("child_process");
63149
63068
  var import_node_crypto9 = require("crypto");
63150
63069
  var import_node_fs35 = __toESM(require("fs"), 1);
63151
- var import_node_path40 = __toESM(require("path"), 1);
63070
+ var import_node_path39 = __toESM(require("path"), 1);
63152
63071
 
63153
63072
  // src/tools/pi-events.ts
63154
63073
  init_protocol();
@@ -63325,7 +63244,7 @@ ${dirs.map((d2) => `- ${d2}`).join("\n")}`;
63325
63244
  function createPiSession(ctx, sink, deps = {}) {
63326
63245
  const cmd = process.env.PI_BIN ?? "pi";
63327
63246
  const sessionId = ctx.toolSessionId ?? (0, import_node_crypto9.randomUUID)();
63328
- const skillsDir = import_node_path40.default.join(ctx.cwd, ".claude", "skills");
63247
+ const skillsDir = import_node_path39.default.join(ctx.cwd, ".claude", "skills");
63329
63248
  const exists = deps.skillsDirExists ?? ((d2) => import_node_fs35.default.existsSync(d2));
63330
63249
  const args = buildPiArgs(ctx, {
63331
63250
  sessionId,
@@ -63444,20 +63363,20 @@ function createPiSession(ctx, sink, deps = {}) {
63444
63363
  // src/tools/pi-history.ts
63445
63364
  var import_node_fs36 = __toESM(require("fs"), 1);
63446
63365
  var import_node_os10 = __toESM(require("os"), 1);
63447
- var import_node_path41 = __toESM(require("path"), 1);
63366
+ var import_node_path40 = __toESM(require("path"), 1);
63448
63367
  var PI_LIST_SESSIONS_LIMIT = 100;
63449
63368
  var PI_LIST_SESSIONS_SCAN_CAP = 4e3;
63450
63369
  function piAgentDir(env = process.env) {
63451
- return env.PI_CODING_AGENT_DIR || import_node_path41.default.join(import_node_os10.default.homedir(), ".pi", "agent");
63370
+ return env.PI_CODING_AGENT_DIR || import_node_path40.default.join(import_node_os10.default.homedir(), ".pi", "agent");
63452
63371
  }
63453
63372
  function piSessionsRoot(env = process.env) {
63454
- return import_node_path41.default.join(piAgentDir(env), "sessions");
63373
+ return import_node_path40.default.join(piAgentDir(env), "sessions");
63455
63374
  }
63456
63375
  function encodePiCwd(cwd) {
63457
63376
  return `--${cwd.replace(/^[\\/]+/, "").replace(/[\\/:]/g, "-")}--`;
63458
63377
  }
63459
63378
  function piProjectSessionDir(sessionsRoot, cwd) {
63460
- return import_node_path41.default.join(sessionsRoot, encodePiCwd(cwd));
63379
+ return import_node_path40.default.join(sessionsRoot, encodePiCwd(cwd));
63461
63380
  }
63462
63381
  function findInDir(dir, toolSessionId) {
63463
63382
  let names;
@@ -63468,7 +63387,7 @@ function findInDir(dir, toolSessionId) {
63468
63387
  }
63469
63388
  const suffix = `_${toolSessionId}.jsonl`;
63470
63389
  const hit = names.filter((n2) => n2.endsWith(suffix)).sort().at(-1);
63471
- return hit ? import_node_path41.default.join(dir, hit) : null;
63390
+ return hit ? import_node_path40.default.join(dir, hit) : null;
63472
63391
  }
63473
63392
  function locatePiSessionFile(sessionsRoot, cwd, toolSessionId) {
63474
63393
  const direct = findInDir(piProjectSessionDir(sessionsRoot, cwd), toolSessionId);
@@ -63480,7 +63399,7 @@ function locatePiSessionFile(sessionsRoot, cwd, toolSessionId) {
63480
63399
  return null;
63481
63400
  }
63482
63401
  for (const d2 of dirs) {
63483
- const hit = findInDir(import_node_path41.default.join(sessionsRoot, d2), toolSessionId);
63402
+ const hit = findInDir(import_node_path40.default.join(sessionsRoot, d2), toolSessionId);
63484
63403
  if (hit) return hit;
63485
63404
  }
63486
63405
  return null;
@@ -63579,7 +63498,7 @@ var PiHistoryReader = class {
63579
63498
  return [];
63580
63499
  }
63581
63500
  async listSessions(args) {
63582
- const want = import_node_path41.default.resolve(args.projectPath);
63501
+ const want = import_node_path40.default.resolve(args.projectPath);
63583
63502
  const dir = piProjectSessionDir(this.deps.sessionsRoot, want);
63584
63503
  let names;
63585
63504
  try {
@@ -63591,12 +63510,12 @@ var PiHistoryReader = class {
63591
63510
  let scanned = 0;
63592
63511
  for (const n2 of names) {
63593
63512
  if (++scanned > PI_LIST_SESSIONS_SCAN_CAP) break;
63594
- const file = import_node_path41.default.join(dir, n2);
63513
+ const file = import_node_path40.default.join(dir, n2);
63595
63514
  const head = parseLine2(readFirstLine(file) ?? "");
63596
63515
  if (!head || head.type !== "session") continue;
63597
63516
  const cwd = str3(head.cwd);
63598
63517
  const id = str3(head.id);
63599
- if (!cwd || !id || import_node_path41.default.resolve(cwd) !== want) continue;
63518
+ if (!cwd || !id || import_node_path40.default.resolve(cwd) !== want) continue;
63600
63519
  let mtimeMs;
63601
63520
  try {
63602
63521
  mtimeMs = import_node_fs36.default.statSync(file).mtimeMs;
@@ -63831,7 +63750,7 @@ var PiAdapter = class {
63831
63750
  init_protocol();
63832
63751
 
63833
63752
  // src/tools/codex-skills.ts
63834
- var import_node_path42 = __toESM(require("path"), 1);
63753
+ var import_node_path41 = __toESM(require("path"), 1);
63835
63754
  function str4(v3) {
63836
63755
  return typeof v3 === "string" ? v3 : void 0;
63837
63756
  }
@@ -63846,13 +63765,13 @@ function mapSkillsListResponse(res) {
63846
63765
  const r2 = s2 ?? {};
63847
63766
  const name = str4(r2.name);
63848
63767
  if (!name) continue;
63849
- const path102 = str4(r2.path);
63768
+ const path100 = str4(r2.path);
63850
63769
  const description = str4(r2.description);
63851
63770
  const isPlugin = name.includes(":");
63852
63771
  out.push({
63853
63772
  name,
63854
63773
  source: isPlugin ? "plugin" : "project",
63855
- ...path102 ? { path: path102 } : {},
63774
+ ...path100 ? { path: path100 } : {},
63856
63775
  ...description ? { description } : {},
63857
63776
  ...isPlugin ? { plugin: name.split(":")[0] } : {}
63858
63777
  });
@@ -63868,7 +63787,7 @@ async function listCodexSkills(cwd, deps = {}) {
63868
63787
  // 先写 extraRoots 再写 list(stdio 按写入顺序处理,fire-and-forget 不 await 回包;
63869
63788
  // codex-session.ts ready 序列同款,两处保持一致)。失败不阻塞 list。
63870
63789
  beforeRequest: (client) => {
63871
- void client.request("skills/extraRoots/set", { extraRoots: [import_node_path42.default.join(cwd, ".claude", "skills")] }).catch(() => void 0);
63790
+ void client.request("skills/extraRoots/set", { extraRoots: [import_node_path41.default.join(cwd, ".claude", "skills")] }).catch(() => void 0);
63872
63791
  }
63873
63792
  });
63874
63793
  return mapSkillsListResponse(res);
@@ -63944,14 +63863,14 @@ function rec4(v3) {
63944
63863
  // src/workspace/browser.ts
63945
63864
  var import_node_fs38 = __toESM(require("fs"), 1);
63946
63865
  var import_node_os11 = __toESM(require("os"), 1);
63947
- var import_node_path43 = __toESM(require("path"), 1);
63866
+ var import_node_path42 = __toESM(require("path"), 1);
63948
63867
  init_protocol();
63949
63868
  var MAX_FILE_BYTES2 = 2 * 1024 * 1024;
63950
63869
  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)) {
63870
+ const absCwd = import_node_path42.default.resolve(cwd);
63871
+ const joined = import_node_path42.default.resolve(absCwd, subpath ?? ".");
63872
+ const rel = import_node_path42.default.relative(absCwd, joined);
63873
+ if (rel.startsWith("..") || import_node_path42.default.isAbsolute(rel)) {
63955
63874
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
63956
63875
  }
63957
63876
  return joined;
@@ -63982,7 +63901,7 @@ var WorkspaceBrowser = class {
63982
63901
  mtime: ""
63983
63902
  };
63984
63903
  try {
63985
- const st2 = import_node_fs38.default.statSync(import_node_path43.default.join(full, d2.name));
63904
+ const st2 = import_node_fs38.default.statSync(import_node_path42.default.join(full, d2.name));
63986
63905
  entry.mtime = new Date(st2.mtimeMs).toISOString();
63987
63906
  if (d2.isFile()) entry.size = st2.size;
63988
63907
  } catch {
@@ -64029,7 +63948,7 @@ var WorkspaceBrowser = class {
64029
63948
  // src/skills/agents-scanner.ts
64030
63949
  var import_node_fs39 = __toESM(require("fs"), 1);
64031
63950
  var import_node_os12 = __toESM(require("os"), 1);
64032
- var import_node_path44 = __toESM(require("path"), 1);
63951
+ var import_node_path43 = __toESM(require("path"), 1);
64033
63952
  var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
64034
63953
  function isDirLikeSync2(p3) {
64035
63954
  try {
@@ -64067,10 +63986,10 @@ function scanAgentsDir(dir, source, seen, out) {
64067
63986
  }
64068
63987
  for (const ent of entries) {
64069
63988
  if (!ent.name.endsWith(".md")) continue;
64070
- if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path44.default.join(dir, ent.name)))) {
63989
+ if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path43.default.join(dir, ent.name)))) {
64071
63990
  continue;
64072
63991
  }
64073
- const filePath = import_node_path44.default.join(dir, ent.name);
63992
+ const filePath = import_node_path43.default.join(dir, ent.name);
64074
63993
  const baseName = ent.name.replace(/\.md$/, "");
64075
63994
  if (seen.has(baseName)) continue;
64076
63995
  seen.add(baseName);
@@ -64093,7 +64012,7 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
64093
64012
  return;
64094
64013
  }
64095
64014
  for (const ent of entries) {
64096
- const childPath = import_node_path44.default.join(dir, ent.name);
64015
+ const childPath = import_node_path43.default.join(dir, ent.name);
64097
64016
  if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
64098
64017
  walk2(childPath, [...namespaces, ent.name]);
64099
64018
  continue;
@@ -64118,9 +64037,9 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
64118
64037
  walk2(root, []);
64119
64038
  }
64120
64039
  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");
64040
+ const pluginsDir = import_node_path43.default.join(home, ".claude", "plugins");
64041
+ const v22 = import_node_path43.default.join(pluginsDir, "installed_plugins_v2.json");
64042
+ const v1 = import_node_path43.default.join(pluginsDir, "installed_plugins.json");
64124
64043
  let raw = null;
64125
64044
  for (const candidate of [v22, v1]) {
64126
64045
  try {
@@ -64149,19 +64068,19 @@ function readInstalledPlugins2(home) {
64149
64068
  return out;
64150
64069
  }
64151
64070
  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;
64071
+ let cur = import_node_path43.default.resolve(startCwd);
64072
+ const fsRoot = import_node_path43.default.parse(cur).root;
64154
64073
  while (true) {
64155
- scanAgentsDir(import_node_path44.default.join(cur, ".claude", "agents"), "project", seen, out);
64074
+ scanAgentsDir(import_node_path43.default.join(cur, ".claude", "agents"), "project", seen, out);
64156
64075
  let hasGit = false;
64157
64076
  try {
64158
- hasGit = import_node_fs39.default.existsSync(import_node_path44.default.join(cur, ".git"));
64077
+ hasGit = import_node_fs39.default.existsSync(import_node_path43.default.join(cur, ".git"));
64159
64078
  } catch {
64160
64079
  }
64161
64080
  if (hasGit) return;
64162
64081
  if (cur === home) return;
64163
64082
  if (cur === fsRoot) return;
64164
- const parent = import_node_path44.default.dirname(cur);
64083
+ const parent = import_node_path43.default.dirname(cur);
64165
64084
  if (parent === cur) return;
64166
64085
  cur = parent;
64167
64086
  }
@@ -64196,7 +64115,7 @@ var AgentsScanner = class {
64196
64115
  }
64197
64116
  const fsBlock = [];
64198
64117
  scanAgentsDir(
64199
- import_node_path44.default.join(this.home, ".claude", "agents"),
64118
+ import_node_path43.default.join(this.home, ".claude", "agents"),
64200
64119
  "global",
64201
64120
  seen,
64202
64121
  fsBlock
@@ -64210,7 +64129,7 @@ var AgentsScanner = class {
64210
64129
  ...this.extraPluginRoots
64211
64130
  ];
64212
64131
  for (const { name, root } of plugins) {
64213
- const agentsRoot = import_node_path44.default.join(root, "agents");
64132
+ const agentsRoot = import_node_path43.default.join(root, "agents");
64214
64133
  scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
64215
64134
  }
64216
64135
  return [...builtinBlock, ...fsBlock];
@@ -64220,13 +64139,13 @@ var AgentsScanner = class {
64220
64139
  // src/observer/session-observer.ts
64221
64140
  var import_node_fs41 = __toESM(require("fs"), 1);
64222
64141
  var import_node_os14 = __toESM(require("os"), 1);
64223
- var import_node_path46 = __toESM(require("path"), 1);
64142
+ var import_node_path45 = __toESM(require("path"), 1);
64224
64143
  init_claude_history();
64225
64144
 
64226
64145
  // src/observer/subagent-meta-observer.ts
64227
64146
  var import_node_fs40 = __toESM(require("fs"), 1);
64228
64147
  var import_node_os13 = __toESM(require("os"), 1);
64229
- var import_node_path45 = __toESM(require("path"), 1);
64148
+ var import_node_path44 = __toESM(require("path"), 1);
64230
64149
  init_claude_history();
64231
64150
  var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
64232
64151
  var SubagentMetaObserver = class {
@@ -64239,7 +64158,7 @@ var SubagentMetaObserver = class {
64239
64158
  watches = /* @__PURE__ */ new Map();
64240
64159
  // public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
64241
64160
  resolveSubagentDir(cwd, toolSessionId) {
64242
- return import_node_path45.default.join(
64161
+ return import_node_path44.default.join(
64243
64162
  this.home,
64244
64163
  ".claude",
64245
64164
  "projects",
@@ -64295,7 +64214,7 @@ var SubagentMetaObserver = class {
64295
64214
  if (!m3) return;
64296
64215
  const agentId = m3[1];
64297
64216
  if (w3.emitted.has(agentId)) return;
64298
- const file = import_node_path45.default.join(w3.dirPath, name);
64217
+ const file = import_node_path44.default.join(w3.dirPath, name);
64299
64218
  let raw;
64300
64219
  try {
64301
64220
  raw = import_node_fs40.default.readFileSync(file, "utf8");
@@ -64355,7 +64274,7 @@ var SessionObserver = class {
64355
64274
  metaObserver;
64356
64275
  resolveJsonlPath(cwd, toolSessionId, override) {
64357
64276
  if (override) return override;
64358
- return import_node_path46.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
64277
+ return import_node_path45.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
64359
64278
  }
64360
64279
  start(args) {
64361
64280
  this.stop(args.sessionId);
@@ -64381,10 +64300,10 @@ var SessionObserver = class {
64381
64300
  lastDeriveMs: 0
64382
64301
  };
64383
64302
  try {
64384
- import_node_fs41.default.mkdirSync(import_node_path46.default.dirname(filePath), { recursive: true });
64303
+ import_node_fs41.default.mkdirSync(import_node_path45.default.dirname(filePath), { recursive: true });
64385
64304
  } catch {
64386
64305
  }
64387
- w3.watcher = import_node_fs41.default.watch(import_node_path46.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
64306
+ w3.watcher = import_node_fs41.default.watch(import_node_path45.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
64388
64307
  if (!changedName || !w3.filePath.endsWith(changedName)) return;
64389
64308
  this.poll(w3);
64390
64309
  });
@@ -64481,7 +64400,7 @@ var SessionObserver = class {
64481
64400
  const now = Date.now();
64482
64401
  if (now - w3.lastRelocateScanMs < 1e3) return;
64483
64402
  w3.lastRelocateScanMs = now;
64484
- const projectsRoot = import_node_path46.default.join(this.home, ".claude", "projects");
64403
+ const projectsRoot = import_node_path45.default.join(this.home, ".claude", "projects");
64485
64404
  const found = findTranscriptByToolSessionId(projectsRoot, w3.toolSessionId);
64486
64405
  if (!found || found === w3.filePath) return;
64487
64406
  try {
@@ -64490,7 +64409,7 @@ var SessionObserver = class {
64490
64409
  }
64491
64410
  w3.filePath = found;
64492
64411
  try {
64493
- w3.watcher = import_node_fs41.default.watch(import_node_path46.default.dirname(found), { persistent: false }, (_event, changedName) => {
64412
+ w3.watcher = import_node_fs41.default.watch(import_node_path45.default.dirname(found), { persistent: false }, (_event, changedName) => {
64494
64413
  if (!changedName || !w3.filePath.endsWith(changedName)) return;
64495
64414
  this.poll(w3);
64496
64415
  });
@@ -64614,7 +64533,7 @@ var import_node_child_process12 = require("child_process");
64614
64533
  init_protocol();
64615
64534
  var import_node_fs42 = __toESM(require("fs"), 1);
64616
64535
  var import_node_os15 = __toESM(require("os"), 1);
64617
- var import_node_path47 = __toESM(require("path"), 1);
64536
+ var import_node_path46 = __toESM(require("path"), 1);
64618
64537
  var TITLE_GEN_DIR_PREFIX = "clawd-title-";
64619
64538
  var TITLE_MODEL_BY_TOOL = {
64620
64539
  claude: "haiku",
@@ -64685,7 +64604,7 @@ async function generateSessionTitle(tool, firstMessage, deps = {}) {
64685
64604
  if (!text) return null;
64686
64605
  let workDir;
64687
64606
  try {
64688
- workDir = import_node_fs42.default.mkdtempSync(import_node_path47.default.join(import_node_os15.default.tmpdir(), TITLE_GEN_DIR_PREFIX));
64607
+ workDir = import_node_fs42.default.mkdtempSync(import_node_path46.default.join(import_node_os15.default.tmpdir(), TITLE_GEN_DIR_PREFIX));
64689
64608
  } catch {
64690
64609
  return null;
64691
64610
  }
@@ -64695,8 +64614,8 @@ async function generateSessionTitle(tool, firstMessage, deps = {}) {
64695
64614
  } catch {
64696
64615
  }
64697
64616
  };
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");
64617
+ const outFile = import_node_path46.default.join(workDir, `codex-title-${process.pid}-${++outFileSeq}-${Date.now()}.txt`);
64618
+ const schemaFile = import_node_path46.default.join(workDir, "title-schema.json");
64700
64619
  if (isCodexFamily(tool)) {
64701
64620
  try {
64702
64621
  import_node_fs42.default.writeFileSync(schemaFile, CODEX_TITLE_SCHEMA);
@@ -65395,7 +65314,7 @@ async function authenticate(token, deps) {
65395
65314
 
65396
65315
  // src/legacy-cleanup.ts
65397
65316
  var fs53 = __toESM(require("fs/promises"), 1);
65398
- var path55 = __toESM(require("path"), 1);
65317
+ var path54 = __toESM(require("path"), 1);
65399
65318
  var LEGACY_FILES = [
65400
65319
  "personal-capability.json",
65401
65320
  "received-capabilities.json",
@@ -65404,7 +65323,7 @@ var LEGACY_FILES = [
65404
65323
  async function cleanupLegacyCapabilityFiles(dataDir, logger) {
65405
65324
  const removed = [];
65406
65325
  for (const name of LEGACY_FILES) {
65407
- const p3 = path55.join(dataDir, name);
65326
+ const p3 = path54.join(dataDir, name);
65408
65327
  try {
65409
65328
  await fs53.unlink(p3);
65410
65329
  removed.push(name);
@@ -65419,7 +65338,7 @@ async function cleanupLegacyCapabilityFiles(dataDir, logger) {
65419
65338
 
65420
65339
  // src/inbox/inbox-store.ts
65421
65340
  var fs54 = __toESM(require("fs"), 1);
65422
- var path56 = __toESM(require("path"), 1);
65341
+ var path55 = __toESM(require("path"), 1);
65423
65342
  var INBOX_SUBDIR = "inbox";
65424
65343
  var InboxStore = class {
65425
65344
  constructor(dataDir) {
@@ -65517,10 +65436,10 @@ var InboxStore = class {
65517
65436
  }
65518
65437
  }
65519
65438
  dirPath() {
65520
- return path56.join(this.dataDir, INBOX_SUBDIR);
65439
+ return path55.join(this.dataDir, INBOX_SUBDIR);
65521
65440
  }
65522
65441
  filePath(peerDeviceId) {
65523
- return path56.join(this.dirPath(), `${peerDeviceId}.jsonl`);
65442
+ return path55.join(this.dirPath(), `${peerDeviceId}.jsonl`);
65524
65443
  }
65525
65444
  };
65526
65445
  function parseAllLines(raw) {
@@ -65609,7 +65528,7 @@ var InboxManager = class {
65609
65528
 
65610
65529
  // src/state/contact-store.ts
65611
65530
  var fs55 = __toESM(require("fs"), 1);
65612
- var path57 = __toESM(require("path"), 1);
65531
+ var path56 = __toESM(require("path"), 1);
65613
65532
  var FILE_NAME = "contacts.json";
65614
65533
  var ContactStore = class {
65615
65534
  constructor(dataDir) {
@@ -65619,7 +65538,7 @@ var ContactStore = class {
65619
65538
  contacts = /* @__PURE__ */ new Map();
65620
65539
  load() {
65621
65540
  this.contacts.clear();
65622
- const file = path57.join(this.dataDir, FILE_NAME);
65541
+ const file = path56.join(this.dataDir, FILE_NAME);
65623
65542
  let raw;
65624
65543
  try {
65625
65544
  raw = fs55.readFileSync(file, "utf8");
@@ -65703,7 +65622,7 @@ var ContactStore = class {
65703
65622
  return true;
65704
65623
  }
65705
65624
  flush() {
65706
- const file = path57.join(this.dataDir, FILE_NAME);
65625
+ const file = path56.join(this.dataDir, FILE_NAME);
65707
65626
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
65708
65627
  const content = JSON.stringify(
65709
65628
  { contacts: Array.from(this.contacts.values()) },
@@ -65825,52 +65744,52 @@ async function connectRemote(args) {
65825
65744
 
65826
65745
  // src/migrations/2026-05-20-flatten-sessions.ts
65827
65746
  var fs56 = __toESM(require("fs"), 1);
65828
- var path58 = __toESM(require("path"), 1);
65747
+ var path57 = __toESM(require("path"), 1);
65829
65748
  var MIGRATION_FLAG_NAME = ".migration.v1.done";
65830
65749
  function migrateFlattenSessions(opts) {
65831
65750
  const dataDir = opts.dataDir;
65832
65751
  const now = opts.now ?? Date.now;
65833
- const sessionsDir = path58.join(dataDir, "sessions");
65834
- const flagPath = path58.join(sessionsDir, MIGRATION_FLAG_NAME);
65752
+ const sessionsDir = path57.join(dataDir, "sessions");
65753
+ const flagPath = path57.join(sessionsDir, MIGRATION_FLAG_NAME);
65835
65754
  if (existsSync3(flagPath)) {
65836
65755
  return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
65837
65756
  }
65838
65757
  let movedBare = 0;
65839
65758
  let movedVmOwner = 0;
65840
65759
  let archivedListener = 0;
65841
- const defaultDir = path58.join(sessionsDir, "default");
65760
+ const defaultDir = path57.join(sessionsDir, "default");
65842
65761
  if (existsSync3(defaultDir)) {
65843
65762
  for (const entry of readdirSafe(defaultDir)) {
65844
65763
  if (!entry.endsWith(".json")) continue;
65845
- const src = path58.join(defaultDir, entry);
65846
- const dst = path58.join(sessionsDir, entry);
65764
+ const src = path57.join(defaultDir, entry);
65765
+ const dst = path57.join(sessionsDir, entry);
65847
65766
  fs56.renameSync(src, dst);
65848
65767
  movedBare += 1;
65849
65768
  }
65850
65769
  rmdirIfEmpty(defaultDir);
65851
65770
  }
65852
65771
  for (const pid of readdirSafe(sessionsDir)) {
65853
- const personaDir = path58.join(sessionsDir, pid);
65772
+ const personaDir = path57.join(sessionsDir, pid);
65854
65773
  if (!isDir(personaDir)) continue;
65855
65774
  if (pid === "default") continue;
65856
- const ownerSrc = path58.join(personaDir, "owner");
65775
+ const ownerSrc = path57.join(personaDir, "owner");
65857
65776
  if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
65858
- const ownerDst = path58.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
65777
+ const ownerDst = path57.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
65859
65778
  fs56.mkdirSync(ownerDst, { recursive: true });
65860
65779
  for (const file of readdirSafe(ownerSrc)) {
65861
65780
  if (!file.endsWith(".json")) continue;
65862
- fs56.renameSync(path58.join(ownerSrc, file), path58.join(ownerDst, file));
65781
+ fs56.renameSync(path57.join(ownerSrc, file), path57.join(ownerDst, file));
65863
65782
  movedVmOwner += 1;
65864
65783
  }
65865
65784
  rmdirIfEmpty(ownerSrc);
65866
65785
  }
65867
- const listenerSrc = path58.join(personaDir, "listener");
65786
+ const listenerSrc = path57.join(personaDir, "listener");
65868
65787
  if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
65869
- const archiveDst = path58.join(dataDir, ".legacy", `listener-${pid}`);
65788
+ const archiveDst = path57.join(dataDir, ".legacy", `listener-${pid}`);
65870
65789
  fs56.mkdirSync(archiveDst, { recursive: true });
65871
65790
  for (const file of readdirSafe(listenerSrc)) {
65872
65791
  if (!file.endsWith(".json")) continue;
65873
- fs56.renameSync(path58.join(listenerSrc, file), path58.join(archiveDst, file));
65792
+ fs56.renameSync(path57.join(listenerSrc, file), path57.join(archiveDst, file));
65874
65793
  archivedListener += 1;
65875
65794
  }
65876
65795
  rmdirIfEmpty(listenerSrc);
@@ -65918,13 +65837,13 @@ function rmdirIfEmpty(p3) {
65918
65837
 
65919
65838
  // src/migrations/2026-08-18-drop-seeded-projects.ts
65920
65839
  var fs57 = __toESM(require("fs"), 1);
65921
- var path59 = __toESM(require("path"), 1);
65840
+ var path58 = __toESM(require("path"), 1);
65922
65841
  var DROP_SEEDED_PROJECTS_FLAG = ".projects-seed-dropped.v1.done";
65923
65842
  function dropSeededProjects(opts) {
65924
65843
  fs57.mkdirSync(opts.dataDir, { recursive: true });
65925
- const flag = path59.join(opts.dataDir, DROP_SEEDED_PROJECTS_FLAG);
65844
+ const flag = path58.join(opts.dataDir, DROP_SEEDED_PROJECTS_FLAG);
65926
65845
  if (fs57.existsSync(flag)) return { skipped: true, dropped: 0, backup: null };
65927
- const file = path59.join(opts.dataDir, "projects.json");
65846
+ const file = path58.join(opts.dataDir, "projects.json");
65928
65847
  let raw = null;
65929
65848
  let dropped = 0;
65930
65849
  try {
@@ -65934,9 +65853,9 @@ function dropSeededProjects(opts) {
65934
65853
  }
65935
65854
  let backup = null;
65936
65855
  if (raw != null && dropped > 0) {
65937
- const dir = path59.join(opts.dataDir, "backups");
65856
+ const dir = path58.join(opts.dataDir, "backups");
65938
65857
  fs57.mkdirSync(dir, { recursive: true });
65939
- backup = path59.join(dir, `projects.seed-dropped.${(opts.now ?? Date.now)()}.json`);
65858
+ backup = path58.join(dir, `projects.seed-dropped.${(opts.now ?? Date.now)()}.json`);
65940
65859
  fs57.writeFileSync(backup, raw);
65941
65860
  }
65942
65861
  if (raw != null || dropped > 0) {
@@ -65948,11 +65867,11 @@ function dropSeededProjects(opts) {
65948
65867
 
65949
65868
  // src/transport/http-router.ts
65950
65869
  var import_node_fs44 = __toESM(require("fs"), 1);
65951
- var import_node_path50 = __toESM(require("path"), 1);
65870
+ var import_node_path49 = __toESM(require("path"), 1);
65952
65871
 
65953
65872
  // src/attachment/upload.ts
65954
65873
  var import_node_fs43 = __toESM(require("fs"), 1);
65955
- var import_node_path48 = __toESM(require("path"), 1);
65874
+ var import_node_path47 = __toESM(require("path"), 1);
65956
65875
  var import_node_crypto11 = __toESM(require("crypto"), 1);
65957
65876
  var import_promises7 = require("stream/promises");
65958
65877
  var UploadError = class extends Error {
@@ -65964,14 +65883,14 @@ var UploadError = class extends Error {
65964
65883
  code;
65965
65884
  };
65966
65885
  function assertValidFileName(fileName) {
65967
- if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path48.default.basename(fileName)) {
65886
+ if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path47.default.basename(fileName)) {
65968
65887
  throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
65969
65888
  }
65970
65889
  }
65971
65890
  var HASH_PREFIX_LEN = 16;
65972
65891
  async function writeUploadedAttachment(args) {
65973
65892
  assertValidFileName(args.fileName);
65974
- const attachmentsRoot = import_node_path48.default.join(args.baseDir, ".attachments");
65893
+ const attachmentsRoot = import_node_path47.default.join(args.baseDir, ".attachments");
65975
65894
  try {
65976
65895
  import_node_fs43.default.mkdirSync(attachmentsRoot, { recursive: true });
65977
65896
  } catch (err) {
@@ -65979,7 +65898,7 @@ async function writeUploadedAttachment(args) {
65979
65898
  }
65980
65899
  const hasher = import_node_crypto11.default.createHash("sha256");
65981
65900
  let actualSize = 0;
65982
- const tmpPath = import_node_path48.default.join(
65901
+ const tmpPath = import_node_path47.default.join(
65983
65902
  attachmentsRoot,
65984
65903
  `.upload-${process.pid}-${Date.now()}-${import_node_crypto11.default.randomBytes(4).toString("hex")}`
65985
65904
  );
@@ -66014,7 +65933,7 @@ async function writeUploadedAttachment(args) {
66014
65933
  );
66015
65934
  }
66016
65935
  const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
66017
- const hashDir = import_node_path48.default.join(attachmentsRoot, attachmentId);
65936
+ const hashDir = import_node_path47.default.join(attachmentsRoot, attachmentId);
66018
65937
  let finalFileName;
66019
65938
  let hashDirExists = false;
66020
65939
  try {
@@ -66032,7 +65951,7 @@ async function writeUploadedAttachment(args) {
66032
65951
  try {
66033
65952
  import_node_fs43.default.mkdirSync(hashDir, { recursive: true });
66034
65953
  finalFileName = args.fileName;
66035
- import_node_fs43.default.renameSync(tmpPath, import_node_path48.default.join(hashDir, finalFileName));
65954
+ import_node_fs43.default.renameSync(tmpPath, import_node_path47.default.join(hashDir, finalFileName));
66036
65955
  } catch (err) {
66037
65956
  try {
66038
65957
  import_node_fs43.default.unlinkSync(tmpPath);
@@ -66041,7 +65960,7 @@ async function writeUploadedAttachment(args) {
66041
65960
  throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
66042
65961
  }
66043
65962
  }
66044
- const absPath = import_node_path48.default.join(hashDir, finalFileName);
65963
+ const absPath = import_node_path47.default.join(hashDir, finalFileName);
66045
65964
  const relPath = absPath;
66046
65965
  args.groupFileStore.upsert(args.scope, args.sessionId, {
66047
65966
  relPath: absPath,
@@ -66056,7 +65975,7 @@ async function writeUploadedAttachment(args) {
66056
65975
 
66057
65976
  // src/extension/import.ts
66058
65977
  var import_promises8 = __toESM(require("fs/promises"), 1);
66059
- var import_node_path49 = __toESM(require("path"), 1);
65978
+ var import_node_path48 = __toESM(require("path"), 1);
66060
65979
  var import_node_os16 = __toESM(require("os"), 1);
66061
65980
  var import_jszip = __toESM(require_lib3(), 1);
66062
65981
  var ImportError = class extends Error {
@@ -66074,7 +65993,7 @@ async function importZip(buf, root) {
66074
65993
  throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
66075
65994
  }
66076
65995
  for (const name of Object.keys(zip.files)) {
66077
- if (name.includes("..") || name.startsWith("/") || import_node_path49.default.isAbsolute(name)) {
65996
+ if (name.includes("..") || name.startsWith("/") || import_node_path48.default.isAbsolute(name)) {
66078
65997
  throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
66079
65998
  }
66080
65999
  }
@@ -66107,7 +66026,7 @@ async function importZip(buf, root) {
66107
66026
  );
66108
66027
  }
66109
66028
  }
66110
- const destDir = import_node_path49.default.join(root, manifest.id);
66029
+ const destDir = import_node_path48.default.join(root, manifest.id);
66111
66030
  let destExists = false;
66112
66031
  try {
66113
66032
  await import_promises8.default.access(destDir);
@@ -66117,15 +66036,15 @@ async function importZip(buf, root) {
66117
66036
  if (destExists) {
66118
66037
  throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
66119
66038
  }
66120
- const stage = await import_promises8.default.mkdtemp(import_node_path49.default.join(import_node_os16.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
66039
+ const stage = await import_promises8.default.mkdtemp(import_node_path48.default.join(import_node_os16.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
66121
66040
  try {
66122
66041
  for (const [name, entry] of Object.entries(zip.files)) {
66123
- const dest = import_node_path49.default.join(stage, name);
66042
+ const dest = import_node_path48.default.join(stage, name);
66124
66043
  if (entry.dir) {
66125
66044
  await import_promises8.default.mkdir(dest, { recursive: true });
66126
66045
  continue;
66127
66046
  }
66128
- await import_promises8.default.mkdir(import_node_path49.default.dirname(dest), { recursive: true });
66047
+ await import_promises8.default.mkdir(import_node_path48.default.dirname(dest), { recursive: true });
66129
66048
  const content = await entry.async("nodebuffer");
66130
66049
  await import_promises8.default.writeFile(dest, content);
66131
66050
  }
@@ -66179,7 +66098,7 @@ var SHARE_UI_ASSET_MIME = {
66179
66098
  ".wasm": "application/wasm"
66180
66099
  };
66181
66100
  function shareUiAssetMime(filePath) {
66182
- const ext = import_node_path50.default.extname(filePath).toLowerCase();
66101
+ const ext = import_node_path49.default.extname(filePath).toLowerCase();
66183
66102
  return SHARE_UI_ASSET_MIME[ext] ?? lookupMime(filePath);
66184
66103
  }
66185
66104
  var AUTHED_RPC_ROUTE_PREFIX = "/rpc/";
@@ -66278,7 +66197,7 @@ function isValidUploadFileName(fileName) {
66278
66197
  if (fileName === "." || fileName === "..") return false;
66279
66198
  if (fileName.startsWith(".")) return false;
66280
66199
  if (fileName.includes("/") || fileName.includes("\\")) return false;
66281
- return fileName === import_node_path50.default.basename(fileName);
66200
+ return fileName === import_node_path49.default.basename(fileName);
66282
66201
  }
66283
66202
  function createHttpRouter(deps) {
66284
66203
  return async (req, res) => {
@@ -66501,7 +66420,7 @@ function createHttpRouter(deps) {
66501
66420
  sendHtml(res, statusByCode[r2.code], loader.renderErrorHtml(r2.code, msgByCode[r2.code]));
66502
66421
  return true;
66503
66422
  }
66504
- sendHtml(res, 200, loader.renderViewerHtml(import_node_path50.default.basename(r2.absPath)));
66423
+ sendHtml(res, 200, loader.renderViewerHtml(import_node_path49.default.basename(r2.absPath)));
66505
66424
  return true;
66506
66425
  }
66507
66426
  const ctx = deps.authResolver.resolveFromHeader(
@@ -66622,7 +66541,7 @@ function createHttpRouter(deps) {
66622
66541
  return true;
66623
66542
  }
66624
66543
  let absPath;
66625
- if (import_node_path50.default.isAbsolute(pathParam)) {
66544
+ if (import_node_path49.default.isAbsolute(pathParam)) {
66626
66545
  absPath = pathParam;
66627
66546
  } else if (deps.sessionStore) {
66628
66547
  const file = deps.sessionStore.read(sid);
@@ -66630,7 +66549,7 @@ function createHttpRouter(deps) {
66630
66549
  sendJson(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
66631
66550
  return true;
66632
66551
  }
66633
- absPath = import_node_path50.default.join(file.cwd, pathParam);
66552
+ absPath = import_node_path49.default.join(file.cwd, pathParam);
66634
66553
  } else {
66635
66554
  sendJson(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
66636
66555
  return true;
@@ -66729,7 +66648,7 @@ function streamFile(res, absPath, logger) {
66729
66648
  return;
66730
66649
  }
66731
66650
  const mime = lookupMime(absPath);
66732
- const basename2 = import_node_path50.default.basename(absPath);
66651
+ const basename2 = import_node_path49.default.basename(absPath);
66733
66652
  res.writeHead(200, {
66734
66653
  "Content-Type": mime,
66735
66654
  "Content-Length": String(stat.size),
@@ -66747,7 +66666,7 @@ function streamFile(res, absPath, logger) {
66747
66666
 
66748
66667
  // src/attachment/gc.ts
66749
66668
  var import_node_fs45 = __toESM(require("fs"), 1);
66750
- var import_node_path51 = __toESM(require("path"), 1);
66669
+ var import_node_path50 = __toESM(require("path"), 1);
66751
66670
  var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
66752
66671
  function runAttachmentGc(args) {
66753
66672
  const now = (args.now ?? Date.now)();
@@ -66756,12 +66675,12 @@ function runAttachmentGc(args) {
66756
66675
  for (const { scope, sessionId } of args.sessionScopes) {
66757
66676
  for (const entry of args.groupFileStore.list(scope, sessionId)) {
66758
66677
  if (entry.stale) continue;
66759
- if (import_node_path51.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
66678
+ if (import_node_path50.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
66760
66679
  }
66761
66680
  }
66762
66681
  const visited = /* @__PURE__ */ new Set();
66763
66682
  for (const { scope, sessionId } of args.sessionScopes) {
66764
- const legacyDir = args.getSessionCwd?.(sessionId) ?? import_node_path51.default.join(
66683
+ const legacyDir = args.getSessionCwd?.(sessionId) ?? import_node_path50.default.join(
66765
66684
  args.dataDir,
66766
66685
  "sessions",
66767
66686
  ...scopeSubPath(scope).map(safeFileName),
@@ -66774,7 +66693,7 @@ function runAttachmentGc(args) {
66774
66693
  return true;
66775
66694
  });
66776
66695
  for (const rootDir of roots) {
66777
- const attRoot = import_node_path51.default.join(rootDir, ".attachments");
66696
+ const attRoot = import_node_path50.default.join(rootDir, ".attachments");
66778
66697
  let hashDirs;
66779
66698
  try {
66780
66699
  hashDirs = import_node_fs45.default.readdirSync(attRoot);
@@ -66784,7 +66703,7 @@ function runAttachmentGc(args) {
66784
66703
  continue;
66785
66704
  }
66786
66705
  for (const hashDir of hashDirs) {
66787
- const hashDirAbs = import_node_path51.default.join(attRoot, hashDir);
66706
+ const hashDirAbs = import_node_path50.default.join(attRoot, hashDir);
66788
66707
  let files;
66789
66708
  try {
66790
66709
  files = import_node_fs45.default.readdirSync(hashDirAbs);
@@ -66792,7 +66711,7 @@ function runAttachmentGc(args) {
66792
66711
  continue;
66793
66712
  }
66794
66713
  for (const name of files) {
66795
- const file = import_node_path51.default.join(hashDirAbs, name);
66714
+ const file = import_node_path50.default.join(hashDirAbs, name);
66796
66715
  let stat;
66797
66716
  try {
66798
66717
  stat = import_node_fs45.default.statSync(file);
@@ -66824,7 +66743,7 @@ function runAttachmentGc(args) {
66824
66743
 
66825
66744
  // src/attachment/group.ts
66826
66745
  var import_node_fs46 = __toESM(require("fs"), 1);
66827
- var import_node_path52 = __toESM(require("path"), 1);
66746
+ var import_node_path51 = __toESM(require("path"), 1);
66828
66747
  var import_node_crypto12 = __toESM(require("crypto"), 1);
66829
66748
  init_protocol();
66830
66749
  var GroupFileStore = class {
@@ -66836,11 +66755,11 @@ var GroupFileStore = class {
66836
66755
  this.logger = opts.logger;
66837
66756
  }
66838
66757
  rootForScope(scope) {
66839
- return import_node_path52.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
66758
+ return import_node_path51.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
66840
66759
  }
66841
66760
  /** 与 SessionStore.filePath 平级,扩展名 .group-files.json */
66842
66761
  filePath(scope, sessionId) {
66843
- return import_node_path52.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
66762
+ return import_node_path51.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
66844
66763
  }
66845
66764
  cacheKey(scope, sessionId) {
66846
66765
  return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
@@ -66875,7 +66794,7 @@ var GroupFileStore = class {
66875
66794
  }
66876
66795
  writeFile(scope, sessionId, entries) {
66877
66796
  const file = this.filePath(scope, sessionId);
66878
- import_node_fs46.default.mkdirSync(import_node_path52.default.dirname(file), { recursive: true });
66797
+ import_node_fs46.default.mkdirSync(import_node_path51.default.dirname(file), { recursive: true });
66879
66798
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
66880
66799
  import_node_fs46.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
66881
66800
  import_node_fs46.default.renameSync(tmp, file);
@@ -66983,7 +66902,7 @@ var GroupFileStore = class {
66983
66902
  * 不在 persona 目录里(见文件头的路径约定)。没树的 persona 是 noop。
66984
66903
  */
66985
66904
  deletePersona(personaId2) {
66986
- import_node_fs46.default.rmSync(import_node_path52.default.join(this.dataDir, "sessions", safeFileName(personaId2)), { recursive: true, force: true });
66905
+ import_node_fs46.default.rmSync(import_node_path51.default.join(this.dataDir, "sessions", safeFileName(personaId2)), { recursive: true, force: true });
66987
66906
  const prefix = `persona:${personaId2}:`;
66988
66907
  for (const key of this.cache.keys()) {
66989
66908
  if (key.startsWith(prefix)) this.cache.delete(key);
@@ -66993,9 +66912,9 @@ var GroupFileStore = class {
66993
66912
 
66994
66913
  // src/discovery/state-file.ts
66995
66914
  var import_node_fs47 = __toESM(require("fs"), 1);
66996
- var import_node_path53 = __toESM(require("path"), 1);
66915
+ var import_node_path52 = __toESM(require("path"), 1);
66997
66916
  function defaultStateFilePath(dataDir) {
66998
- return import_node_path53.default.join(dataDir, "state.json");
66917
+ return import_node_path52.default.join(dataDir, "state.json");
66999
66918
  }
67000
66919
  function isPidAlive(pid) {
67001
66920
  if (!Number.isFinite(pid) || pid <= 0) return false;
@@ -67031,7 +66950,7 @@ var StateFileManager = class {
67031
66950
  return { status: "stale", existing };
67032
66951
  }
67033
66952
  write(state) {
67034
- import_node_fs47.default.mkdirSync(import_node_path53.default.dirname(this.file), { recursive: true });
66953
+ import_node_fs47.default.mkdirSync(import_node_path52.default.dirname(this.file), { recursive: true });
67035
66954
  const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
67036
66955
  import_node_fs47.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
67037
66956
  import_node_fs47.default.renameSync(tmp, this.file);
@@ -67059,13 +66978,13 @@ function readSpawnedByDesktopFromEnv(env = process.env) {
67059
66978
 
67060
66979
  // src/tunnel/tunnel-manager.ts
67061
66980
  var import_node_fs51 = __toESM(require("fs"), 1);
67062
- var import_node_path57 = __toESM(require("path"), 1);
66981
+ var import_node_path56 = __toESM(require("path"), 1);
67063
66982
  var import_node_crypto13 = __toESM(require("crypto"), 1);
67064
66983
  var import_node_child_process15 = require("child_process");
67065
66984
 
67066
66985
  // src/tunnel/tunnel-store.ts
67067
66986
  var import_node_fs48 = __toESM(require("fs"), 1);
67068
- var import_node_path54 = __toESM(require("path"), 1);
66987
+ var import_node_path53 = __toESM(require("path"), 1);
67069
66988
  var TunnelStore = class {
67070
66989
  constructor(filePath) {
67071
66990
  this.filePath = filePath;
@@ -67084,7 +67003,7 @@ var TunnelStore = class {
67084
67003
  }
67085
67004
  }
67086
67005
  async set(v3) {
67087
- const dir = import_node_path54.default.dirname(this.filePath);
67006
+ const dir = import_node_path53.default.dirname(this.filePath);
67088
67007
  await import_node_fs48.default.promises.mkdir(dir, { recursive: true });
67089
67008
  const data = JSON.stringify(v3, null, 2);
67090
67009
  const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
@@ -67196,7 +67115,7 @@ function escape2(v3) {
67196
67115
  // src/tunnel/frpc-binary.ts
67197
67116
  var import_node_fs49 = __toESM(require("fs"), 1);
67198
67117
  var import_node_os17 = __toESM(require("os"), 1);
67199
- var import_node_path55 = __toESM(require("path"), 1);
67118
+ var import_node_path54 = __toESM(require("path"), 1);
67200
67119
  var import_node_child_process13 = require("child_process");
67201
67120
  var import_node_stream3 = require("stream");
67202
67121
  var import_promises9 = require("stream/promises");
@@ -67235,13 +67154,13 @@ async function ensureFrpcBinary(opts) {
67235
67154
  }
67236
67155
  const version2 = opts.version ?? FRPC_VERSION;
67237
67156
  const platform = opts.platform ?? detectPlatform();
67238
- const binDir = import_node_path55.default.join(opts.dataDir, "bin");
67157
+ const binDir = import_node_path54.default.join(opts.dataDir, "bin");
67239
67158
  import_node_fs49.default.mkdirSync(binDir, { recursive: true });
67240
67159
  cleanupStaleArtifacts(binDir);
67241
- const stableBin = import_node_path55.default.join(binDir, "frpc");
67160
+ const stableBin = import_node_path54.default.join(binDir, "frpc");
67242
67161
  if (import_node_fs49.default.existsSync(stableBin)) return stableBin;
67243
67162
  const partialBin = `${stableBin}.partial`;
67244
- const tarballPath = import_node_path55.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
67163
+ const tarballPath = import_node_path54.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
67245
67164
  try {
67246
67165
  const url = frpcDownloadUrl(version2, platform);
67247
67166
  await downloadToFile(url, tarballPath, opts.fetchImpl);
@@ -67267,7 +67186,7 @@ function cleanupStaleArtifacts(binDir) {
67267
67186
  }
67268
67187
  for (const name of entries) {
67269
67188
  if (name.endsWith(".partial") || name.startsWith("extract-")) {
67270
- const full = import_node_path55.default.join(binDir, name);
67189
+ const full = import_node_path54.default.join(binDir, name);
67271
67190
  try {
67272
67191
  import_node_fs49.default.rmSync(full, { recursive: true, force: true });
67273
67192
  } catch {
@@ -67293,7 +67212,7 @@ async function downloadToFile(url, dest, fetchImpl) {
67293
67212
  await (0, import_promises9.pipeline)(nodeStream, out);
67294
67213
  }
67295
67214
  async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
67296
- const work = import_node_path55.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
67215
+ const work = import_node_path54.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
67297
67216
  import_node_fs49.default.mkdirSync(work, { recursive: true });
67298
67217
  try {
67299
67218
  await new Promise((resolve9, reject) => {
@@ -67302,7 +67221,7 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
67302
67221
  proc.on("exit", (code) => code === 0 ? resolve9() : reject(new Error(`tar exited ${code}`)));
67303
67222
  });
67304
67223
  const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
67305
- const src = import_node_path55.default.join(work, dirName, "frpc");
67224
+ const src = import_node_path54.default.join(work, dirName, "frpc");
67306
67225
  if (!import_node_fs49.default.existsSync(src)) {
67307
67226
  throw new Error(`frpc not found inside tarball at ${src}`);
67308
67227
  }
@@ -67314,10 +67233,10 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
67314
67233
 
67315
67234
  // src/tunnel/frpc-process.ts
67316
67235
  var import_node_fs50 = __toESM(require("fs"), 1);
67317
- var import_node_path56 = __toESM(require("path"), 1);
67236
+ var import_node_path55 = __toESM(require("path"), 1);
67318
67237
  var import_node_child_process14 = require("child_process");
67319
67238
  function frpcPidFilePath(dataDir) {
67320
- return import_node_path56.default.join(dataDir, "frpc.pid");
67239
+ return import_node_path55.default.join(dataDir, "frpc.pid");
67321
67240
  }
67322
67241
  function writeFrpcPid(dataDir, pid) {
67323
67242
  try {
@@ -67359,7 +67278,7 @@ function defaultSleep2(ms) {
67359
67278
  }
67360
67279
  async function killStaleFrpc(deps) {
67361
67280
  const pidFile = frpcPidFilePath(deps.dataDir);
67362
- const tomlPath = import_node_path56.default.join(deps.dataDir, "frpc.toml");
67281
+ const tomlPath = import_node_path55.default.join(deps.dataDir, "frpc.toml");
67363
67282
  const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
67364
67283
  const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
67365
67284
  const killPid = deps.killPidImpl ?? defaultKillPid;
@@ -67431,7 +67350,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
67431
67350
  var TunnelManager = class {
67432
67351
  constructor(deps) {
67433
67352
  this.deps = deps;
67434
- this.store = deps.store ?? new TunnelStore(import_node_path57.default.join(deps.dataDir, "tunnel.json"));
67353
+ this.store = deps.store ?? new TunnelStore(import_node_path56.default.join(deps.dataDir, "tunnel.json"));
67435
67354
  this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
67436
67355
  this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
67437
67356
  }
@@ -67558,7 +67477,7 @@ var TunnelManager = class {
67558
67477
  dataDir: this.deps.dataDir,
67559
67478
  override: this.deps.frpcBinaryOverride ?? void 0
67560
67479
  });
67561
- const tomlPath = import_node_path57.default.join(this.deps.dataDir, "frpc.toml");
67480
+ const tomlPath = import_node_path56.default.join(this.deps.dataDir, "frpc.toml");
67562
67481
  const proxyName = `clawd-${t2.subdomain}-${localPort}-${import_node_crypto13.default.randomBytes(3).toString("hex")}`;
67563
67482
  const toml = buildFrpcToml({
67564
67483
  serverAddr: t2.frpsHost,
@@ -67573,9 +67492,9 @@ var TunnelManager = class {
67573
67492
  const proc = (this.deps.spawnImpl ?? import_node_child_process15.spawn)(frpcBin, ["-c", tomlPath], {
67574
67493
  stdio: ["ignore", "pipe", "pipe"]
67575
67494
  });
67576
- const logDir = import_node_path57.default.join(this.deps.dataDir, "log");
67495
+ const logDir = import_node_path56.default.join(this.deps.dataDir, "log");
67577
67496
  import_node_fs51.default.mkdirSync(logDir, { recursive: true });
67578
- const logFilePath = import_node_path57.default.join(logDir, "frpc.log");
67497
+ const logFilePath = import_node_path56.default.join(logDir, "frpc.log");
67579
67498
  const logStream = import_node_fs51.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
67580
67499
  logStream.on("error", () => {
67581
67500
  });
@@ -67659,15 +67578,15 @@ async function waitForFrpcReady(proc, timeoutMs) {
67659
67578
 
67660
67579
  // src/tunnel/device-key.ts
67661
67580
  var import_node_os18 = __toESM(require("os"), 1);
67662
- var import_node_path58 = __toESM(require("path"), 1);
67581
+ var import_node_path57 = __toESM(require("path"), 1);
67663
67582
  var import_node_crypto14 = __toESM(require("crypto"), 1);
67664
67583
  var DERIVE_SALT = "clawd-tunnel-device-v1";
67665
67584
  function deriveStableDeviceKey(opts = {}) {
67666
67585
  const hostname = opts.hostname ?? import_node_os18.default.hostname();
67667
67586
  const uid = opts.uid ?? (typeof import_node_os18.default.userInfo === "function" ? import_node_os18.default.userInfo().uid : 0);
67668
67587
  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;
67588
+ const defaultDataDir = import_node_path57.default.resolve(import_node_path57.default.join(home, ".clawd"));
67589
+ const normalizedDataDir = opts.dataDir ? import_node_path57.default.resolve(opts.dataDir) : null;
67671
67590
  const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
67672
67591
  const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
67673
67592
  return import_node_crypto14.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
@@ -67675,11 +67594,11 @@ function deriveStableDeviceKey(opts = {}) {
67675
67594
 
67676
67595
  // src/auth-store.ts
67677
67596
  var import_node_fs52 = __toESM(require("fs"), 1);
67678
- var import_node_path59 = __toESM(require("path"), 1);
67597
+ var import_node_path58 = __toESM(require("path"), 1);
67679
67598
  var import_node_crypto15 = __toESM(require("crypto"), 1);
67680
67599
  var AUTH_FILE_NAME = "auth.json";
67681
67600
  function authFilePath(dataDir) {
67682
- return import_node_path59.default.join(dataDir, AUTH_FILE_NAME);
67601
+ return import_node_path58.default.join(dataDir, AUTH_FILE_NAME);
67683
67602
  }
67684
67603
  function loadOrCreateAuthFile(opts) {
67685
67604
  const file = authFilePath(opts.dataDir);
@@ -67741,7 +67660,7 @@ function readAuthFile(file) {
67741
67660
  }
67742
67661
  }
67743
67662
  function writeAuthFile(file, content) {
67744
- import_node_fs52.default.mkdirSync(import_node_path59.default.dirname(file), { recursive: true });
67663
+ import_node_fs52.default.mkdirSync(import_node_path58.default.dirname(file), { recursive: true });
67745
67664
  import_node_fs52.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
67746
67665
  try {
67747
67666
  import_node_fs52.default.chmodSync(file, 384);
@@ -67752,10 +67671,10 @@ function writeAuthFile(file, content) {
67752
67671
  // src/owner-profile.ts
67753
67672
  var import_node_fs53 = __toESM(require("fs"), 1);
67754
67673
  var import_node_os19 = __toESM(require("os"), 1);
67755
- var import_node_path60 = __toESM(require("path"), 1);
67674
+ var import_node_path59 = __toESM(require("path"), 1);
67756
67675
  var PROFILE_FILENAME = "profile.json";
67757
67676
  function profilePath(dataDir) {
67758
- return import_node_path60.default.join(dataDir, PROFILE_FILENAME);
67677
+ return import_node_path59.default.join(dataDir, PROFILE_FILENAME);
67759
67678
  }
67760
67679
  function loadOwnerProfile(dataDir) {
67761
67680
  let raw;
@@ -67793,12 +67712,12 @@ function loadOwnerDisplayName(dataDir) {
67793
67712
 
67794
67713
  // src/feishu-auth/owner-identity-store.ts
67795
67714
  var import_node_fs54 = __toESM(require("fs"), 1);
67796
- var import_node_path61 = __toESM(require("path"), 1);
67715
+ var import_node_path60 = __toESM(require("path"), 1);
67797
67716
  var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
67798
67717
  var OwnerIdentityStore = class {
67799
67718
  file;
67800
67719
  constructor(dataDir) {
67801
- this.file = import_node_path61.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
67720
+ this.file = import_node_path60.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
67802
67721
  }
67803
67722
  read() {
67804
67723
  let raw;
@@ -67830,7 +67749,7 @@ var OwnerIdentityStore = class {
67830
67749
  };
67831
67750
  }
67832
67751
  write(record4) {
67833
- import_node_fs54.default.mkdirSync(import_node_path61.default.dirname(this.file), { recursive: true });
67752
+ import_node_fs54.default.mkdirSync(import_node_path60.default.dirname(this.file), { recursive: true });
67834
67753
  import_node_fs54.default.writeFileSync(this.file, JSON.stringify(record4, null, 2), { mode: 384 });
67835
67754
  try {
67836
67755
  import_node_fs54.default.chmodSync(this.file, 384);
@@ -68336,7 +68255,7 @@ function verifyConnectToken(args) {
68336
68255
 
68337
68256
  // src/feishu-auth/server-key.ts
68338
68257
  var fs71 = __toESM(require("fs"), 1);
68339
- var path74 = __toESM(require("path"), 1);
68258
+ var path73 = __toESM(require("path"), 1);
68340
68259
  var FILE_NAME2 = "server-signing-key.json";
68341
68260
  var ServerKeyStore = class {
68342
68261
  constructor(dataDir) {
@@ -68344,7 +68263,7 @@ var ServerKeyStore = class {
68344
68263
  }
68345
68264
  dataDir;
68346
68265
  filePath() {
68347
- return path74.join(this.dataDir, FILE_NAME2);
68266
+ return path73.join(this.dataDir, FILE_NAME2);
68348
68267
  }
68349
68268
  /** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
68350
68269
  read() {
@@ -68379,7 +68298,7 @@ var ServerKeyStore = class {
68379
68298
  init_protocol();
68380
68299
 
68381
68300
  // src/handlers/index.ts
68382
- var import_node_path75 = __toESM(require("path"), 1);
68301
+ var import_node_path74 = __toESM(require("path"), 1);
68383
68302
 
68384
68303
  // src/handlers/session.ts
68385
68304
  init_protocol();
@@ -68387,7 +68306,7 @@ init_protocol();
68387
68306
  // src/session/fork.ts
68388
68307
  var import_node_fs55 = __toESM(require("fs"), 1);
68389
68308
  var import_node_os20 = __toESM(require("os"), 1);
68390
- var import_node_path62 = __toESM(require("path"), 1);
68309
+ var import_node_path61 = __toESM(require("path"), 1);
68391
68310
  var import_node_crypto17 = require("crypto");
68392
68311
  init_claude_history();
68393
68312
  function readJsonlEntries(file) {
@@ -68404,19 +68323,19 @@ function readJsonlEntries(file) {
68404
68323
  return out;
68405
68324
  }
68406
68325
  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`);
68326
+ const baseDir = input.baseDir ?? import_node_path61.default.join(import_node_os20.default.homedir(), ".claude");
68327
+ let projectDir = import_node_path61.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
68328
+ let sourceFile = import_node_path61.default.join(projectDir, `${input.toolSessionId}.jsonl`);
68410
68329
  if (!import_node_fs55.default.existsSync(sourceFile)) {
68411
68330
  const found = findTranscriptByToolSessionId(
68412
- import_node_path62.default.join(baseDir, "projects"),
68331
+ import_node_path61.default.join(baseDir, "projects"),
68413
68332
  input.toolSessionId
68414
68333
  );
68415
68334
  if (!found) {
68416
68335
  throw new Error(`fork: source transcript not found: ${sourceFile}`);
68417
68336
  }
68418
68337
  sourceFile = found;
68419
- projectDir = import_node_path62.default.dirname(found);
68338
+ projectDir = import_node_path61.default.dirname(found);
68420
68339
  }
68421
68340
  const entries = readJsonlEntries(sourceFile);
68422
68341
  const mainEntries = entries.filter((e) => e.isSidechain !== true);
@@ -68445,8 +68364,8 @@ function forkSession(input) {
68445
68364
  }
68446
68365
  forkedLines.push(JSON.stringify(forked));
68447
68366
  }
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`);
68367
+ const outDir = input.targetCwd ? import_node_path61.default.join(baseDir, "projects", cwdToHashDir(input.targetCwd)) : projectDir;
68368
+ const forkedFilePath = import_node_path61.default.join(outDir, `${forkedToolSessionId}.jsonl`);
68450
68369
  import_node_fs55.default.mkdirSync(outDir, { recursive: true });
68451
68370
  import_node_fs55.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
68452
68371
  return { forkedToolSessionId, forkedFilePath };
@@ -68456,16 +68375,16 @@ function forkSession(input) {
68456
68375
  var import_node_fs56 = __toESM(require("fs"), 1);
68457
68376
  var import_promises10 = __toESM(require("fs/promises"), 1);
68458
68377
  var import_node_os21 = __toESM(require("os"), 1);
68459
- var import_node_path63 = __toESM(require("path"), 1);
68378
+ var import_node_path62 = __toESM(require("path"), 1);
68460
68379
  var import_node_module = require("module");
68461
68380
  var import_node_child_process16 = require("child_process");
68462
68381
  var import_meta6 = {};
68463
68382
  function defaultRoots() {
68464
68383
  const home = import_node_os21.default.homedir();
68465
68384
  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")
68385
+ claudeProjectsDir: import_node_path62.default.join(home, ".claude", "projects"),
68386
+ codexDir: import_node_path62.default.join(home, ".codex"),
68387
+ clawdDir: import_node_path62.default.join(home, ".clawd")
68469
68388
  };
68470
68389
  }
68471
68390
  function width(s2) {
@@ -68533,13 +68452,13 @@ async function scanClaude(roots) {
68533
68452
  if (!d2.isDirectory()) continue;
68534
68453
  let files;
68535
68454
  try {
68536
- files = import_node_fs56.default.readdirSync(import_node_path63.default.join(roots.claudeProjectsDir, d2.name));
68455
+ files = import_node_fs56.default.readdirSync(import_node_path62.default.join(roots.claudeProjectsDir, d2.name));
68537
68456
  } catch {
68538
68457
  continue;
68539
68458
  }
68540
68459
  for (const name of files) {
68541
68460
  if (!name.endsWith(".jsonl")) continue;
68542
- const file = import_node_path63.default.join(roots.claudeProjectsDir, d2.name, name);
68461
+ const file = import_node_path62.default.join(roots.claudeProjectsDir, d2.name, name);
68543
68462
  let st2;
68544
68463
  try {
68545
68464
  st2 = import_node_fs56.default.statSync(file);
@@ -68669,7 +68588,7 @@ async function codexFromRows(rows) {
68669
68588
  async function scanCodex(roots) {
68670
68589
  let dbs = [];
68671
68590
  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));
68591
+ 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
68592
  } catch {
68674
68593
  }
68675
68594
  if (!dbs.length) return [];
@@ -68678,14 +68597,14 @@ async function scanCodex(roots) {
68678
68597
  }
68679
68598
  async function scanExternalSessions(rootsIn) {
68680
68599
  const roots = { ...defaultRoots(), ...rootsIn };
68681
- const personaRoot = import_node_path63.default.join(roots.clawdDir, "personas");
68600
+ const personaRoot = import_node_path62.default.join(roots.clawdDir, "personas");
68682
68601
  const all = [...await scanClaude(roots), ...await scanCodex(roots)];
68683
68602
  const out = [];
68684
68603
  for (const c2 of all) {
68685
68604
  if (c2.skip) continue;
68686
68605
  if (c2.turns < 1) continue;
68687
68606
  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)) {
68607
+ 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
68608
  continue;
68690
68609
  }
68691
68610
  out.push({
@@ -68703,12 +68622,12 @@ async function scanExternalSessions(rootsIn) {
68703
68622
 
68704
68623
  // src/session/import-ledger.ts
68705
68624
  var import_node_fs57 = __toESM(require("fs"), 1);
68706
- var import_node_path64 = __toESM(require("path"), 1);
68625
+ var import_node_path63 = __toESM(require("path"), 1);
68707
68626
  var LEDGER_FILENAME = "session-import-ledger.json";
68708
68627
  function readImportLedger(dataDir) {
68709
68628
  try {
68710
68629
  const parsed = JSON.parse(
68711
- import_node_fs57.default.readFileSync(import_node_path64.default.join(dataDir, LEDGER_FILENAME), "utf8")
68630
+ import_node_fs57.default.readFileSync(import_node_path63.default.join(dataDir, LEDGER_FILENAME), "utf8")
68712
68631
  );
68713
68632
  return Array.isArray(parsed) ? parsed : [];
68714
68633
  } catch {
@@ -68716,7 +68635,7 @@ function readImportLedger(dataDir) {
68716
68635
  }
68717
68636
  }
68718
68637
  function appendImportLedger(dataDir, entry) {
68719
- const file = import_node_path64.default.join(dataDir, LEDGER_FILENAME);
68638
+ const file = import_node_path63.default.join(dataDir, LEDGER_FILENAME);
68720
68639
  const entries = readImportLedger(dataDir);
68721
68640
  entries.push(entry);
68722
68641
  import_node_fs57.default.writeFileSync(file, JSON.stringify(entries, null, 2), { encoding: "utf8", mode: 384 });
@@ -69252,7 +69171,7 @@ function buildPermissionHandlers(deps) {
69252
69171
  }
69253
69172
 
69254
69173
  // src/handlers/history.ts
69255
- var path79 = __toESM(require("path"), 1);
69174
+ var path78 = __toESM(require("path"), 1);
69256
69175
  init_protocol();
69257
69176
 
69258
69177
  // src/session/recent-dirs.ts
@@ -69270,7 +69189,7 @@ function listRecentDirs(store, limit = 50) {
69270
69189
  }
69271
69190
 
69272
69191
  // src/permission/persona-paths.ts
69273
- var path78 = __toESM(require("path"), 1);
69192
+ var path77 = __toESM(require("path"), 1);
69274
69193
  function getAllowedPersonaIds(grants, action) {
69275
69194
  const ids = /* @__PURE__ */ new Set();
69276
69195
  for (const g3 of grants) {
@@ -69283,42 +69202,42 @@ function getAllowedPersonaIds(grants, action) {
69283
69202
  return ids;
69284
69203
  }
69285
69204
  function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
69286
- const target = path78.resolve(absPath);
69205
+ const target = path77.resolve(absPath);
69287
69206
  if (userWorkDir) {
69288
- const u2 = path78.resolve(userWorkDir);
69289
- const usep = u2.endsWith(path78.sep) ? "" : path78.sep;
69207
+ const u2 = path77.resolve(userWorkDir);
69208
+ const usep = u2.endsWith(path77.sep) ? "" : path77.sep;
69290
69209
  if (target === u2 || target.startsWith(u2 + usep)) return true;
69291
69210
  }
69292
- const root = path78.resolve(personaRoot);
69293
- const sep4 = root.endsWith(path78.sep) ? "" : path78.sep;
69211
+ const root = path77.resolve(personaRoot);
69212
+ const sep4 = root.endsWith(path77.sep) ? "" : path77.sep;
69294
69213
  if (!target.startsWith(root + sep4)) return false;
69295
- const rel = path78.relative(root, target);
69214
+ const rel = path77.relative(root, target);
69296
69215
  if (!rel || rel.startsWith("..")) return false;
69297
- const personaId2 = rel.split(path78.sep)[0];
69216
+ const personaId2 = rel.split(path77.sep)[0];
69298
69217
  if (!personaId2) return false;
69299
69218
  const allowed = getAllowedPersonaIds(grants, action);
69300
69219
  if (allowed === "*") return true;
69301
69220
  return allowed.has(personaId2);
69302
69221
  }
69303
69222
  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;
69223
+ const root = path77.resolve(personaRoot);
69224
+ const target = path77.resolve(absPath);
69225
+ const sep4 = root.endsWith(path77.sep) ? "" : path77.sep;
69307
69226
  if (!target.startsWith(root + sep4)) return null;
69308
- const rel = path78.relative(root, target);
69227
+ const rel = path77.relative(root, target);
69309
69228
  if (!rel || rel.startsWith("..")) return null;
69310
- const id = rel.split(path78.sep)[0];
69229
+ const id = rel.split(path77.sep)[0];
69311
69230
  return id || null;
69312
69231
  }
69313
69232
  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;
69233
+ const d2 = path77.resolve(dir);
69234
+ const t2 = path77.resolve(absPath);
69235
+ const sep4 = d2.endsWith(path77.sep) ? "" : path77.sep;
69317
69236
  return t2 === d2 || t2.startsWith(d2 + sep4);
69318
69237
  }
69319
69238
  function isPathInGuestBoundary(personaRoot, personaId2, userWorkDir, absPath) {
69320
69239
  if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
69321
- return personaIdFromPath(path78.resolve(absPath), personaRoot) === personaId2;
69240
+ return personaIdFromPath(path77.resolve(absPath), personaRoot) === personaId2;
69322
69241
  }
69323
69242
 
69324
69243
  // src/handlers/history.ts
@@ -69371,7 +69290,7 @@ function buildHistoryHandlers(deps) {
69371
69290
  if (!pid) return false;
69372
69291
  return isGuestPathAllowed(
69373
69292
  ctx.grants,
69374
- path79.join(personaRoot, pid),
69293
+ path78.join(personaRoot, pid),
69375
69294
  personaRoot,
69376
69295
  "read",
69377
69296
  userWorkDir
@@ -69383,7 +69302,7 @@ function buildHistoryHandlers(deps) {
69383
69302
  };
69384
69303
  const list = async (frame, _client, ctx) => {
69385
69304
  const args = HistoryListArgs.parse(frame);
69386
- assertGuestPath(ctx, path79.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
69305
+ assertGuestPath(ctx, path78.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
69387
69306
  const sessions = await history.listSessions(args);
69388
69307
  return { response: { type: "history:list", sessions } };
69389
69308
  };
@@ -69431,14 +69350,14 @@ function buildHistoryHandlers(deps) {
69431
69350
  };
69432
69351
  const subagents = async (frame, _client, ctx) => {
69433
69352
  const args = HistorySubagentsArgs.parse(frame);
69434
- assertGuestPath(ctx, path79.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
69353
+ assertGuestPath(ctx, path78.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
69435
69354
  assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagents");
69436
69355
  const subs = await historyReaderForToolSession(args.toolSessionId).listSubagents(args);
69437
69356
  return { response: { type: "history:subagents", subagents: subs } };
69438
69357
  };
69439
69358
  const subagentRead = async (frame, _client, ctx) => {
69440
69359
  const args = HistorySubagentReadArgs.parse(frame);
69441
- assertGuestPath(ctx, path79.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
69360
+ assertGuestPath(ctx, path78.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
69442
69361
  assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagent-read");
69443
69362
  const res = await historyReaderForToolSession(args.toolSessionId).readSubagent(args);
69444
69363
  return { response: { type: "history:subagent-read", ...res } };
@@ -69448,7 +69367,7 @@ function buildHistoryHandlers(deps) {
69448
69367
  if (ctx?.principal.kind === "guest" && personaRoot) {
69449
69368
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
69450
69369
  const filtered = dirs.filter(
69451
- (d2) => isGuestPathAllowed(ctx.grants, path79.resolve(d2.cwd), personaRoot, "read", userWorkDir)
69370
+ (d2) => isGuestPathAllowed(ctx.grants, path78.resolve(d2.cwd), personaRoot, "read", userWorkDir)
69452
69371
  );
69453
69372
  return { response: { type: "history:recentDirs", dirs: filtered } };
69454
69373
  }
@@ -69467,15 +69386,15 @@ function buildHistoryHandlers(deps) {
69467
69386
  // src/handlers/projects.ts
69468
69387
  var fs75 = __toESM(require("fs"), 1);
69469
69388
  var os23 = __toESM(require("os"), 1);
69470
- var path80 = __toESM(require("path"), 1);
69389
+ var path79 = __toESM(require("path"), 1);
69471
69390
  var import_node_child_process17 = require("child_process");
69472
69391
  init_protocol();
69473
- var DEFAULT_PROJECTS_ROOT = path80.join(os23.homedir(), "Documents", "ChatGPT");
69392
+ var DEFAULT_PROJECTS_ROOT = path79.join(os23.homedir(), "Documents", "ChatGPT");
69474
69393
  function allocateDir(root, name) {
69475
- let candidate = path80.join(root, name);
69394
+ let candidate = path79.join(root, name);
69476
69395
  let n2 = 2;
69477
69396
  while (fs75.existsSync(candidate)) {
69478
- candidate = path80.join(root, `${name} ${n2}`);
69397
+ candidate = path79.join(root, `${name} ${n2}`);
69479
69398
  n2 += 1;
69480
69399
  }
69481
69400
  return candidate;
@@ -69560,7 +69479,7 @@ function buildProjectHandlers(deps) {
69560
69479
  }
69561
69480
 
69562
69481
  // src/handlers/workspace.ts
69563
- var path81 = __toESM(require("path"), 1);
69482
+ var path80 = __toESM(require("path"), 1);
69564
69483
  init_protocol();
69565
69484
  var os24 = __toESM(require("os"), 1);
69566
69485
  init_protocol();
@@ -69603,22 +69522,22 @@ function buildWorkspaceHandlers(deps) {
69603
69522
  const args = WorkspaceListArgs.parse(frame);
69604
69523
  const isGuest = ctx?.principal.kind === "guest";
69605
69524
  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;
69525
+ const resolvedCwd = path80.resolve(args.cwd ?? fallbackCwd);
69526
+ const target = args.path ? path80.resolve(resolvedCwd, args.path) : resolvedCwd;
69608
69527
  assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
69609
69528
  const res = workspace.list({ ...args, cwd: resolvedCwd });
69610
69529
  return { response: { type: "workspace:list", ...res } };
69611
69530
  };
69612
69531
  const read = async (frame, _client, ctx) => {
69613
69532
  const args = WorkspaceReadArgs.parse(frame);
69614
- const target = path81.isAbsolute(args.path) ? path81.resolve(args.path) : path81.resolve(args.cwd, args.path);
69533
+ const target = path80.isAbsolute(args.path) ? path80.resolve(args.path) : path80.resolve(args.cwd, args.path);
69615
69534
  assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
69616
69535
  const res = workspace.read(args);
69617
69536
  return { response: { type: "workspace:read", ...res } };
69618
69537
  };
69619
69538
  const skillsList = async (frame, _client, ctx) => {
69620
69539
  const args = SkillsListArgs.parse(frame);
69621
- const cwdAbs = path81.resolve(args.cwd);
69540
+ const cwdAbs = path80.resolve(args.cwd);
69622
69541
  assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
69623
69542
  const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
69624
69543
  if (ctx?.principal.kind === "guest" && personaRoot) {
@@ -69630,7 +69549,7 @@ function buildWorkspaceHandlers(deps) {
69630
69549
  };
69631
69550
  const agentsList = async (frame, _client, ctx) => {
69632
69551
  const args = AgentsListArgs.parse(frame);
69633
- const cwdAbs = path81.resolve(args.cwd);
69552
+ const cwdAbs = path80.resolve(args.cwd);
69634
69553
  assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
69635
69554
  if (isCodexFamily(args.tool) || args.tool === PI_TOOL_ID) {
69636
69555
  return { response: { type: "agents:list", agents: [] } };
@@ -69652,18 +69571,18 @@ function buildWorkspaceHandlers(deps) {
69652
69571
  }
69653
69572
 
69654
69573
  // src/handlers/git.ts
69655
- var path83 = __toESM(require("path"), 1);
69574
+ var path82 = __toESM(require("path"), 1);
69656
69575
  init_protocol();
69657
69576
  init_protocol();
69658
69577
 
69659
69578
  // src/workspace/git.ts
69660
69579
  var import_node_child_process18 = require("child_process");
69661
69580
  var import_node_fs58 = __toESM(require("fs"), 1);
69662
- var import_node_path65 = __toESM(require("path"), 1);
69581
+ var import_node_path64 = __toESM(require("path"), 1);
69663
69582
  var import_node_util2 = require("util");
69664
69583
  var pexec = (0, import_node_util2.promisify)(import_node_child_process18.execFile);
69665
69584
  function normalizePath(p3) {
69666
- const resolved = import_node_path65.default.resolve(p3);
69585
+ const resolved = import_node_path64.default.resolve(p3);
69667
69586
  try {
69668
69587
  return import_node_fs58.default.realpathSync(resolved);
69669
69588
  } catch {
@@ -69739,7 +69658,7 @@ async function listGitBranches(cwd) {
69739
69658
  function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
69740
69659
  if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
69741
69660
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
69742
- if (!isGuestPathAllowed(ctx.grants, path83.resolve(cwd), personaRoot, "read", userWorkDir)) {
69661
+ if (!isGuestPathAllowed(ctx.grants, path82.resolve(cwd), personaRoot, "read", userWorkDir)) {
69743
69662
  throw new ClawdError(
69744
69663
  ERROR_CODES.UNAUTHORIZED,
69745
69664
  `guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
@@ -69807,8 +69726,8 @@ function refreshPathFromLoginShell() {
69807
69726
  timeout: 3e3,
69808
69727
  stdio: ["ignore", "pipe", "ignore"]
69809
69728
  });
69810
- const path102 = out.trim();
69811
- if (path102) process.env.PATH = path102;
69729
+ const path100 = out.trim();
69730
+ if (path100) process.env.PATH = path100;
69812
69731
  } catch {
69813
69732
  }
69814
69733
  }
@@ -70017,11 +69936,11 @@ async function queryCodexAccount(deps = {}) {
70017
69936
 
70018
69937
  // src/tools/pi-account.ts
70019
69938
  var import_node_fs59 = __toESM(require("fs"), 1);
70020
- var import_node_path66 = __toESM(require("path"), 1);
69939
+ var import_node_path65 = __toESM(require("path"), 1);
70021
69940
  function readPiCredentials(agentDir) {
70022
69941
  let raw;
70023
69942
  try {
70024
- raw = JSON.parse(import_node_fs59.default.readFileSync(import_node_path66.default.join(agentDir, "auth.json"), "utf8"));
69943
+ raw = JSON.parse(import_node_fs59.default.readFileSync(import_node_path65.default.join(agentDir, "auth.json"), "utf8"));
70025
69944
  } catch {
70026
69945
  return {};
70027
69946
  }
@@ -71011,21 +70930,21 @@ function computeMethodAccess(args) {
71011
70930
  }
71012
70931
 
71013
70932
  // src/version.ts
71014
- var version = "0.2.547".length > 0 ? "0.2.547" : "dev";
70933
+ var version = "0.2.549".length > 0 ? "0.2.549" : "dev";
71015
70934
 
71016
70935
  // src/cli-probe/probe.ts
71017
70936
  var fs78 = __toESM(require("fs"), 1);
71018
- var path85 = __toESM(require("path"), 1);
70937
+ var path84 = __toESM(require("path"), 1);
71019
70938
  var PKG_NAME = "@clawos-dev/clawd";
71020
70939
  var BIN_NAME = "clawd";
71021
70940
  var MAX_PARENT_HOPS = 5;
71022
70941
  function probeGlobalCli(pathEnv) {
71023
70942
  if (!pathEnv) return null;
71024
- for (const dir of pathEnv.split(path85.delimiter)) {
70943
+ for (const dir of pathEnv.split(path84.delimiter)) {
71025
70944
  if (!dir) continue;
71026
70945
  let real;
71027
70946
  try {
71028
- real = fs78.realpathSync(path85.join(dir, BIN_NAME));
70947
+ real = fs78.realpathSync(path84.join(dir, BIN_NAME));
71029
70948
  } catch {
71030
70949
  continue;
71031
70950
  }
@@ -71035,15 +70954,15 @@ function probeGlobalCli(pathEnv) {
71035
70954
  return null;
71036
70955
  }
71037
70956
  function readOwnPackageVersion(entryPath) {
71038
- let dir = path85.dirname(entryPath);
70957
+ let dir = path84.dirname(entryPath);
71039
70958
  for (let i2 = 0; i2 < MAX_PARENT_HOPS; i2++) {
71040
70959
  try {
71041
- const raw = fs78.readFileSync(path85.join(dir, "package.json"), "utf8");
70960
+ const raw = fs78.readFileSync(path84.join(dir, "package.json"), "utf8");
71042
70961
  const pkg = JSON.parse(raw);
71043
70962
  if (pkg.name !== PKG_NAME) return null;
71044
70963
  return typeof pkg.version === "string" && pkg.version ? pkg.version : null;
71045
70964
  } catch {
71046
- const parent = path85.dirname(dir);
70965
+ const parent = path84.dirname(dir);
71047
70966
  if (parent === dir) return null;
71048
70967
  dir = parent;
71049
70968
  }
@@ -71219,7 +71138,7 @@ function buildPersonaHandlers(deps) {
71219
71138
  }
71220
71139
 
71221
71140
  // src/handlers/attachment.ts
71222
- var import_node_path67 = __toESM(require("path"), 1);
71141
+ var import_node_path66 = __toESM(require("path"), 1);
71223
71142
  init_protocol();
71224
71143
  init_protocol();
71225
71144
  function assertGuestAttachmentPath(ctx, absPath, personaRoot, method, usersRoot) {
@@ -71298,12 +71217,12 @@ function buildAttachmentHandlers(deps) {
71298
71217
  `session ${args.sessionId} scope unresolved`
71299
71218
  );
71300
71219
  }
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);
71220
+ const cwdAbs = import_node_path66.default.resolve(sessionFile.cwd);
71221
+ 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
71222
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
71304
71223
  const entries = deps.groupFileStore.list(scope, args.sessionId);
71305
71224
  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);
71225
+ 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
71226
  return storedAbs === candidateAbs && !e.stale;
71308
71227
  });
71309
71228
  if (!entry) {
@@ -71327,7 +71246,7 @@ function buildAttachmentHandlers(deps) {
71327
71246
  if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
71328
71247
  const f2 = deps.sessionStore.read(sessionId);
71329
71248
  if (!f2) return;
71330
- assertGuestAttachmentPath(ctx, import_node_path67.default.resolve(f2.cwd), deps.personaRoot, method, deps.usersRoot);
71249
+ assertGuestAttachmentPath(ctx, import_node_path66.default.resolve(f2.cwd), deps.personaRoot, method, deps.usersRoot);
71331
71250
  }
71332
71251
  const groupAdd = async (frame, _client, ctx) => {
71333
71252
  if (!deps.groupFileStore || !deps.getSessionScope) {
@@ -71342,8 +71261,8 @@ function buildAttachmentHandlers(deps) {
71342
71261
  if (!scope) {
71343
71262
  throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
71344
71263
  }
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);
71264
+ const cwdAbs = import_node_path66.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
71265
+ 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
71266
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
71348
71267
  const from = args.origin === "agent" ? "agent" : ctx?.principal.kind === "owner" ? "owner" : "agent";
71349
71268
  const size = 0;
@@ -71402,19 +71321,19 @@ function buildAttachmentHandlers(deps) {
71402
71321
 
71403
71322
  // src/handlers/extension.ts
71404
71323
  var import_promises14 = __toESM(require("fs/promises"), 1);
71405
- var import_node_path72 = __toESM(require("path"), 1);
71324
+ var import_node_path71 = __toESM(require("path"), 1);
71406
71325
  init_protocol();
71407
71326
 
71408
71327
  // src/extension/bundle-zip.ts
71409
71328
  var import_promises11 = __toESM(require("fs/promises"), 1);
71410
- var import_node_path68 = __toESM(require("path"), 1);
71329
+ var import_node_path67 = __toESM(require("path"), 1);
71411
71330
  var import_node_crypto18 = __toESM(require("crypto"), 1);
71412
71331
  var import_jszip2 = __toESM(require_lib3(), 1);
71413
71332
  async function bundleExtensionDir(dir) {
71414
71333
  const entries = await listFilesSorted(dir);
71415
71334
  const zip = new import_jszip2.default();
71416
71335
  for (const rel of entries) {
71417
- const abs = import_node_path68.default.join(dir, rel);
71336
+ const abs = import_node_path67.default.join(dir, rel);
71418
71337
  const content = await import_promises11.default.readFile(abs);
71419
71338
  zip.file(rel, content, { date: FIXED_DATE });
71420
71339
  }
@@ -71435,7 +71354,7 @@ async function listFilesSorted(rootDir) {
71435
71354
  return out;
71436
71355
  }
71437
71356
  async function walk(absRoot, relPrefix, out) {
71438
- const dirAbs = import_node_path68.default.join(absRoot, relPrefix);
71357
+ const dirAbs = import_node_path67.default.join(absRoot, relPrefix);
71439
71358
  const entries = await import_promises11.default.readdir(dirAbs, { withFileTypes: true });
71440
71359
  for (const e of entries) {
71441
71360
  if (IGNORE_BASENAMES.has(e.name)) continue;
@@ -71489,25 +71408,25 @@ function computePublishCheck(args) {
71489
71408
 
71490
71409
  // src/extension/install-flow.ts
71491
71410
  var import_promises12 = __toESM(require("fs/promises"), 1);
71492
- var import_node_path70 = __toESM(require("path"), 1);
71411
+ var import_node_path69 = __toESM(require("path"), 1);
71493
71412
  var import_node_os25 = __toESM(require("os"), 1);
71494
71413
  var import_node_crypto19 = __toESM(require("crypto"), 1);
71495
71414
  var import_jszip3 = __toESM(require_lib3(), 1);
71496
71415
 
71497
71416
  // src/extension/paths.ts
71498
71417
  var import_node_os24 = __toESM(require("os"), 1);
71499
- var import_node_path69 = __toESM(require("path"), 1);
71418
+ var import_node_path68 = __toESM(require("path"), 1);
71500
71419
  function clawdHomeRoot(override) {
71501
- return override ?? process.env.CLAWD_HOME ?? import_node_path69.default.join(import_node_os24.default.homedir(), ".clawd");
71420
+ return override ?? process.env.CLAWD_HOME ?? import_node_path68.default.join(import_node_os24.default.homedir(), ".clawd");
71502
71421
  }
71503
71422
  function extensionsRoot(override) {
71504
- return import_node_path69.default.join(clawdHomeRoot(override), "extensions");
71423
+ return import_node_path68.default.join(clawdHomeRoot(override), "extensions");
71505
71424
  }
71506
71425
  function publishedChannelsFile(override) {
71507
- return import_node_path69.default.join(clawdHomeRoot(override), "extensions-published.json");
71426
+ return import_node_path68.default.join(clawdHomeRoot(override), "extensions-published.json");
71508
71427
  }
71509
71428
  function bundleCacheRoot(override) {
71510
- return import_node_path69.default.join(clawdHomeRoot(override), "extension-bundles");
71429
+ return import_node_path68.default.join(clawdHomeRoot(override), "extension-bundles");
71511
71430
  }
71512
71431
 
71513
71432
  // src/extension/install-flow.ts
@@ -71534,7 +71453,7 @@ async function installFromChannel(args, deps) {
71534
71453
  throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
71535
71454
  }
71536
71455
  for (const name of Object.keys(zip.files)) {
71537
- if (name.includes("..") || name.startsWith("/") || import_node_path70.default.isAbsolute(name)) {
71456
+ if (name.includes("..") || name.startsWith("/") || import_node_path69.default.isAbsolute(name)) {
71538
71457
  throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
71539
71458
  }
71540
71459
  }
@@ -71566,7 +71485,7 @@ async function installFromChannel(args, deps) {
71566
71485
  );
71567
71486
  }
71568
71487
  const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
71569
- const destDir = import_node_path70.default.join(deps.extensionsRoot, localExtId);
71488
+ const destDir = import_node_path69.default.join(deps.extensionsRoot, localExtId);
71570
71489
  let destExists = false;
71571
71490
  try {
71572
71491
  await import_promises12.default.access(destDir);
@@ -71580,16 +71499,16 @@ async function installFromChannel(args, deps) {
71580
71499
  );
71581
71500
  }
71582
71501
  const stage = await import_promises12.default.mkdtemp(
71583
- import_node_path70.default.join(import_node_os25.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
71502
+ import_node_path69.default.join(import_node_os25.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
71584
71503
  );
71585
71504
  try {
71586
71505
  for (const [name, entry] of Object.entries(zip.files)) {
71587
- const dest = import_node_path70.default.join(stage, name);
71506
+ const dest = import_node_path69.default.join(stage, name);
71588
71507
  if (entry.dir) {
71589
71508
  await import_promises12.default.mkdir(dest, { recursive: true });
71590
71509
  continue;
71591
71510
  }
71592
- await import_promises12.default.mkdir(import_node_path70.default.dirname(dest), { recursive: true });
71511
+ await import_promises12.default.mkdir(import_node_path69.default.dirname(dest), { recursive: true });
71593
71512
  if (name === "manifest.json") {
71594
71513
  const rewritten = { ...parsed.data, id: localExtId };
71595
71514
  await import_promises12.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -71610,7 +71529,7 @@ async function installFromChannel(args, deps) {
71610
71529
 
71611
71530
  // src/extension/update-flow.ts
71612
71531
  var import_promises13 = __toESM(require("fs/promises"), 1);
71613
- var import_node_path71 = __toESM(require("path"), 1);
71532
+ var import_node_path70 = __toESM(require("path"), 1);
71614
71533
  var import_node_os26 = __toESM(require("os"), 1);
71615
71534
  var import_node_crypto20 = __toESM(require("crypto"), 1);
71616
71535
  var import_jszip4 = __toESM(require_lib3(), 1);
@@ -71627,11 +71546,11 @@ async function updateFromChannel(args, deps) {
71627
71546
  channelRef.extId,
71628
71547
  channelRef.ownerPrincipalId
71629
71548
  );
71630
- const liveDir = import_node_path71.default.join(deps.extensionsRoot, localExtId);
71549
+ const liveDir = import_node_path70.default.join(deps.extensionsRoot, localExtId);
71631
71550
  const prevDir = `${liveDir}.prev`;
71632
71551
  let existingVersion;
71633
71552
  try {
71634
- const raw = await import_promises13.default.readFile(import_node_path71.default.join(liveDir, "manifest.json"), "utf8");
71553
+ const raw = await import_promises13.default.readFile(import_node_path70.default.join(liveDir, "manifest.json"), "utf8");
71635
71554
  const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
71636
71555
  if (!parsed2.success) {
71637
71556
  throw new UpdateError(
@@ -71664,7 +71583,7 @@ async function updateFromChannel(args, deps) {
71664
71583
  throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
71665
71584
  }
71666
71585
  for (const name of Object.keys(zip.files)) {
71667
- if (name.includes("..") || name.startsWith("/") || import_node_path71.default.isAbsolute(name)) {
71586
+ if (name.includes("..") || name.startsWith("/") || import_node_path70.default.isAbsolute(name)) {
71668
71587
  throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
71669
71588
  }
71670
71589
  }
@@ -71699,16 +71618,16 @@ async function updateFromChannel(args, deps) {
71699
71618
  await import_promises13.default.rm(prevDir, { recursive: true, force: true });
71700
71619
  await import_promises13.default.rename(liveDir, prevDir);
71701
71620
  const stage = await import_promises13.default.mkdtemp(
71702
- import_node_path71.default.join(import_node_os26.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
71621
+ import_node_path70.default.join(import_node_os26.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
71703
71622
  );
71704
71623
  try {
71705
71624
  for (const [name, entry] of Object.entries(zip.files)) {
71706
- const dest = import_node_path71.default.join(stage, name);
71625
+ const dest = import_node_path70.default.join(stage, name);
71707
71626
  if (entry.dir) {
71708
71627
  await import_promises13.default.mkdir(dest, { recursive: true });
71709
71628
  continue;
71710
71629
  }
71711
- await import_promises13.default.mkdir(import_node_path71.default.dirname(dest), { recursive: true });
71630
+ await import_promises13.default.mkdir(import_node_path70.default.dirname(dest), { recursive: true });
71712
71631
  if (name === "manifest.json") {
71713
71632
  const rewritten = { ...parsed.data, id: localExtId };
71714
71633
  await import_promises13.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -71775,7 +71694,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
71775
71694
  );
71776
71695
  }
71777
71696
  }
71778
- const manifestPath = import_node_path72.default.join(root, extId, "manifest.json");
71697
+ const manifestPath = import_node_path71.default.join(root, extId, "manifest.json");
71779
71698
  const manifest = await readManifest(root, extId);
71780
71699
  const next = { ...manifest, version: newVersion };
71781
71700
  const tmp = `${manifestPath}.tmp`;
@@ -71783,7 +71702,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
71783
71702
  await import_promises14.default.rename(tmp, manifestPath);
71784
71703
  }
71785
71704
  async function readManifest(root, extId) {
71786
- const file = import_node_path72.default.join(root, extId, "manifest.json");
71705
+ const file = import_node_path71.default.join(root, extId, "manifest.json");
71787
71706
  let raw;
71788
71707
  try {
71789
71708
  raw = await import_promises14.default.readFile(file, "utf8");
@@ -71867,7 +71786,7 @@ function buildExtensionHandlers(deps) {
71867
71786
  };
71868
71787
  async function buildSnapshotMeta(extId) {
71869
71788
  const manifest = await readManifest(deps.root, extId);
71870
- const { sha256, buffer } = await bundleExtensionDir(import_node_path72.default.join(deps.root, extId));
71789
+ const { sha256, buffer } = await bundleExtensionDir(import_node_path71.default.join(deps.root, extId));
71871
71790
  return { manifest, contentHash: sha256, buffer };
71872
71791
  }
71873
71792
  const publish = async (frame, _client, ctx) => {
@@ -72695,7 +72614,7 @@ function buildVisitorHandlers(deps) {
72695
72614
 
72696
72615
  // src/extension/registry.ts
72697
72616
  var import_promises16 = __toESM(require("fs/promises"), 1);
72698
- var import_node_path73 = __toESM(require("path"), 1);
72617
+ var import_node_path72 = __toESM(require("path"), 1);
72699
72618
  async function loadAll(root) {
72700
72619
  let entries;
72701
72620
  try {
@@ -72708,13 +72627,13 @@ async function loadAll(root) {
72708
72627
  for (const ent of entries) {
72709
72628
  if (!ent.isDirectory()) continue;
72710
72629
  if (ent.name.startsWith(".")) continue;
72711
- records.push(await loadOne(import_node_path73.default.join(root, ent.name), ent.name));
72630
+ records.push(await loadOne(import_node_path72.default.join(root, ent.name), ent.name));
72712
72631
  }
72713
72632
  records.sort((a2, b3) => a2.extId < b3.extId ? -1 : a2.extId > b3.extId ? 1 : 0);
72714
72633
  return records;
72715
72634
  }
72716
72635
  async function loadOne(dir, dirName) {
72717
- const manifestPath = import_node_path73.default.join(dir, "manifest.json");
72636
+ const manifestPath = import_node_path72.default.join(dir, "manifest.json");
72718
72637
  let raw;
72719
72638
  try {
72720
72639
  raw = await import_promises16.default.readFile(manifestPath, "utf8");
@@ -72759,7 +72678,7 @@ async function loadOne(dir, dirName) {
72759
72678
 
72760
72679
  // src/extension/uninstall.ts
72761
72680
  var import_promises17 = __toESM(require("fs/promises"), 1);
72762
- var import_node_path74 = __toESM(require("path"), 1);
72681
+ var import_node_path73 = __toESM(require("path"), 1);
72763
72682
  var UninstallError = class extends Error {
72764
72683
  constructor(code, message) {
72765
72684
  super(message);
@@ -72768,7 +72687,7 @@ var UninstallError = class extends Error {
72768
72687
  code;
72769
72688
  };
72770
72689
  async function uninstall(deps) {
72771
- const dir = import_node_path74.default.join(deps.root, deps.extId);
72690
+ const dir = import_node_path73.default.join(deps.root, deps.extId);
72772
72691
  try {
72773
72692
  await import_promises17.default.access(dir);
72774
72693
  } catch {
@@ -72983,7 +72902,7 @@ function buildMethodHandlers(deps) {
72983
72902
  broadcast: deps.broadcastToOwners
72984
72903
  }),
72985
72904
  ...buildMasterHandlers({
72986
- authorityTablePath: import_node_path75.default.join(deps.masterDataDir, "master-authority.json")
72905
+ authorityTablePath: import_node_path74.default.join(deps.masterDataDir, "master-authority.json")
72987
72906
  }),
72988
72907
  ...buildTopicHandlers({
72989
72908
  topicStore: deps.topicStore,
@@ -73083,45 +73002,6 @@ function buildOnboardingHandlers(deps) {
73083
73002
  return { "onboarding:complete": complete, "tools:probe": toolsProbe, "onboarding:iosInterest": iosInterest };
73084
73003
  }
73085
73004
 
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
73005
  // src/handlers/dispatch-rpc.ts
73126
73006
  init_zod();
73127
73007
  init_protocol();
@@ -73165,7 +73045,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
73165
73045
 
73166
73046
  // src/extension/runtime.ts
73167
73047
  var import_node_child_process24 = require("child_process");
73168
- var import_node_path77 = __toESM(require("path"), 1);
73048
+ var import_node_path75 = __toESM(require("path"), 1);
73169
73049
  var import_promises18 = require("timers/promises");
73170
73050
 
73171
73051
  // src/extension/port-allocator.ts
@@ -73266,7 +73146,7 @@ var Runtime = class {
73266
73146
  /\$CLAWOS_EXT_PORT/g,
73267
73147
  String(port)
73268
73148
  );
73269
- const dir = import_node_path77.default.join(this.root, extId);
73149
+ const dir = import_node_path75.default.join(this.root, extId);
73270
73150
  const env = {
73271
73151
  ...process.env,
73272
73152
  CLAWOS_EXT_PORT: String(port),
@@ -73378,7 +73258,7 @@ ${handle.stderrTail}`
73378
73258
 
73379
73259
  // src/extension/published-channels.ts
73380
73260
  var import_promises19 = __toESM(require("fs/promises"), 1);
73381
- var import_node_path78 = __toESM(require("path"), 1);
73261
+ var import_node_path76 = __toESM(require("path"), 1);
73382
73262
  init_zod();
73383
73263
  var PublishedChannelsError = class extends Error {
73384
73264
  constructor(code, message) {
@@ -73477,7 +73357,7 @@ var PublishedChannelStore = class {
73477
73357
  )
73478
73358
  };
73479
73359
  const tmp = `${this.filePath}.tmp`;
73480
- await import_promises19.default.mkdir(import_node_path78.default.dirname(this.filePath), { recursive: true });
73360
+ await import_promises19.default.mkdir(import_node_path76.default.dirname(this.filePath), { recursive: true });
73481
73361
  await import_promises19.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
73482
73362
  await import_promises19.default.rename(tmp, this.filePath);
73483
73363
  }
@@ -73485,7 +73365,7 @@ var PublishedChannelStore = class {
73485
73365
 
73486
73366
  // src/extension/bundle-cache.ts
73487
73367
  var import_promises20 = __toESM(require("fs/promises"), 1);
73488
- var import_node_path79 = __toESM(require("path"), 1);
73368
+ var import_node_path77 = __toESM(require("path"), 1);
73489
73369
  var BundleCache = class {
73490
73370
  constructor(rootDir) {
73491
73371
  this.rootDir = rootDir;
@@ -73494,14 +73374,14 @@ var BundleCache = class {
73494
73374
  /** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
73495
73375
  async write(snapshotHash, buffer) {
73496
73376
  await import_promises20.default.mkdir(this.rootDir, { recursive: true });
73497
- const file = import_node_path79.default.join(this.rootDir, `${snapshotHash}.zip`);
73377
+ const file = import_node_path77.default.join(this.rootDir, `${snapshotHash}.zip`);
73498
73378
  const tmp = `${file}.tmp`;
73499
73379
  await import_promises20.default.writeFile(tmp, buffer, { mode: 384 });
73500
73380
  await import_promises20.default.rename(tmp, file);
73501
73381
  }
73502
73382
  /** Returns the bundle bytes, or null when the file doesn't exist. */
73503
73383
  async read(snapshotHash) {
73504
- const file = import_node_path79.default.join(this.rootDir, `${snapshotHash}.zip`);
73384
+ const file = import_node_path77.default.join(this.rootDir, `${snapshotHash}.zip`);
73505
73385
  try {
73506
73386
  return await import_promises20.default.readFile(file);
73507
73387
  } catch (e) {
@@ -73511,7 +73391,7 @@ var BundleCache = class {
73511
73391
  }
73512
73392
  /** Idempotent — missing file is not an error. */
73513
73393
  async delete(snapshotHash) {
73514
- const file = import_node_path79.default.join(this.rootDir, `${snapshotHash}.zip`);
73394
+ const file = import_node_path77.default.join(this.rootDir, `${snapshotHash}.zip`);
73515
73395
  await import_promises20.default.rm(file, { force: true });
73516
73396
  }
73517
73397
  };
@@ -73534,24 +73414,24 @@ async function startDaemon(config) {
73534
73414
  sampling: logShippingCfg.sampling,
73535
73415
  homeDir: import_node_os28.default.homedir()
73536
73416
  });
73537
- const logDir = import_node_path80.default.join(config.dataDir, "log");
73538
- import_node_fs61.default.mkdirSync(logDir, { recursive: true });
73417
+ const logDir = import_node_path78.default.join(config.dataDir, "log");
73418
+ import_node_fs60.default.mkdirSync(logDir, { recursive: true });
73539
73419
  const logger = createLogger({
73540
73420
  level: config.logLevel,
73541
- file: import_node_path80.default.join(logDir, "clawd.log"),
73421
+ file: import_node_path78.default.join(logDir, "clawd.log"),
73542
73422
  logClient
73543
73423
  });
73544
73424
  logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
73545
73425
  const screenIdleProbeLogger = createFileOnlyLogger({
73546
- file: import_node_path80.default.join(logDir, "screen-idle-probe.log"),
73426
+ file: import_node_path78.default.join(logDir, "screen-idle-probe.log"),
73547
73427
  level: "debug"
73548
73428
  });
73549
73429
  logger.info("screen-idle probe logger enabled", {
73550
- file: import_node_path80.default.join(logDir, "screen-idle-probe.log")
73430
+ file: import_node_path78.default.join(logDir, "screen-idle-probe.log")
73551
73431
  });
73552
73432
  const CAP_TARGETS = [
73553
- import_node_path80.default.join(logDir, "clawd.log"),
73554
- import_node_path80.default.join(logDir, "screen-idle-probe.log")
73433
+ import_node_path78.default.join(logDir, "clawd.log"),
73434
+ import_node_path78.default.join(logDir, "screen-idle-probe.log")
73555
73435
  ];
73556
73436
  const LOG_CAP_MAX_BYTES = 10 * 1024 * 1024;
73557
73437
  const LOG_CAP_KEEP_BYTES = 5 * 1024 * 1024;
@@ -73673,8 +73553,8 @@ async function startDaemon(config) {
73673
73553
  const agents = new AgentsScanner();
73674
73554
  const history = new ClaudeHistoryReader();
73675
73555
  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");
73556
+ const personaStore = new PersonaStore(import_node_path78.default.join(config.dataDir, "personas"));
73557
+ const usersRoot = import_node_path78.default.join(config.dataDir, "users");
73678
73558
  const defaultsRoot = findDefaultsRoot(logger);
73679
73559
  if (defaultsRoot) {
73680
73560
  seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
@@ -73683,13 +73563,6 @@ async function startDaemon(config) {
73683
73563
  } else {
73684
73564
  logger.warn("persona.seed.skip", { reason: "defaults-root-not-found" });
73685
73565
  }
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
73566
  refreshSandboxSettings({ store: personaStore, logger });
73694
73567
  migrateAgentsMirror({ store: personaStore, logger });
73695
73568
  migrateCodexSandbox({ store: personaStore, logger });
@@ -73698,7 +73571,7 @@ async function startDaemon(config) {
73698
73571
  retirePersonaBuilder({ store: personaStore, logger });
73699
73572
  const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
73700
73573
  const dispatchStore = createDispatchStore({
73701
- filePath: import_node_path80.default.join(config.dataDir, "dispatch.json"),
73574
+ filePath: import_node_path78.default.join(config.dataDir, "dispatch.json"),
73702
73575
  now: () => Date.now(),
73703
73576
  onFlushError: (err) => logger.error("dispatch store flush failed", {
73704
73577
  reason: err instanceof Error ? err.message : String(err)
@@ -73707,7 +73580,7 @@ async function startDaemon(config) {
73707
73580
  await dispatchStore.load();
73708
73581
  dispatchStore.markInterruptedAsFailed((/* @__PURE__ */ new Date()).toISOString());
73709
73582
  const channelStore = createChannelStore({
73710
- filePath: import_node_path80.default.join(config.dataDir, "channels.json"),
73583
+ filePath: import_node_path78.default.join(config.dataDir, "channels.json"),
73711
73584
  now: () => Date.now(),
73712
73585
  genId: () => `ch-${(0, import_node_crypto22.randomUUID)().slice(0, 8)}`,
73713
73586
  onFlushError: (err) => logger.error("channel store flush failed", {
@@ -73716,7 +73589,7 @@ async function startDaemon(config) {
73716
73589
  });
73717
73590
  await channelStore.load();
73718
73591
  const topicStore = createTopicStore({
73719
- filePath: import_node_path80.default.join(config.dataDir, "topics.json"),
73592
+ filePath: import_node_path78.default.join(config.dataDir, "topics.json"),
73720
73593
  now: () => Date.now(),
73721
73594
  genId: () => `tp-${(0, import_node_crypto22.randomUUID)().slice(0, 8)}`,
73722
73595
  onFlushError: (err) => logger.error("topic store flush failed", {
@@ -73743,12 +73616,12 @@ async function startDaemon(config) {
73743
73616
  });
73744
73617
  }
73745
73618
  });
73746
- const here = typeof __dirname === "string" ? __dirname : import_node_path80.default.dirname((0, import_node_url5.fileURLToPath)(import_meta9.url));
73619
+ const here = typeof __dirname === "string" ? __dirname : import_node_path78.default.dirname((0, import_node_url5.fileURLToPath)(import_meta9.url));
73747
73620
  const mcpConfigs = [];
73748
73621
  const secretsBundleRoot = findSecretsBundleRoot(logger);
73749
- const localSecretsDir = import_node_path80.default.join(config.dataDir, LOCAL_SECRETS_DIRNAME);
73622
+ const localSecretsDir = import_node_path78.default.join(config.dataDir, LOCAL_SECRETS_DIRNAME);
73750
73623
  const readSecrets = () => readSecretTable({ bundleRoot: secretsBundleRoot, overrideDir: localSecretsDir, logger });
73751
- const githubTokenFile = import_node_path80.default.join(localSecretsDir, GITHUB_TOKEN_FILE);
73624
+ const githubTokenFile = import_node_path78.default.join(localSecretsDir, GITHUB_TOKEN_FILE);
73752
73625
  const githubIdentity = createGithubIdentity({
73753
73626
  resolve: () => resolveGithubAuth({ exec: runCommand, fileToken: () => readEnvFileVar(githubTokenFile, GITHUB_TOKEN_VAR) }),
73754
73627
  store: (token) => storeGithubAuth({
@@ -73781,29 +73654,27 @@ async function startDaemon(config) {
73781
73654
  logger
73782
73655
  });
73783
73656
  void githubIdentity.refresh();
73784
- let refreshAppBuilderMcpConfig;
73785
73657
  const resolvePersonaMcpConfig = (personaId2) => {
73786
- refreshAppBuilderMcpConfig?.(personaId2);
73787
73658
  const secrets = secretsWithGithubIdentity(readSecrets(), githubIdentity.cached());
73788
73659
  void githubIdentity.refresh();
73789
73660
  return renderPersonaMcpSecrets({
73790
73661
  personaId: personaId2,
73791
- personaDir: import_node_path80.default.join(config.dataDir, "personas", personaId2),
73662
+ personaDir: import_node_path78.default.join(config.dataDir, "personas", personaId2),
73792
73663
  secrets,
73793
- outDir: import_node_path80.default.join(config.dataDir, "persona-mcp"),
73664
+ outDir: import_node_path78.default.join(config.dataDir, "persona-mcp"),
73794
73665
  logger
73795
73666
  });
73796
73667
  };
73797
73668
  const mcpDaemonUrl = `http://127.0.0.1:${config.port}`;
73798
73669
  const dispatchServerCandidates = [
73799
- import_node_path80.default.join(here, "dispatch", "mcp-server.cjs"),
73670
+ import_node_path78.default.join(here, "dispatch", "mcp-server.cjs"),
73800
73671
  // 生产 dist/index → dist/dispatch/mcp-server.cjs
73801
- import_node_path80.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
73672
+ import_node_path78.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
73802
73673
  // dev tsx src/index → ../dist/dispatch/mcp-server.cjs
73803
73674
  ];
73804
- const dispatchServerScriptPath = dispatchServerCandidates.find((p3) => import_node_fs61.default.existsSync(p3));
73675
+ const dispatchServerScriptPath = dispatchServerCandidates.find((p3) => import_node_fs60.default.existsSync(p3));
73805
73676
  if (dispatchServerScriptPath) {
73806
- const dispatchLogPath = import_node_path80.default.join(logDir, "dispatch-mcp-server.log");
73677
+ const dispatchLogPath = import_node_path78.default.join(logDir, "dispatch-mcp-server.log");
73807
73678
  const dispatchCfgPath = writeDispatchMcpConfig({
73808
73679
  dataDir: config.dataDir,
73809
73680
  serverScriptPath: dispatchServerScriptPath,
@@ -73823,12 +73694,12 @@ async function startDaemon(config) {
73823
73694
  });
73824
73695
  }
73825
73696
  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")
73697
+ import_node_path78.default.join(here, "ticket", "mcp-server.cjs"),
73698
+ import_node_path78.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
73828
73699
  ];
73829
- const ticketServerScriptPath = ticketServerCandidates.find((p3) => import_node_fs61.default.existsSync(p3));
73700
+ const ticketServerScriptPath = ticketServerCandidates.find((p3) => import_node_fs60.default.existsSync(p3));
73830
73701
  if (ticketServerScriptPath) {
73831
- const ticketLogPath = import_node_path80.default.join(logDir, "ticket-mcp-server.log");
73702
+ const ticketLogPath = import_node_path78.default.join(logDir, "ticket-mcp-server.log");
73832
73703
  const ticketCfgPath = writeTicketMcpConfig({
73833
73704
  dataDir: config.dataDir,
73834
73705
  serverScriptPath: ticketServerScriptPath,
@@ -73850,12 +73721,12 @@ async function startDaemon(config) {
73850
73721
  });
73851
73722
  }
73852
73723
  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")
73724
+ import_node_path78.default.join(here, "shift", "mcp-server.cjs"),
73725
+ import_node_path78.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
73855
73726
  ];
73856
- const shiftServerScriptPath = shiftServerCandidates.find((p3) => import_node_fs61.default.existsSync(p3));
73727
+ const shiftServerScriptPath = shiftServerCandidates.find((p3) => import_node_fs60.default.existsSync(p3));
73857
73728
  if (shiftServerScriptPath) {
73858
- const shiftLogPath = import_node_path80.default.join(logDir, "shift-mcp-server.log");
73729
+ const shiftLogPath = import_node_path78.default.join(logDir, "shift-mcp-server.log");
73859
73730
  const shiftCfgPath = await writeShiftMcpConfig({
73860
73731
  dataDir: config.dataDir,
73861
73732
  serverScriptPath: shiftServerScriptPath,
@@ -73876,12 +73747,12 @@ async function startDaemon(config) {
73876
73747
  );
73877
73748
  }
73878
73749
  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")
73750
+ import_node_path78.default.join(here, "inbox", "mcp-server.cjs"),
73751
+ import_node_path78.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
73881
73752
  ];
73882
- const inboxServerScriptPath = inboxServerCandidates.find((p3) => import_node_fs61.default.existsSync(p3));
73753
+ const inboxServerScriptPath = inboxServerCandidates.find((p3) => import_node_fs60.default.existsSync(p3));
73883
73754
  if (inboxServerScriptPath) {
73884
- const inboxLogPath = import_node_path80.default.join(logDir, "inbox-mcp-server.log");
73755
+ const inboxLogPath = import_node_path78.default.join(logDir, "inbox-mcp-server.log");
73885
73756
  const inboxCfgPath = await writeInboxMcpConfig({
73886
73757
  dataDir: config.dataDir,
73887
73758
  serverScriptPath: inboxServerScriptPath,
@@ -73902,10 +73773,10 @@ async function startDaemon(config) {
73902
73773
  );
73903
73774
  }
73904
73775
  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")
73776
+ import_node_path78.default.join(here, "peer-ops", "mcp-server.cjs"),
73777
+ import_node_path78.default.join(here, "..", "dist", "peer-ops", "mcp-server.cjs")
73907
73778
  ];
73908
- const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) => import_node_fs61.default.existsSync(p3));
73779
+ const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) => import_node_fs60.default.existsSync(p3));
73909
73780
  if (peerOpsServerScriptPath) {
73910
73781
  const peerOpsCfgPath = writePeerOpsMcpConfig({
73911
73782
  dataDir: config.dataDir,
@@ -73925,12 +73796,12 @@ async function startDaemon(config) {
73925
73796
  );
73926
73797
  }
73927
73798
  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")
73799
+ import_node_path78.default.join(here, "rpc-tool", "mcp-server.cjs"),
73800
+ import_node_path78.default.join(here, "..", "dist", "rpc-tool", "mcp-server.cjs")
73930
73801
  ];
73931
- const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) => import_node_fs61.default.existsSync(p3));
73802
+ const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) => import_node_fs60.default.existsSync(p3));
73932
73803
  if (rpcToolServerScriptPath) {
73933
- const rpcToolLogPath = import_node_path80.default.join(logDir, "rpc-tool-mcp-server.log");
73804
+ const rpcToolLogPath = import_node_path78.default.join(logDir, "rpc-tool-mcp-server.log");
73934
73805
  const rpcToolCfgPath = writeRpcToolMcpConfig({
73935
73806
  dataDir: config.dataDir,
73936
73807
  serverScriptPath: rpcToolServerScriptPath,
@@ -73950,48 +73821,8 @@ async function startDaemon(config) {
73950
73821
  { tried: rpcToolServerCandidates }
73951
73822
  );
73952
73823
  }
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
73824
  const shiftStore = createShiftStore({
73994
- filePath: import_node_path80.default.join(config.dataDir, "shift.json"),
73825
+ filePath: import_node_path78.default.join(config.dataDir, "shift.json"),
73995
73826
  ownerIdProvider: () => ownerPrincipalId,
73996
73827
  now: () => Date.now()
73997
73828
  });
@@ -74013,7 +73844,7 @@ async function startDaemon(config) {
74013
73844
  getAdapter,
74014
73845
  historyReader: history,
74015
73846
  dataDir: config.dataDir,
74016
- personaRoot: import_node_path80.default.join(config.dataDir, "personas"),
73847
+ personaRoot: import_node_path78.default.join(config.dataDir, "personas"),
74017
73848
  // dispatch / shift 自动化 spawn 按 persona 绑定 tool 起 B session(codex persona 用 codex)。
74018
73849
  // personaRegistry 声明在 manager 之后(同作用域 const,调用时机在启动完成后,无 TDZ 风险)。
74019
73850
  getPersonaDefaults: (personaId2) => personaRegistry.get(personaId2),
@@ -74070,10 +73901,10 @@ async function startDaemon(config) {
74070
73901
  // 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
74071
73902
  attachmentGroup: {
74072
73903
  onFileEdit: (input) => {
74073
- const absPath = import_node_path80.default.isAbsolute(input.relPath) ? input.relPath : import_node_path80.default.join(input.cwd, input.relPath);
73904
+ const absPath = import_node_path78.default.isAbsolute(input.relPath) ? input.relPath : import_node_path78.default.join(input.cwd, input.relPath);
74074
73905
  let size = 0;
74075
73906
  try {
74076
- size = import_node_fs61.default.statSync(absPath).size;
73907
+ size = import_node_fs60.default.statSync(absPath).size;
74077
73908
  } catch (err) {
74078
73909
  logger.warn("attachment.onFileEdit stat failed", {
74079
73910
  sessionId: input.sessionId,
@@ -74114,9 +73945,9 @@ async function startDaemon(config) {
74114
73945
  logger.info("projects.seed-dropped", { dropped: droppedSeed.dropped, backup: droppedSeed.backup });
74115
73946
  }
74116
73947
  const projectsStore = new ProjectsStore({
74117
- file: import_node_path80.default.join(config.dataDir, "projects.json"),
73948
+ file: import_node_path78.default.join(config.dataDir, "projects.json"),
74118
73949
  clawdDir: config.dataDir,
74119
- codexStateFile: import_node_path80.default.join(import_node_os28.default.homedir(), ".codex", ".codex-global-state.json"),
73950
+ codexStateFile: import_node_path78.default.join(import_node_os28.default.homedir(), ".codex", ".codex-global-state.json"),
74120
73951
  logger
74121
73952
  });
74122
73953
  const observer = new SessionObserver({
@@ -74181,13 +74012,13 @@ async function startDaemon(config) {
74181
74012
  logger
74182
74013
  });
74183
74014
  registerAdapter("claude", claudeAdapter);
74184
- const codexIsolatedHome = import_node_path80.default.join(config.dataDir, "codex-home");
74015
+ const codexIsolatedHome = import_node_path78.default.join(config.dataDir, "codex-home");
74185
74016
  try {
74186
- import_node_fs61.default.mkdirSync(codexIsolatedHome, { recursive: true });
74017
+ import_node_fs60.default.mkdirSync(codexIsolatedHome, { recursive: true });
74187
74018
  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);
74019
+ const link = import_node_path78.default.join(codexIsolatedHome, f2);
74020
+ const target = import_node_path78.default.join(import_node_os28.default.homedir(), ".codex", f2);
74021
+ if (!import_node_fs60.default.existsSync(link) && import_node_fs60.default.existsSync(target)) import_node_fs60.default.symlinkSync(target, link);
74191
74022
  }
74192
74023
  } catch (err) {
74193
74024
  logger.warn("codex isolated home setup failed", { err: String(err) });
@@ -74198,17 +74029,17 @@ async function startDaemon(config) {
74198
74029
  logger,
74199
74030
  historyReader: new CodexHistoryReader({
74200
74031
  roots: codexRolloutRoots(config.dataDir),
74201
- sharedHome: import_node_path80.default.join(import_node_os28.default.homedir(), ".codex"),
74032
+ sharedHome: import_node_path78.default.join(import_node_os28.default.homedir(), ".codex"),
74202
74033
  logger
74203
74034
  }),
74204
74035
  // projectPaths 每次调用现取 —— 用户新建 project 后立即生效,不用重启 daemon
74205
74036
  codexHomeFor: (cwd) => resolveCodexHome({
74206
74037
  cwd,
74207
- personaRoot: import_node_path80.default.join(config.dataDir, "personas"),
74038
+ personaRoot: import_node_path78.default.join(config.dataDir, "personas"),
74208
74039
  // 必须用 listMerged(Codex registry ∪ 叠加层):只用本地 list() 的话,用户在
74209
74040
  // Codex 里建的 project 不在表里,在它下面开的会话会被误判成隔离 → Codex 侧看不到
74210
74041
  projectPaths: projectsStore.listMerged().map((x2) => x2.path),
74211
- sharedHome: import_node_path80.default.join(import_node_os28.default.homedir(), ".codex"),
74042
+ sharedHome: import_node_path78.default.join(import_node_os28.default.homedir(), ".codex"),
74212
74043
  isolatedHome: codexIsolatedHome
74213
74044
  }),
74214
74045
  // 附件图片验签:与 http-router /files 路由同一把 secret
@@ -74232,10 +74063,10 @@ async function startDaemon(config) {
74232
74063
  })
74233
74064
  );
74234
74065
  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")
74066
+ import_node_path78.default.join(here, "pi-mcp-bridge", "extension.cjs"),
74067
+ import_node_path78.default.join(here, "..", "dist", "pi-mcp-bridge", "extension.cjs")
74237
74068
  ];
74238
- const piMcpBridgePath = piMcpBridgeCandidates.find((p3) => import_node_fs61.default.existsSync(p3));
74069
+ const piMcpBridgePath = piMcpBridgeCandidates.find((p3) => import_node_fs60.default.existsSync(p3));
74239
74070
  if (piMcpBridgePath) {
74240
74071
  logger.info("pi-mcp-bridge extension resolved", { path: piMcpBridgePath });
74241
74072
  } else {
@@ -74530,11 +74361,11 @@ async function startDaemon(config) {
74530
74361
  // 'persona/<pid>/owner',default 走 'default'。
74531
74362
  getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
74532
74363
  // guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
74533
- personaRoot: import_node_path80.default.join(config.dataDir, "personas"),
74364
+ personaRoot: import_node_path78.default.join(config.dataDir, "personas"),
74534
74365
  usersRoot
74535
74366
  },
74536
74367
  // workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
74537
- personaRoot: import_node_path80.default.join(config.dataDir, "personas"),
74368
+ personaRoot: import_node_path78.default.join(config.dataDir, "personas"),
74538
74369
  // v2 多人 persona 隔离:handler 派生 guest user-dir 放行
74539
74370
  usersRoot,
74540
74371
  // v2 Phase 6: whoami handler 装在 owner principal.displayName + persona 解析
@@ -74815,7 +74646,7 @@ async function startDaemon(config) {
74815
74646
  });
74816
74647
  shiftScheduler.start();
74817
74648
  logger.info("shift scheduler started", { shiftCount: shiftStore.list().length });
74818
- const larkBotStore = createLarkBotBindingStore(import_node_path80.default.join(config.dataDir, "personas"));
74649
+ const larkBotStore = createLarkBotBindingStore(import_node_path78.default.join(config.dataDir, "personas"));
74819
74650
  const larkBotCloud = createLarkBotCloudClient({
74820
74651
  api: config.clawosApi ?? DEFAULT_CLAWOS_API,
74821
74652
  getLoginPass: () => ownerIdentityStore.read()?.loginPass ?? null
@@ -74827,7 +74658,7 @@ async function startDaemon(config) {
74827
74658
  store: larkBotStore,
74828
74659
  fetchResource: (appId, messageId, fileKey, maxBytes, type) => larkBotCloud.fetchResource(appId, messageId, fileKey, maxBytes, type),
74829
74660
  // 图片落 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"),
74661
+ mediaRootFor: (chatId) => import_node_path78.default.join(deriveUserWorkDir(`lark-${chatId}`, usersRoot), "lark-media"),
74831
74662
  isShuttingDown: () => larkDraining,
74832
74663
  logger: {
74833
74664
  warn: (msg) => logger.warn(msg),
@@ -75111,8 +74942,8 @@ async function startDaemon(config) {
75111
74942
  const lines = [
75112
74943
  `Tunnel: ${r2.url}`,
75113
74944
  ...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")}`
74945
+ `Frpc config: ${import_node_path78.default.join(config.dataDir, "frpc.toml")}`,
74946
+ `Frpc log: ${import_node_path78.default.join(logDir, "frpc.log")}`
75116
74947
  ];
75117
74948
  const width2 = Math.max(...lines.map((l2) => l2.length));
75118
74949
  const bar = "\u2550".repeat(width2 + 4);
@@ -75125,8 +74956,8 @@ ${bar}
75125
74956
 
75126
74957
  `);
75127
74958
  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 });
74959
+ const connectPath = import_node_path78.default.join(config.dataDir, "connect.txt");
74960
+ import_node_fs60.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
75130
74961
  } catch {
75131
74962
  }
75132
74963
  } catch (err) {
@@ -75224,9 +75055,9 @@ ${bar}
75224
75055
  };
75225
75056
  }
75226
75057
  function migrateDropPersonsDir(dataDir) {
75227
- const dir = import_node_path80.default.join(dataDir, "persons");
75058
+ const dir = import_node_path78.default.join(dataDir, "persons");
75228
75059
  try {
75229
- import_node_fs61.default.rmSync(dir, { recursive: true, force: true });
75060
+ import_node_fs60.default.rmSync(dir, { recursive: true, force: true });
75230
75061
  } catch {
75231
75062
  }
75232
75063
  }