@clawos-dev/clawd 0.2.191-beta.383.956b6ae → 0.2.191

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs CHANGED
@@ -733,8 +733,8 @@ var init_parseUtil = __esm({
733
733
  init_errors2();
734
734
  init_en();
735
735
  makeIssue = (params) => {
736
- const { data, path: path67, errorMaps, issueData } = params;
737
- const fullPath = [...path67, ...issueData.path || []];
736
+ const { data, path: path68, errorMaps, issueData } = params;
737
+ const fullPath = [...path68, ...issueData.path || []];
738
738
  const fullIssue = {
739
739
  ...issueData,
740
740
  path: fullPath
@@ -1045,11 +1045,11 @@ var init_types = __esm({
1045
1045
  init_parseUtil();
1046
1046
  init_util();
1047
1047
  ParseInputLazyPath = class {
1048
- constructor(parent, value, path67, key) {
1048
+ constructor(parent, value, path68, key) {
1049
1049
  this._cachedPath = [];
1050
1050
  this.parent = parent;
1051
1051
  this.data = value;
1052
- this._path = path67;
1052
+ this._path = path68;
1053
1053
  this._key = key;
1054
1054
  }
1055
1055
  get path() {
@@ -6373,8 +6373,8 @@ var require_req = __commonJS({
6373
6373
  if (req.originalUrl) {
6374
6374
  _req.url = req.originalUrl;
6375
6375
  } else {
6376
- const path67 = req.path;
6377
- _req.url = typeof path67 === "string" ? path67 : req.url ? req.url.path || req.url : void 0;
6376
+ const path68 = req.path;
6377
+ _req.url = typeof path68 === "string" ? path68 : req.url ? req.url.path || req.url : void 0;
6378
6378
  }
6379
6379
  if (req.query) {
6380
6380
  _req.query = req.query;
@@ -6539,14 +6539,14 @@ var require_redact = __commonJS({
6539
6539
  }
6540
6540
  return obj;
6541
6541
  }
6542
- function parsePath(path67) {
6542
+ function parsePath(path68) {
6543
6543
  const parts = [];
6544
6544
  let current = "";
6545
6545
  let inBrackets = false;
6546
6546
  let inQuotes = false;
6547
6547
  let quoteChar = "";
6548
- for (let i = 0; i < path67.length; i++) {
6549
- const char = path67[i];
6548
+ for (let i = 0; i < path68.length; i++) {
6549
+ const char = path68[i];
6550
6550
  if (!inBrackets && char === ".") {
6551
6551
  if (current) {
6552
6552
  parts.push(current);
@@ -6677,10 +6677,10 @@ var require_redact = __commonJS({
6677
6677
  return current;
6678
6678
  }
6679
6679
  function redactPaths(obj, paths, censor, remove = false) {
6680
- for (const path67 of paths) {
6681
- const parts = parsePath(path67);
6680
+ for (const path68 of paths) {
6681
+ const parts = parsePath(path68);
6682
6682
  if (parts.includes("*")) {
6683
- redactWildcardPath(obj, parts, censor, path67, remove);
6683
+ redactWildcardPath(obj, parts, censor, path68, remove);
6684
6684
  } else {
6685
6685
  if (remove) {
6686
6686
  removeKey(obj, parts);
@@ -6765,8 +6765,8 @@ var require_redact = __commonJS({
6765
6765
  }
6766
6766
  } else {
6767
6767
  if (afterWildcard.includes("*")) {
6768
- const wrappedCensor = typeof censor === "function" ? (value, path67) => {
6769
- const fullPath = [...pathArray.slice(0, pathLength), ...path67];
6768
+ const wrappedCensor = typeof censor === "function" ? (value, path68) => {
6769
+ const fullPath = [...pathArray.slice(0, pathLength), ...path68];
6770
6770
  return censor(value, fullPath);
6771
6771
  } : censor;
6772
6772
  redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
@@ -6801,8 +6801,8 @@ var require_redact = __commonJS({
6801
6801
  return null;
6802
6802
  }
6803
6803
  const pathStructure = /* @__PURE__ */ new Map();
6804
- for (const path67 of pathsToClone) {
6805
- const parts = parsePath(path67);
6804
+ for (const path68 of pathsToClone) {
6805
+ const parts = parsePath(path68);
6806
6806
  let current = pathStructure;
6807
6807
  for (let i = 0; i < parts.length; i++) {
6808
6808
  const part = parts[i];
@@ -6854,24 +6854,24 @@ var require_redact = __commonJS({
6854
6854
  }
6855
6855
  return cloneSelectively(obj, pathStructure);
6856
6856
  }
6857
- function validatePath(path67) {
6858
- if (typeof path67 !== "string") {
6857
+ function validatePath(path68) {
6858
+ if (typeof path68 !== "string") {
6859
6859
  throw new Error("Paths must be (non-empty) strings");
6860
6860
  }
6861
- if (path67 === "") {
6861
+ if (path68 === "") {
6862
6862
  throw new Error("Invalid redaction path ()");
6863
6863
  }
6864
- if (path67.includes("..")) {
6865
- throw new Error(`Invalid redaction path (${path67})`);
6864
+ if (path68.includes("..")) {
6865
+ throw new Error(`Invalid redaction path (${path68})`);
6866
6866
  }
6867
- if (path67.includes(",")) {
6868
- throw new Error(`Invalid redaction path (${path67})`);
6867
+ if (path68.includes(",")) {
6868
+ throw new Error(`Invalid redaction path (${path68})`);
6869
6869
  }
6870
6870
  let bracketCount = 0;
6871
6871
  let inQuotes = false;
6872
6872
  let quoteChar = "";
6873
- for (let i = 0; i < path67.length; i++) {
6874
- const char = path67[i];
6873
+ for (let i = 0; i < path68.length; i++) {
6874
+ const char = path68[i];
6875
6875
  if ((char === '"' || char === "'") && bracketCount > 0) {
6876
6876
  if (!inQuotes) {
6877
6877
  inQuotes = true;
@@ -6885,20 +6885,20 @@ var require_redact = __commonJS({
6885
6885
  } else if (char === "]" && !inQuotes) {
6886
6886
  bracketCount--;
6887
6887
  if (bracketCount < 0) {
6888
- throw new Error(`Invalid redaction path (${path67})`);
6888
+ throw new Error(`Invalid redaction path (${path68})`);
6889
6889
  }
6890
6890
  }
6891
6891
  }
6892
6892
  if (bracketCount !== 0) {
6893
- throw new Error(`Invalid redaction path (${path67})`);
6893
+ throw new Error(`Invalid redaction path (${path68})`);
6894
6894
  }
6895
6895
  }
6896
6896
  function validatePaths(paths) {
6897
6897
  if (!Array.isArray(paths)) {
6898
6898
  throw new TypeError("paths must be an array");
6899
6899
  }
6900
- for (const path67 of paths) {
6901
- validatePath(path67);
6900
+ for (const path68 of paths) {
6901
+ validatePath(path68);
6902
6902
  }
6903
6903
  }
6904
6904
  function slowRedact(options = {}) {
@@ -7066,8 +7066,8 @@ var require_redaction = __commonJS({
7066
7066
  if (shape[k2] === null) {
7067
7067
  o[k2] = (value) => topCensor(value, [k2]);
7068
7068
  } else {
7069
- const wrappedCensor = typeof censor === "function" ? (value, path67) => {
7070
- return censor(value, [k2, ...path67]);
7069
+ const wrappedCensor = typeof censor === "function" ? (value, path68) => {
7070
+ return censor(value, [k2, ...path68]);
7071
7071
  } : censor;
7072
7072
  o[k2] = Redact({
7073
7073
  paths: shape[k2],
@@ -7288,7 +7288,7 @@ var require_sonic_boom = __commonJS({
7288
7288
  var fs61 = require("fs");
7289
7289
  var EventEmitter3 = require("events");
7290
7290
  var inherits = require("util").inherits;
7291
- var path67 = require("path");
7291
+ var path68 = require("path");
7292
7292
  var sleep2 = require_atomic_sleep();
7293
7293
  var assert = require("assert");
7294
7294
  var BUSY_WRITE_TIMEOUT = 100;
@@ -7342,7 +7342,7 @@ var require_sonic_boom = __commonJS({
7342
7342
  const mode = sonic.mode;
7343
7343
  if (sonic.sync) {
7344
7344
  try {
7345
- if (sonic.mkdir) fs61.mkdirSync(path67.dirname(file), { recursive: true });
7345
+ if (sonic.mkdir) fs61.mkdirSync(path68.dirname(file), { recursive: true });
7346
7346
  const fd = fs61.openSync(file, flags, mode);
7347
7347
  fileOpened(null, fd);
7348
7348
  } catch (err) {
@@ -7350,7 +7350,7 @@ var require_sonic_boom = __commonJS({
7350
7350
  throw err;
7351
7351
  }
7352
7352
  } else if (sonic.mkdir) {
7353
- fs61.mkdir(path67.dirname(file), { recursive: true }, (err) => {
7353
+ fs61.mkdir(path68.dirname(file), { recursive: true }, (err) => {
7354
7354
  if (err) return fileOpened(err);
7355
7355
  fs61.open(file, flags, mode, fileOpened);
7356
7356
  });
@@ -10210,7 +10210,7 @@ var require_multistream = __commonJS({
10210
10210
  var require_pino = __commonJS({
10211
10211
  "../node_modules/.pnpm/pino@9.14.0/node_modules/pino/pino.js"(exports2, module2) {
10212
10212
  "use strict";
10213
- var os22 = require("os");
10213
+ var os23 = require("os");
10214
10214
  var stdSerializers = require_pino_std_serializers();
10215
10215
  var caller = require_caller();
10216
10216
  var redaction = require_redaction();
@@ -10257,7 +10257,7 @@ var require_pino = __commonJS({
10257
10257
  } = symbols;
10258
10258
  var { epochTime, nullTime } = time;
10259
10259
  var { pid } = process;
10260
- var hostname = os22.hostname();
10260
+ var hostname = os23.hostname();
10261
10261
  var defaultErrorSerializer = stdSerializers.err;
10262
10262
  var defaultOptions = {
10263
10263
  level: "info",
@@ -10981,11 +10981,11 @@ var init_lib = __esm({
10981
10981
  }
10982
10982
  }
10983
10983
  },
10984
- addToPath: function addToPath(path67, added, removed, oldPosInc, options) {
10985
- var last = path67.lastComponent;
10984
+ addToPath: function addToPath(path68, added, removed, oldPosInc, options) {
10985
+ var last = path68.lastComponent;
10986
10986
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
10987
10987
  return {
10988
- oldPos: path67.oldPos + oldPosInc,
10988
+ oldPos: path68.oldPos + oldPosInc,
10989
10989
  lastComponent: {
10990
10990
  count: last.count + 1,
10991
10991
  added,
@@ -10995,7 +10995,7 @@ var init_lib = __esm({
10995
10995
  };
10996
10996
  } else {
10997
10997
  return {
10998
- oldPos: path67.oldPos + oldPosInc,
10998
+ oldPos: path68.oldPos + oldPosInc,
10999
10999
  lastComponent: {
11000
11000
  count: 1,
11001
11001
  added,
@@ -11053,7 +11053,7 @@ var init_lib = __esm({
11053
11053
  tokenize: function tokenize(value) {
11054
11054
  return Array.from(value);
11055
11055
  },
11056
- join: function join5(chars) {
11056
+ join: function join3(chars) {
11057
11057
  return chars.join("");
11058
11058
  },
11059
11059
  postProcess: function postProcess(changeObjects) {
@@ -11235,13 +11235,33 @@ var init_tool_result_extra = __esm({
11235
11235
  function cwdToHashDir(cwd) {
11236
11236
  return cwd.replace(/[^a-zA-Z0-9]/g, "-");
11237
11237
  }
11238
+ function newestSubagentMtimeMs(projectsRoot, cwd, toolSessionId) {
11239
+ const dir = import_node_path4.default.join(projectsRoot, cwdToHashDir(cwd), toolSessionId, "subagents");
11240
+ let entries;
11241
+ try {
11242
+ entries = import_node_fs4.default.readdirSync(dir, { withFileTypes: true });
11243
+ } catch {
11244
+ return null;
11245
+ }
11246
+ let newest = null;
11247
+ for (const e of entries) {
11248
+ if (!e.isFile()) continue;
11249
+ if (!e.name.startsWith("agent-") || !e.name.endsWith(".jsonl")) continue;
11250
+ try {
11251
+ const m2 = import_node_fs4.default.statSync(import_node_path4.default.join(dir, e.name)).mtimeMs;
11252
+ if (newest === null || m2 > newest) newest = m2;
11253
+ } catch {
11254
+ }
11255
+ }
11256
+ return newest;
11257
+ }
11238
11258
  function hashDirToCwd(hash) {
11239
11259
  const body = hash.startsWith("-") ? hash.slice(1) : hash;
11240
11260
  return "/" + body.replace(/-/g, "/");
11241
11261
  }
11242
11262
  function safeStatMtime(p2) {
11243
11263
  try {
11244
- return import_node_fs13.default.statSync(p2).mtimeMs;
11264
+ return import_node_fs4.default.statSync(p2).mtimeMs;
11245
11265
  } catch {
11246
11266
  return 0;
11247
11267
  }
@@ -11249,7 +11269,7 @@ function safeStatMtime(p2) {
11249
11269
  function readJsonlLines(file) {
11250
11270
  let raw;
11251
11271
  try {
11252
- raw = import_node_fs13.default.readFileSync(file, "utf8");
11272
+ raw = import_node_fs4.default.readFileSync(file, "utf8");
11253
11273
  } catch (err) {
11254
11274
  if (err.code === "ENOENT") return [];
11255
11275
  throw err;
@@ -11441,10 +11461,10 @@ function attachmentToHistoryMessage(o, ts) {
11441
11461
  const memories = raw.map((m2) => {
11442
11462
  if (!m2 || typeof m2 !== "object") return null;
11443
11463
  const rec3 = m2;
11444
- const path67 = typeof rec3.path === "string" ? rec3.path : null;
11464
+ const path68 = typeof rec3.path === "string" ? rec3.path : null;
11445
11465
  const content = typeof rec3.content === "string" ? rec3.content : null;
11446
- if (!path67 || content == null) return null;
11447
- const entry = { path: path67, content };
11466
+ if (!path68 || content == null) return null;
11467
+ const entry = { path: path68, content };
11448
11468
  if (typeof rec3.mtimeMs === "number") entry.mtimeMs = rec3.mtimeMs;
11449
11469
  return entry;
11450
11470
  }).filter((m2) => m2 !== null);
@@ -11480,8 +11500,8 @@ function attachmentDeferredToolsText(a) {
11480
11500
  function readBackupContent(fileHistoryRoot, toolSessionId, backupFileName) {
11481
11501
  if (backupFileName === null) return null;
11482
11502
  try {
11483
- return import_node_fs13.default.readFileSync(
11484
- import_node_path12.default.join(fileHistoryRoot, toolSessionId, backupFileName),
11503
+ return import_node_fs4.default.readFileSync(
11504
+ import_node_path4.default.join(fileHistoryRoot, toolSessionId, backupFileName),
11485
11505
  "utf8"
11486
11506
  );
11487
11507
  } catch {
@@ -11490,19 +11510,19 @@ function readBackupContent(fileHistoryRoot, toolSessionId, backupFileName) {
11490
11510
  }
11491
11511
  function readCurrentContent(filePath) {
11492
11512
  try {
11493
- return import_node_fs13.default.readFileSync(filePath, "utf8");
11513
+ return import_node_fs4.default.readFileSync(filePath, "utf8");
11494
11514
  } catch (err) {
11495
11515
  if (err.code === "ENOENT") return null;
11496
11516
  return null;
11497
11517
  }
11498
11518
  }
11499
- var import_node_fs13, import_node_os5, import_node_path12, TASK_NOTIFICATION_RE, TASK_ID_RE, TOOL_USE_ID_RE, SLASH_COMMAND_RE, LOCAL_COMMAND_RE, SYSTEM_REMINDER_RE, OPENSPEC_BLOCK_RE, SKILL_HINT_RE, ATTACHMENT_SILENT_SUBTYPES, ClaudeHistoryReader;
11519
+ var import_node_fs4, import_node_os3, import_node_path4, TASK_NOTIFICATION_RE, TASK_ID_RE, TOOL_USE_ID_RE, SLASH_COMMAND_RE, LOCAL_COMMAND_RE, SYSTEM_REMINDER_RE, OPENSPEC_BLOCK_RE, SKILL_HINT_RE, ATTACHMENT_SILENT_SUBTYPES, ClaudeHistoryReader;
11500
11520
  var init_claude_history = __esm({
11501
11521
  "src/tools/claude-history.ts"() {
11502
11522
  "use strict";
11503
- import_node_fs13 = __toESM(require("fs"), 1);
11504
- import_node_os5 = __toESM(require("os"), 1);
11505
- import_node_path12 = __toESM(require("path"), 1);
11523
+ import_node_fs4 = __toESM(require("fs"), 1);
11524
+ import_node_os3 = __toESM(require("os"), 1);
11525
+ import_node_path4 = __toESM(require("path"), 1);
11506
11526
  init_lib();
11507
11527
  init_tool_result_extra();
11508
11528
  TASK_NOTIFICATION_RE = /<task-notification\b[\s\S]*?<\/task-notification>/i;
@@ -11526,14 +11546,14 @@ var init_claude_history = __esm({
11526
11546
  // 每次 user 提交前 trackEdit 拷一份,作为 rewind 回退目标
11527
11547
  fileHistoryRoot;
11528
11548
  constructor(opts = {}) {
11529
- const base = opts.baseDir ?? import_node_path12.default.join(import_node_os5.default.homedir(), ".claude");
11530
- this.projectsRoot = import_node_path12.default.join(base, "projects");
11531
- this.fileHistoryRoot = import_node_path12.default.join(base, "file-history");
11549
+ const base = opts.baseDir ?? import_node_path4.default.join(import_node_os3.default.homedir(), ".claude");
11550
+ this.projectsRoot = import_node_path4.default.join(base, "projects");
11551
+ this.fileHistoryRoot = import_node_path4.default.join(base, "file-history");
11532
11552
  }
11533
11553
  async listProjects() {
11534
11554
  let entries;
11535
11555
  try {
11536
- entries = import_node_fs13.default.readdirSync(this.projectsRoot, { withFileTypes: true });
11556
+ entries = import_node_fs4.default.readdirSync(this.projectsRoot, { withFileTypes: true });
11537
11557
  } catch (err) {
11538
11558
  if (err.code === "ENOENT") return [];
11539
11559
  throw err;
@@ -11541,9 +11561,9 @@ var init_claude_history = __esm({
11541
11561
  const out = [];
11542
11562
  for (const ent of entries) {
11543
11563
  if (!ent.isDirectory()) continue;
11544
- const dir = import_node_path12.default.join(this.projectsRoot, ent.name);
11545
- const files = import_node_fs13.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
11546
- const updatedAtMs = files.reduce((m2, f) => Math.max(m2, safeStatMtime(import_node_path12.default.join(dir, f))), 0);
11564
+ const dir = import_node_path4.default.join(this.projectsRoot, ent.name);
11565
+ const files = import_node_fs4.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
11566
+ const updatedAtMs = files.reduce((m2, f) => Math.max(m2, safeStatMtime(import_node_path4.default.join(dir, f))), 0);
11547
11567
  out.push({
11548
11568
  projectPath: hashDirToCwd(ent.name),
11549
11569
  hashDir: ent.name,
@@ -11555,17 +11575,17 @@ var init_claude_history = __esm({
11555
11575
  return out;
11556
11576
  }
11557
11577
  async listSessions(args) {
11558
- const dir = import_node_path12.default.join(this.projectsRoot, cwdToHashDir(args.projectPath));
11578
+ const dir = import_node_path4.default.join(this.projectsRoot, cwdToHashDir(args.projectPath));
11559
11579
  let files;
11560
11580
  try {
11561
- files = import_node_fs13.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
11581
+ files = import_node_fs4.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
11562
11582
  } catch (err) {
11563
11583
  if (err.code === "ENOENT") return [];
11564
11584
  throw err;
11565
11585
  }
11566
11586
  const out = [];
11567
11587
  for (const f of files) {
11568
- const full = import_node_path12.default.join(dir, f);
11588
+ const full = import_node_path4.default.join(dir, f);
11569
11589
  const toolSessionId = f.slice(0, -".jsonl".length);
11570
11590
  const lines = readJsonlLines(full);
11571
11591
  let summary = "";
@@ -11620,7 +11640,7 @@ var init_claude_history = __esm({
11620
11640
  return out;
11621
11641
  }
11622
11642
  async read(args) {
11623
- const file = import_node_path12.default.join(
11643
+ const file = import_node_path4.default.join(
11624
11644
  this.projectsRoot,
11625
11645
  cwdToHashDir(args.cwd),
11626
11646
  `${args.toolSessionId}.jsonl`
@@ -11657,7 +11677,7 @@ var init_claude_history = __esm({
11657
11677
  // 独立目录路径:<projectsRoot>/<cwdHash>/<toolSessionId>/subagents/*.jsonl
11658
11678
  // 返回 null 表示目录不存在(调用方回退旧实现);返回空数组表示目录存在但无 jsonl
11659
11679
  listSubagentsFromDirectory(cwd, toolSessionId) {
11660
- const dir = import_node_path12.default.join(
11680
+ const dir = import_node_path4.default.join(
11661
11681
  this.projectsRoot,
11662
11682
  cwdToHashDir(cwd),
11663
11683
  toolSessionId,
@@ -11665,7 +11685,7 @@ var init_claude_history = __esm({
11665
11685
  );
11666
11686
  let entries;
11667
11687
  try {
11668
- entries = import_node_fs13.default.readdirSync(dir, { withFileTypes: true });
11688
+ entries = import_node_fs4.default.readdirSync(dir, { withFileTypes: true });
11669
11689
  } catch (err) {
11670
11690
  if (err.code === "ENOENT") return null;
11671
11691
  return null;
@@ -11675,7 +11695,7 @@ var init_claude_history = __esm({
11675
11695
  if (!e.isFile()) continue;
11676
11696
  if (!e.name.startsWith("agent-") || !e.name.endsWith(".jsonl")) continue;
11677
11697
  const subagentId = e.name.slice("agent-".length, -".jsonl".length);
11678
- const filePath = import_node_path12.default.join(dir, e.name);
11698
+ const filePath = import_node_path4.default.join(dir, e.name);
11679
11699
  const lines = readJsonlLines(filePath);
11680
11700
  let firstText = "";
11681
11701
  let messageCount = 0;
@@ -11692,7 +11712,7 @@ var init_claude_history = __esm({
11692
11712
  return out;
11693
11713
  }
11694
11714
  listSubagentsFromMainJsonl(cwd, toolSessionId) {
11695
- const file = import_node_path12.default.join(
11715
+ const file = import_node_path4.default.join(
11696
11716
  this.projectsRoot,
11697
11717
  cwdToHashDir(cwd),
11698
11718
  `${toolSessionId}.jsonl`
@@ -11727,7 +11747,7 @@ var init_claude_history = __esm({
11727
11747
  }
11728
11748
  // 独立文件路径:agent-<subagentId>.jsonl;文件不存在返回 null 让调用方回退旧实现
11729
11749
  readSubagentFromFile(cwd, toolSessionId, subagentId) {
11730
- const file = import_node_path12.default.join(
11750
+ const file = import_node_path4.default.join(
11731
11751
  this.projectsRoot,
11732
11752
  cwdToHashDir(cwd),
11733
11753
  toolSessionId,
@@ -11736,7 +11756,7 @@ var init_claude_history = __esm({
11736
11756
  );
11737
11757
  let exists = false;
11738
11758
  try {
11739
- exists = import_node_fs13.default.statSync(file).isFile();
11759
+ exists = import_node_fs4.default.statSync(file).isFile();
11740
11760
  } catch {
11741
11761
  return null;
11742
11762
  }
@@ -11755,7 +11775,7 @@ var init_claude_history = __esm({
11755
11775
  * "那一刻每个 tracked 文件对应的 backup 文件名"
11756
11776
  */
11757
11777
  readFileHistorySnapshots(args) {
11758
- const file = import_node_path12.default.join(
11778
+ const file = import_node_path4.default.join(
11759
11779
  this.projectsRoot,
11760
11780
  cwdToHashDir(args.cwd),
11761
11781
  `${args.toolSessionId}.jsonl`
@@ -11800,7 +11820,7 @@ var init_claude_history = __esm({
11800
11820
  for (const [anchorId, target] of snapshots) {
11801
11821
  let hasAny = false;
11802
11822
  for (const [rawPath, backup] of Object.entries(target)) {
11803
- const absPath = import_node_path12.default.isAbsolute(rawPath) ? rawPath : import_node_path12.default.join(args.cwd, rawPath);
11823
+ const absPath = import_node_path4.default.isAbsolute(rawPath) ? rawPath : import_node_path4.default.join(args.cwd, rawPath);
11804
11824
  const backupContent = readBackupContent(
11805
11825
  this.fileHistoryRoot,
11806
11826
  args.toolSessionId,
@@ -11840,7 +11860,7 @@ var init_claude_history = __esm({
11840
11860
  let totalInsertions = 0;
11841
11861
  let totalDeletions = 0;
11842
11862
  for (const [rawPath, backup] of Object.entries(target)) {
11843
- const absPath = import_node_path12.default.isAbsolute(rawPath) ? rawPath : import_node_path12.default.join(args.cwd, rawPath);
11863
+ const absPath = import_node_path4.default.isAbsolute(rawPath) ? rawPath : import_node_path4.default.join(args.cwd, rawPath);
11844
11864
  const backupContent = readBackupContent(
11845
11865
  this.fileHistoryRoot,
11846
11866
  args.toolSessionId,
@@ -11887,7 +11907,7 @@ var init_claude_history = __esm({
11887
11907
  };
11888
11908
  }
11889
11909
  readSubagentFromMainJsonl(cwd, toolSessionId, subagentId) {
11890
- const file = import_node_path12.default.join(
11910
+ const file = import_node_path4.default.join(
11891
11911
  this.projectsRoot,
11892
11912
  cwdToHashDir(cwd),
11893
11913
  `${toolSessionId}.jsonl`
@@ -12256,10 +12276,10 @@ function parseAttachment(obj) {
12256
12276
  const memories = raw.map((m2) => {
12257
12277
  if (!m2 || typeof m2 !== "object") return null;
12258
12278
  const rec3 = m2;
12259
- const path67 = typeof rec3.path === "string" ? rec3.path : null;
12279
+ const path68 = typeof rec3.path === "string" ? rec3.path : null;
12260
12280
  const content = typeof rec3.content === "string" ? rec3.content : null;
12261
- if (!path67 || content == null) return null;
12262
- const out = { path: path67, content };
12281
+ if (!path68 || content == null) return null;
12282
+ const out = { path: path68, content };
12263
12283
  if (typeof rec3.mtimeMs === "number") out.mtimeMs = rec3.mtimeMs;
12264
12284
  return out;
12265
12285
  }).filter((m2) => m2 !== null);
@@ -12391,8 +12411,9 @@ var init_claude = __esm({
12391
12411
  };
12392
12412
  CLAUDE_MODELS = [
12393
12413
  { id: "", label: "Default", description: "CLI default model", contextWindowSize: 2e5, default: true },
12394
- { id: "sonnet", label: "Sonnet", description: "Fast, balanced", contextWindowSize: 2e5 },
12395
12414
  { id: "opus", label: "Opus", description: "Most capable", contextWindowSize: 1e6 },
12415
+ { id: "fable", label: "Fable", contextWindowSize: 2e5 },
12416
+ { id: "sonnet", label: "Sonnet", description: "Fast, balanced", contextWindowSize: 2e5 },
12396
12417
  { id: "haiku", label: "Haiku", description: "Fastest, lightest", contextWindowSize: 2e5 }
12397
12418
  ];
12398
12419
  CLAUDE_PERMISSION_MODES = [
@@ -33223,8 +33244,8 @@ var require_utils = __commonJS({
33223
33244
  var result = transform[inputType][outputType](input);
33224
33245
  return result;
33225
33246
  };
33226
- exports2.resolve = function(path67) {
33227
- var parts = path67.split("/");
33247
+ exports2.resolve = function(path68) {
33248
+ var parts = path68.split("/");
33228
33249
  var result = [];
33229
33250
  for (var index = 0; index < parts.length; index++) {
33230
33251
  var part = parts[index];
@@ -39077,18 +39098,18 @@ var require_object = __commonJS({
39077
39098
  var object = new ZipObject(name, zipObjectContent, o);
39078
39099
  this.files[name] = object;
39079
39100
  };
39080
- var parentFolder = function(path67) {
39081
- if (path67.slice(-1) === "/") {
39082
- path67 = path67.substring(0, path67.length - 1);
39101
+ var parentFolder = function(path68) {
39102
+ if (path68.slice(-1) === "/") {
39103
+ path68 = path68.substring(0, path68.length - 1);
39083
39104
  }
39084
- var lastSlash = path67.lastIndexOf("/");
39085
- return lastSlash > 0 ? path67.substring(0, lastSlash) : "";
39105
+ var lastSlash = path68.lastIndexOf("/");
39106
+ return lastSlash > 0 ? path68.substring(0, lastSlash) : "";
39086
39107
  };
39087
- var forceTrailingSlash = function(path67) {
39088
- if (path67.slice(-1) !== "/") {
39089
- path67 += "/";
39108
+ var forceTrailingSlash = function(path68) {
39109
+ if (path68.slice(-1) !== "/") {
39110
+ path68 += "/";
39090
39111
  }
39091
- return path67;
39112
+ return path68;
39092
39113
  };
39093
39114
  var folderAdd = function(name, createFolders) {
39094
39115
  createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
@@ -40090,7 +40111,7 @@ var require_lib3 = __commonJS({
40090
40111
  // src/run-case/recorder.ts
40091
40112
  function startRunCaseRecorder(opts) {
40092
40113
  const now = opts.now ?? Date.now;
40093
- const dir = import_node_path55.default.dirname(opts.recordPath);
40114
+ const dir = import_node_path56.default.dirname(opts.recordPath);
40094
40115
  let stream = null;
40095
40116
  let closing = false;
40096
40117
  let closedSettled = false;
@@ -40130,12 +40151,12 @@ function startRunCaseRecorder(opts) {
40130
40151
  };
40131
40152
  return { tap, close, closed };
40132
40153
  }
40133
- var import_node_fs43, import_node_path55;
40154
+ var import_node_fs43, import_node_path56;
40134
40155
  var init_recorder = __esm({
40135
40156
  "src/run-case/recorder.ts"() {
40136
40157
  "use strict";
40137
40158
  import_node_fs43 = __toESM(require("fs"), 1);
40138
- import_node_path55 = __toESM(require("path"), 1);
40159
+ import_node_path56 = __toESM(require("path"), 1);
40139
40160
  }
40140
40161
  });
40141
40162
 
@@ -40178,7 +40199,7 @@ var init_wire = __esm({
40178
40199
  // src/run-case/controller.ts
40179
40200
  async function runController(opts) {
40180
40201
  const now = opts.now ?? Date.now;
40181
- const cwd = opts.cwd ?? (0, import_node_fs44.mkdtempSync)(import_node_path56.default.join(import_node_os21.default.tmpdir(), "clawd-runcase-"));
40202
+ const cwd = opts.cwd ?? (0, import_node_fs44.mkdtempSync)(import_node_path57.default.join(import_node_os22.default.tmpdir(), "clawd-runcase-"));
40182
40203
  const ownsCwd = opts.cwd === void 0;
40183
40204
  const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
40184
40205
  const spawnCtx = { cwd };
@@ -40345,13 +40366,13 @@ async function runController(opts) {
40345
40366
  }
40346
40367
  return exitCode ?? 0;
40347
40368
  }
40348
- var import_node_fs44, import_node_os21, import_node_path56;
40369
+ var import_node_fs44, import_node_os22, import_node_path57;
40349
40370
  var init_controller = __esm({
40350
40371
  "src/run-case/controller.ts"() {
40351
40372
  "use strict";
40352
40373
  import_node_fs44 = require("fs");
40353
- import_node_os21 = __toESM(require("os"), 1);
40354
- import_node_path56 = __toESM(require("path"), 1);
40374
+ import_node_os22 = __toESM(require("os"), 1);
40375
+ import_node_path57 = __toESM(require("path"), 1);
40355
40376
  init_claude();
40356
40377
  init_stdout_splitter();
40357
40378
  init_permission_stdio();
@@ -40613,9 +40634,9 @@ Env (advanced):
40613
40634
  `;
40614
40635
 
40615
40636
  // src/index.ts
40616
- var import_node_path54 = __toESM(require("path"), 1);
40637
+ var import_node_path55 = __toESM(require("path"), 1);
40617
40638
  var import_node_fs42 = __toESM(require("fs"), 1);
40618
- var import_node_os20 = __toESM(require("os"), 1);
40639
+ var import_node_os21 = __toESM(require("os"), 1);
40619
40640
 
40620
40641
  // ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/stringify.js
40621
40642
  var byteToHex = [];
@@ -41232,9 +41253,9 @@ var SessionStoreFactory = class {
41232
41253
  };
41233
41254
 
41234
41255
  // src/session/manager.ts
41235
- var import_node_fs6 = __toESM(require("fs"), 1);
41236
- var import_node_path6 = __toESM(require("path"), 1);
41237
- var import_node_os3 = __toESM(require("os"), 1);
41256
+ var import_node_fs7 = __toESM(require("fs"), 1);
41257
+ var import_node_path8 = __toESM(require("path"), 1);
41258
+ var import_node_os5 = __toESM(require("os"), 1);
41238
41259
  init_protocol();
41239
41260
 
41240
41261
  // src/tools/guest-settings.ts
@@ -41332,6 +41353,10 @@ function escapeAttr(v2) {
41332
41353
  return v2.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
41333
41354
  }
41334
41355
 
41356
+ // src/session/runner.ts
41357
+ var import_node_os4 = __toESM(require("os"), 1);
41358
+ var import_node_path6 = __toESM(require("path"), 1);
41359
+
41335
41360
  // src/session/reducer.ts
41336
41361
  init_runtime();
41337
41362
 
@@ -41418,7 +41443,7 @@ var ATTACHMENT_SHARING_HINT = `## \u628A\u4EA7\u51FA\u6587\u4EF6\u5206\u4EAB\u7E
41418
41443
  // src/dispatch/system-prompt.ts
41419
41444
  var DISPATCH_SYSTEM_PROMPT_HINT = `## \u59D4\u6D3E\u7ED9\u53E6\u4E00\u4E2A persona\uFF08dispatch\uFF09
41420
41445
 
41421
- \u5F53\u7528\u6237\u6D88\u606F\u91CC\u542B \`@persona/<id>\`\uFF08\u5982 \`@persona/persona-bug-fixer\`\uFF09\u65F6\uFF0C**\u4F60\u5FC5\u987B**\u7ACB\u5373\u8C03 MCP tool \`mcp__clawd-dispatch__personaDispatch\` \u59D4\u6D3E\uFF0C\u4E0D\u8981\u5C1D\u8BD5\u81EA\u5DF1\u6267\u884C\uFF1A
41446
+ \u5F53\u7528\u6237\u6D88\u606F\u91CC\u542B \`@persona/<id>\`\uFF08\u5982 \`@persona/persona-app-builder\`\uFF09\u65F6\uFF0C**\u4F60\u5FC5\u987B**\u7ACB\u5373\u8C03 MCP tool \`mcp__clawd-dispatch__personaDispatch\` \u59D4\u6D3E\uFF0C\u4E0D\u8981\u5C1D\u8BD5\u81EA\u5DF1\u6267\u884C\uFF1A
41422
41447
 
41423
41448
  - \`targetPersona = <id>\`\uFF08@ token \u91CC\u7684 persona id\uFF09
41424
41449
  - \`prompt = \u53BB\u6389 @persona/<id> token \u7684\u7528\u6237\u539F\u6587\`
@@ -41470,7 +41495,7 @@ function cloneState(s) {
41470
41495
  pendingSend: s.pendingSend.slice()
41471
41496
  };
41472
41497
  }
41473
- var IDLE_KILL_DELAY_MS = 6e4;
41498
+ var IDLE_KILL_DELAY_MS = 6e5;
41474
41499
  function tryFlushPending(state, deps) {
41475
41500
  if (!state.readyForSend || state.pendingSend.length === 0) return [];
41476
41501
  const text = state.pendingSend.shift();
@@ -42141,6 +42166,18 @@ function reduceSession(state, input, deps) {
42141
42166
  if (state.status !== "running-idle") {
42142
42167
  return { state, effects: [] };
42143
42168
  }
42169
+ if (input.subagentActive) {
42170
+ return {
42171
+ state,
42172
+ effects: [
42173
+ {
42174
+ kind: "schedule-idle-kill",
42175
+ sessionId: state.file.sessionId,
42176
+ ms: IDLE_KILL_DELAY_MS
42177
+ }
42178
+ ]
42179
+ };
42180
+ }
42144
42181
  const next = cloneState(state);
42145
42182
  next.status = "stopping";
42146
42183
  return {
@@ -42197,10 +42234,11 @@ function reduceSession(state, input, deps) {
42197
42234
  // src/session/runner.ts
42198
42235
  init_stdout_splitter();
42199
42236
  init_permission_stdio();
42237
+ init_claude_history();
42200
42238
 
42201
42239
  // src/ipc-recorder.ts
42202
- var import_node_fs4 = __toESM(require("fs"), 1);
42203
- var import_node_path4 = __toESM(require("path"), 1);
42240
+ var import_node_fs5 = __toESM(require("fs"), 1);
42241
+ var import_node_path5 = __toESM(require("path"), 1);
42204
42242
  function tsForFilename(ms) {
42205
42243
  return new Date(ms).toISOString().replace(/[:.]/g, "-");
42206
42244
  }
@@ -42211,8 +42249,8 @@ function startRecorder(opts) {
42211
42249
  return null;
42212
42250
  }
42213
42251
  const now = opts.now ?? Date.now;
42214
- const dir = import_node_path4.default.join(opts.dataDir, "ipc-recordings", opts.sessionId);
42215
- const filePath = import_node_path4.default.join(dir, `${tsForFilename(now())}.jsonl`);
42252
+ const dir = import_node_path5.default.join(opts.dataDir, "ipc-recordings", opts.sessionId);
42253
+ const filePath = import_node_path5.default.join(dir, `${tsForFilename(now())}.jsonl`);
42216
42254
  let stream = null;
42217
42255
  let closedResolve;
42218
42256
  const closed = new Promise((resolve6) => {
@@ -42221,8 +42259,8 @@ function startRecorder(opts) {
42221
42259
  let exited = false;
42222
42260
  const ensureStream = () => {
42223
42261
  if (stream) return stream;
42224
- import_node_fs4.default.mkdirSync(dir, { recursive: true });
42225
- stream = import_node_fs4.default.createWriteStream(filePath, { flags: "a" });
42262
+ import_node_fs5.default.mkdirSync(dir, { recursive: true });
42263
+ stream = import_node_fs5.default.createWriteStream(filePath, { flags: "a" });
42226
42264
  stream.on("close", () => closedResolve());
42227
42265
  return stream;
42228
42266
  };
@@ -42267,6 +42305,7 @@ function encodeAllowWithInputControlResponse(requestId, updatedInput) {
42267
42305
  return JSON.stringify(payload) + "\n";
42268
42306
  }
42269
42307
  var DEFAULT_WAIT_STOP_TIMEOUT_MS = 3e3;
42308
+ var SUBAGENT_ACTIVE_WINDOW_MS = 3e5;
42270
42309
  var SessionRunner = class {
42271
42310
  constructor(initial, hooks) {
42272
42311
  this.hooks = hooks;
@@ -42579,7 +42618,7 @@ var SessionRunner = class {
42579
42618
  if (existing) clearTimeout(existing);
42580
42619
  const timer = setTimeout(() => {
42581
42620
  this.idleKillTimers.delete(effect.sessionId);
42582
- this.input({ kind: "idle-kill-fired" });
42621
+ this.input({ kind: "idle-kill-fired", subagentActive: this.isSubagentActive() });
42583
42622
  }, effect.ms);
42584
42623
  timer.unref?.();
42585
42624
  this.idleKillTimers.set(effect.sessionId, timer);
@@ -42595,6 +42634,18 @@ var SessionRunner = class {
42595
42634
  }
42596
42635
  }
42597
42636
  }
42637
+ // idle-kill 到点判定:本 session 的 subagents/ 里是否还有 agent-*.jsonl 在近期写盘。
42638
+ // 新鲜(近 SUBAGENT_ACTIVE_WINDOW_MS 内有写)= 后台 subagent 还在干活 → 不该杀。
42639
+ // 没有 toolSessionId(SDK 模式 CC 内生 id)/ 无目录 / 无 agent 文件 → false(照常回收)。
42640
+ isSubagentActive() {
42641
+ const toolSessionId = this.state.file.toolSessionId;
42642
+ if (!toolSessionId) return false;
42643
+ const projectsRoot = import_node_path6.default.join(this.hooks.home ?? import_node_os4.default.homedir(), ".claude", "projects");
42644
+ const mtime = newestSubagentMtimeMs(projectsRoot, this.state.file.cwd, toolSessionId);
42645
+ if (mtime === null) return false;
42646
+ const now = (this.hooks.now ?? Date.now)();
42647
+ return now - mtime < SUBAGENT_ACTIVE_WINDOW_MS;
42648
+ }
42598
42649
  // 清空所有 idle-kill timer(runner dispose / proc 永久退出时调用)。
42599
42650
  // 不喂 idle-kill-fired —— dispose 路径不再翻 reducer 状态
42600
42651
  clearIdleKillTimers() {
@@ -42677,15 +42728,15 @@ function extractEditPath(input) {
42677
42728
  }
42678
42729
 
42679
42730
  // src/debug/pty-probe.ts
42680
- var import_node_fs5 = __toESM(require("fs"), 1);
42681
- var import_node_path5 = __toESM(require("path"), 1);
42731
+ var import_node_fs6 = __toESM(require("fs"), 1);
42732
+ var import_node_path7 = __toESM(require("path"), 1);
42682
42733
  var PROBE_DIR = "/tmp/clawd-probe";
42683
- var EVENTS_FILE = import_node_path5.default.join(PROBE_DIR, "events.jsonl");
42734
+ var EVENTS_FILE = import_node_path7.default.join(PROBE_DIR, "events.jsonl");
42684
42735
  var inited = false;
42685
42736
  function ensureDir() {
42686
42737
  if (inited) return true;
42687
42738
  try {
42688
- import_node_fs5.default.mkdirSync(PROBE_DIR, { recursive: true });
42739
+ import_node_fs6.default.mkdirSync(PROBE_DIR, { recursive: true });
42689
42740
  inited = true;
42690
42741
  return true;
42691
42742
  } catch {
@@ -42696,15 +42747,15 @@ function probeEvent(event, data = {}) {
42696
42747
  try {
42697
42748
  if (!ensureDir()) return;
42698
42749
  const line = JSON.stringify({ ts: Date.now(), event, ...data }) + "\n";
42699
- import_node_fs5.default.appendFileSync(EVENTS_FILE, line);
42750
+ import_node_fs6.default.appendFileSync(EVENTS_FILE, line);
42700
42751
  } catch {
42701
42752
  }
42702
42753
  }
42703
42754
  function probeDumpReplay(sessionId, payload) {
42704
42755
  try {
42705
42756
  if (!ensureDir()) return "";
42706
- const file = import_node_path5.default.join(PROBE_DIR, `replay-${sessionId}-${Date.now()}.ans`);
42707
- import_node_fs5.default.writeFileSync(file, payload, "utf8");
42757
+ const file = import_node_path7.default.join(PROBE_DIR, `replay-${sessionId}-${Date.now()}.ans`);
42758
+ import_node_fs6.default.writeFileSync(file, payload, "utf8");
42708
42759
  return file;
42709
42760
  } catch {
42710
42761
  return "";
@@ -42811,7 +42862,7 @@ function derivePersonaSpawnCwd(file, personaRoot) {
42811
42862
  `derivePersonaSpawnCwd: personaRoot missing for owner session ${file.sessionId} (ownerPersonaId=${personaId})`
42812
42863
  );
42813
42864
  }
42814
- return import_node_path6.default.join(personaRoot, safeFileName(personaId));
42865
+ return import_node_path8.default.join(personaRoot, safeFileName(personaId));
42815
42866
  }
42816
42867
  function makeInitialState(file, subSessionMeta) {
42817
42868
  return {
@@ -42936,10 +42987,10 @@ var SessionManager = class {
42936
42987
  // <dataDir>/sessions/ 列子目录 (排除 'default').
42937
42988
  listPersonaIdsOnDisk() {
42938
42989
  if (!this.deps.dataDir) return [];
42939
- const root = this.deps.storeFactory ? import_node_path6.default.join(this.deps.dataDir, "personas") : import_node_path6.default.join(this.deps.dataDir, "sessions");
42990
+ const root = this.deps.storeFactory ? import_node_path8.default.join(this.deps.dataDir, "personas") : import_node_path8.default.join(this.deps.dataDir, "sessions");
42940
42991
  let entries;
42941
42992
  try {
42942
- entries = import_node_fs6.default.readdirSync(root, { withFileTypes: true });
42993
+ entries = import_node_fs7.default.readdirSync(root, { withFileTypes: true });
42943
42994
  } catch (err) {
42944
42995
  const code = err?.code;
42945
42996
  if (code === "ENOENT") return [];
@@ -42952,7 +43003,7 @@ var SessionManager = class {
42952
43003
  // 只在 storeFactory 注入 (新布局) 下生效, 老布局无 guest 目录.
42953
43004
  listGuestCapIdsForPersona(personaId) {
42954
43005
  if (!this.deps.dataDir || !this.deps.storeFactory) return [];
42955
- const root = import_node_path6.default.join(
43006
+ const root = import_node_path8.default.join(
42956
43007
  this.deps.dataDir,
42957
43008
  "personas",
42958
43009
  personaId,
@@ -42962,7 +43013,7 @@ var SessionManager = class {
42962
43013
  );
42963
43014
  let entries;
42964
43015
  try {
42965
- entries = import_node_fs6.default.readdirSync(root, { withFileTypes: true });
43016
+ entries = import_node_fs7.default.readdirSync(root, { withFileTypes: true });
42966
43017
  } catch (err) {
42967
43018
  const code = err?.code;
42968
43019
  if (code === "ENOENT") return [];
@@ -43081,7 +43132,7 @@ var SessionManager = class {
43081
43132
  callerDisplayName
43082
43133
  );
43083
43134
  if (subSessionMeta?.userWorkDir) {
43084
- import_node_fs6.default.mkdirSync(subSessionMeta.userWorkDir, { recursive: true });
43135
+ import_node_fs7.default.mkdirSync(subSessionMeta.userWorkDir, { recursive: true });
43085
43136
  }
43086
43137
  if (scope.kind === "persona" && scope.mode === "guest") {
43087
43138
  if (!this.deps.personaRoot || !subSessionMeta?.userWorkDir) {
@@ -43092,8 +43143,8 @@ var SessionManager = class {
43092
43143
  const base = this.deps.personaStore?.readSandboxSettings(scope.personaId) ?? null;
43093
43144
  const settings = composeGuestSandbox(base, subSessionMeta.userWorkDir, file.cwd);
43094
43145
  subSessionMeta.extraSettings = JSON.stringify(settings);
43095
- const home = import_node_os3.default.homedir();
43096
- const expand = (p2) => p2 === "~" ? home : p2.startsWith("~/") ? import_node_path6.default.join(home, p2.slice(2)) : p2;
43146
+ const home = import_node_os5.default.homedir();
43147
+ const expand = (p2) => p2 === "~" ? home : p2.startsWith("~/") ? import_node_path8.default.join(home, p2.slice(2)) : p2;
43097
43148
  const codexCfg = this.deps.personaStore?.readCodexSandboxSettings(scope.personaId) ?? null;
43098
43149
  subSessionMeta.codexSandbox = {
43099
43150
  writableRoots: [subSessionMeta.userWorkDir, ...(codexCfg?.writableRoots ?? []).map(expand)],
@@ -43246,7 +43297,7 @@ var SessionManager = class {
43246
43297
  throw new ClawdError(ERROR_CODES.INVALID_CWD, "cwd required when ownerPersonaId is absent");
43247
43298
  }
43248
43299
  try {
43249
- const stat = import_node_fs6.default.statSync(cwd);
43300
+ const stat = import_node_fs7.default.statSync(cwd);
43250
43301
  if (!stat.isDirectory()) throw new Error("not dir");
43251
43302
  } catch {
43252
43303
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${cwd}`);
@@ -43777,7 +43828,7 @@ var SessionManager = class {
43777
43828
  */
43778
43829
  createForScope(args) {
43779
43830
  try {
43780
- const stat = import_node_fs6.default.statSync(args.cwd);
43831
+ const stat = import_node_fs7.default.statSync(args.cwd);
43781
43832
  if (!stat.isDirectory()) throw new Error("not dir");
43782
43833
  } catch {
43783
43834
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${args.cwd}`);
@@ -43993,7 +44044,7 @@ var SessionManager = class {
43993
44044
  personaId: args.targetPersona,
43994
44045
  mode: "owner"
43995
44046
  };
43996
- const cwd = import_node_path6.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
44047
+ const cwd = import_node_path8.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
43997
44048
  const now = (/* @__PURE__ */ new Date()).toISOString();
43998
44049
  const file = {
43999
44050
  sessionId,
@@ -44058,7 +44109,7 @@ var SessionManager = class {
44058
44109
  personaId: args.targetPersona,
44059
44110
  mode: "owner"
44060
44111
  };
44061
- const cwd = import_node_path6.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
44112
+ const cwd = import_node_path8.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
44062
44113
  const now = (/* @__PURE__ */ new Date()).toISOString();
44063
44114
  const file = {
44064
44115
  sessionId,
@@ -44540,28 +44591,28 @@ var SessionManager = class {
44540
44591
  };
44541
44592
 
44542
44593
  // src/persona/store.ts
44543
- var fs7 = __toESM(require("fs"), 1);
44544
- var path9 = __toESM(require("path"), 1);
44594
+ var fs8 = __toESM(require("fs"), 1);
44595
+ var path11 = __toESM(require("path"), 1);
44545
44596
  init_protocol();
44546
44597
  var PersonaStore = class {
44547
44598
  constructor(root) {
44548
44599
  this.root = root;
44549
- fs7.mkdirSync(root, { recursive: true });
44600
+ fs8.mkdirSync(root, { recursive: true });
44550
44601
  }
44551
44602
  root;
44552
44603
  personaDir(personaId) {
44553
- return path9.join(this.root, safeFileName(personaId));
44604
+ return path11.join(this.root, safeFileName(personaId));
44554
44605
  }
44555
44606
  metaPath(personaId) {
44556
- return path9.join(this.personaDir(personaId), ".clawd", "persona.json");
44607
+ return path11.join(this.personaDir(personaId), ".clawd", "persona.json");
44557
44608
  }
44558
44609
  claudeMdPath(personaId) {
44559
- return path9.join(this.personaDir(personaId), "CLAUDE.md");
44610
+ return path11.join(this.personaDir(personaId), "CLAUDE.md");
44560
44611
  }
44561
44612
  // codex 原生读 cwd 的 AGENTS.md。人格双写镜像:claude 读 CLAUDE.md、codex 读 AGENTS.md,
44562
44613
  // 两份内容恒一致,persona 切 tool 零迁移。
44563
44614
  agentsMdPath(personaId) {
44564
- return path9.join(this.personaDir(personaId), "AGENTS.md");
44615
+ return path11.join(this.personaDir(personaId), "AGENTS.md");
44565
44616
  }
44566
44617
  /**
44567
44618
  * persona 级 sandbox base 落盘路径 —— 故意放 `.clawd/` 而非 `.claude/`,让 CC 的 project
@@ -44570,11 +44621,11 @@ var PersonaStore = class {
44570
44621
  * spawn 前 per-guest 动态拼到各自 session 目录的那份(base + 强制底座 + 本 guest userWorkDir carve)。
44571
44622
  */
44572
44623
  sandboxSettingsPath(personaId) {
44573
- return path9.join(this.personaDir(personaId), ".clawd", "sandbox-settings.json");
44624
+ return path11.join(this.personaDir(personaId), ".clawd", "sandbox-settings.json");
44574
44625
  }
44575
44626
  write(persona, personality) {
44576
44627
  const dir = this.personaDir(persona.personaId);
44577
- fs7.mkdirSync(path9.join(dir, ".clawd"), { recursive: true });
44628
+ fs8.mkdirSync(path11.join(dir, ".clawd"), { recursive: true });
44578
44629
  this.atomicWrite(this.claudeMdPath(persona.personaId), personality);
44579
44630
  this.atomicWrite(this.agentsMdPath(persona.personaId), personality);
44580
44631
  this.writeSandboxSettings(persona.personaId, buildGuestSettingsV1());
@@ -44593,9 +44644,9 @@ var PersonaStore = class {
44593
44644
  ensureAgentsMirror(personaId) {
44594
44645
  const claudeMd = this.claudeMdPath(personaId);
44595
44646
  const agentsMd = this.agentsMdPath(personaId);
44596
- if (!fs7.existsSync(claudeMd)) return false;
44597
- if (fs7.existsSync(agentsMd)) return false;
44598
- this.atomicWrite(agentsMd, fs7.readFileSync(claudeMd, "utf8"));
44647
+ if (!fs8.existsSync(claudeMd)) return false;
44648
+ if (fs8.existsSync(agentsMd)) return false;
44649
+ this.atomicWrite(agentsMd, fs8.readFileSync(claudeMd, "utf8"));
44599
44650
  return true;
44600
44651
  }
44601
44652
  /**
@@ -44619,22 +44670,22 @@ var PersonaStore = class {
44619
44670
  return { ...s, permissions: { ...s.permissions ?? {}, deny: [...prev, rule] } };
44620
44671
  }
44621
44672
  codexSandboxSettingsPath(personaId) {
44622
- return path9.join(this.personaDir(personaId), ".clawd", "codex-sandbox.json");
44673
+ return path11.join(this.personaDir(personaId), ".clawd", "codex-sandbox.json");
44623
44674
  }
44624
44675
  /** 读 codex-sandbox.json;不存在/损坏 → null。 */
44625
44676
  readCodexSandboxSettings(personaId) {
44626
44677
  const p2 = this.codexSandboxSettingsPath(personaId);
44627
- if (!fs7.existsSync(p2)) return null;
44678
+ if (!fs8.existsSync(p2)) return null;
44628
44679
  try {
44629
- return CodexSandboxSettingsSchema.parse(JSON.parse(fs7.readFileSync(p2, "utf8")));
44680
+ return CodexSandboxSettingsSchema.parse(JSON.parse(fs8.readFileSync(p2, "utf8")));
44630
44681
  } catch {
44631
44682
  return null;
44632
44683
  }
44633
44684
  }
44634
44685
  /** 覆盖写 codex-sandbox.json(seed/migrate 用)。 */
44635
44686
  writeCodexSandboxSettings(personaId, settings) {
44636
- const dir = path9.join(this.personaDir(personaId), ".clawd");
44637
- fs7.mkdirSync(dir, { recursive: true });
44687
+ const dir = path11.join(this.personaDir(personaId), ".clawd");
44688
+ fs8.mkdirSync(dir, { recursive: true });
44638
44689
  this.atomicWrite(this.codexSandboxSettingsPath(personaId), JSON.stringify(settings, null, 2));
44639
44690
  }
44640
44691
  writeMeta(persona) {
@@ -44642,8 +44693,8 @@ var PersonaStore = class {
44642
44693
  }
44643
44694
  read(personaId) {
44644
44695
  const p2 = this.metaPath(personaId);
44645
- if (!fs7.existsSync(p2)) return null;
44646
- const raw = JSON.parse(fs7.readFileSync(p2, "utf8"));
44696
+ if (!fs8.existsSync(p2)) return null;
44697
+ const raw = JSON.parse(fs8.readFileSync(p2, "utf8"));
44647
44698
  if (raw && typeof raw === "object" && "tokenMap" in raw) {
44648
44699
  delete raw.tokenMap;
44649
44700
  this.atomicWrite(p2, JSON.stringify(raw, null, 2));
@@ -44651,13 +44702,13 @@ var PersonaStore = class {
44651
44702
  return PersonaFileSchema.parse(raw);
44652
44703
  }
44653
44704
  has(personaId) {
44654
- return fs7.existsSync(this.metaPath(personaId));
44705
+ return fs8.existsSync(this.metaPath(personaId));
44655
44706
  }
44656
44707
  readPersonality(personaId) {
44657
44708
  const claudeMd = this.claudeMdPath(personaId);
44658
- if (fs7.existsSync(claudeMd)) return fs7.readFileSync(claudeMd, "utf8");
44709
+ if (fs8.existsSync(claudeMd)) return fs8.readFileSync(claudeMd, "utf8");
44659
44710
  const agentsMd = this.agentsMdPath(personaId);
44660
- if (fs7.existsSync(agentsMd)) return fs7.readFileSync(agentsMd, "utf8");
44711
+ if (fs8.existsSync(agentsMd)) return fs8.readFileSync(agentsMd, "utf8");
44661
44712
  return null;
44662
44713
  }
44663
44714
  /**
@@ -44666,23 +44717,23 @@ var PersonaStore = class {
44666
44717
  */
44667
44718
  readSandboxSettings(personaId) {
44668
44719
  const p2 = this.sandboxSettingsPath(personaId);
44669
- if (!fs7.existsSync(p2)) return null;
44720
+ if (!fs8.existsSync(p2)) return null;
44670
44721
  try {
44671
- return JSON.parse(fs7.readFileSync(p2, "utf8"));
44722
+ return JSON.parse(fs8.readFileSync(p2, "utf8"));
44672
44723
  } catch {
44673
44724
  return null;
44674
44725
  }
44675
44726
  }
44676
44727
  /** Persona 私有 skills 目录路径:<personaDir>/.claude/skills */
44677
44728
  skillsDir(personaId) {
44678
- return path9.join(this.personaDir(personaId), ".claude", "skills");
44729
+ return path11.join(this.personaDir(personaId), ".claude", "skills");
44679
44730
  }
44680
44731
  /**
44681
44732
  * Claude Code 项目级 settings 路径:`<personaDir>/.claude/settings.json`。
44682
44733
  * 这里只读 `enabledPlugins` 字段,由 owner 通过 CC `/plugin` 之类命令维护,daemon 不写。
44683
44734
  */
44684
44735
  claudeSettingsPath(personaId) {
44685
- return path9.join(this.personaDir(personaId), ".claude", "settings.json");
44736
+ return path11.join(this.personaDir(personaId), ".claude", "settings.json");
44686
44737
  }
44687
44738
  /**
44688
44739
  * 读取 persona 的 `.claude/settings.json` 中 `enabledPlugins` map,把 value === true
@@ -44697,10 +44748,10 @@ var PersonaStore = class {
44697
44748
  */
44698
44749
  readEnabledPlugins(personaId) {
44699
44750
  const p2 = this.claudeSettingsPath(personaId);
44700
- if (!fs7.existsSync(p2)) return [];
44751
+ if (!fs8.existsSync(p2)) return [];
44701
44752
  let raw;
44702
44753
  try {
44703
- raw = JSON.parse(fs7.readFileSync(p2, "utf8"));
44754
+ raw = JSON.parse(fs8.readFileSync(p2, "utf8"));
44704
44755
  } catch {
44705
44756
  return [];
44706
44757
  }
@@ -44714,22 +44765,22 @@ var PersonaStore = class {
44714
44765
  return out;
44715
44766
  }
44716
44767
  list() {
44717
- if (!fs7.existsSync(this.root)) return [];
44718
- return fs7.readdirSync(this.root).filter((name) => {
44719
- return fs7.existsSync(path9.join(this.root, name, ".clawd", "persona.json"));
44768
+ if (!fs8.existsSync(this.root)) return [];
44769
+ return fs8.readdirSync(this.root).filter((name) => {
44770
+ return fs8.existsSync(path11.join(this.root, name, ".clawd", "persona.json"));
44720
44771
  });
44721
44772
  }
44722
44773
  remove(personaId) {
44723
44774
  const dir = this.personaDir(personaId);
44724
- if (fs7.existsSync(dir)) fs7.rmSync(dir, { recursive: true, force: true });
44775
+ if (fs8.existsSync(dir)) fs8.rmSync(dir, { recursive: true, force: true });
44725
44776
  }
44726
44777
  personaDirPath(personaId) {
44727
44778
  return this.personaDir(personaId);
44728
44779
  }
44729
44780
  atomicWrite(file, content) {
44730
44781
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
44731
- fs7.writeFileSync(tmp, content, { mode: 384 });
44732
- fs7.renameSync(tmp, file);
44782
+ fs8.writeFileSync(tmp, content, { mode: 384 });
44783
+ fs8.renameSync(tmp, file);
44733
44784
  }
44734
44785
  };
44735
44786
 
@@ -44775,9 +44826,9 @@ var PersonaRegistry = class {
44775
44826
  var import_node_crypto3 = __toESM(require("crypto"), 1);
44776
44827
 
44777
44828
  // src/skills/scanner.ts
44778
- var import_node_fs7 = __toESM(require("fs"), 1);
44779
- var import_node_os4 = __toESM(require("os"), 1);
44780
- var import_node_path7 = __toESM(require("path"), 1);
44829
+ var import_node_fs8 = __toESM(require("fs"), 1);
44830
+ var import_node_os6 = __toESM(require("os"), 1);
44831
+ var import_node_path9 = __toESM(require("path"), 1);
44781
44832
 
44782
44833
  // src/skills/frontmatter.ts
44783
44834
  var STRIP_QUOTES = /^["']|["']$/g;
@@ -44886,7 +44937,7 @@ function parseDescription(content) {
44886
44937
  }
44887
44938
  function isDirLikeSync(p2) {
44888
44939
  try {
44889
- return import_node_fs7.default.statSync(p2).isDirectory();
44940
+ return import_node_fs8.default.statSync(p2).isDirectory();
44890
44941
  } catch {
44891
44942
  return false;
44892
44943
  }
@@ -44894,19 +44945,19 @@ function isDirLikeSync(p2) {
44894
44945
  function scanSkillDir(dir, source, seen, out, pluginName) {
44895
44946
  let entries;
44896
44947
  try {
44897
- entries = import_node_fs7.default.readdirSync(dir, { withFileTypes: true });
44948
+ entries = import_node_fs8.default.readdirSync(dir, { withFileTypes: true });
44898
44949
  } catch {
44899
44950
  return;
44900
44951
  }
44901
44952
  for (const ent of entries) {
44902
- const entryPath = import_node_path7.default.join(dir, ent.name);
44953
+ const entryPath = import_node_path9.default.join(dir, ent.name);
44903
44954
  if (!ent.isDirectory() && !(ent.isSymbolicLink() && isDirLikeSync(entryPath))) continue;
44904
44955
  let content;
44905
44956
  try {
44906
- content = import_node_fs7.default.readFileSync(import_node_path7.default.join(entryPath, "SKILL.md"), "utf8");
44957
+ content = import_node_fs8.default.readFileSync(import_node_path9.default.join(entryPath, "SKILL.md"), "utf8");
44907
44958
  } catch {
44908
44959
  try {
44909
- content = import_node_fs7.default.readFileSync(import_node_path7.default.join(entryPath, "skill.md"), "utf8");
44960
+ content = import_node_fs8.default.readFileSync(import_node_path9.default.join(entryPath, "skill.md"), "utf8");
44910
44961
  } catch {
44911
44962
  continue;
44912
44963
  }
@@ -44930,26 +44981,26 @@ function listSkillsForDir(dir, source) {
44930
44981
  function scanCommandDir(dir, source, seen, out, pluginName) {
44931
44982
  let entries;
44932
44983
  try {
44933
- entries = import_node_fs7.default.readdirSync(dir, { withFileTypes: true });
44984
+ entries = import_node_fs8.default.readdirSync(dir, { withFileTypes: true });
44934
44985
  } catch {
44935
44986
  return;
44936
44987
  }
44937
44988
  for (const ent of entries) {
44938
- const entryPath = import_node_path7.default.join(dir, ent.name);
44989
+ const entryPath = import_node_path9.default.join(dir, ent.name);
44939
44990
  if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync(entryPath)) {
44940
44991
  const ns = ent.name;
44941
44992
  let subEntries;
44942
44993
  try {
44943
- subEntries = import_node_fs7.default.readdirSync(entryPath, { withFileTypes: true });
44994
+ subEntries = import_node_fs8.default.readdirSync(entryPath, { withFileTypes: true });
44944
44995
  } catch {
44945
44996
  continue;
44946
44997
  }
44947
44998
  for (const se of subEntries) {
44948
44999
  if (!se.name.endsWith(".md")) continue;
44949
- const sePath = import_node_path7.default.join(entryPath, se.name);
45000
+ const sePath = import_node_path9.default.join(entryPath, se.name);
44950
45001
  let content;
44951
45002
  try {
44952
- content = import_node_fs7.default.readFileSync(sePath, "utf8");
45003
+ content = import_node_fs8.default.readFileSync(sePath, "utf8");
44953
45004
  } catch {
44954
45005
  continue;
44955
45006
  }
@@ -44966,7 +45017,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
44966
45017
  } else if (ent.name.endsWith(".md")) {
44967
45018
  let content;
44968
45019
  try {
44969
- content = import_node_fs7.default.readFileSync(entryPath, "utf8");
45020
+ content = import_node_fs8.default.readFileSync(entryPath, "utf8");
44970
45021
  } catch {
44971
45022
  continue;
44972
45023
  }
@@ -44982,10 +45033,10 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
44982
45033
  }
44983
45034
  }
44984
45035
  function readInstalledPlugins(home) {
44985
- const file = import_node_path7.default.join(home, ".claude", "plugins", "installed_plugins.json");
45036
+ const file = import_node_path9.default.join(home, ".claude", "plugins", "installed_plugins.json");
44986
45037
  let raw;
44987
45038
  try {
44988
- raw = import_node_fs7.default.readFileSync(file, "utf8");
45039
+ raw = import_node_fs8.default.readFileSync(file, "utf8");
44989
45040
  } catch {
44990
45041
  return [];
44991
45042
  }
@@ -45010,7 +45061,7 @@ var SkillsScanner = class {
45010
45061
  home;
45011
45062
  extraPluginRoots;
45012
45063
  constructor(opts = {}) {
45013
- this.home = opts.home ?? import_node_os4.default.homedir();
45064
+ this.home = opts.home ?? import_node_os6.default.homedir();
45014
45065
  this.extraPluginRoots = opts.extraPluginRoots ?? [];
45015
45066
  }
45016
45067
  /**
@@ -45033,14 +45084,14 @@ var SkillsScanner = class {
45033
45084
  });
45034
45085
  }
45035
45086
  const fsBlock = [];
45036
- scanSkillDir(import_node_path7.default.join(this.home, ".claude", "skills"), "global", seen, fsBlock);
45037
- scanCommandDir(import_node_path7.default.join(this.home, ".claude", "commands"), "global", seen, fsBlock);
45038
- scanSkillDir(import_node_path7.default.join(args.cwd, ".claude", "skills"), "project", seen, fsBlock);
45039
- scanCommandDir(import_node_path7.default.join(args.cwd, ".claude", "commands"), "project", seen, fsBlock);
45087
+ scanSkillDir(import_node_path9.default.join(this.home, ".claude", "skills"), "global", seen, fsBlock);
45088
+ scanCommandDir(import_node_path9.default.join(this.home, ".claude", "commands"), "global", seen, fsBlock);
45089
+ scanSkillDir(import_node_path9.default.join(args.cwd, ".claude", "skills"), "project", seen, fsBlock);
45090
+ scanCommandDir(import_node_path9.default.join(args.cwd, ".claude", "commands"), "project", seen, fsBlock);
45040
45091
  const plugins = [...readInstalledPlugins(this.home), ...this.extraPluginRoots];
45041
45092
  for (const { name, root } of plugins) {
45042
- scanSkillDir(import_node_path7.default.join(root, "skills"), "plugin", seen, fsBlock, name);
45043
- scanCommandDir(import_node_path7.default.join(root, "commands"), "plugin", seen, fsBlock, name);
45093
+ scanSkillDir(import_node_path9.default.join(root, "skills"), "plugin", seen, fsBlock, name);
45094
+ scanCommandDir(import_node_path9.default.join(root, "commands"), "plugin", seen, fsBlock, name);
45044
45095
  }
45045
45096
  fsBlock.sort((a, b2) => a.name < b2.name ? -1 : a.name > b2.name ? 1 : 0);
45046
45097
  return [...builtinBlock, ...fsBlock];
@@ -45146,8 +45197,8 @@ var PersonaManager = class {
45146
45197
  };
45147
45198
 
45148
45199
  // src/persona/seed.ts
45149
- var fs9 = __toESM(require("fs"), 1);
45150
- var path11 = __toESM(require("path"), 1);
45200
+ var fs10 = __toESM(require("fs"), 1);
45201
+ var path13 = __toESM(require("path"), 1);
45151
45202
  var import_node_url = require("url");
45152
45203
  var import_meta = {};
45153
45204
  var DEFAULT_BYPASS_PROFILE = {
@@ -45178,16 +45229,6 @@ var DEFAULT_PERSONAS = [
45178
45229
  public: false,
45179
45230
  sandboxProfile: DEFAULT_BYPASS_PROFILE
45180
45231
  },
45181
- {
45182
- // 工单管理员:纯操作员,按指令调 clawd-ticket MCP 增删改查 ticket。MCP 由 daemon 全局
45183
- // 注入(index.ts ticket-mcp wiring),persona 端不需要单独 .mcp.json。
45184
- personaId: "persona-ticket-manager",
45185
- label: "\u5DE5\u5355\u7BA1\u7406\u5458",
45186
- model: "opus",
45187
- iconKey: "assist",
45188
- public: false,
45189
- sandboxProfile: DEFAULT_BYPASS_PROFILE
45190
- },
45191
45232
  {
45192
45233
  personaId: "persona-feishu-assistant",
45193
45234
  label: "\u98DE\u4E66\u52A9\u7406",
@@ -45281,14 +45322,6 @@ var DEFAULT_PERSONAS = [
45281
45322
  public: false,
45282
45323
  sandboxProfile: DEFAULT_BYPASS_PROFILE
45283
45324
  },
45284
- {
45285
- personaId: "persona-bug-fixer",
45286
- label: "Bug \u4FEE\u590D\u5E08",
45287
- model: "opus",
45288
- iconKey: "debug",
45289
- public: false,
45290
- sandboxProfile: DEFAULT_BYPASS_PROFILE
45291
- },
45292
45325
  {
45293
45326
  // HTML PPT 制作师:把想法/文字/旧 PPT 转成单文件 HTML 演示稿
45294
45327
  // bundle 含 frontend-slides skill(MIT,Zara Zhang),daemon ship 进 .claude/skills/
@@ -45335,24 +45368,24 @@ function bundleSiblingFromArgv(argv1, sibling) {
45335
45368
  if (!argv1) return null;
45336
45369
  let real = argv1;
45337
45370
  try {
45338
- real = fs9.realpathSync(argv1);
45371
+ real = fs10.realpathSync(argv1);
45339
45372
  } catch {
45340
45373
  }
45341
- return path11.resolve(path11.dirname(real), sibling);
45374
+ return path13.resolve(path13.dirname(real), sibling);
45342
45375
  }
45343
45376
  function findDefaultsRoot(logger) {
45344
45377
  const candidates = [];
45345
45378
  try {
45346
- const here = path11.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
45347
- candidates.push(path11.resolve(here, "defaults"));
45348
- candidates.push(path11.resolve(here, "persona-defaults"));
45379
+ const here = path13.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
45380
+ candidates.push(path13.resolve(here, "defaults"));
45381
+ candidates.push(path13.resolve(here, "persona-defaults"));
45349
45382
  } catch {
45350
45383
  }
45351
45384
  const fromArgv = bundleSiblingFromArgv(process.argv[1], "persona-defaults");
45352
45385
  if (fromArgv) candidates.push(fromArgv);
45353
45386
  for (const c of candidates) {
45354
45387
  try {
45355
- if (fs9.statSync(c).isDirectory()) {
45388
+ if (fs10.statSync(c).isDirectory()) {
45356
45389
  logger?.info("persona.defaults-root.resolved", { root: c });
45357
45390
  return c;
45358
45391
  }
@@ -45369,8 +45402,8 @@ function seedDefaultPersonas(args) {
45369
45402
  args.logger.info("persona.seed.skip", { personaId: entry.personaId, reason: "exists" });
45370
45403
  continue;
45371
45404
  }
45372
- const bundleDir = path11.join(args.defaultsRoot, entry.personaId);
45373
- if (!fs9.existsSync(bundleDir)) {
45405
+ const bundleDir = path13.join(args.defaultsRoot, entry.personaId);
45406
+ if (!fs10.existsSync(bundleDir)) {
45374
45407
  args.logger.warn("persona.seed.skip", {
45375
45408
  personaId: entry.personaId,
45376
45409
  reason: "bundle-missing",
@@ -45378,8 +45411,8 @@ function seedDefaultPersonas(args) {
45378
45411
  });
45379
45412
  continue;
45380
45413
  }
45381
- const claudeMdPath = path11.join(bundleDir, "CLAUDE.md");
45382
- if (!fs9.existsSync(claudeMdPath)) {
45414
+ const claudeMdPath = path13.join(bundleDir, "CLAUDE.md");
45415
+ if (!fs10.existsSync(claudeMdPath)) {
45383
45416
  args.logger.warn("persona.seed.skip", {
45384
45417
  personaId: entry.personaId,
45385
45418
  reason: "no-CLAUDE.md",
@@ -45387,7 +45420,7 @@ function seedDefaultPersonas(args) {
45387
45420
  });
45388
45421
  continue;
45389
45422
  }
45390
- const personality = fs9.readFileSync(claudeMdPath, "utf8");
45423
+ const personality = fs10.readFileSync(claudeMdPath, "utf8");
45391
45424
  const now = Date.now();
45392
45425
  const persona = {
45393
45426
  personaId: entry.personaId,
@@ -45413,17 +45446,17 @@ function seedDefaultPersonas(args) {
45413
45446
  }
45414
45447
  }
45415
45448
  function skipNodeModulesUnder(srcRoot) {
45416
- return (src) => !path11.relative(srcRoot, src).split(path11.sep).includes("node_modules");
45449
+ return (src) => !path13.relative(srcRoot, src).split(path13.sep).includes("node_modules");
45417
45450
  }
45418
45451
  function copyBundleExtras(srcDir, dstDir) {
45419
- for (const entry of fs9.readdirSync(srcDir, { withFileTypes: true })) {
45452
+ for (const entry of fs10.readdirSync(srcDir, { withFileTypes: true })) {
45420
45453
  if (entry.name === "CLAUDE.md" || entry.name === ".clawd") continue;
45421
- const srcPath = path11.join(srcDir, entry.name);
45422
- const dstPath = path11.join(dstDir, entry.name);
45454
+ const srcPath = path13.join(srcDir, entry.name);
45455
+ const dstPath = path13.join(dstDir, entry.name);
45423
45456
  if (entry.isDirectory()) {
45424
- fs9.cpSync(srcPath, dstPath, { recursive: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
45457
+ fs10.cpSync(srcPath, dstPath, { recursive: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
45425
45458
  } else if (entry.isFile()) {
45426
- fs9.copyFileSync(srcPath, dstPath);
45459
+ fs10.copyFileSync(srcPath, dstPath);
45427
45460
  }
45428
45461
  }
45429
45462
  }
@@ -45431,16 +45464,16 @@ var DAEMON_MANAGED_PATHS = ["extension-kit", "CLAUDE.md", ".mcp.json"];
45431
45464
  function refreshDaemonManagedDirs(args) {
45432
45465
  const entries = args.entries ?? DEFAULT_PERSONAS;
45433
45466
  for (const entry of entries) {
45434
- const bundleDir = path11.join(args.defaultsRoot, entry.personaId);
45435
- if (!fs9.existsSync(bundleDir)) continue;
45467
+ const bundleDir = path13.join(args.defaultsRoot, entry.personaId);
45468
+ if (!fs10.existsSync(bundleDir)) continue;
45436
45469
  const personaDir = args.store.personaDirPath(entry.personaId);
45437
- if (!fs9.existsSync(personaDir)) continue;
45470
+ if (!fs10.existsSync(personaDir)) continue;
45438
45471
  for (const relPath of DAEMON_MANAGED_PATHS) {
45439
- const srcPath = path11.join(bundleDir, relPath);
45440
- if (!fs9.existsSync(srcPath)) continue;
45441
- const dstPath = path11.join(personaDir, relPath);
45472
+ const srcPath = path13.join(bundleDir, relPath);
45473
+ if (!fs10.existsSync(srcPath)) continue;
45474
+ const dstPath = path13.join(personaDir, relPath);
45442
45475
  try {
45443
- fs9.cpSync(srcPath, dstPath, { recursive: true, force: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
45476
+ fs10.cpSync(srcPath, dstPath, { recursive: true, force: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
45444
45477
  args.logger.info("persona.refresh.synced", {
45445
45478
  personaId: entry.personaId,
45446
45479
  path: relPath
@@ -45500,15 +45533,15 @@ function migrateCodexSandbox(args) {
45500
45533
  function findDeployKitRoot(logger) {
45501
45534
  const candidates = [];
45502
45535
  try {
45503
- const here = path11.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
45504
- candidates.push(path11.resolve(here, "..", "deploy-kit"));
45536
+ const here = path13.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
45537
+ candidates.push(path13.resolve(here, "..", "deploy-kit"));
45505
45538
  } catch {
45506
45539
  }
45507
45540
  const fromArgv = bundleSiblingFromArgv(process.argv[1], "deploy-kit");
45508
45541
  if (fromArgv) candidates.push(fromArgv);
45509
45542
  for (const c of candidates) {
45510
45543
  try {
45511
- if (fs9.statSync(c).isDirectory()) {
45544
+ if (fs10.statSync(c).isDirectory()) {
45512
45545
  logger?.info("persona.deploy-kit-root.resolved", { root: c });
45513
45546
  return c;
45514
45547
  }
@@ -45519,8 +45552,8 @@ function findDeployKitRoot(logger) {
45519
45552
  return null;
45520
45553
  }
45521
45554
  function seedDeployKit(args) {
45522
- const dst = path11.join(args.dataDir, "deploy-kit");
45523
- fs9.cpSync(args.deployKitBundleRoot, dst, {
45555
+ const dst = path13.join(args.dataDir, "deploy-kit");
45556
+ fs10.cpSync(args.deployKitBundleRoot, dst, {
45524
45557
  recursive: true,
45525
45558
  dereference: true,
45526
45559
  force: false,
@@ -45529,35 +45562,35 @@ function seedDeployKit(args) {
45529
45562
  args.logger.info("deploy-kit.seed.done", { dst });
45530
45563
  }
45531
45564
  function refreshDeployKit(args) {
45532
- const dst = path11.join(args.dataDir, "deploy-kit");
45533
- if (!fs9.existsSync(dst)) {
45565
+ const dst = path13.join(args.dataDir, "deploy-kit");
45566
+ if (!fs10.existsSync(dst)) {
45534
45567
  seedDeployKit(args);
45535
45568
  return;
45536
45569
  }
45537
45570
  for (const sub of ["scripts", "contract"]) {
45538
- const s = path11.join(args.deployKitBundleRoot, sub);
45539
- if (fs9.existsSync(s)) {
45540
- fs9.cpSync(s, path11.join(dst, sub), { recursive: true, force: true, dereference: true });
45571
+ const s = path13.join(args.deployKitBundleRoot, sub);
45572
+ if (fs10.existsSync(s)) {
45573
+ fs10.cpSync(s, path13.join(dst, sub), { recursive: true, force: true, dereference: true });
45541
45574
  }
45542
45575
  }
45543
- const secretsSrc = path11.join(args.deployKitBundleRoot, ".secrets");
45544
- if (fs9.existsSync(secretsSrc)) {
45545
- fs9.mkdirSync(path11.join(dst, ".secrets"), { recursive: true });
45546
- for (const f of fs9.readdirSync(secretsSrc)) {
45576
+ const secretsSrc = path13.join(args.deployKitBundleRoot, ".secrets");
45577
+ if (fs10.existsSync(secretsSrc)) {
45578
+ fs10.mkdirSync(path13.join(dst, ".secrets"), { recursive: true });
45579
+ for (const f of fs10.readdirSync(secretsSrc)) {
45547
45580
  if (!f.endsWith(".example")) continue;
45548
- fs9.copyFileSync(path11.join(secretsSrc, f), path11.join(dst, ".secrets", f));
45581
+ fs10.copyFileSync(path13.join(secretsSrc, f), path13.join(dst, ".secrets", f));
45549
45582
  }
45550
45583
  }
45551
45584
  args.logger.info("deploy-kit.refresh.done", { dst });
45552
45585
  }
45553
45586
 
45554
45587
  // src/share-md-viewer/load.ts
45555
- var import_node_fs9 = __toESM(require("fs"), 1);
45556
- var import_node_path8 = __toESM(require("path"), 1);
45588
+ var import_node_fs10 = __toESM(require("fs"), 1);
45589
+ var import_node_path10 = __toESM(require("path"), 1);
45557
45590
  var import_node_url2 = require("url");
45558
45591
 
45559
45592
  // src/share-md-viewer/asset-loader.ts
45560
- var import_node_fs8 = __toESM(require("fs"), 1);
45593
+ var import_node_fs9 = __toESM(require("fs"), 1);
45561
45594
  function htmlEscape(s) {
45562
45595
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
45563
45596
  }
@@ -45565,12 +45598,12 @@ function createViewerAssetLoader(opts) {
45565
45598
  let viewerTemplate;
45566
45599
  let errorTemplate;
45567
45600
  try {
45568
- viewerTemplate = import_node_fs8.default.readFileSync(opts.viewerHtmlPath, "utf8");
45601
+ viewerTemplate = import_node_fs9.default.readFileSync(opts.viewerHtmlPath, "utf8");
45569
45602
  } catch (err) {
45570
45603
  throw new Error(`viewer asset not found at ${opts.viewerHtmlPath}: ${err.message}`);
45571
45604
  }
45572
45605
  try {
45573
- errorTemplate = import_node_fs8.default.readFileSync(opts.errorHtmlPath, "utf8");
45606
+ errorTemplate = import_node_fs9.default.readFileSync(opts.errorHtmlPath, "utf8");
45574
45607
  } catch (err) {
45575
45608
  throw new Error(`viewer error asset not found at ${opts.errorHtmlPath}: ${err.message}`);
45576
45609
  }
@@ -45589,25 +45622,25 @@ var import_meta2 = {};
45589
45622
  function tryLoadViewerAssets(logger) {
45590
45623
  const candidates = [];
45591
45624
  try {
45592
- const here = import_node_path8.default.dirname((0, import_node_url2.fileURLToPath)(import_meta2.url));
45625
+ const here = import_node_path10.default.dirname((0, import_node_url2.fileURLToPath)(import_meta2.url));
45593
45626
  candidates.push(here);
45594
- candidates.push(import_node_path8.default.resolve(here, ".."));
45595
- candidates.push(import_node_path8.default.resolve(here, "..", "..", "dist"));
45627
+ candidates.push(import_node_path10.default.resolve(here, ".."));
45628
+ candidates.push(import_node_path10.default.resolve(here, "..", "..", "dist"));
45596
45629
  } catch {
45597
45630
  }
45598
45631
  if (process.argv[1]) {
45599
45632
  let real = process.argv[1];
45600
45633
  try {
45601
- real = import_node_fs9.default.realpathSync(process.argv[1]);
45634
+ real = import_node_fs10.default.realpathSync(process.argv[1]);
45602
45635
  } catch {
45603
45636
  }
45604
- candidates.push(import_node_path8.default.dirname(real));
45637
+ candidates.push(import_node_path10.default.dirname(real));
45605
45638
  }
45606
45639
  for (const root of candidates) {
45607
- const viewerHtmlPath = import_node_path8.default.join(root, "share-md-viewer.html");
45608
- const errorHtmlPath = import_node_path8.default.join(root, "share-md-viewer-error.html");
45640
+ const viewerHtmlPath = import_node_path10.default.join(root, "share-md-viewer.html");
45641
+ const errorHtmlPath = import_node_path10.default.join(root, "share-md-viewer-error.html");
45609
45642
  try {
45610
- if (import_node_fs9.default.statSync(viewerHtmlPath).isFile() && import_node_fs9.default.statSync(errorHtmlPath).isFile()) {
45643
+ if (import_node_fs10.default.statSync(viewerHtmlPath).isFile() && import_node_fs10.default.statSync(errorHtmlPath).isFile()) {
45611
45644
  logger?.info("share-md-viewer.assets-root.resolved", { root });
45612
45645
  return createViewerAssetLoader({ viewerHtmlPath, errorHtmlPath });
45613
45646
  }
@@ -45622,30 +45655,30 @@ function tryLoadViewerAssets(logger) {
45622
45655
  }
45623
45656
 
45624
45657
  // src/share-ui/load.ts
45625
- var import_node_fs11 = __toESM(require("fs"), 1);
45626
- var import_node_path10 = __toESM(require("path"), 1);
45658
+ var import_node_fs12 = __toESM(require("fs"), 1);
45659
+ var import_node_path12 = __toESM(require("path"), 1);
45627
45660
  var import_node_url3 = require("url");
45628
45661
 
45629
45662
  // src/share-ui/asset-loader.ts
45630
- var import_node_fs10 = __toESM(require("fs"), 1);
45631
- var import_node_path9 = __toESM(require("path"), 1);
45663
+ var import_node_fs11 = __toESM(require("fs"), 1);
45664
+ var import_node_path11 = __toESM(require("path"), 1);
45632
45665
  function createShareUiAssetLoader(opts) {
45633
45666
  let indexHtml;
45634
45667
  try {
45635
- indexHtml = import_node_fs10.default.readFileSync(opts.indexHtmlPath, "utf8");
45668
+ indexHtml = import_node_fs11.default.readFileSync(opts.indexHtmlPath, "utf8");
45636
45669
  } catch (err) {
45637
45670
  throw new Error(`share-ui index.html not found at ${opts.indexHtmlPath}: ${err.message}`);
45638
45671
  }
45639
- const assetsDir = import_node_path9.default.resolve(opts.assetsDir);
45672
+ const assetsDir = import_node_path11.default.resolve(opts.assetsDir);
45640
45673
  return {
45641
45674
  renderIndexHtml() {
45642
45675
  return indexHtml;
45643
45676
  },
45644
45677
  resolveAssetPath(rel) {
45645
- const resolved = import_node_path9.default.resolve(assetsDir, rel);
45646
- if (resolved !== assetsDir && !resolved.startsWith(assetsDir + import_node_path9.default.sep)) return null;
45678
+ const resolved = import_node_path11.default.resolve(assetsDir, rel);
45679
+ if (resolved !== assetsDir && !resolved.startsWith(assetsDir + import_node_path11.default.sep)) return null;
45647
45680
  try {
45648
- if (import_node_fs10.default.statSync(resolved).isFile()) return resolved;
45681
+ if (import_node_fs11.default.statSync(resolved).isFile()) return resolved;
45649
45682
  } catch {
45650
45683
  }
45651
45684
  return null;
@@ -45659,28 +45692,28 @@ function bundleDirFromArgv(argv1) {
45659
45692
  if (!argv1) return null;
45660
45693
  let real = argv1;
45661
45694
  try {
45662
- real = import_node_fs11.default.realpathSync(argv1);
45695
+ real = import_node_fs12.default.realpathSync(argv1);
45663
45696
  } catch {
45664
45697
  }
45665
- return import_node_path10.default.dirname(real);
45698
+ return import_node_path12.default.dirname(real);
45666
45699
  }
45667
45700
  function tryLoadShareUi(logger) {
45668
45701
  const candidates = [];
45669
45702
  try {
45670
- const here = import_node_path10.default.dirname((0, import_node_url3.fileURLToPath)(import_meta3.url));
45703
+ const here = import_node_path12.default.dirname((0, import_node_url3.fileURLToPath)(import_meta3.url));
45671
45704
  candidates.push(here);
45672
- candidates.push(import_node_path10.default.resolve(here, ".."));
45673
- candidates.push(import_node_path10.default.resolve(here, "..", "..", "dist"));
45705
+ candidates.push(import_node_path12.default.resolve(here, ".."));
45706
+ candidates.push(import_node_path12.default.resolve(here, "..", "..", "dist"));
45674
45707
  } catch {
45675
45708
  }
45676
45709
  const argvDir = bundleDirFromArgv(process.argv[1]);
45677
45710
  if (argvDir) candidates.push(argvDir);
45678
45711
  for (const root of candidates) {
45679
- const shareUiDir = import_node_path10.default.join(root, "share-ui");
45680
- const indexHtmlPath = import_node_path10.default.join(shareUiDir, "guest.html");
45681
- const assetsDir = import_node_path10.default.join(shareUiDir, "assets");
45712
+ const shareUiDir = import_node_path12.default.join(root, "share-ui");
45713
+ const indexHtmlPath = import_node_path12.default.join(shareUiDir, "guest.html");
45714
+ const assetsDir = import_node_path12.default.join(shareUiDir, "assets");
45682
45715
  try {
45683
- if (import_node_fs11.default.statSync(indexHtmlPath).isFile() && import_node_fs11.default.statSync(assetsDir).isDirectory()) {
45716
+ if (import_node_fs12.default.statSync(indexHtmlPath).isFile() && import_node_fs12.default.statSync(assetsDir).isDirectory()) {
45684
45717
  logger?.info("share-ui.assets-root.resolved", { root: shareUiDir });
45685
45718
  return createShareUiAssetLoader({ indexHtmlPath, assetsDir });
45686
45719
  }
@@ -45762,20 +45795,20 @@ function buildVisitorLogin(deps) {
45762
45795
  }
45763
45796
 
45764
45797
  // src/visitor/visitor-store.ts
45765
- var import_node_fs12 = __toESM(require("fs"), 1);
45766
- var import_node_path11 = __toESM(require("path"), 1);
45798
+ var import_node_fs13 = __toESM(require("fs"), 1);
45799
+ var import_node_path13 = __toESM(require("path"), 1);
45767
45800
  function createVisitorStore(opts) {
45768
- const file = import_node_path11.default.join(opts.dir, "visitors.json");
45801
+ const file = import_node_path13.default.join(opts.dir, "visitors.json");
45769
45802
  const read = () => {
45770
45803
  try {
45771
- return JSON.parse(import_node_fs12.default.readFileSync(file, "utf8"));
45804
+ return JSON.parse(import_node_fs13.default.readFileSync(file, "utf8"));
45772
45805
  } catch {
45773
45806
  return [];
45774
45807
  }
45775
45808
  };
45776
45809
  const write = (rows) => {
45777
- import_node_fs12.default.mkdirSync(opts.dir, { recursive: true });
45778
- import_node_fs12.default.writeFileSync(file, JSON.stringify(rows, null, 2));
45810
+ import_node_fs13.default.mkdirSync(opts.dir, { recursive: true });
45811
+ import_node_fs13.default.writeFileSync(file, JSON.stringify(rows, null, 2));
45779
45812
  };
45780
45813
  return {
45781
45814
  upsert(r) {
@@ -46057,8 +46090,8 @@ function turnStartInput(text) {
46057
46090
  const items = [];
46058
46091
  let leftover = text;
46059
46092
  for (const m2 of text.matchAll(SKILL_RE)) {
46060
- const [marker, name, path67] = m2;
46061
- items.push({ type: "skill", name, path: path67 });
46093
+ const [marker, name, path68] = m2;
46094
+ items.push({ type: "skill", name, path: path68 });
46062
46095
  leftover = leftover.replace(marker, "");
46063
46096
  }
46064
46097
  for (const m2 of text.matchAll(ATTACHMENT_RE2)) {
@@ -46291,8 +46324,8 @@ var CodexAdapter = class {
46291
46324
 
46292
46325
  // src/tools/claude-tui.ts
46293
46326
  var import_node_fs16 = __toESM(require("fs"), 1);
46294
- var import_node_os6 = __toESM(require("os"), 1);
46295
- var import_node_path13 = __toESM(require("path"), 1);
46327
+ var import_node_os7 = __toESM(require("os"), 1);
46328
+ var import_node_path14 = __toESM(require("path"), 1);
46296
46329
  var import_headless = __toESM(require_xterm_headless(), 1);
46297
46330
 
46298
46331
  // ../node_modules/.pnpm/@xterm+addon-serialize@0.14.0/node_modules/@xterm/addon-serialize/lib/addon-serialize.mjs
@@ -47428,8 +47461,8 @@ function buildTuiSpawnArgs(ctx, isResume = false) {
47428
47461
  }
47429
47462
  function jsonlExistsForCtx(ctx) {
47430
47463
  if (!ctx.toolSessionId) return false;
47431
- const home = import_node_os6.default.homedir();
47432
- const file = import_node_path13.default.join(home, ".claude", "projects", cwdToHashDir(ctx.cwd), `${ctx.toolSessionId}.jsonl`);
47464
+ const home = import_node_os7.default.homedir();
47465
+ const file = import_node_path14.default.join(home, ".claude", "projects", cwdToHashDir(ctx.cwd), `${ctx.toolSessionId}.jsonl`);
47433
47466
  try {
47434
47467
  return import_node_fs16.default.statSync(file).isFile();
47435
47468
  } catch {
@@ -47501,9 +47534,9 @@ var PersonaDispatchManager = class {
47501
47534
 
47502
47535
  // src/dispatch/mcp-config.ts
47503
47536
  var import_node_fs17 = __toESM(require("fs"), 1);
47504
- var import_node_path14 = __toESM(require("path"), 1);
47537
+ var import_node_path15 = __toESM(require("path"), 1);
47505
47538
  function dispatchMcpConfigPath(dataDir) {
47506
- return import_node_path14.default.join(dataDir, "dispatch.mcp.json");
47539
+ return import_node_path15.default.join(dataDir, "dispatch.mcp.json");
47507
47540
  }
47508
47541
  function writeDispatchMcpConfig(args) {
47509
47542
  const cfgPath = dispatchMcpConfigPath(args.dataDir);
@@ -47525,9 +47558,9 @@ function writeDispatchMcpConfig(args) {
47525
47558
 
47526
47559
  // src/ticket/mcp-config.ts
47527
47560
  var import_node_fs18 = __toESM(require("fs"), 1);
47528
- var import_node_path15 = __toESM(require("path"), 1);
47561
+ var import_node_path16 = __toESM(require("path"), 1);
47529
47562
  function ticketMcpConfigPath(dataDir) {
47530
- return import_node_path15.default.join(dataDir, "ticket.mcp.json");
47563
+ return import_node_path16.default.join(dataDir, "ticket.mcp.json");
47531
47564
  }
47532
47565
  function writeTicketMcpConfig(args) {
47533
47566
  const cfgPath = ticketMcpConfigPath(args.dataDir);
@@ -47555,9 +47588,9 @@ function writeTicketMcpConfig(args) {
47555
47588
 
47556
47589
  // src/shift/mcp-config.ts
47557
47590
  var import_node_fs19 = __toESM(require("fs"), 1);
47558
- var import_node_path16 = __toESM(require("path"), 1);
47591
+ var import_node_path17 = __toESM(require("path"), 1);
47559
47592
  function shiftMcpConfigPath(dataDir) {
47560
- return import_node_path16.default.join(dataDir, "shift.mcp.json");
47593
+ return import_node_path17.default.join(dataDir, "shift.mcp.json");
47561
47594
  }
47562
47595
  async function writeShiftMcpConfig(args) {
47563
47596
  const cfgPath = shiftMcpConfigPath(args.dataDir);
@@ -47579,9 +47612,9 @@ async function writeShiftMcpConfig(args) {
47579
47612
 
47580
47613
  // src/inbox/mcp-config.ts
47581
47614
  var import_node_fs20 = __toESM(require("fs"), 1);
47582
- var import_node_path17 = __toESM(require("path"), 1);
47615
+ var import_node_path18 = __toESM(require("path"), 1);
47583
47616
  function inboxMcpConfigPath(dataDir) {
47584
- return import_node_path17.default.join(dataDir, "inbox.mcp.json");
47617
+ return import_node_path18.default.join(dataDir, "inbox.mcp.json");
47585
47618
  }
47586
47619
  async function writeInboxMcpConfig(args) {
47587
47620
  const cfgPath = inboxMcpConfigPath(args.dataDir);
@@ -47603,7 +47636,7 @@ async function writeInboxMcpConfig(args) {
47603
47636
 
47604
47637
  // src/shift/store.ts
47605
47638
  var import_promises = __toESM(require("fs/promises"), 1);
47606
- var import_node_path18 = __toESM(require("path"), 1);
47639
+ var import_node_path19 = __toESM(require("path"), 1);
47607
47640
  var import_node_crypto5 = require("crypto");
47608
47641
 
47609
47642
  // src/shift/constants.ts
@@ -47672,7 +47705,7 @@ function createShiftStore(deps) {
47672
47705
  flushTimer = null;
47673
47706
  }
47674
47707
  const content = { version: 1, shifts };
47675
- await import_promises.default.mkdir(import_node_path18.default.dirname(deps.filePath), { recursive: true });
47708
+ await import_promises.default.mkdir(import_node_path19.default.dirname(deps.filePath), { recursive: true });
47676
47709
  const tmp = `${deps.filePath}.tmp-${deps.now()}-${Math.floor(Math.random() * 1e6)}`;
47677
47710
  await import_promises.default.writeFile(tmp, JSON.stringify(content, null, 2), "utf8");
47678
47711
  await import_promises.default.rename(tmp, deps.filePath);
@@ -48476,13 +48509,13 @@ function mapSkillsListResponse(res) {
48476
48509
  const r = s ?? {};
48477
48510
  const name = str3(r.name);
48478
48511
  if (!name) continue;
48479
- const path67 = str3(r.path);
48512
+ const path68 = str3(r.path);
48480
48513
  const description = str3(r.description);
48481
48514
  const isPlugin = name.includes(":");
48482
48515
  out.push({
48483
48516
  name,
48484
48517
  source: isPlugin ? "plugin" : "project",
48485
- ...path67 ? { path: path67 } : {},
48518
+ ...path68 ? { path: path68 } : {},
48486
48519
  ...description ? { description } : {},
48487
48520
  ...isPlugin ? { plugin: name.split(":")[0] } : {}
48488
48521
  });
@@ -48522,15 +48555,15 @@ async function listCodexSkills(cwd, deps = {}) {
48522
48555
 
48523
48556
  // src/workspace/browser.ts
48524
48557
  var import_node_fs21 = __toESM(require("fs"), 1);
48525
- var import_node_os7 = __toESM(require("os"), 1);
48526
- var import_node_path19 = __toESM(require("path"), 1);
48558
+ var import_node_os8 = __toESM(require("os"), 1);
48559
+ var import_node_path20 = __toESM(require("path"), 1);
48527
48560
  init_protocol();
48528
48561
  var MAX_FILE_BYTES = 2 * 1024 * 1024;
48529
48562
  function resolveInsideCwd(cwd, subpath) {
48530
- const absCwd = import_node_path19.default.resolve(cwd);
48531
- const joined = import_node_path19.default.resolve(absCwd, subpath ?? ".");
48532
- const rel = import_node_path19.default.relative(absCwd, joined);
48533
- if (rel.startsWith("..") || import_node_path19.default.isAbsolute(rel)) {
48563
+ const absCwd = import_node_path20.default.resolve(cwd);
48564
+ const joined = import_node_path20.default.resolve(absCwd, subpath ?? ".");
48565
+ const rel = import_node_path20.default.relative(absCwd, joined);
48566
+ if (rel.startsWith("..") || import_node_path20.default.isAbsolute(rel)) {
48534
48567
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
48535
48568
  }
48536
48569
  return joined;
@@ -48548,7 +48581,7 @@ function ensureCwd(cwd) {
48548
48581
  }
48549
48582
  var WorkspaceBrowser = class {
48550
48583
  list(args) {
48551
- const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os7.default.homedir();
48584
+ const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os8.default.homedir();
48552
48585
  ensureCwd(cwd);
48553
48586
  const full = resolveInsideCwd(cwd, args.path);
48554
48587
  const dirents = import_node_fs21.default.readdirSync(full, { withFileTypes: true });
@@ -48561,7 +48594,7 @@ var WorkspaceBrowser = class {
48561
48594
  mtime: ""
48562
48595
  };
48563
48596
  try {
48564
- const st = import_node_fs21.default.statSync(import_node_path19.default.join(full, d.name));
48597
+ const st = import_node_fs21.default.statSync(import_node_path20.default.join(full, d.name));
48565
48598
  entry.mtime = new Date(st.mtimeMs).toISOString();
48566
48599
  if (d.isFile()) entry.size = st.size;
48567
48600
  } catch {
@@ -48607,8 +48640,8 @@ var WorkspaceBrowser = class {
48607
48640
 
48608
48641
  // src/skills/agents-scanner.ts
48609
48642
  var import_node_fs22 = __toESM(require("fs"), 1);
48610
- var import_node_os8 = __toESM(require("os"), 1);
48611
- var import_node_path20 = __toESM(require("path"), 1);
48643
+ var import_node_os9 = __toESM(require("os"), 1);
48644
+ var import_node_path21 = __toESM(require("path"), 1);
48612
48645
  var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
48613
48646
  function isDirLikeSync2(p2) {
48614
48647
  try {
@@ -48646,10 +48679,10 @@ function scanAgentsDir(dir, source, seen, out) {
48646
48679
  }
48647
48680
  for (const ent of entries) {
48648
48681
  if (!ent.name.endsWith(".md")) continue;
48649
- if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path20.default.join(dir, ent.name)))) {
48682
+ if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path21.default.join(dir, ent.name)))) {
48650
48683
  continue;
48651
48684
  }
48652
- const filePath = import_node_path20.default.join(dir, ent.name);
48685
+ const filePath = import_node_path21.default.join(dir, ent.name);
48653
48686
  const baseName = ent.name.replace(/\.md$/, "");
48654
48687
  if (seen.has(baseName)) continue;
48655
48688
  seen.add(baseName);
@@ -48672,7 +48705,7 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
48672
48705
  return;
48673
48706
  }
48674
48707
  for (const ent of entries) {
48675
- const childPath = import_node_path20.default.join(dir, ent.name);
48708
+ const childPath = import_node_path21.default.join(dir, ent.name);
48676
48709
  if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
48677
48710
  walk2(childPath, [...namespaces, ent.name]);
48678
48711
  continue;
@@ -48697,9 +48730,9 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
48697
48730
  walk2(root, []);
48698
48731
  }
48699
48732
  function readInstalledPlugins2(home) {
48700
- const pluginsDir = import_node_path20.default.join(home, ".claude", "plugins");
48701
- const v2 = import_node_path20.default.join(pluginsDir, "installed_plugins_v2.json");
48702
- const v1 = import_node_path20.default.join(pluginsDir, "installed_plugins.json");
48733
+ const pluginsDir = import_node_path21.default.join(home, ".claude", "plugins");
48734
+ const v2 = import_node_path21.default.join(pluginsDir, "installed_plugins_v2.json");
48735
+ const v1 = import_node_path21.default.join(pluginsDir, "installed_plugins.json");
48703
48736
  let raw = null;
48704
48737
  for (const candidate of [v2, v1]) {
48705
48738
  try {
@@ -48728,19 +48761,19 @@ function readInstalledPlugins2(home) {
48728
48761
  return out;
48729
48762
  }
48730
48763
  function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
48731
- let cur = import_node_path20.default.resolve(startCwd);
48732
- const fsRoot = import_node_path20.default.parse(cur).root;
48764
+ let cur = import_node_path21.default.resolve(startCwd);
48765
+ const fsRoot = import_node_path21.default.parse(cur).root;
48733
48766
  while (true) {
48734
- scanAgentsDir(import_node_path20.default.join(cur, ".claude", "agents"), "project", seen, out);
48767
+ scanAgentsDir(import_node_path21.default.join(cur, ".claude", "agents"), "project", seen, out);
48735
48768
  let hasGit = false;
48736
48769
  try {
48737
- hasGit = import_node_fs22.default.existsSync(import_node_path20.default.join(cur, ".git"));
48770
+ hasGit = import_node_fs22.default.existsSync(import_node_path21.default.join(cur, ".git"));
48738
48771
  } catch {
48739
48772
  }
48740
48773
  if (hasGit) return;
48741
48774
  if (cur === home) return;
48742
48775
  if (cur === fsRoot) return;
48743
- const parent = import_node_path20.default.dirname(cur);
48776
+ const parent = import_node_path21.default.dirname(cur);
48744
48777
  if (parent === cur) return;
48745
48778
  cur = parent;
48746
48779
  }
@@ -48750,7 +48783,7 @@ var AgentsScanner = class {
48750
48783
  extraPluginRoots;
48751
48784
  policyDir;
48752
48785
  constructor(opts = {}) {
48753
- this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os8.default.homedir();
48786
+ this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os9.default.homedir();
48754
48787
  this.extraPluginRoots = opts.extraPluginRoots ?? [];
48755
48788
  if (opts.policyDir !== void 0) {
48756
48789
  this.policyDir = opts.policyDir;
@@ -48775,7 +48808,7 @@ var AgentsScanner = class {
48775
48808
  }
48776
48809
  const fsBlock = [];
48777
48810
  scanAgentsDir(
48778
- import_node_path20.default.join(this.home, ".claude", "agents"),
48811
+ import_node_path21.default.join(this.home, ".claude", "agents"),
48779
48812
  "global",
48780
48813
  seen,
48781
48814
  fsBlock
@@ -48789,7 +48822,7 @@ var AgentsScanner = class {
48789
48822
  ...this.extraPluginRoots
48790
48823
  ];
48791
48824
  for (const { name, root } of plugins) {
48792
- const agentsRoot = import_node_path20.default.join(root, "agents");
48825
+ const agentsRoot = import_node_path21.default.join(root, "agents");
48793
48826
  scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
48794
48827
  }
48795
48828
  return [...builtinBlock, ...fsBlock];
@@ -48798,27 +48831,27 @@ var AgentsScanner = class {
48798
48831
 
48799
48832
  // src/observer/session-observer.ts
48800
48833
  var import_node_fs24 = __toESM(require("fs"), 1);
48801
- var import_node_os10 = __toESM(require("os"), 1);
48802
- var import_node_path22 = __toESM(require("path"), 1);
48834
+ var import_node_os11 = __toESM(require("os"), 1);
48835
+ var import_node_path23 = __toESM(require("path"), 1);
48803
48836
  init_claude_history();
48804
48837
 
48805
48838
  // src/observer/subagent-meta-observer.ts
48806
48839
  var import_node_fs23 = __toESM(require("fs"), 1);
48807
- var import_node_os9 = __toESM(require("os"), 1);
48808
- var import_node_path21 = __toESM(require("path"), 1);
48840
+ var import_node_os10 = __toESM(require("os"), 1);
48841
+ var import_node_path22 = __toESM(require("path"), 1);
48809
48842
  init_claude_history();
48810
48843
  var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
48811
48844
  var SubagentMetaObserver = class {
48812
48845
  constructor(opts) {
48813
48846
  this.opts = opts;
48814
- this.home = opts.home ?? import_node_os9.default.homedir();
48847
+ this.home = opts.home ?? import_node_os10.default.homedir();
48815
48848
  }
48816
48849
  opts;
48817
48850
  home;
48818
48851
  watches = /* @__PURE__ */ new Map();
48819
48852
  // public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
48820
48853
  resolveSubagentDir(cwd, toolSessionId) {
48821
- return import_node_path21.default.join(
48854
+ return import_node_path22.default.join(
48822
48855
  this.home,
48823
48856
  ".claude",
48824
48857
  "projects",
@@ -48874,7 +48907,7 @@ var SubagentMetaObserver = class {
48874
48907
  if (!m2) return;
48875
48908
  const agentId = m2[1];
48876
48909
  if (w2.emitted.has(agentId)) return;
48877
- const file = import_node_path21.default.join(w2.dirPath, name);
48910
+ const file = import_node_path22.default.join(w2.dirPath, name);
48878
48911
  let raw;
48879
48912
  try {
48880
48913
  raw = import_node_fs23.default.readFileSync(file, "utf8");
@@ -48922,7 +48955,7 @@ var SubagentMetaObserver = class {
48922
48955
  var SessionObserver = class {
48923
48956
  constructor(opts) {
48924
48957
  this.opts = opts;
48925
- this.home = opts.home ?? import_node_os10.default.homedir();
48958
+ this.home = opts.home ?? import_node_os11.default.homedir();
48926
48959
  this.metaObserver = opts.enableSubagentMetaObserver ? new SubagentMetaObserver({ home: this.home, onEvent: opts.onEvent }) : null;
48927
48960
  }
48928
48961
  opts;
@@ -48934,7 +48967,7 @@ var SessionObserver = class {
48934
48967
  metaObserver;
48935
48968
  resolveJsonlPath(cwd, toolSessionId, override) {
48936
48969
  if (override) return override;
48937
- return import_node_path22.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
48970
+ return import_node_path23.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
48938
48971
  }
48939
48972
  start(args) {
48940
48973
  this.stop(args.sessionId);
@@ -48955,10 +48988,10 @@ var SessionObserver = class {
48955
48988
  prevIsRejectSentinel: false
48956
48989
  };
48957
48990
  try {
48958
- import_node_fs24.default.mkdirSync(import_node_path22.default.dirname(filePath), { recursive: true });
48991
+ import_node_fs24.default.mkdirSync(import_node_path23.default.dirname(filePath), { recursive: true });
48959
48992
  } catch {
48960
48993
  }
48961
- w2.watcher = import_node_fs24.default.watch(import_node_path22.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
48994
+ w2.watcher = import_node_fs24.default.watch(import_node_path23.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
48962
48995
  if (!changedName || !filePath.endsWith(changedName)) return;
48963
48996
  this.poll(w2);
48964
48997
  });
@@ -49840,7 +49873,7 @@ async function authenticate(token, deps) {
49840
49873
 
49841
49874
  // src/permission/capability-store.ts
49842
49875
  var fs28 = __toESM(require("fs"), 1);
49843
- var path27 = __toESM(require("path"), 1);
49876
+ var path28 = __toESM(require("path"), 1);
49844
49877
  var CAPABILITIES_FILE_NAME = "capabilities.json";
49845
49878
  var FILE_VERSION = 1;
49846
49879
  var CapabilityStore = class {
@@ -49870,7 +49903,7 @@ var CapabilityStore = class {
49870
49903
  this.flush();
49871
49904
  }
49872
49905
  filePath() {
49873
- return path27.join(this.dataDir, CAPABILITIES_FILE_NAME);
49906
+ return path28.join(this.dataDir, CAPABILITIES_FILE_NAME);
49874
49907
  }
49875
49908
  readFromDisk() {
49876
49909
  const file = this.filePath();
@@ -50017,7 +50050,7 @@ function cleanupGuestSessionsForCapability(cap, factory) {
50017
50050
 
50018
50051
  // src/inbox/inbox-store.ts
50019
50052
  var fs30 = __toESM(require("fs"), 1);
50020
- var path28 = __toESM(require("path"), 1);
50053
+ var path29 = __toESM(require("path"), 1);
50021
50054
  var INBOX_SUBDIR = "inbox";
50022
50055
  var InboxStore = class {
50023
50056
  constructor(dataDir) {
@@ -50115,10 +50148,10 @@ var InboxStore = class {
50115
50148
  }
50116
50149
  }
50117
50150
  dirPath() {
50118
- return path28.join(this.dataDir, INBOX_SUBDIR);
50151
+ return path29.join(this.dataDir, INBOX_SUBDIR);
50119
50152
  }
50120
50153
  filePath(peerDeviceId) {
50121
- return path28.join(this.dirPath(), `${peerDeviceId}.jsonl`);
50154
+ return path29.join(this.dirPath(), `${peerDeviceId}.jsonl`);
50122
50155
  }
50123
50156
  };
50124
50157
  function parseAllLines(raw) {
@@ -50207,7 +50240,7 @@ var InboxManager = class {
50207
50240
 
50208
50241
  // src/state/contact-store.ts
50209
50242
  var fs31 = __toESM(require("fs"), 1);
50210
- var path29 = __toESM(require("path"), 1);
50243
+ var path30 = __toESM(require("path"), 1);
50211
50244
  var FILE_NAME = "contacts.json";
50212
50245
  var ContactStore = class {
50213
50246
  constructor(dataDir) {
@@ -50217,7 +50250,7 @@ var ContactStore = class {
50217
50250
  contacts = /* @__PURE__ */ new Map();
50218
50251
  load() {
50219
50252
  this.contacts.clear();
50220
- const file = path29.join(this.dataDir, FILE_NAME);
50253
+ const file = path30.join(this.dataDir, FILE_NAME);
50221
50254
  let raw;
50222
50255
  try {
50223
50256
  raw = fs31.readFileSync(file, "utf8");
@@ -50263,7 +50296,7 @@ var ContactStore = class {
50263
50296
  return existed;
50264
50297
  }
50265
50298
  flush() {
50266
- const file = path29.join(this.dataDir, FILE_NAME);
50299
+ const file = path30.join(this.dataDir, FILE_NAME);
50267
50300
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
50268
50301
  const content = JSON.stringify(
50269
50302
  { contacts: Array.from(this.contacts.values()) },
@@ -50427,52 +50460,52 @@ async function autoReverseContact(args) {
50427
50460
 
50428
50461
  // src/migrations/2026-05-20-flatten-sessions.ts
50429
50462
  var fs32 = __toESM(require("fs"), 1);
50430
- var path30 = __toESM(require("path"), 1);
50463
+ var path31 = __toESM(require("path"), 1);
50431
50464
  var MIGRATION_FLAG_NAME = ".migration.v1.done";
50432
50465
  function migrateFlattenSessions(opts) {
50433
50466
  const dataDir = opts.dataDir;
50434
50467
  const now = opts.now ?? Date.now;
50435
- const sessionsDir = path30.join(dataDir, "sessions");
50436
- const flagPath = path30.join(sessionsDir, MIGRATION_FLAG_NAME);
50468
+ const sessionsDir = path31.join(dataDir, "sessions");
50469
+ const flagPath = path31.join(sessionsDir, MIGRATION_FLAG_NAME);
50437
50470
  if (existsSync3(flagPath)) {
50438
50471
  return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
50439
50472
  }
50440
50473
  let movedBare = 0;
50441
50474
  let movedVmOwner = 0;
50442
50475
  let archivedListener = 0;
50443
- const defaultDir = path30.join(sessionsDir, "default");
50476
+ const defaultDir = path31.join(sessionsDir, "default");
50444
50477
  if (existsSync3(defaultDir)) {
50445
50478
  for (const entry of readdirSafe(defaultDir)) {
50446
50479
  if (!entry.endsWith(".json")) continue;
50447
- const src = path30.join(defaultDir, entry);
50448
- const dst = path30.join(sessionsDir, entry);
50480
+ const src = path31.join(defaultDir, entry);
50481
+ const dst = path31.join(sessionsDir, entry);
50449
50482
  fs32.renameSync(src, dst);
50450
50483
  movedBare += 1;
50451
50484
  }
50452
50485
  rmdirIfEmpty(defaultDir);
50453
50486
  }
50454
50487
  for (const pid of readdirSafe(sessionsDir)) {
50455
- const personaDir = path30.join(sessionsDir, pid);
50488
+ const personaDir = path31.join(sessionsDir, pid);
50456
50489
  if (!isDir(personaDir)) continue;
50457
50490
  if (pid === "default") continue;
50458
- const ownerSrc = path30.join(personaDir, "owner");
50491
+ const ownerSrc = path31.join(personaDir, "owner");
50459
50492
  if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
50460
- const ownerDst = path30.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
50493
+ const ownerDst = path31.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
50461
50494
  fs32.mkdirSync(ownerDst, { recursive: true });
50462
50495
  for (const file of readdirSafe(ownerSrc)) {
50463
50496
  if (!file.endsWith(".json")) continue;
50464
- fs32.renameSync(path30.join(ownerSrc, file), path30.join(ownerDst, file));
50497
+ fs32.renameSync(path31.join(ownerSrc, file), path31.join(ownerDst, file));
50465
50498
  movedVmOwner += 1;
50466
50499
  }
50467
50500
  rmdirIfEmpty(ownerSrc);
50468
50501
  }
50469
- const listenerSrc = path30.join(personaDir, "listener");
50502
+ const listenerSrc = path31.join(personaDir, "listener");
50470
50503
  if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
50471
- const archiveDst = path30.join(dataDir, ".legacy", `listener-${pid}`);
50504
+ const archiveDst = path31.join(dataDir, ".legacy", `listener-${pid}`);
50472
50505
  fs32.mkdirSync(archiveDst, { recursive: true });
50473
50506
  for (const file of readdirSafe(listenerSrc)) {
50474
50507
  if (!file.endsWith(".json")) continue;
50475
- fs32.renameSync(path30.join(listenerSrc, file), path30.join(archiveDst, file));
50508
+ fs32.renameSync(path31.join(listenerSrc, file), path31.join(archiveDst, file));
50476
50509
  archivedListener += 1;
50477
50510
  }
50478
50511
  rmdirIfEmpty(listenerSrc);
@@ -50520,10 +50553,10 @@ function rmdirIfEmpty(p2) {
50520
50553
 
50521
50554
  // src/transport/http-router.ts
50522
50555
  var import_node_fs26 = __toESM(require("fs"), 1);
50523
- var import_node_path26 = __toESM(require("path"), 1);
50556
+ var import_node_path27 = __toESM(require("path"), 1);
50524
50557
 
50525
50558
  // src/attachment/mime.ts
50526
- var import_node_path23 = __toESM(require("path"), 1);
50559
+ var import_node_path24 = __toESM(require("path"), 1);
50527
50560
  var TEXT_PLAIN = "text/plain; charset=utf-8";
50528
50561
  var EXT_TO_NATIVE_MIME = {
50529
50562
  // 图片
@@ -50630,7 +50663,7 @@ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
50630
50663
  ".mk"
50631
50664
  ]);
50632
50665
  function lookupMime(filePathOrName) {
50633
- const ext = import_node_path23.default.extname(filePathOrName).toLowerCase();
50666
+ const ext = import_node_path24.default.extname(filePathOrName).toLowerCase();
50634
50667
  if (EXT_TO_NATIVE_MIME[ext]) return EXT_TO_NATIVE_MIME[ext];
50635
50668
  if (TEXT_EXTENSIONS.has(ext)) return TEXT_PLAIN;
50636
50669
  return "application/octet-stream";
@@ -50700,7 +50733,7 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
50700
50733
 
50701
50734
  // src/attachment/upload.ts
50702
50735
  var import_node_fs25 = __toESM(require("fs"), 1);
50703
- var import_node_path24 = __toESM(require("path"), 1);
50736
+ var import_node_path25 = __toESM(require("path"), 1);
50704
50737
  var import_node_crypto7 = __toESM(require("crypto"), 1);
50705
50738
  var import_promises2 = require("stream/promises");
50706
50739
  var UploadError = class extends Error {
@@ -50712,14 +50745,14 @@ var UploadError = class extends Error {
50712
50745
  code;
50713
50746
  };
50714
50747
  function assertValidFileName(fileName) {
50715
- if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path24.default.basename(fileName)) {
50748
+ if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path25.default.basename(fileName)) {
50716
50749
  throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
50717
50750
  }
50718
50751
  }
50719
50752
  var HASH_PREFIX_LEN = 16;
50720
50753
  async function writeUploadedAttachment(args) {
50721
50754
  assertValidFileName(args.fileName);
50722
- const attachmentsRoot = import_node_path24.default.join(args.sessionDir, ".attachments");
50755
+ const attachmentsRoot = import_node_path25.default.join(args.sessionDir, ".attachments");
50723
50756
  try {
50724
50757
  import_node_fs25.default.mkdirSync(attachmentsRoot, { recursive: true });
50725
50758
  } catch (err) {
@@ -50727,7 +50760,7 @@ async function writeUploadedAttachment(args) {
50727
50760
  }
50728
50761
  const hasher = import_node_crypto7.default.createHash("sha256");
50729
50762
  let actualSize = 0;
50730
- const tmpPath = import_node_path24.default.join(
50763
+ const tmpPath = import_node_path25.default.join(
50731
50764
  attachmentsRoot,
50732
50765
  `.upload-${process.pid}-${Date.now()}-${import_node_crypto7.default.randomBytes(4).toString("hex")}`
50733
50766
  );
@@ -50762,7 +50795,7 @@ async function writeUploadedAttachment(args) {
50762
50795
  );
50763
50796
  }
50764
50797
  const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
50765
- const hashDir = import_node_path24.default.join(attachmentsRoot, attachmentId);
50798
+ const hashDir = import_node_path25.default.join(attachmentsRoot, attachmentId);
50766
50799
  let finalFileName;
50767
50800
  let hashDirExists = false;
50768
50801
  try {
@@ -50780,7 +50813,7 @@ async function writeUploadedAttachment(args) {
50780
50813
  try {
50781
50814
  import_node_fs25.default.mkdirSync(hashDir, { recursive: true });
50782
50815
  finalFileName = args.fileName;
50783
- import_node_fs25.default.renameSync(tmpPath, import_node_path24.default.join(hashDir, finalFileName));
50816
+ import_node_fs25.default.renameSync(tmpPath, import_node_path25.default.join(hashDir, finalFileName));
50784
50817
  } catch (err) {
50785
50818
  try {
50786
50819
  import_node_fs25.default.unlinkSync(tmpPath);
@@ -50789,8 +50822,8 @@ async function writeUploadedAttachment(args) {
50789
50822
  throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
50790
50823
  }
50791
50824
  }
50792
- const absPath = import_node_path24.default.join(hashDir, finalFileName);
50793
- const relPath = import_node_path24.default.relative(args.sessionDir, absPath);
50825
+ const absPath = import_node_path25.default.join(hashDir, finalFileName);
50826
+ const relPath = import_node_path25.default.relative(args.sessionDir, absPath);
50794
50827
  args.groupFileStore.upsert(args.scope, args.sessionId, {
50795
50828
  relPath: absPath,
50796
50829
  // 存绝对路径,与现有 agent 入清单的形态一致(attachment.ts:144 双形态兼容)
@@ -50804,8 +50837,8 @@ async function writeUploadedAttachment(args) {
50804
50837
 
50805
50838
  // src/extension/import.ts
50806
50839
  var import_promises3 = __toESM(require("fs/promises"), 1);
50807
- var import_node_path25 = __toESM(require("path"), 1);
50808
- var import_node_os11 = __toESM(require("os"), 1);
50840
+ var import_node_path26 = __toESM(require("path"), 1);
50841
+ var import_node_os12 = __toESM(require("os"), 1);
50809
50842
  var import_jszip = __toESM(require_lib3(), 1);
50810
50843
  var ImportError = class extends Error {
50811
50844
  constructor(code, message) {
@@ -50822,7 +50855,7 @@ async function importZip(buf, root) {
50822
50855
  throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
50823
50856
  }
50824
50857
  for (const name of Object.keys(zip.files)) {
50825
- if (name.includes("..") || name.startsWith("/") || import_node_path25.default.isAbsolute(name)) {
50858
+ if (name.includes("..") || name.startsWith("/") || import_node_path26.default.isAbsolute(name)) {
50826
50859
  throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
50827
50860
  }
50828
50861
  }
@@ -50855,7 +50888,7 @@ async function importZip(buf, root) {
50855
50888
  );
50856
50889
  }
50857
50890
  }
50858
- const destDir = import_node_path25.default.join(root, manifest.id);
50891
+ const destDir = import_node_path26.default.join(root, manifest.id);
50859
50892
  let destExists = false;
50860
50893
  try {
50861
50894
  await import_promises3.default.access(destDir);
@@ -50865,15 +50898,15 @@ async function importZip(buf, root) {
50865
50898
  if (destExists) {
50866
50899
  throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
50867
50900
  }
50868
- const stage = await import_promises3.default.mkdtemp(import_node_path25.default.join(import_node_os11.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
50901
+ const stage = await import_promises3.default.mkdtemp(import_node_path26.default.join(import_node_os12.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
50869
50902
  try {
50870
50903
  for (const [name, entry] of Object.entries(zip.files)) {
50871
- const dest = import_node_path25.default.join(stage, name);
50904
+ const dest = import_node_path26.default.join(stage, name);
50872
50905
  if (entry.dir) {
50873
50906
  await import_promises3.default.mkdir(dest, { recursive: true });
50874
50907
  continue;
50875
50908
  }
50876
- await import_promises3.default.mkdir(import_node_path25.default.dirname(dest), { recursive: true });
50909
+ await import_promises3.default.mkdir(import_node_path26.default.dirname(dest), { recursive: true });
50877
50910
  const content = await entry.async("nodebuffer");
50878
50911
  await import_promises3.default.writeFile(dest, content);
50879
50912
  }
@@ -50904,7 +50937,7 @@ var SHARE_UI_ASSET_MIME = {
50904
50937
  ".wasm": "application/wasm"
50905
50938
  };
50906
50939
  function shareUiAssetMime(filePath) {
50907
- const ext = import_node_path26.default.extname(filePath).toLowerCase();
50940
+ const ext = import_node_path27.default.extname(filePath).toLowerCase();
50908
50941
  return SHARE_UI_ASSET_MIME[ext] ?? lookupMime(filePath);
50909
50942
  }
50910
50943
  var DISPATCH_HEARTBEAT_MS = 25e3;
@@ -50991,7 +51024,7 @@ function isValidUploadFileName(fileName) {
50991
51024
  if (fileName === "." || fileName === "..") return false;
50992
51025
  if (fileName.startsWith(".")) return false;
50993
51026
  if (fileName.includes("/") || fileName.includes("\\")) return false;
50994
- return fileName === import_node_path26.default.basename(fileName);
51027
+ return fileName === import_node_path27.default.basename(fileName);
50995
51028
  }
50996
51029
  function createHttpRouter(deps) {
50997
51030
  return async (req, res) => {
@@ -51287,7 +51320,7 @@ function createHttpRouter(deps) {
51287
51320
  sendHtml(res, statusByCode[r.code], loader.renderErrorHtml(r.code, msgByCode[r.code]));
51288
51321
  return true;
51289
51322
  }
51290
- sendHtml(res, 200, loader.renderViewerHtml(import_node_path26.default.basename(r.absPath)));
51323
+ sendHtml(res, 200, loader.renderViewerHtml(import_node_path27.default.basename(r.absPath)));
51291
51324
  return true;
51292
51325
  }
51293
51326
  const ctx = deps.authResolver.resolveFromHeader(
@@ -51408,7 +51441,7 @@ function createHttpRouter(deps) {
51408
51441
  return true;
51409
51442
  }
51410
51443
  let absPath;
51411
- if (import_node_path26.default.isAbsolute(pathParam)) {
51444
+ if (import_node_path27.default.isAbsolute(pathParam)) {
51412
51445
  absPath = pathParam;
51413
51446
  } else if (deps.sessionStore) {
51414
51447
  const file = deps.sessionStore.read(sid);
@@ -51416,7 +51449,7 @@ function createHttpRouter(deps) {
51416
51449
  sendJson(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
51417
51450
  return true;
51418
51451
  }
51419
- absPath = import_node_path26.default.join(file.cwd, pathParam);
51452
+ absPath = import_node_path27.default.join(file.cwd, pathParam);
51420
51453
  } else {
51421
51454
  sendJson(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
51422
51455
  return true;
@@ -51518,7 +51551,7 @@ function streamFile(res, absPath, logger) {
51518
51551
  return;
51519
51552
  }
51520
51553
  const mime = lookupMime(absPath);
51521
- const basename = import_node_path26.default.basename(absPath);
51554
+ const basename = import_node_path27.default.basename(absPath);
51522
51555
  res.writeHead(200, {
51523
51556
  "Content-Type": mime,
51524
51557
  "Content-Length": String(stat.size),
@@ -51536,7 +51569,7 @@ function streamFile(res, absPath, logger) {
51536
51569
 
51537
51570
  // src/attachment/gc.ts
51538
51571
  var import_node_fs27 = __toESM(require("fs"), 1);
51539
- var import_node_path27 = __toESM(require("path"), 1);
51572
+ var import_node_path28 = __toESM(require("path"), 1);
51540
51573
  var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
51541
51574
  function runAttachmentGc(args) {
51542
51575
  const now = (args.now ?? Date.now)();
@@ -51545,17 +51578,17 @@ function runAttachmentGc(args) {
51545
51578
  for (const { scope, sessionId } of args.sessionScopes) {
51546
51579
  for (const entry of args.groupFileStore.list(scope, sessionId)) {
51547
51580
  if (entry.stale) continue;
51548
- if (import_node_path27.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
51581
+ if (import_node_path28.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
51549
51582
  }
51550
51583
  }
51551
51584
  for (const { scope, sessionId } of args.sessionScopes) {
51552
- const sessionDir = args.getSessionCwd?.(sessionId) ?? import_node_path27.default.join(
51585
+ const sessionDir = args.getSessionCwd?.(sessionId) ?? import_node_path28.default.join(
51553
51586
  args.dataDir,
51554
51587
  "sessions",
51555
51588
  ...scopeSubPath(scope).map(safeFileName),
51556
51589
  safeFileName(sessionId)
51557
51590
  );
51558
- const attRoot = import_node_path27.default.join(sessionDir, ".attachments");
51591
+ const attRoot = import_node_path28.default.join(sessionDir, ".attachments");
51559
51592
  let hashDirs;
51560
51593
  try {
51561
51594
  hashDirs = import_node_fs27.default.readdirSync(attRoot);
@@ -51565,7 +51598,7 @@ function runAttachmentGc(args) {
51565
51598
  continue;
51566
51599
  }
51567
51600
  for (const hashDir of hashDirs) {
51568
- const hashDirAbs = import_node_path27.default.join(attRoot, hashDir);
51601
+ const hashDirAbs = import_node_path28.default.join(attRoot, hashDir);
51569
51602
  let files;
51570
51603
  try {
51571
51604
  files = import_node_fs27.default.readdirSync(hashDirAbs);
@@ -51573,7 +51606,7 @@ function runAttachmentGc(args) {
51573
51606
  continue;
51574
51607
  }
51575
51608
  for (const name of files) {
51576
- const file = import_node_path27.default.join(hashDirAbs, name);
51609
+ const file = import_node_path28.default.join(hashDirAbs, name);
51577
51610
  let stat;
51578
51611
  try {
51579
51612
  stat = import_node_fs27.default.statSync(file);
@@ -51604,7 +51637,7 @@ function runAttachmentGc(args) {
51604
51637
 
51605
51638
  // src/attachment/group.ts
51606
51639
  var import_node_fs28 = __toESM(require("fs"), 1);
51607
- var import_node_path28 = __toESM(require("path"), 1);
51640
+ var import_node_path29 = __toESM(require("path"), 1);
51608
51641
  var import_node_crypto8 = __toESM(require("crypto"), 1);
51609
51642
  init_protocol();
51610
51643
  var GroupFileStore = class {
@@ -51616,11 +51649,11 @@ var GroupFileStore = class {
51616
51649
  this.logger = opts.logger;
51617
51650
  }
51618
51651
  rootForScope(scope) {
51619
- return import_node_path28.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
51652
+ return import_node_path29.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
51620
51653
  }
51621
51654
  /** 与 SessionStore.filePath 平级,扩展名 .group-files.json */
51622
51655
  filePath(scope, sessionId) {
51623
- return import_node_path28.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
51656
+ return import_node_path29.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
51624
51657
  }
51625
51658
  cacheKey(scope, sessionId) {
51626
51659
  return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
@@ -51655,7 +51688,7 @@ var GroupFileStore = class {
51655
51688
  }
51656
51689
  writeFile(scope, sessionId, entries) {
51657
51690
  const file = this.filePath(scope, sessionId);
51658
- import_node_fs28.default.mkdirSync(import_node_path28.default.dirname(file), { recursive: true });
51691
+ import_node_fs28.default.mkdirSync(import_node_path29.default.dirname(file), { recursive: true });
51659
51692
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
51660
51693
  import_node_fs28.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
51661
51694
  import_node_fs28.default.renameSync(tmp, file);
@@ -51745,9 +51778,9 @@ var GroupFileStore = class {
51745
51778
 
51746
51779
  // src/discovery/state-file.ts
51747
51780
  var import_node_fs29 = __toESM(require("fs"), 1);
51748
- var import_node_path29 = __toESM(require("path"), 1);
51781
+ var import_node_path30 = __toESM(require("path"), 1);
51749
51782
  function defaultStateFilePath(dataDir) {
51750
- return import_node_path29.default.join(dataDir, "state.json");
51783
+ return import_node_path30.default.join(dataDir, "state.json");
51751
51784
  }
51752
51785
  function isPidAlive(pid) {
51753
51786
  if (!Number.isFinite(pid) || pid <= 0) return false;
@@ -51783,7 +51816,7 @@ var StateFileManager = class {
51783
51816
  return { status: "stale", existing };
51784
51817
  }
51785
51818
  write(state) {
51786
- import_node_fs29.default.mkdirSync(import_node_path29.default.dirname(this.file), { recursive: true });
51819
+ import_node_fs29.default.mkdirSync(import_node_path30.default.dirname(this.file), { recursive: true });
51787
51820
  const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
51788
51821
  import_node_fs29.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
51789
51822
  import_node_fs29.default.renameSync(tmp, this.file);
@@ -51812,13 +51845,13 @@ function readDaemonSourceFromEnv(env = process.env) {
51812
51845
 
51813
51846
  // src/tunnel/tunnel-manager.ts
51814
51847
  var import_node_fs33 = __toESM(require("fs"), 1);
51815
- var import_node_path33 = __toESM(require("path"), 1);
51848
+ var import_node_path34 = __toESM(require("path"), 1);
51816
51849
  var import_node_crypto9 = __toESM(require("crypto"), 1);
51817
51850
  var import_node_child_process9 = require("child_process");
51818
51851
 
51819
51852
  // src/tunnel/tunnel-store.ts
51820
51853
  var import_node_fs30 = __toESM(require("fs"), 1);
51821
- var import_node_path30 = __toESM(require("path"), 1);
51854
+ var import_node_path31 = __toESM(require("path"), 1);
51822
51855
  var TunnelStore = class {
51823
51856
  constructor(filePath) {
51824
51857
  this.filePath = filePath;
@@ -51837,7 +51870,7 @@ var TunnelStore = class {
51837
51870
  }
51838
51871
  }
51839
51872
  async set(v2) {
51840
- const dir = import_node_path30.default.dirname(this.filePath);
51873
+ const dir = import_node_path31.default.dirname(this.filePath);
51841
51874
  await import_node_fs30.default.promises.mkdir(dir, { recursive: true });
51842
51875
  const data = JSON.stringify(v2, null, 2);
51843
51876
  const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
@@ -51948,8 +51981,8 @@ function escape(v2) {
51948
51981
 
51949
51982
  // src/tunnel/frpc-binary.ts
51950
51983
  var import_node_fs31 = __toESM(require("fs"), 1);
51951
- var import_node_os12 = __toESM(require("os"), 1);
51952
- var import_node_path31 = __toESM(require("path"), 1);
51984
+ var import_node_os13 = __toESM(require("os"), 1);
51985
+ var import_node_path32 = __toESM(require("path"), 1);
51953
51986
  var import_node_child_process7 = require("child_process");
51954
51987
  var import_node_stream3 = require("stream");
51955
51988
  var import_promises4 = require("stream/promises");
@@ -51988,13 +52021,13 @@ async function ensureFrpcBinary(opts) {
51988
52021
  }
51989
52022
  const version2 = opts.version ?? FRPC_VERSION;
51990
52023
  const platform = opts.platform ?? detectPlatform();
51991
- const binDir = import_node_path31.default.join(opts.dataDir, "bin");
52024
+ const binDir = import_node_path32.default.join(opts.dataDir, "bin");
51992
52025
  import_node_fs31.default.mkdirSync(binDir, { recursive: true });
51993
52026
  cleanupStaleArtifacts(binDir);
51994
- const stableBin = import_node_path31.default.join(binDir, "frpc");
52027
+ const stableBin = import_node_path32.default.join(binDir, "frpc");
51995
52028
  if (import_node_fs31.default.existsSync(stableBin)) return stableBin;
51996
52029
  const partialBin = `${stableBin}.partial`;
51997
- const tarballPath = import_node_path31.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
52030
+ const tarballPath = import_node_path32.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
51998
52031
  try {
51999
52032
  const url = frpcDownloadUrl(version2, platform);
52000
52033
  await downloadToFile(url, tarballPath, opts.fetchImpl);
@@ -52020,7 +52053,7 @@ function cleanupStaleArtifacts(binDir) {
52020
52053
  }
52021
52054
  for (const name of entries) {
52022
52055
  if (name.endsWith(".partial") || name.startsWith("extract-")) {
52023
- const full = import_node_path31.default.join(binDir, name);
52056
+ const full = import_node_path32.default.join(binDir, name);
52024
52057
  try {
52025
52058
  import_node_fs31.default.rmSync(full, { recursive: true, force: true });
52026
52059
  } catch {
@@ -52046,7 +52079,7 @@ async function downloadToFile(url, dest, fetchImpl) {
52046
52079
  await (0, import_promises4.pipeline)(nodeStream, out);
52047
52080
  }
52048
52081
  async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
52049
- const work = import_node_path31.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
52082
+ const work = import_node_path32.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
52050
52083
  import_node_fs31.default.mkdirSync(work, { recursive: true });
52051
52084
  try {
52052
52085
  await new Promise((resolve6, reject) => {
@@ -52055,7 +52088,7 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
52055
52088
  proc.on("exit", (code) => code === 0 ? resolve6() : reject(new Error(`tar exited ${code}`)));
52056
52089
  });
52057
52090
  const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
52058
- const src = import_node_path31.default.join(work, dirName, "frpc");
52091
+ const src = import_node_path32.default.join(work, dirName, "frpc");
52059
52092
  if (!import_node_fs31.default.existsSync(src)) {
52060
52093
  throw new Error(`frpc not found inside tarball at ${src}`);
52061
52094
  }
@@ -52067,10 +52100,10 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
52067
52100
 
52068
52101
  // src/tunnel/frpc-process.ts
52069
52102
  var import_node_fs32 = __toESM(require("fs"), 1);
52070
- var import_node_path32 = __toESM(require("path"), 1);
52103
+ var import_node_path33 = __toESM(require("path"), 1);
52071
52104
  var import_node_child_process8 = require("child_process");
52072
52105
  function frpcPidFilePath(dataDir) {
52073
- return import_node_path32.default.join(dataDir, "frpc.pid");
52106
+ return import_node_path33.default.join(dataDir, "frpc.pid");
52074
52107
  }
52075
52108
  function writeFrpcPid(dataDir, pid) {
52076
52109
  try {
@@ -52112,7 +52145,7 @@ function defaultSleep(ms) {
52112
52145
  }
52113
52146
  async function killStaleFrpc(deps) {
52114
52147
  const pidFile = frpcPidFilePath(deps.dataDir);
52115
- const tomlPath = import_node_path32.default.join(deps.dataDir, "frpc.toml");
52148
+ const tomlPath = import_node_path33.default.join(deps.dataDir, "frpc.toml");
52116
52149
  const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
52117
52150
  const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
52118
52151
  const killPid = deps.killPidImpl ?? defaultKillPid;
@@ -52184,7 +52217,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
52184
52217
  var TunnelManager = class {
52185
52218
  constructor(deps) {
52186
52219
  this.deps = deps;
52187
- this.store = deps.store ?? new TunnelStore(import_node_path33.default.join(deps.dataDir, "tunnel.json"));
52220
+ this.store = deps.store ?? new TunnelStore(import_node_path34.default.join(deps.dataDir, "tunnel.json"));
52188
52221
  this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
52189
52222
  this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
52190
52223
  }
@@ -52311,7 +52344,7 @@ var TunnelManager = class {
52311
52344
  dataDir: this.deps.dataDir,
52312
52345
  override: this.deps.frpcBinaryOverride ?? void 0
52313
52346
  });
52314
- const tomlPath = import_node_path33.default.join(this.deps.dataDir, "frpc.toml");
52347
+ const tomlPath = import_node_path34.default.join(this.deps.dataDir, "frpc.toml");
52315
52348
  const proxyName = `clawd-${t.subdomain}-${localPort}-${import_node_crypto9.default.randomBytes(3).toString("hex")}`;
52316
52349
  const toml = buildFrpcToml({
52317
52350
  serverAddr: t.frpsHost,
@@ -52326,7 +52359,7 @@ var TunnelManager = class {
52326
52359
  const proc = (this.deps.spawnImpl ?? import_node_child_process9.spawn)(frpcBin, ["-c", tomlPath], {
52327
52360
  stdio: ["ignore", "pipe", "pipe"]
52328
52361
  });
52329
- const logFilePath = import_node_path33.default.join(this.deps.dataDir, "frpc.log");
52362
+ const logFilePath = import_node_path34.default.join(this.deps.dataDir, "frpc.log");
52330
52363
  const logStream = import_node_fs33.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
52331
52364
  logStream.on("error", () => {
52332
52365
  });
@@ -52409,16 +52442,16 @@ async function waitForFrpcReady(proc, timeoutMs) {
52409
52442
  }
52410
52443
 
52411
52444
  // src/tunnel/device-key.ts
52412
- var import_node_os13 = __toESM(require("os"), 1);
52413
- var import_node_path34 = __toESM(require("path"), 1);
52445
+ var import_node_os14 = __toESM(require("os"), 1);
52446
+ var import_node_path35 = __toESM(require("path"), 1);
52414
52447
  var import_node_crypto10 = __toESM(require("crypto"), 1);
52415
52448
  var DERIVE_SALT = "clawd-tunnel-device-v1";
52416
52449
  function deriveStableDeviceKey(opts = {}) {
52417
- const hostname = opts.hostname ?? import_node_os13.default.hostname();
52418
- const uid = opts.uid ?? (typeof import_node_os13.default.userInfo === "function" ? import_node_os13.default.userInfo().uid : 0);
52419
- const home = opts.home ?? import_node_os13.default.homedir();
52420
- const defaultDataDir = import_node_path34.default.resolve(import_node_path34.default.join(home, ".clawd"));
52421
- const normalizedDataDir = opts.dataDir ? import_node_path34.default.resolve(opts.dataDir) : null;
52450
+ const hostname = opts.hostname ?? import_node_os14.default.hostname();
52451
+ const uid = opts.uid ?? (typeof import_node_os14.default.userInfo === "function" ? import_node_os14.default.userInfo().uid : 0);
52452
+ const home = opts.home ?? import_node_os14.default.homedir();
52453
+ const defaultDataDir = import_node_path35.default.resolve(import_node_path35.default.join(home, ".clawd"));
52454
+ const normalizedDataDir = opts.dataDir ? import_node_path35.default.resolve(opts.dataDir) : null;
52422
52455
  const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
52423
52456
  const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
52424
52457
  return import_node_crypto10.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
@@ -52426,11 +52459,11 @@ function deriveStableDeviceKey(opts = {}) {
52426
52459
 
52427
52460
  // src/auth-store.ts
52428
52461
  var import_node_fs34 = __toESM(require("fs"), 1);
52429
- var import_node_path35 = __toESM(require("path"), 1);
52462
+ var import_node_path36 = __toESM(require("path"), 1);
52430
52463
  var import_node_crypto11 = __toESM(require("crypto"), 1);
52431
52464
  var AUTH_FILE_NAME = "auth.json";
52432
52465
  function authFilePath(dataDir) {
52433
- return import_node_path35.default.join(dataDir, AUTH_FILE_NAME);
52466
+ return import_node_path36.default.join(dataDir, AUTH_FILE_NAME);
52434
52467
  }
52435
52468
  function loadOrCreateAuthFile(opts) {
52436
52469
  const file = authFilePath(opts.dataDir);
@@ -52486,7 +52519,7 @@ function readAuthFile(file) {
52486
52519
  }
52487
52520
  }
52488
52521
  function writeAuthFile(file, content) {
52489
- import_node_fs34.default.mkdirSync(import_node_path35.default.dirname(file), { recursive: true });
52522
+ import_node_fs34.default.mkdirSync(import_node_path36.default.dirname(file), { recursive: true });
52490
52523
  import_node_fs34.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
52491
52524
  try {
52492
52525
  import_node_fs34.default.chmodSync(file, 384);
@@ -52496,12 +52529,12 @@ function writeAuthFile(file, content) {
52496
52529
 
52497
52530
  // src/owner-profile.ts
52498
52531
  var import_node_fs35 = __toESM(require("fs"), 1);
52499
- var import_node_os14 = __toESM(require("os"), 1);
52500
- var import_node_path36 = __toESM(require("path"), 1);
52532
+ var import_node_os15 = __toESM(require("os"), 1);
52533
+ var import_node_path37 = __toESM(require("path"), 1);
52501
52534
  var PROFILE_FILENAME = "profile.json";
52502
52535
  function loadOwnerDisplayName(dataDir) {
52503
- const fallback = import_node_os14.default.userInfo().username;
52504
- const profilePath = import_node_path36.default.join(dataDir, PROFILE_FILENAME);
52536
+ const fallback = import_node_os15.default.userInfo().username;
52537
+ const profilePath = import_node_path37.default.join(dataDir, PROFILE_FILENAME);
52505
52538
  let raw;
52506
52539
  try {
52507
52540
  raw = import_node_fs35.default.readFileSync(profilePath, "utf8");
@@ -52528,12 +52561,12 @@ function loadOwnerDisplayName(dataDir) {
52528
52561
 
52529
52562
  // src/feishu-auth/owner-identity-store.ts
52530
52563
  var import_node_fs36 = __toESM(require("fs"), 1);
52531
- var import_node_path37 = __toESM(require("path"), 1);
52564
+ var import_node_path38 = __toESM(require("path"), 1);
52532
52565
  var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
52533
52566
  var OwnerIdentityStore = class {
52534
52567
  file;
52535
52568
  constructor(dataDir) {
52536
- this.file = import_node_path37.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
52569
+ this.file = import_node_path38.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
52537
52570
  }
52538
52571
  read() {
52539
52572
  let raw;
@@ -52566,7 +52599,7 @@ var OwnerIdentityStore = class {
52566
52599
  };
52567
52600
  }
52568
52601
  write(record) {
52569
- import_node_fs36.default.mkdirSync(import_node_path37.default.dirname(this.file), { recursive: true });
52602
+ import_node_fs36.default.mkdirSync(import_node_path38.default.dirname(this.file), { recursive: true });
52570
52603
  import_node_fs36.default.writeFileSync(this.file, JSON.stringify(record, null, 2), { mode: 384 });
52571
52604
  try {
52572
52605
  import_node_fs36.default.chmodSync(this.file, 384);
@@ -52696,9 +52729,9 @@ var CentralClientError = class extends Error {
52696
52729
  code;
52697
52730
  cause;
52698
52731
  };
52699
- async function centralRequest(opts, path67, init) {
52732
+ async function centralRequest(opts, path68, init) {
52700
52733
  const f = opts.fetchImpl ?? globalThis.fetch;
52701
- const url = `${opts.api.replace(/\/+$/, "")}${path67}`;
52734
+ const url = `${opts.api.replace(/\/+$/, "")}${path68}`;
52702
52735
  const ctrl = new AbortController();
52703
52736
  const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
52704
52737
  let res;
@@ -52841,7 +52874,7 @@ function verifyConnectToken(args) {
52841
52874
 
52842
52875
  // src/feishu-auth/server-key.ts
52843
52876
  var fs46 = __toESM(require("fs"), 1);
52844
- var path46 = __toESM(require("path"), 1);
52877
+ var path47 = __toESM(require("path"), 1);
52845
52878
  var FILE_NAME2 = "server-signing-key.json";
52846
52879
  var ServerKeyStore = class {
52847
52880
  constructor(dataDir) {
@@ -52849,7 +52882,7 @@ var ServerKeyStore = class {
52849
52882
  }
52850
52883
  dataDir;
52851
52884
  filePath() {
52852
- return path46.join(this.dataDir, FILE_NAME2);
52885
+ return path47.join(this.dataDir, FILE_NAME2);
52853
52886
  }
52854
52887
  /** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
52855
52888
  read() {
@@ -52888,8 +52921,8 @@ init_protocol();
52888
52921
 
52889
52922
  // src/session/fork.ts
52890
52923
  var import_node_fs37 = __toESM(require("fs"), 1);
52891
- var import_node_os15 = __toESM(require("os"), 1);
52892
- var import_node_path38 = __toESM(require("path"), 1);
52924
+ var import_node_os16 = __toESM(require("os"), 1);
52925
+ var import_node_path39 = __toESM(require("path"), 1);
52893
52926
  init_claude_history();
52894
52927
  function readJsonlEntries(file) {
52895
52928
  const raw = import_node_fs37.default.readFileSync(file, "utf8");
@@ -52905,9 +52938,9 @@ function readJsonlEntries(file) {
52905
52938
  return out;
52906
52939
  }
52907
52940
  function forkSession(input) {
52908
- const baseDir = input.baseDir ?? import_node_path38.default.join(import_node_os15.default.homedir(), ".claude");
52909
- const projectDir = import_node_path38.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
52910
- const sourceFile = import_node_path38.default.join(projectDir, `${input.toolSessionId}.jsonl`);
52941
+ const baseDir = input.baseDir ?? import_node_path39.default.join(import_node_os16.default.homedir(), ".claude");
52942
+ const projectDir = import_node_path39.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
52943
+ const sourceFile = import_node_path39.default.join(projectDir, `${input.toolSessionId}.jsonl`);
52911
52944
  if (!import_node_fs37.default.existsSync(sourceFile)) {
52912
52945
  throw new Error(`fork: source transcript not found: ${sourceFile}`);
52913
52946
  }
@@ -52938,7 +52971,7 @@ function forkSession(input) {
52938
52971
  }
52939
52972
  forkedLines.push(JSON.stringify(forked));
52940
52973
  }
52941
- const forkedFilePath = import_node_path38.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
52974
+ const forkedFilePath = import_node_path39.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
52942
52975
  import_node_fs37.default.mkdirSync(projectDir, { recursive: true });
52943
52976
  import_node_fs37.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
52944
52977
  return { forkedToolSessionId, forkedFilePath };
@@ -53292,7 +53325,7 @@ function buildPermissionHandlers(deps) {
53292
53325
  }
53293
53326
 
53294
53327
  // src/handlers/history.ts
53295
- var path49 = __toESM(require("path"), 1);
53328
+ var path50 = __toESM(require("path"), 1);
53296
53329
  init_protocol();
53297
53330
 
53298
53331
  // src/session/recent-dirs.ts
@@ -53310,7 +53343,7 @@ function listRecentDirs(store, limit = 50) {
53310
53343
  }
53311
53344
 
53312
53345
  // src/permission/persona-paths.ts
53313
- var path48 = __toESM(require("path"), 1);
53346
+ var path49 = __toESM(require("path"), 1);
53314
53347
  function getAllowedPersonaIds(grants, action) {
53315
53348
  const ids = /* @__PURE__ */ new Set();
53316
53349
  for (const g2 of grants) {
@@ -53323,42 +53356,42 @@ function getAllowedPersonaIds(grants, action) {
53323
53356
  return ids;
53324
53357
  }
53325
53358
  function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
53326
- const target = path48.resolve(absPath);
53359
+ const target = path49.resolve(absPath);
53327
53360
  if (userWorkDir) {
53328
- const u = path48.resolve(userWorkDir);
53329
- const usep = u.endsWith(path48.sep) ? "" : path48.sep;
53361
+ const u = path49.resolve(userWorkDir);
53362
+ const usep = u.endsWith(path49.sep) ? "" : path49.sep;
53330
53363
  if (target === u || target.startsWith(u + usep)) return true;
53331
53364
  }
53332
- const root = path48.resolve(personaRoot);
53333
- const sep3 = root.endsWith(path48.sep) ? "" : path48.sep;
53365
+ const root = path49.resolve(personaRoot);
53366
+ const sep3 = root.endsWith(path49.sep) ? "" : path49.sep;
53334
53367
  if (!target.startsWith(root + sep3)) return false;
53335
- const rel = path48.relative(root, target);
53368
+ const rel = path49.relative(root, target);
53336
53369
  if (!rel || rel.startsWith("..")) return false;
53337
- const personaId = rel.split(path48.sep)[0];
53370
+ const personaId = rel.split(path49.sep)[0];
53338
53371
  if (!personaId) return false;
53339
53372
  const allowed = getAllowedPersonaIds(grants, action);
53340
53373
  if (allowed === "*") return true;
53341
53374
  return allowed.has(personaId);
53342
53375
  }
53343
53376
  function personaIdFromPath(absPath, personaRoot) {
53344
- const root = path48.resolve(personaRoot);
53345
- const target = path48.resolve(absPath);
53346
- const sep3 = root.endsWith(path48.sep) ? "" : path48.sep;
53377
+ const root = path49.resolve(personaRoot);
53378
+ const target = path49.resolve(absPath);
53379
+ const sep3 = root.endsWith(path49.sep) ? "" : path49.sep;
53347
53380
  if (!target.startsWith(root + sep3)) return null;
53348
- const rel = path48.relative(root, target);
53381
+ const rel = path49.relative(root, target);
53349
53382
  if (!rel || rel.startsWith("..")) return null;
53350
- const id = rel.split(path48.sep)[0];
53383
+ const id = rel.split(path49.sep)[0];
53351
53384
  return id || null;
53352
53385
  }
53353
53386
  function isPathWithin(dir, absPath) {
53354
- const d = path48.resolve(dir);
53355
- const t = path48.resolve(absPath);
53356
- const sep3 = d.endsWith(path48.sep) ? "" : path48.sep;
53387
+ const d = path49.resolve(dir);
53388
+ const t = path49.resolve(absPath);
53389
+ const sep3 = d.endsWith(path49.sep) ? "" : path49.sep;
53357
53390
  return t === d || t.startsWith(d + sep3);
53358
53391
  }
53359
53392
  function isPathInGuestBoundary(personaRoot, personaId, userWorkDir, absPath) {
53360
53393
  if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
53361
- return personaIdFromPath(path48.resolve(absPath), personaRoot) === personaId;
53394
+ return personaIdFromPath(path49.resolve(absPath), personaRoot) === personaId;
53362
53395
  }
53363
53396
 
53364
53397
  // src/handlers/history.ts
@@ -53384,7 +53417,7 @@ function buildHistoryHandlers(deps) {
53384
53417
  if (!pid) return false;
53385
53418
  return isGuestPathAllowed(
53386
53419
  ctx.grants,
53387
- path49.join(personaRoot, pid),
53420
+ path50.join(personaRoot, pid),
53388
53421
  personaRoot,
53389
53422
  "read",
53390
53423
  userWorkDir
@@ -53396,7 +53429,7 @@ function buildHistoryHandlers(deps) {
53396
53429
  };
53397
53430
  const list = async (frame, _client, ctx) => {
53398
53431
  const args = HistoryListArgs.parse(frame);
53399
- assertGuestPath(ctx, path49.resolve(args.projectPath), personaRoot, "history:list");
53432
+ assertGuestPath(ctx, path50.resolve(args.projectPath), personaRoot, "history:list");
53400
53433
  const sessions = await history.listSessions(args);
53401
53434
  return { response: { type: "history:list", sessions } };
53402
53435
  };
@@ -53428,13 +53461,13 @@ function buildHistoryHandlers(deps) {
53428
53461
  };
53429
53462
  const subagents = async (frame, _client, ctx) => {
53430
53463
  const args = HistorySubagentsArgs.parse(frame);
53431
- assertGuestPath(ctx, path49.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
53464
+ assertGuestPath(ctx, path50.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
53432
53465
  const subs = await history.listSubagents(args);
53433
53466
  return { response: { type: "history:subagents", subagents: subs } };
53434
53467
  };
53435
53468
  const subagentRead = async (frame, _client, ctx) => {
53436
53469
  const args = HistorySubagentReadArgs.parse(frame);
53437
- assertGuestPath(ctx, path49.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
53470
+ assertGuestPath(ctx, path50.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
53438
53471
  const res = await history.readSubagent(args);
53439
53472
  return { response: { type: "history:subagent-read", ...res } };
53440
53473
  };
@@ -53443,7 +53476,7 @@ function buildHistoryHandlers(deps) {
53443
53476
  if (ctx?.principal.kind === "guest" && personaRoot) {
53444
53477
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
53445
53478
  const filtered = dirs.filter(
53446
- (d) => isGuestPathAllowed(ctx.grants, path49.resolve(d.cwd), personaRoot, "read", userWorkDir)
53479
+ (d) => isGuestPathAllowed(ctx.grants, path50.resolve(d.cwd), personaRoot, "read", userWorkDir)
53447
53480
  );
53448
53481
  return { response: { type: "history:recentDirs", dirs: filtered } };
53449
53482
  }
@@ -53460,8 +53493,8 @@ function buildHistoryHandlers(deps) {
53460
53493
  }
53461
53494
 
53462
53495
  // src/handlers/workspace.ts
53463
- var path50 = __toESM(require("path"), 1);
53464
- var os15 = __toESM(require("os"), 1);
53496
+ var path51 = __toESM(require("path"), 1);
53497
+ var os16 = __toESM(require("os"), 1);
53465
53498
  init_protocol();
53466
53499
  init_protocol();
53467
53500
  function buildEnabledPluginNames(personaManager, personaId) {
@@ -53501,23 +53534,23 @@ function buildWorkspaceHandlers(deps) {
53501
53534
  const list = async (frame, _client, ctx) => {
53502
53535
  const args = WorkspaceListArgs.parse(frame);
53503
53536
  const isGuest = ctx?.principal.kind === "guest";
53504
- const fallbackCwd = isGuest && personaRoot ? personaRoot : os15.homedir();
53505
- const resolvedCwd = path50.resolve(args.cwd ?? fallbackCwd);
53506
- const target = args.path ? path50.resolve(resolvedCwd, args.path) : resolvedCwd;
53537
+ const fallbackCwd = isGuest && personaRoot ? personaRoot : os16.homedir();
53538
+ const resolvedCwd = path51.resolve(args.cwd ?? fallbackCwd);
53539
+ const target = args.path ? path51.resolve(resolvedCwd, args.path) : resolvedCwd;
53507
53540
  assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
53508
53541
  const res = workspace.list({ ...args, cwd: resolvedCwd });
53509
53542
  return { response: { type: "workspace:list", ...res } };
53510
53543
  };
53511
53544
  const read = async (frame, _client, ctx) => {
53512
53545
  const args = WorkspaceReadArgs.parse(frame);
53513
- const target = path50.isAbsolute(args.path) ? path50.resolve(args.path) : path50.resolve(args.cwd, args.path);
53546
+ const target = path51.isAbsolute(args.path) ? path51.resolve(args.path) : path51.resolve(args.cwd, args.path);
53514
53547
  assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
53515
53548
  const res = workspace.read(args);
53516
53549
  return { response: { type: "workspace:read", ...res } };
53517
53550
  };
53518
53551
  const skillsList = async (frame, _client, ctx) => {
53519
53552
  const args = SkillsListArgs.parse(frame);
53520
- const cwdAbs = path50.resolve(args.cwd);
53553
+ const cwdAbs = path51.resolve(args.cwd);
53521
53554
  assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
53522
53555
  const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
53523
53556
  if (ctx?.principal.kind === "guest" && personaRoot) {
@@ -53529,7 +53562,7 @@ function buildWorkspaceHandlers(deps) {
53529
53562
  };
53530
53563
  const agentsList = async (frame, _client, ctx) => {
53531
53564
  const args = AgentsListArgs.parse(frame);
53532
- const cwdAbs = path50.resolve(args.cwd);
53565
+ const cwdAbs = path51.resolve(args.cwd);
53533
53566
  assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
53534
53567
  if (args.tool === "codex") {
53535
53568
  return { response: { type: "agents:list", agents: [] } };
@@ -53551,18 +53584,18 @@ function buildWorkspaceHandlers(deps) {
53551
53584
  }
53552
53585
 
53553
53586
  // src/handlers/git.ts
53554
- var path52 = __toESM(require("path"), 1);
53587
+ var path53 = __toESM(require("path"), 1);
53555
53588
  init_protocol();
53556
53589
  init_protocol();
53557
53590
 
53558
53591
  // src/workspace/git.ts
53559
53592
  var import_node_child_process10 = require("child_process");
53560
53593
  var import_node_fs38 = __toESM(require("fs"), 1);
53561
- var import_node_path39 = __toESM(require("path"), 1);
53594
+ var import_node_path40 = __toESM(require("path"), 1);
53562
53595
  var import_node_util = require("util");
53563
53596
  var pexec = (0, import_node_util.promisify)(import_node_child_process10.execFile);
53564
53597
  function normalizePath(p2) {
53565
- const resolved = import_node_path39.default.resolve(p2);
53598
+ const resolved = import_node_path40.default.resolve(p2);
53566
53599
  try {
53567
53600
  return import_node_fs38.default.realpathSync(resolved);
53568
53601
  } catch {
@@ -53638,7 +53671,7 @@ async function listGitBranches(cwd) {
53638
53671
  function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
53639
53672
  if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
53640
53673
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
53641
- if (!isGuestPathAllowed(ctx.grants, path52.resolve(cwd), personaRoot, "read", userWorkDir)) {
53674
+ if (!isGuestPathAllowed(ctx.grants, path53.resolve(cwd), personaRoot, "read", userWorkDir)) {
53642
53675
  throw new ClawdError(
53643
53676
  ERROR_CODES.UNAUTHORIZED,
53644
53677
  `guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
@@ -54124,7 +54157,7 @@ function buildDeviceHandlers(deps) {
54124
54157
  }
54125
54158
 
54126
54159
  // src/handlers/meta.ts
54127
- var import_node_os16 = __toESM(require("os"), 1);
54160
+ var import_node_os17 = __toESM(require("os"), 1);
54128
54161
  init_protocol();
54129
54162
 
54130
54163
  // src/version.ts
@@ -54156,7 +54189,7 @@ function buildReadyFrame(deps, client) {
54156
54189
  return {
54157
54190
  version,
54158
54191
  protocolVersion: PROTOCOL_VERSION,
54159
- hostname: import_node_os16.default.hostname(),
54192
+ hostname: import_node_os17.default.hostname(),
54160
54193
  os: process.platform,
54161
54194
  tools,
54162
54195
  runningSessions: info.runningSessions,
@@ -54253,7 +54286,7 @@ function buildPersonaHandlers(deps) {
54253
54286
  }
54254
54287
 
54255
54288
  // src/handlers/attachment.ts
54256
- var import_node_path40 = __toESM(require("path"), 1);
54289
+ var import_node_path41 = __toESM(require("path"), 1);
54257
54290
  init_protocol();
54258
54291
  init_protocol();
54259
54292
  var DEFAULT_TTL_SECONDS = 24 * 3600;
@@ -54333,12 +54366,12 @@ function buildAttachmentHandlers(deps) {
54333
54366
  `session ${args.sessionId} scope unresolved`
54334
54367
  );
54335
54368
  }
54336
- const cwdAbs = import_node_path40.default.resolve(sessionFile.cwd);
54337
- const candidateAbs = import_node_path40.default.isAbsolute(args.relPath) ? import_node_path40.default.resolve(args.relPath) : import_node_path40.default.resolve(cwdAbs, args.relPath);
54369
+ const cwdAbs = import_node_path41.default.resolve(sessionFile.cwd);
54370
+ const candidateAbs = import_node_path41.default.isAbsolute(args.relPath) ? import_node_path41.default.resolve(args.relPath) : import_node_path41.default.resolve(cwdAbs, args.relPath);
54338
54371
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
54339
54372
  const entries = deps.groupFileStore.list(scope, args.sessionId);
54340
54373
  const entry = entries.find((e) => {
54341
- const storedAbs = import_node_path40.default.isAbsolute(e.relPath) ? import_node_path40.default.resolve(e.relPath) : import_node_path40.default.resolve(cwdAbs, e.relPath);
54374
+ const storedAbs = import_node_path41.default.isAbsolute(e.relPath) ? import_node_path41.default.resolve(e.relPath) : import_node_path41.default.resolve(cwdAbs, e.relPath);
54342
54375
  return storedAbs === candidateAbs && !e.stale;
54343
54376
  });
54344
54377
  if (!entry) {
@@ -54363,7 +54396,7 @@ function buildAttachmentHandlers(deps) {
54363
54396
  if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
54364
54397
  const f = deps.sessionStore.read(sessionId);
54365
54398
  if (!f) return;
54366
- assertGuestAttachmentPath(ctx, import_node_path40.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
54399
+ assertGuestAttachmentPath(ctx, import_node_path41.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
54367
54400
  }
54368
54401
  const groupAdd = async (frame, _client, ctx) => {
54369
54402
  if (!deps.groupFileStore || !deps.getSessionScope) {
@@ -54378,8 +54411,8 @@ function buildAttachmentHandlers(deps) {
54378
54411
  if (!scope) {
54379
54412
  throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
54380
54413
  }
54381
- const cwdAbs = import_node_path40.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
54382
- const candidateAbs = import_node_path40.default.isAbsolute(args.relPath) ? import_node_path40.default.resolve(args.relPath) : import_node_path40.default.resolve(cwdAbs, args.relPath);
54414
+ const cwdAbs = import_node_path41.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
54415
+ const candidateAbs = import_node_path41.default.isAbsolute(args.relPath) ? import_node_path41.default.resolve(args.relPath) : import_node_path41.default.resolve(cwdAbs, args.relPath);
54383
54416
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
54384
54417
  const from = ctx?.principal.kind === "owner" ? "owner" : "agent";
54385
54418
  const size = 0;
@@ -54438,19 +54471,19 @@ function buildAttachmentHandlers(deps) {
54438
54471
 
54439
54472
  // src/handlers/extension.ts
54440
54473
  var import_promises8 = __toESM(require("fs/promises"), 1);
54441
- var import_node_path45 = __toESM(require("path"), 1);
54474
+ var import_node_path46 = __toESM(require("path"), 1);
54442
54475
  init_protocol();
54443
54476
 
54444
54477
  // src/extension/bundle-zip.ts
54445
54478
  var import_promises5 = __toESM(require("fs/promises"), 1);
54446
- var import_node_path41 = __toESM(require("path"), 1);
54479
+ var import_node_path42 = __toESM(require("path"), 1);
54447
54480
  var import_node_crypto13 = __toESM(require("crypto"), 1);
54448
54481
  var import_jszip2 = __toESM(require_lib3(), 1);
54449
54482
  async function bundleExtensionDir(dir) {
54450
54483
  const entries = await listFilesSorted(dir);
54451
54484
  const zip = new import_jszip2.default();
54452
54485
  for (const rel of entries) {
54453
- const abs = import_node_path41.default.join(dir, rel);
54486
+ const abs = import_node_path42.default.join(dir, rel);
54454
54487
  const content = await import_promises5.default.readFile(abs);
54455
54488
  zip.file(rel, content, { date: FIXED_DATE });
54456
54489
  }
@@ -54471,7 +54504,7 @@ async function listFilesSorted(rootDir) {
54471
54504
  return out;
54472
54505
  }
54473
54506
  async function walk(absRoot, relPrefix, out) {
54474
- const dirAbs = import_node_path41.default.join(absRoot, relPrefix);
54507
+ const dirAbs = import_node_path42.default.join(absRoot, relPrefix);
54475
54508
  const entries = await import_promises5.default.readdir(dirAbs, { withFileTypes: true });
54476
54509
  for (const e of entries) {
54477
54510
  if (IGNORE_BASENAMES.has(e.name)) continue;
@@ -54525,25 +54558,25 @@ function computePublishCheck(args) {
54525
54558
 
54526
54559
  // src/extension/install-flow.ts
54527
54560
  var import_promises6 = __toESM(require("fs/promises"), 1);
54528
- var import_node_path43 = __toESM(require("path"), 1);
54529
- var import_node_os18 = __toESM(require("os"), 1);
54561
+ var import_node_path44 = __toESM(require("path"), 1);
54562
+ var import_node_os19 = __toESM(require("os"), 1);
54530
54563
  var import_node_crypto14 = __toESM(require("crypto"), 1);
54531
54564
  var import_jszip3 = __toESM(require_lib3(), 1);
54532
54565
 
54533
54566
  // src/extension/paths.ts
54534
- var import_node_os17 = __toESM(require("os"), 1);
54535
- var import_node_path42 = __toESM(require("path"), 1);
54567
+ var import_node_os18 = __toESM(require("os"), 1);
54568
+ var import_node_path43 = __toESM(require("path"), 1);
54536
54569
  function clawdHomeRoot(override) {
54537
- return override ?? process.env.CLAWD_HOME ?? import_node_path42.default.join(import_node_os17.default.homedir(), ".clawd");
54570
+ return override ?? process.env.CLAWD_HOME ?? import_node_path43.default.join(import_node_os18.default.homedir(), ".clawd");
54538
54571
  }
54539
54572
  function extensionsRoot(override) {
54540
- return import_node_path42.default.join(clawdHomeRoot(override), "extensions");
54573
+ return import_node_path43.default.join(clawdHomeRoot(override), "extensions");
54541
54574
  }
54542
54575
  function publishedChannelsFile(override) {
54543
- return import_node_path42.default.join(clawdHomeRoot(override), "extensions-published.json");
54576
+ return import_node_path43.default.join(clawdHomeRoot(override), "extensions-published.json");
54544
54577
  }
54545
54578
  function bundleCacheRoot(override) {
54546
- return import_node_path42.default.join(clawdHomeRoot(override), "extension-bundles");
54579
+ return import_node_path43.default.join(clawdHomeRoot(override), "extension-bundles");
54547
54580
  }
54548
54581
 
54549
54582
  // src/extension/install-flow.ts
@@ -54570,7 +54603,7 @@ async function installFromChannel(args, deps) {
54570
54603
  throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
54571
54604
  }
54572
54605
  for (const name of Object.keys(zip.files)) {
54573
- if (name.includes("..") || name.startsWith("/") || import_node_path43.default.isAbsolute(name)) {
54606
+ if (name.includes("..") || name.startsWith("/") || import_node_path44.default.isAbsolute(name)) {
54574
54607
  throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
54575
54608
  }
54576
54609
  }
@@ -54602,7 +54635,7 @@ async function installFromChannel(args, deps) {
54602
54635
  );
54603
54636
  }
54604
54637
  const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
54605
- const destDir = import_node_path43.default.join(deps.extensionsRoot, localExtId);
54638
+ const destDir = import_node_path44.default.join(deps.extensionsRoot, localExtId);
54606
54639
  let destExists = false;
54607
54640
  try {
54608
54641
  await import_promises6.default.access(destDir);
@@ -54616,16 +54649,16 @@ async function installFromChannel(args, deps) {
54616
54649
  );
54617
54650
  }
54618
54651
  const stage = await import_promises6.default.mkdtemp(
54619
- import_node_path43.default.join(import_node_os18.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
54652
+ import_node_path44.default.join(import_node_os19.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
54620
54653
  );
54621
54654
  try {
54622
54655
  for (const [name, entry] of Object.entries(zip.files)) {
54623
- const dest = import_node_path43.default.join(stage, name);
54656
+ const dest = import_node_path44.default.join(stage, name);
54624
54657
  if (entry.dir) {
54625
54658
  await import_promises6.default.mkdir(dest, { recursive: true });
54626
54659
  continue;
54627
54660
  }
54628
- await import_promises6.default.mkdir(import_node_path43.default.dirname(dest), { recursive: true });
54661
+ await import_promises6.default.mkdir(import_node_path44.default.dirname(dest), { recursive: true });
54629
54662
  if (name === "manifest.json") {
54630
54663
  const rewritten = { ...parsed.data, id: localExtId };
54631
54664
  await import_promises6.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -54646,8 +54679,8 @@ async function installFromChannel(args, deps) {
54646
54679
 
54647
54680
  // src/extension/update-flow.ts
54648
54681
  var import_promises7 = __toESM(require("fs/promises"), 1);
54649
- var import_node_path44 = __toESM(require("path"), 1);
54650
- var import_node_os19 = __toESM(require("os"), 1);
54682
+ var import_node_path45 = __toESM(require("path"), 1);
54683
+ var import_node_os20 = __toESM(require("os"), 1);
54651
54684
  var import_node_crypto15 = __toESM(require("crypto"), 1);
54652
54685
  var import_jszip4 = __toESM(require_lib3(), 1);
54653
54686
  var UpdateError = class extends Error {
@@ -54663,11 +54696,11 @@ async function updateFromChannel(args, deps) {
54663
54696
  channelRef.extId,
54664
54697
  channelRef.ownerPrincipalId
54665
54698
  );
54666
- const liveDir = import_node_path44.default.join(deps.extensionsRoot, localExtId);
54699
+ const liveDir = import_node_path45.default.join(deps.extensionsRoot, localExtId);
54667
54700
  const prevDir = `${liveDir}.prev`;
54668
54701
  let existingVersion;
54669
54702
  try {
54670
- const raw = await import_promises7.default.readFile(import_node_path44.default.join(liveDir, "manifest.json"), "utf8");
54703
+ const raw = await import_promises7.default.readFile(import_node_path45.default.join(liveDir, "manifest.json"), "utf8");
54671
54704
  const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
54672
54705
  if (!parsed2.success) {
54673
54706
  throw new UpdateError(
@@ -54700,7 +54733,7 @@ async function updateFromChannel(args, deps) {
54700
54733
  throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
54701
54734
  }
54702
54735
  for (const name of Object.keys(zip.files)) {
54703
- if (name.includes("..") || name.startsWith("/") || import_node_path44.default.isAbsolute(name)) {
54736
+ if (name.includes("..") || name.startsWith("/") || import_node_path45.default.isAbsolute(name)) {
54704
54737
  throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
54705
54738
  }
54706
54739
  }
@@ -54735,16 +54768,16 @@ async function updateFromChannel(args, deps) {
54735
54768
  await import_promises7.default.rm(prevDir, { recursive: true, force: true });
54736
54769
  await import_promises7.default.rename(liveDir, prevDir);
54737
54770
  const stage = await import_promises7.default.mkdtemp(
54738
- import_node_path44.default.join(import_node_os19.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
54771
+ import_node_path45.default.join(import_node_os20.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
54739
54772
  );
54740
54773
  try {
54741
54774
  for (const [name, entry] of Object.entries(zip.files)) {
54742
- const dest = import_node_path44.default.join(stage, name);
54775
+ const dest = import_node_path45.default.join(stage, name);
54743
54776
  if (entry.dir) {
54744
54777
  await import_promises7.default.mkdir(dest, { recursive: true });
54745
54778
  continue;
54746
54779
  }
54747
- await import_promises7.default.mkdir(import_node_path44.default.dirname(dest), { recursive: true });
54780
+ await import_promises7.default.mkdir(import_node_path45.default.dirname(dest), { recursive: true });
54748
54781
  if (name === "manifest.json") {
54749
54782
  const rewritten = { ...parsed.data, id: localExtId };
54750
54783
  await import_promises7.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -54837,7 +54870,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
54837
54870
  );
54838
54871
  }
54839
54872
  }
54840
- const manifestPath = import_node_path45.default.join(root, extId, "manifest.json");
54873
+ const manifestPath = import_node_path46.default.join(root, extId, "manifest.json");
54841
54874
  const manifest = await readManifest(root, extId);
54842
54875
  const next = { ...manifest, version: newVersion };
54843
54876
  const tmp = `${manifestPath}.tmp`;
@@ -54845,7 +54878,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
54845
54878
  await import_promises8.default.rename(tmp, manifestPath);
54846
54879
  }
54847
54880
  async function readManifest(root, extId) {
54848
- const file = import_node_path45.default.join(root, extId, "manifest.json");
54881
+ const file = import_node_path46.default.join(root, extId, "manifest.json");
54849
54882
  let raw;
54850
54883
  try {
54851
54884
  raw = await import_promises8.default.readFile(file, "utf8");
@@ -54936,7 +54969,7 @@ function buildExtensionHandlers(deps) {
54936
54969
  };
54937
54970
  async function buildSnapshotMeta(extId) {
54938
54971
  const manifest = await readManifest(deps.root, extId);
54939
- const { sha256, buffer } = await bundleExtensionDir(import_node_path45.default.join(deps.root, extId));
54972
+ const { sha256, buffer } = await bundleExtensionDir(import_node_path46.default.join(deps.root, extId));
54940
54973
  return { manifest, contentHash: sha256, buffer };
54941
54974
  }
54942
54975
  const publish = async (frame, _client, ctx) => {
@@ -55119,7 +55152,7 @@ function buildExtensionHandlers(deps) {
55119
55152
  // src/app-builder/project-store.ts
55120
55153
  var import_node_fs39 = require("fs");
55121
55154
  var import_node_child_process11 = require("child_process");
55122
- var import_node_path46 = require("path");
55155
+ var import_node_path47 = require("path");
55123
55156
  init_protocol();
55124
55157
  var PROJECTS_DIR = "projects";
55125
55158
  var META_FILE = ".clawd-project.json";
@@ -55133,14 +55166,14 @@ var ProjectStore = class {
55133
55166
  root;
55134
55167
  /** projects/<name>/.clawd-project.json 路径 */
55135
55168
  metaPath(name) {
55136
- return (0, import_node_path46.join)(this.projectsRoot(), name, META_FILE);
55169
+ return (0, import_node_path47.join)(this.projectsRoot(), name, META_FILE);
55137
55170
  }
55138
55171
  /** projects/<name>/ 目录路径(cwd 用) */
55139
55172
  projectDir(name) {
55140
- return (0, import_node_path46.join)(this.projectsRoot(), name);
55173
+ return (0, import_node_path47.join)(this.projectsRoot(), name);
55141
55174
  }
55142
55175
  projectsRoot() {
55143
- return (0, import_node_path46.join)(this.root, PROJECTS_DIR);
55176
+ return (0, import_node_path47.join)(this.root, PROJECTS_DIR);
55144
55177
  }
55145
55178
  async list() {
55146
55179
  let entries;
@@ -55443,7 +55476,7 @@ var PublishJobRegistry = class {
55443
55476
  // src/app-builder/publish-job-runner.ts
55444
55477
  var import_node_child_process13 = require("child_process");
55445
55478
  var import_node_fs40 = require("fs");
55446
- var import_node_path47 = require("path");
55479
+ var import_node_path48 = require("path");
55447
55480
 
55448
55481
  // src/app-builder/publish-stage-parser.ts
55449
55482
  var STAGE_RE = /^\s*::stage::(build|deploy|verify)\s*$/;
@@ -55475,7 +55508,7 @@ async function startPublishJob(deps, args) {
55475
55508
  return { jobId: registry2.get(args.name).jobId, status: "already-publishing" };
55476
55509
  }
55477
55510
  const projDir = projectDir(args.name);
55478
- const logPath = (0, import_node_path47.join)(projDir, ".publish.log");
55511
+ const logPath = (0, import_node_path48.join)(projDir, ".publish.log");
55479
55512
  let logStream = null;
55480
55513
  try {
55481
55514
  logStream = (0, import_node_fs40.createWriteStream)(logPath, { flags: "w" });
@@ -55735,7 +55768,7 @@ async function recoverInterruptedJobs(deps) {
55735
55768
 
55736
55769
  // src/handlers/app-builder.ts
55737
55770
  init_protocol();
55738
- var import_node_path48 = require("path");
55771
+ var import_node_path49 = require("path");
55739
55772
  var import_node_fs41 = require("fs");
55740
55773
  var APP_BUILDER_PERSONAS = ["persona-app-builder", "persona-dataclaw-builder"];
55741
55774
  var DEV_SERVER_READY_TIMEOUT_MS = 3e4;
@@ -55893,8 +55926,8 @@ function buildAppBuilderHandlers(deps) {
55893
55926
  const project = await userStore.create(f.name, reservedPorts);
55894
55927
  try {
55895
55928
  const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(session.ownerPersonaId ?? "") : deps.personaRoot;
55896
- const templateSrcDir = (0, import_node_path48.join)(personaRoot, "extension-kit", "examples", DEFAULT_TEMPLATE);
55897
- const scaffoldScript = (0, import_node_path48.join)(deps.deployKitRoot, "scripts", "new-extension.sh");
55929
+ const templateSrcDir = (0, import_node_path49.join)(personaRoot, "extension-kit", "examples", DEFAULT_TEMPLATE);
55930
+ const scaffoldScript = (0, import_node_path49.join)(deps.deployKitRoot, "scripts", "new-extension.sh");
55898
55931
  const scaffoldResult = await userStore.scaffold(project.name, templateSrcDir, scaffoldScript);
55899
55932
  deps.logger?.info("app-builder.scaffold.done", {
55900
55933
  name: project.name,
@@ -56115,7 +56148,7 @@ function buildAppBuilderHandlers(deps) {
56115
56148
  await userStore.clearPublishJob(args.name);
56116
56149
  }
56117
56150
  const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(boundSession.ownerPersonaId ?? "") : deps.personaRoot;
56118
- const scriptPath = (0, import_node_path48.join)(deps.deployKitRoot, "scripts", "publish.sh");
56151
+ const scriptPath = (0, import_node_path49.join)(deps.deployKitRoot, "scripts", "publish.sh");
56119
56152
  deps.logger?.info("app-builder.publish.start", {
56120
56153
  name: args.name,
56121
56154
  sessionId: boundSession.sessionId,
@@ -56284,7 +56317,7 @@ function buildVisitorHandlers(deps) {
56284
56317
 
56285
56318
  // src/extension/registry.ts
56286
56319
  var import_promises9 = __toESM(require("fs/promises"), 1);
56287
- var import_node_path49 = __toESM(require("path"), 1);
56320
+ var import_node_path50 = __toESM(require("path"), 1);
56288
56321
  async function loadAll(root) {
56289
56322
  let entries;
56290
56323
  try {
@@ -56297,13 +56330,13 @@ async function loadAll(root) {
56297
56330
  for (const ent of entries) {
56298
56331
  if (!ent.isDirectory()) continue;
56299
56332
  if (ent.name.startsWith(".")) continue;
56300
- records.push(await loadOne(import_node_path49.default.join(root, ent.name), ent.name));
56333
+ records.push(await loadOne(import_node_path50.default.join(root, ent.name), ent.name));
56301
56334
  }
56302
56335
  records.sort((a, b2) => a.extId < b2.extId ? -1 : a.extId > b2.extId ? 1 : 0);
56303
56336
  return records;
56304
56337
  }
56305
56338
  async function loadOne(dir, dirName) {
56306
- const manifestPath = import_node_path49.default.join(dir, "manifest.json");
56339
+ const manifestPath = import_node_path50.default.join(dir, "manifest.json");
56307
56340
  let raw;
56308
56341
  try {
56309
56342
  raw = await import_promises9.default.readFile(manifestPath, "utf8");
@@ -56348,7 +56381,7 @@ async function loadOne(dir, dirName) {
56348
56381
 
56349
56382
  // src/extension/uninstall.ts
56350
56383
  var import_promises10 = __toESM(require("fs/promises"), 1);
56351
- var import_node_path50 = __toESM(require("path"), 1);
56384
+ var import_node_path51 = __toESM(require("path"), 1);
56352
56385
  var UninstallError = class extends Error {
56353
56386
  constructor(code, message) {
56354
56387
  super(message);
@@ -56357,7 +56390,7 @@ var UninstallError = class extends Error {
56357
56390
  code;
56358
56391
  };
56359
56392
  async function uninstall(deps) {
56360
- const dir = import_node_path50.default.join(deps.root, deps.extId);
56393
+ const dir = import_node_path51.default.join(deps.root, deps.extId);
56361
56394
  try {
56362
56395
  await import_promises10.default.access(dir);
56363
56396
  } catch {
@@ -56926,7 +56959,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
56926
56959
 
56927
56960
  // src/extension/runtime.ts
56928
56961
  var import_node_child_process15 = require("child_process");
56929
- var import_node_path51 = __toESM(require("path"), 1);
56962
+ var import_node_path52 = __toESM(require("path"), 1);
56930
56963
  var import_promises11 = require("timers/promises");
56931
56964
 
56932
56965
  // src/extension/port-allocator.ts
@@ -57027,7 +57060,7 @@ var Runtime = class {
57027
57060
  /\$CLAWOS_EXT_PORT/g,
57028
57061
  String(port)
57029
57062
  );
57030
- const dir = import_node_path51.default.join(this.root, extId);
57063
+ const dir = import_node_path52.default.join(this.root, extId);
57031
57064
  const env = {
57032
57065
  ...process.env,
57033
57066
  CLAWOS_EXT_PORT: String(port),
@@ -57139,7 +57172,7 @@ ${handle.stderrTail}`
57139
57172
 
57140
57173
  // src/extension/published-channels.ts
57141
57174
  var import_promises12 = __toESM(require("fs/promises"), 1);
57142
- var import_node_path52 = __toESM(require("path"), 1);
57175
+ var import_node_path53 = __toESM(require("path"), 1);
57143
57176
  init_zod();
57144
57177
  var PublishedChannelsError = class extends Error {
57145
57178
  constructor(code, message) {
@@ -57238,7 +57271,7 @@ var PublishedChannelStore = class {
57238
57271
  )
57239
57272
  };
57240
57273
  const tmp = `${this.filePath}.tmp`;
57241
- await import_promises12.default.mkdir(import_node_path52.default.dirname(this.filePath), { recursive: true });
57274
+ await import_promises12.default.mkdir(import_node_path53.default.dirname(this.filePath), { recursive: true });
57242
57275
  await import_promises12.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
57243
57276
  await import_promises12.default.rename(tmp, this.filePath);
57244
57277
  }
@@ -57246,7 +57279,7 @@ var PublishedChannelStore = class {
57246
57279
 
57247
57280
  // src/extension/bundle-cache.ts
57248
57281
  var import_promises13 = __toESM(require("fs/promises"), 1);
57249
- var import_node_path53 = __toESM(require("path"), 1);
57282
+ var import_node_path54 = __toESM(require("path"), 1);
57250
57283
  var BundleCache = class {
57251
57284
  constructor(rootDir) {
57252
57285
  this.rootDir = rootDir;
@@ -57255,14 +57288,14 @@ var BundleCache = class {
57255
57288
  /** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
57256
57289
  async write(snapshotHash, buffer) {
57257
57290
  await import_promises13.default.mkdir(this.rootDir, { recursive: true });
57258
- const file = import_node_path53.default.join(this.rootDir, `${snapshotHash}.zip`);
57291
+ const file = import_node_path54.default.join(this.rootDir, `${snapshotHash}.zip`);
57259
57292
  const tmp = `${file}.tmp`;
57260
57293
  await import_promises13.default.writeFile(tmp, buffer, { mode: 384 });
57261
57294
  await import_promises13.default.rename(tmp, file);
57262
57295
  }
57263
57296
  /** Returns the bundle bytes, or null when the file doesn't exist. */
57264
57297
  async read(snapshotHash) {
57265
- const file = import_node_path53.default.join(this.rootDir, `${snapshotHash}.zip`);
57298
+ const file = import_node_path54.default.join(this.rootDir, `${snapshotHash}.zip`);
57266
57299
  try {
57267
57300
  return await import_promises13.default.readFile(file);
57268
57301
  } catch (e) {
@@ -57272,7 +57305,7 @@ var BundleCache = class {
57272
57305
  }
57273
57306
  /** Idempotent — missing file is not an error. */
57274
57307
  async delete(snapshotHash) {
57275
- const file = import_node_path53.default.join(this.rootDir, `${snapshotHash}.zip`);
57308
+ const file = import_node_path54.default.join(this.rootDir, `${snapshotHash}.zip`);
57276
57309
  await import_promises13.default.rm(file, { force: true });
57277
57310
  }
57278
57311
  };
@@ -57293,11 +57326,11 @@ async function startDaemon(config) {
57293
57326
  },
57294
57327
  source: "daemon",
57295
57328
  sampling: logShippingCfg.sampling,
57296
- homeDir: import_node_os20.default.homedir()
57329
+ homeDir: import_node_os21.default.homedir()
57297
57330
  });
57298
57331
  const logger = createLogger({
57299
57332
  level: config.logLevel,
57300
- file: import_node_path54.default.join(config.dataDir, "clawd.log"),
57333
+ file: import_node_path55.default.join(config.dataDir, "clawd.log"),
57301
57334
  logClient
57302
57335
  });
57303
57336
  logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
@@ -57437,8 +57470,8 @@ async function startDaemon(config) {
57437
57470
  const agents = new AgentsScanner();
57438
57471
  const history = new ClaudeHistoryReader();
57439
57472
  let transport = null;
57440
- const personaStore = new PersonaStore(import_node_path54.default.join(config.dataDir, "personas"));
57441
- const usersRoot = import_node_path54.default.join(config.dataDir, "users");
57473
+ const personaStore = new PersonaStore(import_node_path55.default.join(config.dataDir, "personas"));
57474
+ const usersRoot = import_node_path55.default.join(config.dataDir, "users");
57442
57475
  const defaultsRoot = findDefaultsRoot(logger);
57443
57476
  if (defaultsRoot) {
57444
57477
  seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
@@ -57458,17 +57491,17 @@ async function startDaemon(config) {
57458
57491
  migrateCodexSandbox({ store: personaStore, logger });
57459
57492
  const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
57460
57493
  const personaDispatchManager = new PersonaDispatchManager({ genId: () => v4_default() });
57461
- const here = typeof __dirname === "string" ? __dirname : import_node_path54.default.dirname((0, import_node_url4.fileURLToPath)(import_meta6.url));
57494
+ const here = typeof __dirname === "string" ? __dirname : import_node_path55.default.dirname((0, import_node_url4.fileURLToPath)(import_meta6.url));
57462
57495
  const dispatchServerCandidates = [
57463
- import_node_path54.default.join(here, "dispatch", "mcp-server.cjs"),
57496
+ import_node_path55.default.join(here, "dispatch", "mcp-server.cjs"),
57464
57497
  // 生产 dist/index → dist/dispatch/mcp-server.cjs
57465
- import_node_path54.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
57498
+ import_node_path55.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
57466
57499
  // dev tsx src/index → ../dist/dispatch/mcp-server.cjs
57467
57500
  ];
57468
57501
  const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs42.default.existsSync(p2));
57469
57502
  let dispatchMcpConfigPath2;
57470
57503
  if (dispatchServerScriptPath) {
57471
- const dispatchLogPath = import_node_path54.default.join(config.dataDir, "dispatch-mcp-server.log");
57504
+ const dispatchLogPath = import_node_path55.default.join(config.dataDir, "dispatch-mcp-server.log");
57472
57505
  dispatchMcpConfigPath2 = writeDispatchMcpConfig({
57473
57506
  dataDir: config.dataDir,
57474
57507
  serverScriptPath: dispatchServerScriptPath,
@@ -57485,15 +57518,15 @@ async function startDaemon(config) {
57485
57518
  });
57486
57519
  }
57487
57520
  const ticketServerCandidates = [
57488
- import_node_path54.default.join(here, "ticket", "mcp-server.cjs"),
57489
- import_node_path54.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
57521
+ import_node_path55.default.join(here, "ticket", "mcp-server.cjs"),
57522
+ import_node_path55.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
57490
57523
  ];
57491
57524
  const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs42.default.existsSync(p2));
57492
57525
  const ticketOwnerUnionId = feishuIdentity?.identity.unionId ?? "";
57493
57526
  const ticketOwnerName = feishuIdentity?.identity.displayName ?? "";
57494
57527
  let ticketMcpConfigPath2;
57495
57528
  if (ticketServerScriptPath && ticketOwnerUnionId) {
57496
- const ticketLogPath = import_node_path54.default.join(config.dataDir, "ticket-mcp-server.log");
57529
+ const ticketLogPath = import_node_path55.default.join(config.dataDir, "ticket-mcp-server.log");
57497
57530
  ticketMcpConfigPath2 = writeTicketMcpConfig({
57498
57531
  dataDir: config.dataDir,
57499
57532
  serverScriptPath: ticketServerScriptPath,
@@ -57514,13 +57547,13 @@ async function startDaemon(config) {
57514
57547
  });
57515
57548
  }
57516
57549
  const shiftServerCandidates = [
57517
- import_node_path54.default.join(here, "shift", "mcp-server.cjs"),
57518
- import_node_path54.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
57550
+ import_node_path55.default.join(here, "shift", "mcp-server.cjs"),
57551
+ import_node_path55.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
57519
57552
  ];
57520
57553
  const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs42.default.existsSync(p2));
57521
57554
  let shiftMcpConfigPath2;
57522
57555
  if (shiftServerScriptPath) {
57523
- const shiftLogPath = import_node_path54.default.join(config.dataDir, "shift-mcp-server.log");
57556
+ const shiftLogPath = import_node_path55.default.join(config.dataDir, "shift-mcp-server.log");
57524
57557
  shiftMcpConfigPath2 = await writeShiftMcpConfig({
57525
57558
  dataDir: config.dataDir,
57526
57559
  serverScriptPath: shiftServerScriptPath,
@@ -57538,13 +57571,13 @@ async function startDaemon(config) {
57538
57571
  );
57539
57572
  }
57540
57573
  const inboxServerCandidates = [
57541
- import_node_path54.default.join(here, "inbox", "mcp-server.cjs"),
57542
- import_node_path54.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
57574
+ import_node_path55.default.join(here, "inbox", "mcp-server.cjs"),
57575
+ import_node_path55.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
57543
57576
  ];
57544
57577
  const inboxServerScriptPath = inboxServerCandidates.find((p2) => import_node_fs42.default.existsSync(p2));
57545
57578
  let inboxMcpConfigPath2;
57546
57579
  if (inboxServerScriptPath) {
57547
- const inboxLogPath = import_node_path54.default.join(config.dataDir, "inbox-mcp-server.log");
57580
+ const inboxLogPath = import_node_path55.default.join(config.dataDir, "inbox-mcp-server.log");
57548
57581
  inboxMcpConfigPath2 = await writeInboxMcpConfig({
57549
57582
  dataDir: config.dataDir,
57550
57583
  serverScriptPath: inboxServerScriptPath,
@@ -57562,7 +57595,7 @@ async function startDaemon(config) {
57562
57595
  );
57563
57596
  }
57564
57597
  const shiftStore = createShiftStore({
57565
- filePath: import_node_path54.default.join(config.dataDir, "shift.json"),
57598
+ filePath: import_node_path55.default.join(config.dataDir, "shift.json"),
57566
57599
  ownerIdProvider: () => ownerPrincipalId,
57567
57600
  now: () => Date.now()
57568
57601
  });
@@ -57580,7 +57613,7 @@ async function startDaemon(config) {
57580
57613
  getAdapter,
57581
57614
  historyReader: history,
57582
57615
  dataDir: config.dataDir,
57583
- personaRoot: import_node_path54.default.join(config.dataDir, "personas"),
57616
+ personaRoot: import_node_path55.default.join(config.dataDir, "personas"),
57584
57617
  usersRoot,
57585
57618
  personaStore,
57586
57619
  ownerDisplayName,
@@ -57623,7 +57656,7 @@ async function startDaemon(config) {
57623
57656
  // 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
57624
57657
  attachmentGroup: {
57625
57658
  onFileEdit: (input) => {
57626
- const absPath = import_node_path54.default.isAbsolute(input.relPath) ? input.relPath : import_node_path54.default.join(input.cwd, input.relPath);
57659
+ const absPath = import_node_path55.default.isAbsolute(input.relPath) ? input.relPath : import_node_path55.default.join(input.cwd, input.relPath);
57627
57660
  let size = 0;
57628
57661
  try {
57629
57662
  size = import_node_fs42.default.statSync(absPath).size;
@@ -57824,11 +57857,11 @@ async function startDaemon(config) {
57824
57857
  // 'persona/<pid>/owner',default 走 'default'。
57825
57858
  getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
57826
57859
  // guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
57827
- personaRoot: import_node_path54.default.join(config.dataDir, "personas"),
57860
+ personaRoot: import_node_path55.default.join(config.dataDir, "personas"),
57828
57861
  usersRoot
57829
57862
  },
57830
57863
  // workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
57831
- personaRoot: import_node_path54.default.join(config.dataDir, "personas"),
57864
+ personaRoot: import_node_path55.default.join(config.dataDir, "personas"),
57832
57865
  // v2 多人 persona 隔离:handler 派生 guest user-dir 放行
57833
57866
  usersRoot,
57834
57867
  // capability:list / delete handler 依赖
@@ -57937,11 +57970,11 @@ async function startDaemon(config) {
57937
57970
  // 发布上线脚手架化 (spec 2026-06-03 §5.2):
57938
57971
  // appBuilderPersonaRoot 用于拼 publish.sh 绝对路径(persona-app-builder 安装在
57939
57972
  // dataDir/personas/persona-app-builder 之下,extension-kit/scripts/publish.sh 是相对路径)。
57940
- appBuilderPersonaRoot: import_node_path54.default.join(config.dataDir, "personas", "persona-app-builder"),
57973
+ appBuilderPersonaRoot: import_node_path55.default.join(config.dataDir, "personas", "persona-app-builder"),
57941
57974
  // 共享 deploy-kit 根:scaffold/publish 脚本骨架 + 阿里云凭证单一真源。
57942
- deployKitRoot: import_node_path54.default.join(config.dataDir, "deploy-kit"),
57975
+ deployKitRoot: import_node_path55.default.join(config.dataDir, "deploy-kit"),
57943
57976
  // scaffold/publish 按当前 session 的 persona 解析其安装根,让每个 persona 用自己的模板/注入配置。
57944
- resolvePersonaRoot: (personaId) => import_node_path54.default.join(config.dataDir, "personas", personaId),
57977
+ resolvePersonaRoot: (personaId) => import_node_path55.default.join(config.dataDir, "personas", personaId),
57945
57978
  // 发布上线脚手架化 (spec 2026-06-03 §5.2.2):
57946
57979
  // 复用 SessionManagerDeps.broadcastFrame 同款 dispatch 逻辑 —— runner 调 manager.send
57947
57980
  // 取回 broadcast 帧后逐帧 push 到 transport,跟 manager 自身的 deps 一致。
@@ -57984,8 +58017,8 @@ async function startDaemon(config) {
57984
58017
  }
57985
58018
  let sourceJsonlPath = "(no transcript yet \u2014 operate from the task description alone)";
57986
58019
  if (sourceFile && sourceFile.toolSessionId) {
57987
- sourceJsonlPath = import_node_path54.default.join(
57988
- import_node_os20.default.homedir(),
58020
+ sourceJsonlPath = import_node_path55.default.join(
58021
+ import_node_os21.default.homedir(),
57989
58022
  ".claude",
57990
58023
  "projects",
57991
58024
  cwdToHashDir(sourceFile.cwd),
@@ -58284,8 +58317,8 @@ async function startDaemon(config) {
58284
58317
  const lines = [
58285
58318
  `Tunnel: ${r.url}`,
58286
58319
  ...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
58287
- `Frpc config: ${import_node_path54.default.join(config.dataDir, "frpc.toml")}`,
58288
- `Frpc log: ${import_node_path54.default.join(config.dataDir, "frpc.log")}`
58320
+ `Frpc config: ${import_node_path55.default.join(config.dataDir, "frpc.toml")}`,
58321
+ `Frpc log: ${import_node_path55.default.join(config.dataDir, "frpc.log")}`
58289
58322
  ];
58290
58323
  const width = Math.max(...lines.map((l) => l.length));
58291
58324
  const bar = "\u2550".repeat(width + 4);
@@ -58298,7 +58331,7 @@ ${bar}
58298
58331
 
58299
58332
  `);
58300
58333
  try {
58301
- const connectPath = import_node_path54.default.join(config.dataDir, "connect.txt");
58334
+ const connectPath = import_node_path55.default.join(config.dataDir, "connect.txt");
58302
58335
  import_node_fs42.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
58303
58336
  } catch {
58304
58337
  }
@@ -58371,7 +58404,7 @@ ${bar}
58371
58404
  };
58372
58405
  }
58373
58406
  function migrateDropPersonsDir(dataDir) {
58374
- const dir = import_node_path54.default.join(dataDir, "persons");
58407
+ const dir = import_node_path55.default.join(dataDir, "persons");
58375
58408
  try {
58376
58409
  import_node_fs42.default.rmSync(dir, { recursive: true, force: true });
58377
58410
  } catch {