@clawos-dev/clawd 0.2.188 → 0.2.189-beta.376.57d5363

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.cjs +589 -538
  2. package/package.json +1 -1
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: path66, errorMaps, issueData } = params;
737
- const fullPath = [...path66, ...issueData.path || []];
736
+ const { data, path: path67, errorMaps, issueData } = params;
737
+ const fullPath = [...path67, ...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, path66, key) {
1048
+ constructor(parent, value, path67, key) {
1049
1049
  this._cachedPath = [];
1050
1050
  this.parent = parent;
1051
1051
  this.data = value;
1052
- this._path = path66;
1052
+ this._path = path67;
1053
1053
  this._key = key;
1054
1054
  }
1055
1055
  get path() {
@@ -6364,8 +6364,8 @@ var require_req = __commonJS({
6364
6364
  if (req.originalUrl) {
6365
6365
  _req.url = req.originalUrl;
6366
6366
  } else {
6367
- const path66 = req.path;
6368
- _req.url = typeof path66 === "string" ? path66 : req.url ? req.url.path || req.url : void 0;
6367
+ const path67 = req.path;
6368
+ _req.url = typeof path67 === "string" ? path67 : req.url ? req.url.path || req.url : void 0;
6369
6369
  }
6370
6370
  if (req.query) {
6371
6371
  _req.query = req.query;
@@ -6530,14 +6530,14 @@ var require_redact = __commonJS({
6530
6530
  }
6531
6531
  return obj;
6532
6532
  }
6533
- function parsePath(path66) {
6533
+ function parsePath(path67) {
6534
6534
  const parts = [];
6535
6535
  let current = "";
6536
6536
  let inBrackets = false;
6537
6537
  let inQuotes = false;
6538
6538
  let quoteChar = "";
6539
- for (let i = 0; i < path66.length; i++) {
6540
- const char = path66[i];
6539
+ for (let i = 0; i < path67.length; i++) {
6540
+ const char = path67[i];
6541
6541
  if (!inBrackets && char === ".") {
6542
6542
  if (current) {
6543
6543
  parts.push(current);
@@ -6668,10 +6668,10 @@ var require_redact = __commonJS({
6668
6668
  return current;
6669
6669
  }
6670
6670
  function redactPaths(obj, paths, censor, remove = false) {
6671
- for (const path66 of paths) {
6672
- const parts = parsePath(path66);
6671
+ for (const path67 of paths) {
6672
+ const parts = parsePath(path67);
6673
6673
  if (parts.includes("*")) {
6674
- redactWildcardPath(obj, parts, censor, path66, remove);
6674
+ redactWildcardPath(obj, parts, censor, path67, remove);
6675
6675
  } else {
6676
6676
  if (remove) {
6677
6677
  removeKey(obj, parts);
@@ -6756,8 +6756,8 @@ var require_redact = __commonJS({
6756
6756
  }
6757
6757
  } else {
6758
6758
  if (afterWildcard.includes("*")) {
6759
- const wrappedCensor = typeof censor === "function" ? (value, path66) => {
6760
- const fullPath = [...pathArray.slice(0, pathLength), ...path66];
6759
+ const wrappedCensor = typeof censor === "function" ? (value, path67) => {
6760
+ const fullPath = [...pathArray.slice(0, pathLength), ...path67];
6761
6761
  return censor(value, fullPath);
6762
6762
  } : censor;
6763
6763
  redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
@@ -6792,8 +6792,8 @@ var require_redact = __commonJS({
6792
6792
  return null;
6793
6793
  }
6794
6794
  const pathStructure = /* @__PURE__ */ new Map();
6795
- for (const path66 of pathsToClone) {
6796
- const parts = parsePath(path66);
6795
+ for (const path67 of pathsToClone) {
6796
+ const parts = parsePath(path67);
6797
6797
  let current = pathStructure;
6798
6798
  for (let i = 0; i < parts.length; i++) {
6799
6799
  const part = parts[i];
@@ -6845,24 +6845,24 @@ var require_redact = __commonJS({
6845
6845
  }
6846
6846
  return cloneSelectively(obj, pathStructure);
6847
6847
  }
6848
- function validatePath(path66) {
6849
- if (typeof path66 !== "string") {
6848
+ function validatePath(path67) {
6849
+ if (typeof path67 !== "string") {
6850
6850
  throw new Error("Paths must be (non-empty) strings");
6851
6851
  }
6852
- if (path66 === "") {
6852
+ if (path67 === "") {
6853
6853
  throw new Error("Invalid redaction path ()");
6854
6854
  }
6855
- if (path66.includes("..")) {
6856
- throw new Error(`Invalid redaction path (${path66})`);
6855
+ if (path67.includes("..")) {
6856
+ throw new Error(`Invalid redaction path (${path67})`);
6857
6857
  }
6858
- if (path66.includes(",")) {
6859
- throw new Error(`Invalid redaction path (${path66})`);
6858
+ if (path67.includes(",")) {
6859
+ throw new Error(`Invalid redaction path (${path67})`);
6860
6860
  }
6861
6861
  let bracketCount = 0;
6862
6862
  let inQuotes = false;
6863
6863
  let quoteChar = "";
6864
- for (let i = 0; i < path66.length; i++) {
6865
- const char = path66[i];
6864
+ for (let i = 0; i < path67.length; i++) {
6865
+ const char = path67[i];
6866
6866
  if ((char === '"' || char === "'") && bracketCount > 0) {
6867
6867
  if (!inQuotes) {
6868
6868
  inQuotes = true;
@@ -6876,20 +6876,20 @@ var require_redact = __commonJS({
6876
6876
  } else if (char === "]" && !inQuotes) {
6877
6877
  bracketCount--;
6878
6878
  if (bracketCount < 0) {
6879
- throw new Error(`Invalid redaction path (${path66})`);
6879
+ throw new Error(`Invalid redaction path (${path67})`);
6880
6880
  }
6881
6881
  }
6882
6882
  }
6883
6883
  if (bracketCount !== 0) {
6884
- throw new Error(`Invalid redaction path (${path66})`);
6884
+ throw new Error(`Invalid redaction path (${path67})`);
6885
6885
  }
6886
6886
  }
6887
6887
  function validatePaths(paths) {
6888
6888
  if (!Array.isArray(paths)) {
6889
6889
  throw new TypeError("paths must be an array");
6890
6890
  }
6891
- for (const path66 of paths) {
6892
- validatePath(path66);
6891
+ for (const path67 of paths) {
6892
+ validatePath(path67);
6893
6893
  }
6894
6894
  }
6895
6895
  function slowRedact(options = {}) {
@@ -7057,8 +7057,8 @@ var require_redaction = __commonJS({
7057
7057
  if (shape[k2] === null) {
7058
7058
  o[k2] = (value) => topCensor(value, [k2]);
7059
7059
  } else {
7060
- const wrappedCensor = typeof censor === "function" ? (value, path66) => {
7061
- return censor(value, [k2, ...path66]);
7060
+ const wrappedCensor = typeof censor === "function" ? (value, path67) => {
7061
+ return censor(value, [k2, ...path67]);
7062
7062
  } : censor;
7063
7063
  o[k2] = Redact({
7064
7064
  paths: shape[k2],
@@ -7279,7 +7279,7 @@ var require_sonic_boom = __commonJS({
7279
7279
  var fs60 = require("fs");
7280
7280
  var EventEmitter3 = require("events");
7281
7281
  var inherits = require("util").inherits;
7282
- var path66 = require("path");
7282
+ var path67 = require("path");
7283
7283
  var sleep2 = require_atomic_sleep();
7284
7284
  var assert = require("assert");
7285
7285
  var BUSY_WRITE_TIMEOUT = 100;
@@ -7333,7 +7333,7 @@ var require_sonic_boom = __commonJS({
7333
7333
  const mode = sonic.mode;
7334
7334
  if (sonic.sync) {
7335
7335
  try {
7336
- if (sonic.mkdir) fs60.mkdirSync(path66.dirname(file), { recursive: true });
7336
+ if (sonic.mkdir) fs60.mkdirSync(path67.dirname(file), { recursive: true });
7337
7337
  const fd = fs60.openSync(file, flags, mode);
7338
7338
  fileOpened(null, fd);
7339
7339
  } catch (err) {
@@ -7341,7 +7341,7 @@ var require_sonic_boom = __commonJS({
7341
7341
  throw err;
7342
7342
  }
7343
7343
  } else if (sonic.mkdir) {
7344
- fs60.mkdir(path66.dirname(file), { recursive: true }, (err) => {
7344
+ fs60.mkdir(path67.dirname(file), { recursive: true }, (err) => {
7345
7345
  if (err) return fileOpened(err);
7346
7346
  fs60.open(file, flags, mode, fileOpened);
7347
7347
  });
@@ -10201,7 +10201,7 @@ var require_multistream = __commonJS({
10201
10201
  var require_pino = __commonJS({
10202
10202
  "../node_modules/.pnpm/pino@9.14.0/node_modules/pino/pino.js"(exports2, module2) {
10203
10203
  "use strict";
10204
- var os22 = require("os");
10204
+ var os23 = require("os");
10205
10205
  var stdSerializers = require_pino_std_serializers();
10206
10206
  var caller = require_caller();
10207
10207
  var redaction = require_redaction();
@@ -10248,7 +10248,7 @@ var require_pino = __commonJS({
10248
10248
  } = symbols;
10249
10249
  var { epochTime, nullTime } = time;
10250
10250
  var { pid } = process;
10251
- var hostname = os22.hostname();
10251
+ var hostname = os23.hostname();
10252
10252
  var defaultErrorSerializer = stdSerializers.err;
10253
10253
  var defaultOptions = {
10254
10254
  level: "info",
@@ -10972,11 +10972,11 @@ var init_lib = __esm({
10972
10972
  }
10973
10973
  }
10974
10974
  },
10975
- addToPath: function addToPath(path66, added, removed, oldPosInc, options) {
10976
- var last = path66.lastComponent;
10975
+ addToPath: function addToPath(path67, added, removed, oldPosInc, options) {
10976
+ var last = path67.lastComponent;
10977
10977
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
10978
10978
  return {
10979
- oldPos: path66.oldPos + oldPosInc,
10979
+ oldPos: path67.oldPos + oldPosInc,
10980
10980
  lastComponent: {
10981
10981
  count: last.count + 1,
10982
10982
  added,
@@ -10986,7 +10986,7 @@ var init_lib = __esm({
10986
10986
  };
10987
10987
  } else {
10988
10988
  return {
10989
- oldPos: path66.oldPos + oldPosInc,
10989
+ oldPos: path67.oldPos + oldPosInc,
10990
10990
  lastComponent: {
10991
10991
  count: 1,
10992
10992
  added,
@@ -11044,7 +11044,7 @@ var init_lib = __esm({
11044
11044
  tokenize: function tokenize(value) {
11045
11045
  return Array.from(value);
11046
11046
  },
11047
- join: function join5(chars) {
11047
+ join: function join3(chars) {
11048
11048
  return chars.join("");
11049
11049
  },
11050
11050
  postProcess: function postProcess(changeObjects) {
@@ -11226,13 +11226,33 @@ var init_tool_result_extra = __esm({
11226
11226
  function cwdToHashDir(cwd) {
11227
11227
  return cwd.replace(/[^a-zA-Z0-9]/g, "-");
11228
11228
  }
11229
+ function newestSubagentMtimeMs(projectsRoot, cwd, toolSessionId) {
11230
+ const dir = import_node_path4.default.join(projectsRoot, cwdToHashDir(cwd), toolSessionId, "subagents");
11231
+ let entries;
11232
+ try {
11233
+ entries = import_node_fs4.default.readdirSync(dir, { withFileTypes: true });
11234
+ } catch {
11235
+ return null;
11236
+ }
11237
+ let newest = null;
11238
+ for (const e of entries) {
11239
+ if (!e.isFile()) continue;
11240
+ if (!e.name.startsWith("agent-") || !e.name.endsWith(".jsonl")) continue;
11241
+ try {
11242
+ const m2 = import_node_fs4.default.statSync(import_node_path4.default.join(dir, e.name)).mtimeMs;
11243
+ if (newest === null || m2 > newest) newest = m2;
11244
+ } catch {
11245
+ }
11246
+ }
11247
+ return newest;
11248
+ }
11229
11249
  function hashDirToCwd(hash) {
11230
11250
  const body = hash.startsWith("-") ? hash.slice(1) : hash;
11231
11251
  return "/" + body.replace(/-/g, "/");
11232
11252
  }
11233
11253
  function safeStatMtime(p2) {
11234
11254
  try {
11235
- return import_node_fs13.default.statSync(p2).mtimeMs;
11255
+ return import_node_fs4.default.statSync(p2).mtimeMs;
11236
11256
  } catch {
11237
11257
  return 0;
11238
11258
  }
@@ -11240,7 +11260,7 @@ function safeStatMtime(p2) {
11240
11260
  function readJsonlLines(file) {
11241
11261
  let raw;
11242
11262
  try {
11243
- raw = import_node_fs13.default.readFileSync(file, "utf8");
11263
+ raw = import_node_fs4.default.readFileSync(file, "utf8");
11244
11264
  } catch (err) {
11245
11265
  if (err.code === "ENOENT") return [];
11246
11266
  throw err;
@@ -11432,10 +11452,10 @@ function attachmentToHistoryMessage(o, ts) {
11432
11452
  const memories = raw.map((m2) => {
11433
11453
  if (!m2 || typeof m2 !== "object") return null;
11434
11454
  const rec3 = m2;
11435
- const path66 = typeof rec3.path === "string" ? rec3.path : null;
11455
+ const path67 = typeof rec3.path === "string" ? rec3.path : null;
11436
11456
  const content = typeof rec3.content === "string" ? rec3.content : null;
11437
- if (!path66 || content == null) return null;
11438
- const entry = { path: path66, content };
11457
+ if (!path67 || content == null) return null;
11458
+ const entry = { path: path67, content };
11439
11459
  if (typeof rec3.mtimeMs === "number") entry.mtimeMs = rec3.mtimeMs;
11440
11460
  return entry;
11441
11461
  }).filter((m2) => m2 !== null);
@@ -11471,8 +11491,8 @@ function attachmentDeferredToolsText(a) {
11471
11491
  function readBackupContent(fileHistoryRoot, toolSessionId, backupFileName) {
11472
11492
  if (backupFileName === null) return null;
11473
11493
  try {
11474
- return import_node_fs13.default.readFileSync(
11475
- import_node_path12.default.join(fileHistoryRoot, toolSessionId, backupFileName),
11494
+ return import_node_fs4.default.readFileSync(
11495
+ import_node_path4.default.join(fileHistoryRoot, toolSessionId, backupFileName),
11476
11496
  "utf8"
11477
11497
  );
11478
11498
  } catch {
@@ -11481,19 +11501,19 @@ function readBackupContent(fileHistoryRoot, toolSessionId, backupFileName) {
11481
11501
  }
11482
11502
  function readCurrentContent(filePath) {
11483
11503
  try {
11484
- return import_node_fs13.default.readFileSync(filePath, "utf8");
11504
+ return import_node_fs4.default.readFileSync(filePath, "utf8");
11485
11505
  } catch (err) {
11486
11506
  if (err.code === "ENOENT") return null;
11487
11507
  return null;
11488
11508
  }
11489
11509
  }
11490
- 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;
11510
+ 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;
11491
11511
  var init_claude_history = __esm({
11492
11512
  "src/tools/claude-history.ts"() {
11493
11513
  "use strict";
11494
- import_node_fs13 = __toESM(require("fs"), 1);
11495
- import_node_os5 = __toESM(require("os"), 1);
11496
- import_node_path12 = __toESM(require("path"), 1);
11514
+ import_node_fs4 = __toESM(require("fs"), 1);
11515
+ import_node_os3 = __toESM(require("os"), 1);
11516
+ import_node_path4 = __toESM(require("path"), 1);
11497
11517
  init_lib();
11498
11518
  init_tool_result_extra();
11499
11519
  TASK_NOTIFICATION_RE = /<task-notification\b[\s\S]*?<\/task-notification>/i;
@@ -11517,14 +11537,14 @@ var init_claude_history = __esm({
11517
11537
  // 每次 user 提交前 trackEdit 拷一份,作为 rewind 回退目标
11518
11538
  fileHistoryRoot;
11519
11539
  constructor(opts = {}) {
11520
- const base = opts.baseDir ?? import_node_path12.default.join(import_node_os5.default.homedir(), ".claude");
11521
- this.projectsRoot = import_node_path12.default.join(base, "projects");
11522
- this.fileHistoryRoot = import_node_path12.default.join(base, "file-history");
11540
+ const base = opts.baseDir ?? import_node_path4.default.join(import_node_os3.default.homedir(), ".claude");
11541
+ this.projectsRoot = import_node_path4.default.join(base, "projects");
11542
+ this.fileHistoryRoot = import_node_path4.default.join(base, "file-history");
11523
11543
  }
11524
11544
  async listProjects() {
11525
11545
  let entries;
11526
11546
  try {
11527
- entries = import_node_fs13.default.readdirSync(this.projectsRoot, { withFileTypes: true });
11547
+ entries = import_node_fs4.default.readdirSync(this.projectsRoot, { withFileTypes: true });
11528
11548
  } catch (err) {
11529
11549
  if (err.code === "ENOENT") return [];
11530
11550
  throw err;
@@ -11532,9 +11552,9 @@ var init_claude_history = __esm({
11532
11552
  const out = [];
11533
11553
  for (const ent of entries) {
11534
11554
  if (!ent.isDirectory()) continue;
11535
- const dir = import_node_path12.default.join(this.projectsRoot, ent.name);
11536
- const files = import_node_fs13.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
11537
- const updatedAtMs = files.reduce((m2, f) => Math.max(m2, safeStatMtime(import_node_path12.default.join(dir, f))), 0);
11555
+ const dir = import_node_path4.default.join(this.projectsRoot, ent.name);
11556
+ const files = import_node_fs4.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
11557
+ const updatedAtMs = files.reduce((m2, f) => Math.max(m2, safeStatMtime(import_node_path4.default.join(dir, f))), 0);
11538
11558
  out.push({
11539
11559
  projectPath: hashDirToCwd(ent.name),
11540
11560
  hashDir: ent.name,
@@ -11546,17 +11566,17 @@ var init_claude_history = __esm({
11546
11566
  return out;
11547
11567
  }
11548
11568
  async listSessions(args) {
11549
- const dir = import_node_path12.default.join(this.projectsRoot, cwdToHashDir(args.projectPath));
11569
+ const dir = import_node_path4.default.join(this.projectsRoot, cwdToHashDir(args.projectPath));
11550
11570
  let files;
11551
11571
  try {
11552
- files = import_node_fs13.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
11572
+ files = import_node_fs4.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
11553
11573
  } catch (err) {
11554
11574
  if (err.code === "ENOENT") return [];
11555
11575
  throw err;
11556
11576
  }
11557
11577
  const out = [];
11558
11578
  for (const f of files) {
11559
- const full = import_node_path12.default.join(dir, f);
11579
+ const full = import_node_path4.default.join(dir, f);
11560
11580
  const toolSessionId = f.slice(0, -".jsonl".length);
11561
11581
  const lines = readJsonlLines(full);
11562
11582
  let summary = "";
@@ -11611,7 +11631,7 @@ var init_claude_history = __esm({
11611
11631
  return out;
11612
11632
  }
11613
11633
  async read(args) {
11614
- const file = import_node_path12.default.join(
11634
+ const file = import_node_path4.default.join(
11615
11635
  this.projectsRoot,
11616
11636
  cwdToHashDir(args.cwd),
11617
11637
  `${args.toolSessionId}.jsonl`
@@ -11648,7 +11668,7 @@ var init_claude_history = __esm({
11648
11668
  // 独立目录路径:<projectsRoot>/<cwdHash>/<toolSessionId>/subagents/*.jsonl
11649
11669
  // 返回 null 表示目录不存在(调用方回退旧实现);返回空数组表示目录存在但无 jsonl
11650
11670
  listSubagentsFromDirectory(cwd, toolSessionId) {
11651
- const dir = import_node_path12.default.join(
11671
+ const dir = import_node_path4.default.join(
11652
11672
  this.projectsRoot,
11653
11673
  cwdToHashDir(cwd),
11654
11674
  toolSessionId,
@@ -11656,7 +11676,7 @@ var init_claude_history = __esm({
11656
11676
  );
11657
11677
  let entries;
11658
11678
  try {
11659
- entries = import_node_fs13.default.readdirSync(dir, { withFileTypes: true });
11679
+ entries = import_node_fs4.default.readdirSync(dir, { withFileTypes: true });
11660
11680
  } catch (err) {
11661
11681
  if (err.code === "ENOENT") return null;
11662
11682
  return null;
@@ -11666,7 +11686,7 @@ var init_claude_history = __esm({
11666
11686
  if (!e.isFile()) continue;
11667
11687
  if (!e.name.startsWith("agent-") || !e.name.endsWith(".jsonl")) continue;
11668
11688
  const subagentId = e.name.slice("agent-".length, -".jsonl".length);
11669
- const filePath = import_node_path12.default.join(dir, e.name);
11689
+ const filePath = import_node_path4.default.join(dir, e.name);
11670
11690
  const lines = readJsonlLines(filePath);
11671
11691
  let firstText = "";
11672
11692
  let messageCount = 0;
@@ -11683,7 +11703,7 @@ var init_claude_history = __esm({
11683
11703
  return out;
11684
11704
  }
11685
11705
  listSubagentsFromMainJsonl(cwd, toolSessionId) {
11686
- const file = import_node_path12.default.join(
11706
+ const file = import_node_path4.default.join(
11687
11707
  this.projectsRoot,
11688
11708
  cwdToHashDir(cwd),
11689
11709
  `${toolSessionId}.jsonl`
@@ -11718,7 +11738,7 @@ var init_claude_history = __esm({
11718
11738
  }
11719
11739
  // 独立文件路径:agent-<subagentId>.jsonl;文件不存在返回 null 让调用方回退旧实现
11720
11740
  readSubagentFromFile(cwd, toolSessionId, subagentId) {
11721
- const file = import_node_path12.default.join(
11741
+ const file = import_node_path4.default.join(
11722
11742
  this.projectsRoot,
11723
11743
  cwdToHashDir(cwd),
11724
11744
  toolSessionId,
@@ -11727,7 +11747,7 @@ var init_claude_history = __esm({
11727
11747
  );
11728
11748
  let exists = false;
11729
11749
  try {
11730
- exists = import_node_fs13.default.statSync(file).isFile();
11750
+ exists = import_node_fs4.default.statSync(file).isFile();
11731
11751
  } catch {
11732
11752
  return null;
11733
11753
  }
@@ -11746,7 +11766,7 @@ var init_claude_history = __esm({
11746
11766
  * "那一刻每个 tracked 文件对应的 backup 文件名"
11747
11767
  */
11748
11768
  readFileHistorySnapshots(args) {
11749
- const file = import_node_path12.default.join(
11769
+ const file = import_node_path4.default.join(
11750
11770
  this.projectsRoot,
11751
11771
  cwdToHashDir(args.cwd),
11752
11772
  `${args.toolSessionId}.jsonl`
@@ -11791,7 +11811,7 @@ var init_claude_history = __esm({
11791
11811
  for (const [anchorId, target] of snapshots) {
11792
11812
  let hasAny = false;
11793
11813
  for (const [rawPath, backup] of Object.entries(target)) {
11794
- const absPath = import_node_path12.default.isAbsolute(rawPath) ? rawPath : import_node_path12.default.join(args.cwd, rawPath);
11814
+ const absPath = import_node_path4.default.isAbsolute(rawPath) ? rawPath : import_node_path4.default.join(args.cwd, rawPath);
11795
11815
  const backupContent = readBackupContent(
11796
11816
  this.fileHistoryRoot,
11797
11817
  args.toolSessionId,
@@ -11831,7 +11851,7 @@ var init_claude_history = __esm({
11831
11851
  let totalInsertions = 0;
11832
11852
  let totalDeletions = 0;
11833
11853
  for (const [rawPath, backup] of Object.entries(target)) {
11834
- const absPath = import_node_path12.default.isAbsolute(rawPath) ? rawPath : import_node_path12.default.join(args.cwd, rawPath);
11854
+ const absPath = import_node_path4.default.isAbsolute(rawPath) ? rawPath : import_node_path4.default.join(args.cwd, rawPath);
11835
11855
  const backupContent = readBackupContent(
11836
11856
  this.fileHistoryRoot,
11837
11857
  args.toolSessionId,
@@ -11878,7 +11898,7 @@ var init_claude_history = __esm({
11878
11898
  };
11879
11899
  }
11880
11900
  readSubagentFromMainJsonl(cwd, toolSessionId, subagentId) {
11881
- const file = import_node_path12.default.join(
11901
+ const file = import_node_path4.default.join(
11882
11902
  this.projectsRoot,
11883
11903
  cwdToHashDir(cwd),
11884
11904
  `${toolSessionId}.jsonl`
@@ -12244,10 +12264,10 @@ function parseAttachment(obj) {
12244
12264
  const memories = raw.map((m2) => {
12245
12265
  if (!m2 || typeof m2 !== "object") return null;
12246
12266
  const rec3 = m2;
12247
- const path66 = typeof rec3.path === "string" ? rec3.path : null;
12267
+ const path67 = typeof rec3.path === "string" ? rec3.path : null;
12248
12268
  const content = typeof rec3.content === "string" ? rec3.content : null;
12249
- if (!path66 || content == null) return null;
12250
- const out = { path: path66, content };
12269
+ if (!path67 || content == null) return null;
12270
+ const out = { path: path67, content };
12251
12271
  if (typeof rec3.mtimeMs === "number") out.mtimeMs = rec3.mtimeMs;
12252
12272
  return out;
12253
12273
  }).filter((m2) => m2 !== null);
@@ -33211,8 +33231,8 @@ var require_utils = __commonJS({
33211
33231
  var result = transform[inputType][outputType](input);
33212
33232
  return result;
33213
33233
  };
33214
- exports2.resolve = function(path66) {
33215
- var parts = path66.split("/");
33234
+ exports2.resolve = function(path67) {
33235
+ var parts = path67.split("/");
33216
33236
  var result = [];
33217
33237
  for (var index = 0; index < parts.length; index++) {
33218
33238
  var part = parts[index];
@@ -39065,18 +39085,18 @@ var require_object = __commonJS({
39065
39085
  var object = new ZipObject(name, zipObjectContent, o);
39066
39086
  this.files[name] = object;
39067
39087
  };
39068
- var parentFolder = function(path66) {
39069
- if (path66.slice(-1) === "/") {
39070
- path66 = path66.substring(0, path66.length - 1);
39088
+ var parentFolder = function(path67) {
39089
+ if (path67.slice(-1) === "/") {
39090
+ path67 = path67.substring(0, path67.length - 1);
39071
39091
  }
39072
- var lastSlash = path66.lastIndexOf("/");
39073
- return lastSlash > 0 ? path66.substring(0, lastSlash) : "";
39092
+ var lastSlash = path67.lastIndexOf("/");
39093
+ return lastSlash > 0 ? path67.substring(0, lastSlash) : "";
39074
39094
  };
39075
- var forceTrailingSlash = function(path66) {
39076
- if (path66.slice(-1) !== "/") {
39077
- path66 += "/";
39095
+ var forceTrailingSlash = function(path67) {
39096
+ if (path67.slice(-1) !== "/") {
39097
+ path67 += "/";
39078
39098
  }
39079
- return path66;
39099
+ return path67;
39080
39100
  };
39081
39101
  var folderAdd = function(name, createFolders) {
39082
39102
  createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
@@ -40078,7 +40098,7 @@ var require_lib3 = __commonJS({
40078
40098
  // src/run-case/recorder.ts
40079
40099
  function startRunCaseRecorder(opts) {
40080
40100
  const now = opts.now ?? Date.now;
40081
- const dir = import_node_path54.default.dirname(opts.recordPath);
40101
+ const dir = import_node_path55.default.dirname(opts.recordPath);
40082
40102
  let stream = null;
40083
40103
  let closing = false;
40084
40104
  let closedSettled = false;
@@ -40118,12 +40138,12 @@ function startRunCaseRecorder(opts) {
40118
40138
  };
40119
40139
  return { tap, close, closed };
40120
40140
  }
40121
- var import_node_fs42, import_node_path54;
40141
+ var import_node_fs42, import_node_path55;
40122
40142
  var init_recorder = __esm({
40123
40143
  "src/run-case/recorder.ts"() {
40124
40144
  "use strict";
40125
40145
  import_node_fs42 = __toESM(require("fs"), 1);
40126
- import_node_path54 = __toESM(require("path"), 1);
40146
+ import_node_path55 = __toESM(require("path"), 1);
40127
40147
  }
40128
40148
  });
40129
40149
 
@@ -40166,7 +40186,7 @@ var init_wire = __esm({
40166
40186
  // src/run-case/controller.ts
40167
40187
  async function runController(opts) {
40168
40188
  const now = opts.now ?? Date.now;
40169
- const cwd = opts.cwd ?? (0, import_node_fs43.mkdtempSync)(import_node_path55.default.join(import_node_os21.default.tmpdir(), "clawd-runcase-"));
40189
+ const cwd = opts.cwd ?? (0, import_node_fs43.mkdtempSync)(import_node_path56.default.join(import_node_os22.default.tmpdir(), "clawd-runcase-"));
40170
40190
  const ownsCwd = opts.cwd === void 0;
40171
40191
  const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
40172
40192
  const spawnCtx = { cwd };
@@ -40333,13 +40353,13 @@ async function runController(opts) {
40333
40353
  }
40334
40354
  return exitCode ?? 0;
40335
40355
  }
40336
- var import_node_fs43, import_node_os21, import_node_path55;
40356
+ var import_node_fs43, import_node_os22, import_node_path56;
40337
40357
  var init_controller = __esm({
40338
40358
  "src/run-case/controller.ts"() {
40339
40359
  "use strict";
40340
40360
  import_node_fs43 = require("fs");
40341
- import_node_os21 = __toESM(require("os"), 1);
40342
- import_node_path55 = __toESM(require("path"), 1);
40361
+ import_node_os22 = __toESM(require("os"), 1);
40362
+ import_node_path56 = __toESM(require("path"), 1);
40343
40363
  init_claude();
40344
40364
  init_stdout_splitter();
40345
40365
  init_permission_stdio();
@@ -40601,9 +40621,9 @@ Env (advanced):
40601
40621
  `;
40602
40622
 
40603
40623
  // src/index.ts
40604
- var import_node_path53 = __toESM(require("path"), 1);
40624
+ var import_node_path54 = __toESM(require("path"), 1);
40605
40625
  var import_node_fs41 = __toESM(require("fs"), 1);
40606
- var import_node_os20 = __toESM(require("os"), 1);
40626
+ var import_node_os21 = __toESM(require("os"), 1);
40607
40627
 
40608
40628
  // ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/stringify.js
40609
40629
  var byteToHex = [];
@@ -41220,9 +41240,9 @@ var SessionStoreFactory = class {
41220
41240
  };
41221
41241
 
41222
41242
  // src/session/manager.ts
41223
- var import_node_fs6 = __toESM(require("fs"), 1);
41224
- var import_node_path6 = __toESM(require("path"), 1);
41225
- var import_node_os3 = __toESM(require("os"), 1);
41243
+ var import_node_fs7 = __toESM(require("fs"), 1);
41244
+ var import_node_path8 = __toESM(require("path"), 1);
41245
+ var import_node_os5 = __toESM(require("os"), 1);
41226
41246
  init_protocol();
41227
41247
 
41228
41248
  // src/tools/guest-settings.ts
@@ -41320,6 +41340,10 @@ function escapeAttr(v2) {
41320
41340
  return v2.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
41321
41341
  }
41322
41342
 
41343
+ // src/session/runner.ts
41344
+ var import_node_os4 = __toESM(require("os"), 1);
41345
+ var import_node_path6 = __toESM(require("path"), 1);
41346
+
41323
41347
  // src/session/reducer.ts
41324
41348
  init_runtime();
41325
41349
 
@@ -41458,7 +41482,8 @@ function cloneState(s) {
41458
41482
  pendingSend: s.pendingSend.slice()
41459
41483
  };
41460
41484
  }
41461
- var IDLE_KILL_DELAY_MS = 6e4;
41485
+ var IDLE_KILL_DELAY_MS = 36e5;
41486
+ var IDLE_KILL_SUBAGENT_RECHECK_MS = 3e5;
41462
41487
  function tryFlushPending(state, deps) {
41463
41488
  if (!state.readyForSend || state.pendingSend.length === 0) return [];
41464
41489
  const text = state.pendingSend.shift();
@@ -42127,6 +42152,18 @@ function reduceSession(state, input, deps) {
42127
42152
  if (state.status !== "running-idle") {
42128
42153
  return { state, effects: [] };
42129
42154
  }
42155
+ if (input.subagentActive) {
42156
+ return {
42157
+ state,
42158
+ effects: [
42159
+ {
42160
+ kind: "schedule-idle-kill",
42161
+ sessionId: state.file.sessionId,
42162
+ ms: IDLE_KILL_SUBAGENT_RECHECK_MS
42163
+ }
42164
+ ]
42165
+ };
42166
+ }
42130
42167
  const next = cloneState(state);
42131
42168
  next.status = "stopping";
42132
42169
  return {
@@ -42183,10 +42220,11 @@ function reduceSession(state, input, deps) {
42183
42220
  // src/session/runner.ts
42184
42221
  init_stdout_splitter();
42185
42222
  init_permission_stdio();
42223
+ init_claude_history();
42186
42224
 
42187
42225
  // src/ipc-recorder.ts
42188
- var import_node_fs4 = __toESM(require("fs"), 1);
42189
- var import_node_path4 = __toESM(require("path"), 1);
42226
+ var import_node_fs5 = __toESM(require("fs"), 1);
42227
+ var import_node_path5 = __toESM(require("path"), 1);
42190
42228
  function tsForFilename(ms) {
42191
42229
  return new Date(ms).toISOString().replace(/[:.]/g, "-");
42192
42230
  }
@@ -42197,8 +42235,8 @@ function startRecorder(opts) {
42197
42235
  return null;
42198
42236
  }
42199
42237
  const now = opts.now ?? Date.now;
42200
- const dir = import_node_path4.default.join(opts.dataDir, "ipc-recordings", opts.sessionId);
42201
- const filePath = import_node_path4.default.join(dir, `${tsForFilename(now())}.jsonl`);
42238
+ const dir = import_node_path5.default.join(opts.dataDir, "ipc-recordings", opts.sessionId);
42239
+ const filePath = import_node_path5.default.join(dir, `${tsForFilename(now())}.jsonl`);
42202
42240
  let stream = null;
42203
42241
  let closedResolve;
42204
42242
  const closed = new Promise((resolve6) => {
@@ -42207,8 +42245,8 @@ function startRecorder(opts) {
42207
42245
  let exited = false;
42208
42246
  const ensureStream = () => {
42209
42247
  if (stream) return stream;
42210
- import_node_fs4.default.mkdirSync(dir, { recursive: true });
42211
- stream = import_node_fs4.default.createWriteStream(filePath, { flags: "a" });
42248
+ import_node_fs5.default.mkdirSync(dir, { recursive: true });
42249
+ stream = import_node_fs5.default.createWriteStream(filePath, { flags: "a" });
42212
42250
  stream.on("close", () => closedResolve());
42213
42251
  return stream;
42214
42252
  };
@@ -42253,6 +42291,7 @@ function encodeAllowWithInputControlResponse(requestId, updatedInput) {
42253
42291
  return JSON.stringify(payload) + "\n";
42254
42292
  }
42255
42293
  var DEFAULT_WAIT_STOP_TIMEOUT_MS = 3e3;
42294
+ var SUBAGENT_ACTIVE_WINDOW_MS = 3e5;
42256
42295
  var SessionRunner = class {
42257
42296
  constructor(initial, hooks) {
42258
42297
  this.hooks = hooks;
@@ -42564,7 +42603,7 @@ var SessionRunner = class {
42564
42603
  if (existing) clearTimeout(existing);
42565
42604
  const timer = setTimeout(() => {
42566
42605
  this.idleKillTimers.delete(effect.sessionId);
42567
- this.input({ kind: "idle-kill-fired" });
42606
+ this.input({ kind: "idle-kill-fired", subagentActive: this.isSubagentActive() });
42568
42607
  }, effect.ms);
42569
42608
  timer.unref?.();
42570
42609
  this.idleKillTimers.set(effect.sessionId, timer);
@@ -42580,6 +42619,18 @@ var SessionRunner = class {
42580
42619
  }
42581
42620
  }
42582
42621
  }
42622
+ // idle-kill 到点判定:本 session 的 subagents/ 里是否还有 agent-*.jsonl 在近期写盘。
42623
+ // 新鲜(近 SUBAGENT_ACTIVE_WINDOW_MS 内有写)= 后台 subagent 还在干活 → 不该杀。
42624
+ // 没有 toolSessionId(SDK 模式 CC 内生 id)/ 无目录 / 无 agent 文件 → false(照常回收)。
42625
+ isSubagentActive() {
42626
+ const toolSessionId = this.state.file.toolSessionId;
42627
+ if (!toolSessionId) return false;
42628
+ const projectsRoot = import_node_path6.default.join(this.hooks.home ?? import_node_os4.default.homedir(), ".claude", "projects");
42629
+ const mtime = newestSubagentMtimeMs(projectsRoot, this.state.file.cwd, toolSessionId);
42630
+ if (mtime === null) return false;
42631
+ const now = (this.hooks.now ?? Date.now)();
42632
+ return now - mtime < SUBAGENT_ACTIVE_WINDOW_MS;
42633
+ }
42583
42634
  // 清空所有 idle-kill timer(runner dispose / proc 永久退出时调用)。
42584
42635
  // 不喂 idle-kill-fired —— dispose 路径不再翻 reducer 状态
42585
42636
  clearIdleKillTimers() {
@@ -42662,15 +42713,15 @@ function extractEditPath(input) {
42662
42713
  }
42663
42714
 
42664
42715
  // src/debug/pty-probe.ts
42665
- var import_node_fs5 = __toESM(require("fs"), 1);
42666
- var import_node_path5 = __toESM(require("path"), 1);
42716
+ var import_node_fs6 = __toESM(require("fs"), 1);
42717
+ var import_node_path7 = __toESM(require("path"), 1);
42667
42718
  var PROBE_DIR = "/tmp/clawd-probe";
42668
- var EVENTS_FILE = import_node_path5.default.join(PROBE_DIR, "events.jsonl");
42719
+ var EVENTS_FILE = import_node_path7.default.join(PROBE_DIR, "events.jsonl");
42669
42720
  var inited = false;
42670
42721
  function ensureDir() {
42671
42722
  if (inited) return true;
42672
42723
  try {
42673
- import_node_fs5.default.mkdirSync(PROBE_DIR, { recursive: true });
42724
+ import_node_fs6.default.mkdirSync(PROBE_DIR, { recursive: true });
42674
42725
  inited = true;
42675
42726
  return true;
42676
42727
  } catch {
@@ -42681,15 +42732,15 @@ function probeEvent(event, data = {}) {
42681
42732
  try {
42682
42733
  if (!ensureDir()) return;
42683
42734
  const line = JSON.stringify({ ts: Date.now(), event, ...data }) + "\n";
42684
- import_node_fs5.default.appendFileSync(EVENTS_FILE, line);
42735
+ import_node_fs6.default.appendFileSync(EVENTS_FILE, line);
42685
42736
  } catch {
42686
42737
  }
42687
42738
  }
42688
42739
  function probeDumpReplay(sessionId, payload) {
42689
42740
  try {
42690
42741
  if (!ensureDir()) return "";
42691
- const file = import_node_path5.default.join(PROBE_DIR, `replay-${sessionId}-${Date.now()}.ans`);
42692
- import_node_fs5.default.writeFileSync(file, payload, "utf8");
42742
+ const file = import_node_path7.default.join(PROBE_DIR, `replay-${sessionId}-${Date.now()}.ans`);
42743
+ import_node_fs6.default.writeFileSync(file, payload, "utf8");
42693
42744
  return file;
42694
42745
  } catch {
42695
42746
  return "";
@@ -42796,7 +42847,7 @@ function derivePersonaSpawnCwd(file, personaRoot) {
42796
42847
  `derivePersonaSpawnCwd: personaRoot missing for owner session ${file.sessionId} (ownerPersonaId=${personaId})`
42797
42848
  );
42798
42849
  }
42799
- return import_node_path6.default.join(personaRoot, safeFileName(personaId));
42850
+ return import_node_path8.default.join(personaRoot, safeFileName(personaId));
42800
42851
  }
42801
42852
  function makeInitialState(file, subSessionMeta) {
42802
42853
  return {
@@ -42921,10 +42972,10 @@ var SessionManager = class {
42921
42972
  // <dataDir>/sessions/ 列子目录 (排除 'default').
42922
42973
  listPersonaIdsOnDisk() {
42923
42974
  if (!this.deps.dataDir) return [];
42924
- const root = this.deps.storeFactory ? import_node_path6.default.join(this.deps.dataDir, "personas") : import_node_path6.default.join(this.deps.dataDir, "sessions");
42975
+ const root = this.deps.storeFactory ? import_node_path8.default.join(this.deps.dataDir, "personas") : import_node_path8.default.join(this.deps.dataDir, "sessions");
42925
42976
  let entries;
42926
42977
  try {
42927
- entries = import_node_fs6.default.readdirSync(root, { withFileTypes: true });
42978
+ entries = import_node_fs7.default.readdirSync(root, { withFileTypes: true });
42928
42979
  } catch (err) {
42929
42980
  const code = err?.code;
42930
42981
  if (code === "ENOENT") return [];
@@ -42937,7 +42988,7 @@ var SessionManager = class {
42937
42988
  // 只在 storeFactory 注入 (新布局) 下生效, 老布局无 guest 目录.
42938
42989
  listGuestCapIdsForPersona(personaId) {
42939
42990
  if (!this.deps.dataDir || !this.deps.storeFactory) return [];
42940
- const root = import_node_path6.default.join(
42991
+ const root = import_node_path8.default.join(
42941
42992
  this.deps.dataDir,
42942
42993
  "personas",
42943
42994
  personaId,
@@ -42947,7 +42998,7 @@ var SessionManager = class {
42947
42998
  );
42948
42999
  let entries;
42949
43000
  try {
42950
- entries = import_node_fs6.default.readdirSync(root, { withFileTypes: true });
43001
+ entries = import_node_fs7.default.readdirSync(root, { withFileTypes: true });
42951
43002
  } catch (err) {
42952
43003
  const code = err?.code;
42953
43004
  if (code === "ENOENT") return [];
@@ -43066,7 +43117,7 @@ var SessionManager = class {
43066
43117
  callerDisplayName
43067
43118
  );
43068
43119
  if (subSessionMeta?.userWorkDir) {
43069
- import_node_fs6.default.mkdirSync(subSessionMeta.userWorkDir, { recursive: true });
43120
+ import_node_fs7.default.mkdirSync(subSessionMeta.userWorkDir, { recursive: true });
43070
43121
  }
43071
43122
  if (scope.kind === "persona" && scope.mode === "guest") {
43072
43123
  if (!this.deps.personaRoot || !subSessionMeta?.userWorkDir) {
@@ -43077,8 +43128,8 @@ var SessionManager = class {
43077
43128
  const base = this.deps.personaStore?.readSandboxSettings(scope.personaId) ?? null;
43078
43129
  const settings = composeGuestSandbox(base, subSessionMeta.userWorkDir, file.cwd);
43079
43130
  subSessionMeta.extraSettings = JSON.stringify(settings);
43080
- const home = import_node_os3.default.homedir();
43081
- const expand = (p2) => p2 === "~" ? home : p2.startsWith("~/") ? import_node_path6.default.join(home, p2.slice(2)) : p2;
43131
+ const home = import_node_os5.default.homedir();
43132
+ const expand = (p2) => p2 === "~" ? home : p2.startsWith("~/") ? import_node_path8.default.join(home, p2.slice(2)) : p2;
43082
43133
  const codexCfg = this.deps.personaStore?.readCodexSandboxSettings(scope.personaId) ?? null;
43083
43134
  subSessionMeta.codexSandbox = {
43084
43135
  writableRoots: [subSessionMeta.userWorkDir, ...(codexCfg?.writableRoots ?? []).map(expand)],
@@ -43230,7 +43281,7 @@ var SessionManager = class {
43230
43281
  throw new ClawdError(ERROR_CODES.INVALID_CWD, "cwd required when ownerPersonaId is absent");
43231
43282
  }
43232
43283
  try {
43233
- const stat = import_node_fs6.default.statSync(cwd);
43284
+ const stat = import_node_fs7.default.statSync(cwd);
43234
43285
  if (!stat.isDirectory()) throw new Error("not dir");
43235
43286
  } catch {
43236
43287
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${cwd}`);
@@ -43761,7 +43812,7 @@ var SessionManager = class {
43761
43812
  */
43762
43813
  createForScope(args) {
43763
43814
  try {
43764
- const stat = import_node_fs6.default.statSync(args.cwd);
43815
+ const stat = import_node_fs7.default.statSync(args.cwd);
43765
43816
  if (!stat.isDirectory()) throw new Error("not dir");
43766
43817
  } catch {
43767
43818
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${args.cwd}`);
@@ -43977,7 +44028,7 @@ var SessionManager = class {
43977
44028
  personaId: args.targetPersona,
43978
44029
  mode: "owner"
43979
44030
  };
43980
- const cwd = import_node_path6.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
44031
+ const cwd = import_node_path8.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
43981
44032
  const now = (/* @__PURE__ */ new Date()).toISOString();
43982
44033
  const file = {
43983
44034
  sessionId,
@@ -44042,7 +44093,7 @@ var SessionManager = class {
44042
44093
  personaId: args.targetPersona,
44043
44094
  mode: "owner"
44044
44095
  };
44045
- const cwd = import_node_path6.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
44096
+ const cwd = import_node_path8.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
44046
44097
  const now = (/* @__PURE__ */ new Date()).toISOString();
44047
44098
  const file = {
44048
44099
  sessionId,
@@ -44524,28 +44575,28 @@ var SessionManager = class {
44524
44575
  };
44525
44576
 
44526
44577
  // src/persona/store.ts
44527
- var fs7 = __toESM(require("fs"), 1);
44528
- var path9 = __toESM(require("path"), 1);
44578
+ var fs8 = __toESM(require("fs"), 1);
44579
+ var path11 = __toESM(require("path"), 1);
44529
44580
  init_protocol();
44530
44581
  var PersonaStore = class {
44531
44582
  constructor(root) {
44532
44583
  this.root = root;
44533
- fs7.mkdirSync(root, { recursive: true });
44584
+ fs8.mkdirSync(root, { recursive: true });
44534
44585
  }
44535
44586
  root;
44536
44587
  personaDir(personaId) {
44537
- return path9.join(this.root, safeFileName(personaId));
44588
+ return path11.join(this.root, safeFileName(personaId));
44538
44589
  }
44539
44590
  metaPath(personaId) {
44540
- return path9.join(this.personaDir(personaId), ".clawd", "persona.json");
44591
+ return path11.join(this.personaDir(personaId), ".clawd", "persona.json");
44541
44592
  }
44542
44593
  claudeMdPath(personaId) {
44543
- return path9.join(this.personaDir(personaId), "CLAUDE.md");
44594
+ return path11.join(this.personaDir(personaId), "CLAUDE.md");
44544
44595
  }
44545
44596
  // codex 原生读 cwd 的 AGENTS.md。人格双写镜像:claude 读 CLAUDE.md、codex 读 AGENTS.md,
44546
44597
  // 两份内容恒一致,persona 切 tool 零迁移。
44547
44598
  agentsMdPath(personaId) {
44548
- return path9.join(this.personaDir(personaId), "AGENTS.md");
44599
+ return path11.join(this.personaDir(personaId), "AGENTS.md");
44549
44600
  }
44550
44601
  /**
44551
44602
  * persona 级 sandbox base 落盘路径 —— 故意放 `.clawd/` 而非 `.claude/`,让 CC 的 project
@@ -44554,11 +44605,11 @@ var PersonaStore = class {
44554
44605
  * spawn 前 per-guest 动态拼到各自 session 目录的那份(base + 强制底座 + 本 guest userWorkDir carve)。
44555
44606
  */
44556
44607
  sandboxSettingsPath(personaId) {
44557
- return path9.join(this.personaDir(personaId), ".clawd", "sandbox-settings.json");
44608
+ return path11.join(this.personaDir(personaId), ".clawd", "sandbox-settings.json");
44558
44609
  }
44559
44610
  write(persona, personality) {
44560
44611
  const dir = this.personaDir(persona.personaId);
44561
- fs7.mkdirSync(path9.join(dir, ".clawd"), { recursive: true });
44612
+ fs8.mkdirSync(path11.join(dir, ".clawd"), { recursive: true });
44562
44613
  this.atomicWrite(this.claudeMdPath(persona.personaId), personality);
44563
44614
  this.atomicWrite(this.agentsMdPath(persona.personaId), personality);
44564
44615
  this.writeSandboxSettings(persona.personaId, buildGuestSettingsV1());
@@ -44577,9 +44628,9 @@ var PersonaStore = class {
44577
44628
  ensureAgentsMirror(personaId) {
44578
44629
  const claudeMd = this.claudeMdPath(personaId);
44579
44630
  const agentsMd = this.agentsMdPath(personaId);
44580
- if (!fs7.existsSync(claudeMd)) return false;
44581
- if (fs7.existsSync(agentsMd)) return false;
44582
- this.atomicWrite(agentsMd, fs7.readFileSync(claudeMd, "utf8"));
44631
+ if (!fs8.existsSync(claudeMd)) return false;
44632
+ if (fs8.existsSync(agentsMd)) return false;
44633
+ this.atomicWrite(agentsMd, fs8.readFileSync(claudeMd, "utf8"));
44583
44634
  return true;
44584
44635
  }
44585
44636
  /**
@@ -44603,22 +44654,22 @@ var PersonaStore = class {
44603
44654
  return { ...s, permissions: { ...s.permissions ?? {}, deny: [...prev, rule] } };
44604
44655
  }
44605
44656
  codexSandboxSettingsPath(personaId) {
44606
- return path9.join(this.personaDir(personaId), ".clawd", "codex-sandbox.json");
44657
+ return path11.join(this.personaDir(personaId), ".clawd", "codex-sandbox.json");
44607
44658
  }
44608
44659
  /** 读 codex-sandbox.json;不存在/损坏 → null。 */
44609
44660
  readCodexSandboxSettings(personaId) {
44610
44661
  const p2 = this.codexSandboxSettingsPath(personaId);
44611
- if (!fs7.existsSync(p2)) return null;
44662
+ if (!fs8.existsSync(p2)) return null;
44612
44663
  try {
44613
- return CodexSandboxSettingsSchema.parse(JSON.parse(fs7.readFileSync(p2, "utf8")));
44664
+ return CodexSandboxSettingsSchema.parse(JSON.parse(fs8.readFileSync(p2, "utf8")));
44614
44665
  } catch {
44615
44666
  return null;
44616
44667
  }
44617
44668
  }
44618
44669
  /** 覆盖写 codex-sandbox.json(seed/migrate 用)。 */
44619
44670
  writeCodexSandboxSettings(personaId, settings) {
44620
- const dir = path9.join(this.personaDir(personaId), ".clawd");
44621
- fs7.mkdirSync(dir, { recursive: true });
44671
+ const dir = path11.join(this.personaDir(personaId), ".clawd");
44672
+ fs8.mkdirSync(dir, { recursive: true });
44622
44673
  this.atomicWrite(this.codexSandboxSettingsPath(personaId), JSON.stringify(settings, null, 2));
44623
44674
  }
44624
44675
  writeMeta(persona) {
@@ -44626,8 +44677,8 @@ var PersonaStore = class {
44626
44677
  }
44627
44678
  read(personaId) {
44628
44679
  const p2 = this.metaPath(personaId);
44629
- if (!fs7.existsSync(p2)) return null;
44630
- const raw = JSON.parse(fs7.readFileSync(p2, "utf8"));
44680
+ if (!fs8.existsSync(p2)) return null;
44681
+ const raw = JSON.parse(fs8.readFileSync(p2, "utf8"));
44631
44682
  if (raw && typeof raw === "object" && "tokenMap" in raw) {
44632
44683
  delete raw.tokenMap;
44633
44684
  this.atomicWrite(p2, JSON.stringify(raw, null, 2));
@@ -44635,13 +44686,13 @@ var PersonaStore = class {
44635
44686
  return PersonaFileSchema.parse(raw);
44636
44687
  }
44637
44688
  has(personaId) {
44638
- return fs7.existsSync(this.metaPath(personaId));
44689
+ return fs8.existsSync(this.metaPath(personaId));
44639
44690
  }
44640
44691
  readPersonality(personaId) {
44641
44692
  const claudeMd = this.claudeMdPath(personaId);
44642
- if (fs7.existsSync(claudeMd)) return fs7.readFileSync(claudeMd, "utf8");
44693
+ if (fs8.existsSync(claudeMd)) return fs8.readFileSync(claudeMd, "utf8");
44643
44694
  const agentsMd = this.agentsMdPath(personaId);
44644
- if (fs7.existsSync(agentsMd)) return fs7.readFileSync(agentsMd, "utf8");
44695
+ if (fs8.existsSync(agentsMd)) return fs8.readFileSync(agentsMd, "utf8");
44645
44696
  return null;
44646
44697
  }
44647
44698
  /**
@@ -44650,23 +44701,23 @@ var PersonaStore = class {
44650
44701
  */
44651
44702
  readSandboxSettings(personaId) {
44652
44703
  const p2 = this.sandboxSettingsPath(personaId);
44653
- if (!fs7.existsSync(p2)) return null;
44704
+ if (!fs8.existsSync(p2)) return null;
44654
44705
  try {
44655
- return JSON.parse(fs7.readFileSync(p2, "utf8"));
44706
+ return JSON.parse(fs8.readFileSync(p2, "utf8"));
44656
44707
  } catch {
44657
44708
  return null;
44658
44709
  }
44659
44710
  }
44660
44711
  /** Persona 私有 skills 目录路径:<personaDir>/.claude/skills */
44661
44712
  skillsDir(personaId) {
44662
- return path9.join(this.personaDir(personaId), ".claude", "skills");
44713
+ return path11.join(this.personaDir(personaId), ".claude", "skills");
44663
44714
  }
44664
44715
  /**
44665
44716
  * Claude Code 项目级 settings 路径:`<personaDir>/.claude/settings.json`。
44666
44717
  * 这里只读 `enabledPlugins` 字段,由 owner 通过 CC `/plugin` 之类命令维护,daemon 不写。
44667
44718
  */
44668
44719
  claudeSettingsPath(personaId) {
44669
- return path9.join(this.personaDir(personaId), ".claude", "settings.json");
44720
+ return path11.join(this.personaDir(personaId), ".claude", "settings.json");
44670
44721
  }
44671
44722
  /**
44672
44723
  * 读取 persona 的 `.claude/settings.json` 中 `enabledPlugins` map,把 value === true
@@ -44681,10 +44732,10 @@ var PersonaStore = class {
44681
44732
  */
44682
44733
  readEnabledPlugins(personaId) {
44683
44734
  const p2 = this.claudeSettingsPath(personaId);
44684
- if (!fs7.existsSync(p2)) return [];
44735
+ if (!fs8.existsSync(p2)) return [];
44685
44736
  let raw;
44686
44737
  try {
44687
- raw = JSON.parse(fs7.readFileSync(p2, "utf8"));
44738
+ raw = JSON.parse(fs8.readFileSync(p2, "utf8"));
44688
44739
  } catch {
44689
44740
  return [];
44690
44741
  }
@@ -44698,22 +44749,22 @@ var PersonaStore = class {
44698
44749
  return out;
44699
44750
  }
44700
44751
  list() {
44701
- if (!fs7.existsSync(this.root)) return [];
44702
- return fs7.readdirSync(this.root).filter((name) => {
44703
- return fs7.existsSync(path9.join(this.root, name, ".clawd", "persona.json"));
44752
+ if (!fs8.existsSync(this.root)) return [];
44753
+ return fs8.readdirSync(this.root).filter((name) => {
44754
+ return fs8.existsSync(path11.join(this.root, name, ".clawd", "persona.json"));
44704
44755
  });
44705
44756
  }
44706
44757
  remove(personaId) {
44707
44758
  const dir = this.personaDir(personaId);
44708
- if (fs7.existsSync(dir)) fs7.rmSync(dir, { recursive: true, force: true });
44759
+ if (fs8.existsSync(dir)) fs8.rmSync(dir, { recursive: true, force: true });
44709
44760
  }
44710
44761
  personaDirPath(personaId) {
44711
44762
  return this.personaDir(personaId);
44712
44763
  }
44713
44764
  atomicWrite(file, content) {
44714
44765
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
44715
- fs7.writeFileSync(tmp, content, { mode: 384 });
44716
- fs7.renameSync(tmp, file);
44766
+ fs8.writeFileSync(tmp, content, { mode: 384 });
44767
+ fs8.renameSync(tmp, file);
44717
44768
  }
44718
44769
  };
44719
44770
 
@@ -44759,9 +44810,9 @@ var PersonaRegistry = class {
44759
44810
  var import_node_crypto3 = __toESM(require("crypto"), 1);
44760
44811
 
44761
44812
  // src/skills/scanner.ts
44762
- var import_node_fs7 = __toESM(require("fs"), 1);
44763
- var import_node_os4 = __toESM(require("os"), 1);
44764
- var import_node_path7 = __toESM(require("path"), 1);
44813
+ var import_node_fs8 = __toESM(require("fs"), 1);
44814
+ var import_node_os6 = __toESM(require("os"), 1);
44815
+ var import_node_path9 = __toESM(require("path"), 1);
44765
44816
 
44766
44817
  // src/skills/frontmatter.ts
44767
44818
  var STRIP_QUOTES = /^["']|["']$/g;
@@ -44870,7 +44921,7 @@ function parseDescription(content) {
44870
44921
  }
44871
44922
  function isDirLikeSync(p2) {
44872
44923
  try {
44873
- return import_node_fs7.default.statSync(p2).isDirectory();
44924
+ return import_node_fs8.default.statSync(p2).isDirectory();
44874
44925
  } catch {
44875
44926
  return false;
44876
44927
  }
@@ -44878,19 +44929,19 @@ function isDirLikeSync(p2) {
44878
44929
  function scanSkillDir(dir, source, seen, out, pluginName) {
44879
44930
  let entries;
44880
44931
  try {
44881
- entries = import_node_fs7.default.readdirSync(dir, { withFileTypes: true });
44932
+ entries = import_node_fs8.default.readdirSync(dir, { withFileTypes: true });
44882
44933
  } catch {
44883
44934
  return;
44884
44935
  }
44885
44936
  for (const ent of entries) {
44886
- const entryPath = import_node_path7.default.join(dir, ent.name);
44937
+ const entryPath = import_node_path9.default.join(dir, ent.name);
44887
44938
  if (!ent.isDirectory() && !(ent.isSymbolicLink() && isDirLikeSync(entryPath))) continue;
44888
44939
  let content;
44889
44940
  try {
44890
- content = import_node_fs7.default.readFileSync(import_node_path7.default.join(entryPath, "SKILL.md"), "utf8");
44941
+ content = import_node_fs8.default.readFileSync(import_node_path9.default.join(entryPath, "SKILL.md"), "utf8");
44891
44942
  } catch {
44892
44943
  try {
44893
- content = import_node_fs7.default.readFileSync(import_node_path7.default.join(entryPath, "skill.md"), "utf8");
44944
+ content = import_node_fs8.default.readFileSync(import_node_path9.default.join(entryPath, "skill.md"), "utf8");
44894
44945
  } catch {
44895
44946
  continue;
44896
44947
  }
@@ -44914,26 +44965,26 @@ function listSkillsForDir(dir, source) {
44914
44965
  function scanCommandDir(dir, source, seen, out, pluginName) {
44915
44966
  let entries;
44916
44967
  try {
44917
- entries = import_node_fs7.default.readdirSync(dir, { withFileTypes: true });
44968
+ entries = import_node_fs8.default.readdirSync(dir, { withFileTypes: true });
44918
44969
  } catch {
44919
44970
  return;
44920
44971
  }
44921
44972
  for (const ent of entries) {
44922
- const entryPath = import_node_path7.default.join(dir, ent.name);
44973
+ const entryPath = import_node_path9.default.join(dir, ent.name);
44923
44974
  if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync(entryPath)) {
44924
44975
  const ns = ent.name;
44925
44976
  let subEntries;
44926
44977
  try {
44927
- subEntries = import_node_fs7.default.readdirSync(entryPath, { withFileTypes: true });
44978
+ subEntries = import_node_fs8.default.readdirSync(entryPath, { withFileTypes: true });
44928
44979
  } catch {
44929
44980
  continue;
44930
44981
  }
44931
44982
  for (const se of subEntries) {
44932
44983
  if (!se.name.endsWith(".md")) continue;
44933
- const sePath = import_node_path7.default.join(entryPath, se.name);
44984
+ const sePath = import_node_path9.default.join(entryPath, se.name);
44934
44985
  let content;
44935
44986
  try {
44936
- content = import_node_fs7.default.readFileSync(sePath, "utf8");
44987
+ content = import_node_fs8.default.readFileSync(sePath, "utf8");
44937
44988
  } catch {
44938
44989
  continue;
44939
44990
  }
@@ -44950,7 +45001,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
44950
45001
  } else if (ent.name.endsWith(".md")) {
44951
45002
  let content;
44952
45003
  try {
44953
- content = import_node_fs7.default.readFileSync(entryPath, "utf8");
45004
+ content = import_node_fs8.default.readFileSync(entryPath, "utf8");
44954
45005
  } catch {
44955
45006
  continue;
44956
45007
  }
@@ -44966,10 +45017,10 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
44966
45017
  }
44967
45018
  }
44968
45019
  function readInstalledPlugins(home) {
44969
- const file = import_node_path7.default.join(home, ".claude", "plugins", "installed_plugins.json");
45020
+ const file = import_node_path9.default.join(home, ".claude", "plugins", "installed_plugins.json");
44970
45021
  let raw;
44971
45022
  try {
44972
- raw = import_node_fs7.default.readFileSync(file, "utf8");
45023
+ raw = import_node_fs8.default.readFileSync(file, "utf8");
44973
45024
  } catch {
44974
45025
  return [];
44975
45026
  }
@@ -44994,7 +45045,7 @@ var SkillsScanner = class {
44994
45045
  home;
44995
45046
  extraPluginRoots;
44996
45047
  constructor(opts = {}) {
44997
- this.home = opts.home ?? import_node_os4.default.homedir();
45048
+ this.home = opts.home ?? import_node_os6.default.homedir();
44998
45049
  this.extraPluginRoots = opts.extraPluginRoots ?? [];
44999
45050
  }
45000
45051
  /**
@@ -45017,14 +45068,14 @@ var SkillsScanner = class {
45017
45068
  });
45018
45069
  }
45019
45070
  const fsBlock = [];
45020
- scanSkillDir(import_node_path7.default.join(this.home, ".claude", "skills"), "global", seen, fsBlock);
45021
- scanCommandDir(import_node_path7.default.join(this.home, ".claude", "commands"), "global", seen, fsBlock);
45022
- scanSkillDir(import_node_path7.default.join(args.cwd, ".claude", "skills"), "project", seen, fsBlock);
45023
- scanCommandDir(import_node_path7.default.join(args.cwd, ".claude", "commands"), "project", seen, fsBlock);
45071
+ scanSkillDir(import_node_path9.default.join(this.home, ".claude", "skills"), "global", seen, fsBlock);
45072
+ scanCommandDir(import_node_path9.default.join(this.home, ".claude", "commands"), "global", seen, fsBlock);
45073
+ scanSkillDir(import_node_path9.default.join(args.cwd, ".claude", "skills"), "project", seen, fsBlock);
45074
+ scanCommandDir(import_node_path9.default.join(args.cwd, ".claude", "commands"), "project", seen, fsBlock);
45024
45075
  const plugins = [...readInstalledPlugins(this.home), ...this.extraPluginRoots];
45025
45076
  for (const { name, root } of plugins) {
45026
- scanSkillDir(import_node_path7.default.join(root, "skills"), "plugin", seen, fsBlock, name);
45027
- scanCommandDir(import_node_path7.default.join(root, "commands"), "plugin", seen, fsBlock, name);
45077
+ scanSkillDir(import_node_path9.default.join(root, "skills"), "plugin", seen, fsBlock, name);
45078
+ scanCommandDir(import_node_path9.default.join(root, "commands"), "plugin", seen, fsBlock, name);
45028
45079
  }
45029
45080
  fsBlock.sort((a, b2) => a.name < b2.name ? -1 : a.name > b2.name ? 1 : 0);
45030
45081
  return [...builtinBlock, ...fsBlock];
@@ -45130,8 +45181,8 @@ var PersonaManager = class {
45130
45181
  };
45131
45182
 
45132
45183
  // src/persona/seed.ts
45133
- var fs9 = __toESM(require("fs"), 1);
45134
- var path11 = __toESM(require("path"), 1);
45184
+ var fs10 = __toESM(require("fs"), 1);
45185
+ var path13 = __toESM(require("path"), 1);
45135
45186
  var import_node_url = require("url");
45136
45187
  var import_meta = {};
45137
45188
  var DEFAULT_BYPASS_PROFILE = {
@@ -45301,24 +45352,24 @@ function bundleSiblingFromArgv(argv1, sibling) {
45301
45352
  if (!argv1) return null;
45302
45353
  let real = argv1;
45303
45354
  try {
45304
- real = fs9.realpathSync(argv1);
45355
+ real = fs10.realpathSync(argv1);
45305
45356
  } catch {
45306
45357
  }
45307
- return path11.resolve(path11.dirname(real), sibling);
45358
+ return path13.resolve(path13.dirname(real), sibling);
45308
45359
  }
45309
45360
  function findDefaultsRoot(logger) {
45310
45361
  const candidates = [];
45311
45362
  try {
45312
- const here = path11.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
45313
- candidates.push(path11.resolve(here, "defaults"));
45314
- candidates.push(path11.resolve(here, "persona-defaults"));
45363
+ const here = path13.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
45364
+ candidates.push(path13.resolve(here, "defaults"));
45365
+ candidates.push(path13.resolve(here, "persona-defaults"));
45315
45366
  } catch {
45316
45367
  }
45317
45368
  const fromArgv = bundleSiblingFromArgv(process.argv[1], "persona-defaults");
45318
45369
  if (fromArgv) candidates.push(fromArgv);
45319
45370
  for (const c of candidates) {
45320
45371
  try {
45321
- if (fs9.statSync(c).isDirectory()) {
45372
+ if (fs10.statSync(c).isDirectory()) {
45322
45373
  logger?.info("persona.defaults-root.resolved", { root: c });
45323
45374
  return c;
45324
45375
  }
@@ -45335,8 +45386,8 @@ function seedDefaultPersonas(args) {
45335
45386
  args.logger.info("persona.seed.skip", { personaId: entry.personaId, reason: "exists" });
45336
45387
  continue;
45337
45388
  }
45338
- const bundleDir = path11.join(args.defaultsRoot, entry.personaId);
45339
- if (!fs9.existsSync(bundleDir)) {
45389
+ const bundleDir = path13.join(args.defaultsRoot, entry.personaId);
45390
+ if (!fs10.existsSync(bundleDir)) {
45340
45391
  args.logger.warn("persona.seed.skip", {
45341
45392
  personaId: entry.personaId,
45342
45393
  reason: "bundle-missing",
@@ -45344,8 +45395,8 @@ function seedDefaultPersonas(args) {
45344
45395
  });
45345
45396
  continue;
45346
45397
  }
45347
- const claudeMdPath = path11.join(bundleDir, "CLAUDE.md");
45348
- if (!fs9.existsSync(claudeMdPath)) {
45398
+ const claudeMdPath = path13.join(bundleDir, "CLAUDE.md");
45399
+ if (!fs10.existsSync(claudeMdPath)) {
45349
45400
  args.logger.warn("persona.seed.skip", {
45350
45401
  personaId: entry.personaId,
45351
45402
  reason: "no-CLAUDE.md",
@@ -45353,7 +45404,7 @@ function seedDefaultPersonas(args) {
45353
45404
  });
45354
45405
  continue;
45355
45406
  }
45356
- const personality = fs9.readFileSync(claudeMdPath, "utf8");
45407
+ const personality = fs10.readFileSync(claudeMdPath, "utf8");
45357
45408
  const now = Date.now();
45358
45409
  const persona = {
45359
45410
  personaId: entry.personaId,
@@ -45379,17 +45430,17 @@ function seedDefaultPersonas(args) {
45379
45430
  }
45380
45431
  }
45381
45432
  function skipNodeModulesUnder(srcRoot) {
45382
- return (src) => !path11.relative(srcRoot, src).split(path11.sep).includes("node_modules");
45433
+ return (src) => !path13.relative(srcRoot, src).split(path13.sep).includes("node_modules");
45383
45434
  }
45384
45435
  function copyBundleExtras(srcDir, dstDir) {
45385
- for (const entry of fs9.readdirSync(srcDir, { withFileTypes: true })) {
45436
+ for (const entry of fs10.readdirSync(srcDir, { withFileTypes: true })) {
45386
45437
  if (entry.name === "CLAUDE.md" || entry.name === ".clawd") continue;
45387
- const srcPath = path11.join(srcDir, entry.name);
45388
- const dstPath = path11.join(dstDir, entry.name);
45438
+ const srcPath = path13.join(srcDir, entry.name);
45439
+ const dstPath = path13.join(dstDir, entry.name);
45389
45440
  if (entry.isDirectory()) {
45390
- fs9.cpSync(srcPath, dstPath, { recursive: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
45441
+ fs10.cpSync(srcPath, dstPath, { recursive: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
45391
45442
  } else if (entry.isFile()) {
45392
- fs9.copyFileSync(srcPath, dstPath);
45443
+ fs10.copyFileSync(srcPath, dstPath);
45393
45444
  }
45394
45445
  }
45395
45446
  }
@@ -45397,16 +45448,16 @@ var DAEMON_MANAGED_PATHS = ["extension-kit", "CLAUDE.md", ".mcp.json"];
45397
45448
  function refreshDaemonManagedDirs(args) {
45398
45449
  const entries = args.entries ?? DEFAULT_PERSONAS;
45399
45450
  for (const entry of entries) {
45400
- const bundleDir = path11.join(args.defaultsRoot, entry.personaId);
45401
- if (!fs9.existsSync(bundleDir)) continue;
45451
+ const bundleDir = path13.join(args.defaultsRoot, entry.personaId);
45452
+ if (!fs10.existsSync(bundleDir)) continue;
45402
45453
  const personaDir = args.store.personaDirPath(entry.personaId);
45403
- if (!fs9.existsSync(personaDir)) continue;
45454
+ if (!fs10.existsSync(personaDir)) continue;
45404
45455
  for (const relPath of DAEMON_MANAGED_PATHS) {
45405
- const srcPath = path11.join(bundleDir, relPath);
45406
- if (!fs9.existsSync(srcPath)) continue;
45407
- const dstPath = path11.join(personaDir, relPath);
45456
+ const srcPath = path13.join(bundleDir, relPath);
45457
+ if (!fs10.existsSync(srcPath)) continue;
45458
+ const dstPath = path13.join(personaDir, relPath);
45408
45459
  try {
45409
- fs9.cpSync(srcPath, dstPath, { recursive: true, force: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
45460
+ fs10.cpSync(srcPath, dstPath, { recursive: true, force: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
45410
45461
  args.logger.info("persona.refresh.synced", {
45411
45462
  personaId: entry.personaId,
45412
45463
  path: relPath
@@ -45466,15 +45517,15 @@ function migrateCodexSandbox(args) {
45466
45517
  function findDeployKitRoot(logger) {
45467
45518
  const candidates = [];
45468
45519
  try {
45469
- const here = path11.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
45470
- candidates.push(path11.resolve(here, "..", "deploy-kit"));
45520
+ const here = path13.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
45521
+ candidates.push(path13.resolve(here, "..", "deploy-kit"));
45471
45522
  } catch {
45472
45523
  }
45473
45524
  const fromArgv = bundleSiblingFromArgv(process.argv[1], "deploy-kit");
45474
45525
  if (fromArgv) candidates.push(fromArgv);
45475
45526
  for (const c of candidates) {
45476
45527
  try {
45477
- if (fs9.statSync(c).isDirectory()) {
45528
+ if (fs10.statSync(c).isDirectory()) {
45478
45529
  logger?.info("persona.deploy-kit-root.resolved", { root: c });
45479
45530
  return c;
45480
45531
  }
@@ -45485,8 +45536,8 @@ function findDeployKitRoot(logger) {
45485
45536
  return null;
45486
45537
  }
45487
45538
  function seedDeployKit(args) {
45488
- const dst = path11.join(args.dataDir, "deploy-kit");
45489
- fs9.cpSync(args.deployKitBundleRoot, dst, {
45539
+ const dst = path13.join(args.dataDir, "deploy-kit");
45540
+ fs10.cpSync(args.deployKitBundleRoot, dst, {
45490
45541
  recursive: true,
45491
45542
  dereference: true,
45492
45543
  force: false,
@@ -45495,35 +45546,35 @@ function seedDeployKit(args) {
45495
45546
  args.logger.info("deploy-kit.seed.done", { dst });
45496
45547
  }
45497
45548
  function refreshDeployKit(args) {
45498
- const dst = path11.join(args.dataDir, "deploy-kit");
45499
- if (!fs9.existsSync(dst)) {
45549
+ const dst = path13.join(args.dataDir, "deploy-kit");
45550
+ if (!fs10.existsSync(dst)) {
45500
45551
  seedDeployKit(args);
45501
45552
  return;
45502
45553
  }
45503
45554
  for (const sub of ["scripts", "contract"]) {
45504
- const s = path11.join(args.deployKitBundleRoot, sub);
45505
- if (fs9.existsSync(s)) {
45506
- fs9.cpSync(s, path11.join(dst, sub), { recursive: true, force: true, dereference: true });
45555
+ const s = path13.join(args.deployKitBundleRoot, sub);
45556
+ if (fs10.existsSync(s)) {
45557
+ fs10.cpSync(s, path13.join(dst, sub), { recursive: true, force: true, dereference: true });
45507
45558
  }
45508
45559
  }
45509
- const secretsSrc = path11.join(args.deployKitBundleRoot, ".secrets");
45510
- if (fs9.existsSync(secretsSrc)) {
45511
- fs9.mkdirSync(path11.join(dst, ".secrets"), { recursive: true });
45512
- for (const f of fs9.readdirSync(secretsSrc)) {
45560
+ const secretsSrc = path13.join(args.deployKitBundleRoot, ".secrets");
45561
+ if (fs10.existsSync(secretsSrc)) {
45562
+ fs10.mkdirSync(path13.join(dst, ".secrets"), { recursive: true });
45563
+ for (const f of fs10.readdirSync(secretsSrc)) {
45513
45564
  if (!f.endsWith(".example")) continue;
45514
- fs9.copyFileSync(path11.join(secretsSrc, f), path11.join(dst, ".secrets", f));
45565
+ fs10.copyFileSync(path13.join(secretsSrc, f), path13.join(dst, ".secrets", f));
45515
45566
  }
45516
45567
  }
45517
45568
  args.logger.info("deploy-kit.refresh.done", { dst });
45518
45569
  }
45519
45570
 
45520
45571
  // src/share-md-viewer/load.ts
45521
- var import_node_fs9 = __toESM(require("fs"), 1);
45522
- var import_node_path8 = __toESM(require("path"), 1);
45572
+ var import_node_fs10 = __toESM(require("fs"), 1);
45573
+ var import_node_path10 = __toESM(require("path"), 1);
45523
45574
  var import_node_url2 = require("url");
45524
45575
 
45525
45576
  // src/share-md-viewer/asset-loader.ts
45526
- var import_node_fs8 = __toESM(require("fs"), 1);
45577
+ var import_node_fs9 = __toESM(require("fs"), 1);
45527
45578
  function htmlEscape(s) {
45528
45579
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
45529
45580
  }
@@ -45531,12 +45582,12 @@ function createViewerAssetLoader(opts) {
45531
45582
  let viewerTemplate;
45532
45583
  let errorTemplate;
45533
45584
  try {
45534
- viewerTemplate = import_node_fs8.default.readFileSync(opts.viewerHtmlPath, "utf8");
45585
+ viewerTemplate = import_node_fs9.default.readFileSync(opts.viewerHtmlPath, "utf8");
45535
45586
  } catch (err) {
45536
45587
  throw new Error(`viewer asset not found at ${opts.viewerHtmlPath}: ${err.message}`);
45537
45588
  }
45538
45589
  try {
45539
- errorTemplate = import_node_fs8.default.readFileSync(opts.errorHtmlPath, "utf8");
45590
+ errorTemplate = import_node_fs9.default.readFileSync(opts.errorHtmlPath, "utf8");
45540
45591
  } catch (err) {
45541
45592
  throw new Error(`viewer error asset not found at ${opts.errorHtmlPath}: ${err.message}`);
45542
45593
  }
@@ -45555,25 +45606,25 @@ var import_meta2 = {};
45555
45606
  function tryLoadViewerAssets(logger) {
45556
45607
  const candidates = [];
45557
45608
  try {
45558
- const here = import_node_path8.default.dirname((0, import_node_url2.fileURLToPath)(import_meta2.url));
45609
+ const here = import_node_path10.default.dirname((0, import_node_url2.fileURLToPath)(import_meta2.url));
45559
45610
  candidates.push(here);
45560
- candidates.push(import_node_path8.default.resolve(here, ".."));
45561
- candidates.push(import_node_path8.default.resolve(here, "..", "..", "dist"));
45611
+ candidates.push(import_node_path10.default.resolve(here, ".."));
45612
+ candidates.push(import_node_path10.default.resolve(here, "..", "..", "dist"));
45562
45613
  } catch {
45563
45614
  }
45564
45615
  if (process.argv[1]) {
45565
45616
  let real = process.argv[1];
45566
45617
  try {
45567
- real = import_node_fs9.default.realpathSync(process.argv[1]);
45618
+ real = import_node_fs10.default.realpathSync(process.argv[1]);
45568
45619
  } catch {
45569
45620
  }
45570
- candidates.push(import_node_path8.default.dirname(real));
45621
+ candidates.push(import_node_path10.default.dirname(real));
45571
45622
  }
45572
45623
  for (const root of candidates) {
45573
- const viewerHtmlPath = import_node_path8.default.join(root, "share-md-viewer.html");
45574
- const errorHtmlPath = import_node_path8.default.join(root, "share-md-viewer-error.html");
45624
+ const viewerHtmlPath = import_node_path10.default.join(root, "share-md-viewer.html");
45625
+ const errorHtmlPath = import_node_path10.default.join(root, "share-md-viewer-error.html");
45575
45626
  try {
45576
- if (import_node_fs9.default.statSync(viewerHtmlPath).isFile() && import_node_fs9.default.statSync(errorHtmlPath).isFile()) {
45627
+ if (import_node_fs10.default.statSync(viewerHtmlPath).isFile() && import_node_fs10.default.statSync(errorHtmlPath).isFile()) {
45577
45628
  logger?.info("share-md-viewer.assets-root.resolved", { root });
45578
45629
  return createViewerAssetLoader({ viewerHtmlPath, errorHtmlPath });
45579
45630
  }
@@ -45588,30 +45639,30 @@ function tryLoadViewerAssets(logger) {
45588
45639
  }
45589
45640
 
45590
45641
  // src/share-ui/load.ts
45591
- var import_node_fs11 = __toESM(require("fs"), 1);
45592
- var import_node_path10 = __toESM(require("path"), 1);
45642
+ var import_node_fs12 = __toESM(require("fs"), 1);
45643
+ var import_node_path12 = __toESM(require("path"), 1);
45593
45644
  var import_node_url3 = require("url");
45594
45645
 
45595
45646
  // src/share-ui/asset-loader.ts
45596
- var import_node_fs10 = __toESM(require("fs"), 1);
45597
- var import_node_path9 = __toESM(require("path"), 1);
45647
+ var import_node_fs11 = __toESM(require("fs"), 1);
45648
+ var import_node_path11 = __toESM(require("path"), 1);
45598
45649
  function createShareUiAssetLoader(opts) {
45599
45650
  let indexHtml;
45600
45651
  try {
45601
- indexHtml = import_node_fs10.default.readFileSync(opts.indexHtmlPath, "utf8");
45652
+ indexHtml = import_node_fs11.default.readFileSync(opts.indexHtmlPath, "utf8");
45602
45653
  } catch (err) {
45603
45654
  throw new Error(`share-ui index.html not found at ${opts.indexHtmlPath}: ${err.message}`);
45604
45655
  }
45605
- const assetsDir = import_node_path9.default.resolve(opts.assetsDir);
45656
+ const assetsDir = import_node_path11.default.resolve(opts.assetsDir);
45606
45657
  return {
45607
45658
  renderIndexHtml() {
45608
45659
  return indexHtml;
45609
45660
  },
45610
45661
  resolveAssetPath(rel) {
45611
- const resolved = import_node_path9.default.resolve(assetsDir, rel);
45612
- if (resolved !== assetsDir && !resolved.startsWith(assetsDir + import_node_path9.default.sep)) return null;
45662
+ const resolved = import_node_path11.default.resolve(assetsDir, rel);
45663
+ if (resolved !== assetsDir && !resolved.startsWith(assetsDir + import_node_path11.default.sep)) return null;
45613
45664
  try {
45614
- if (import_node_fs10.default.statSync(resolved).isFile()) return resolved;
45665
+ if (import_node_fs11.default.statSync(resolved).isFile()) return resolved;
45615
45666
  } catch {
45616
45667
  }
45617
45668
  return null;
@@ -45625,28 +45676,28 @@ function bundleDirFromArgv(argv1) {
45625
45676
  if (!argv1) return null;
45626
45677
  let real = argv1;
45627
45678
  try {
45628
- real = import_node_fs11.default.realpathSync(argv1);
45679
+ real = import_node_fs12.default.realpathSync(argv1);
45629
45680
  } catch {
45630
45681
  }
45631
- return import_node_path10.default.dirname(real);
45682
+ return import_node_path12.default.dirname(real);
45632
45683
  }
45633
45684
  function tryLoadShareUi(logger) {
45634
45685
  const candidates = [];
45635
45686
  try {
45636
- const here = import_node_path10.default.dirname((0, import_node_url3.fileURLToPath)(import_meta3.url));
45687
+ const here = import_node_path12.default.dirname((0, import_node_url3.fileURLToPath)(import_meta3.url));
45637
45688
  candidates.push(here);
45638
- candidates.push(import_node_path10.default.resolve(here, ".."));
45639
- candidates.push(import_node_path10.default.resolve(here, "..", "..", "dist"));
45689
+ candidates.push(import_node_path12.default.resolve(here, ".."));
45690
+ candidates.push(import_node_path12.default.resolve(here, "..", "..", "dist"));
45640
45691
  } catch {
45641
45692
  }
45642
45693
  const argvDir = bundleDirFromArgv(process.argv[1]);
45643
45694
  if (argvDir) candidates.push(argvDir);
45644
45695
  for (const root of candidates) {
45645
- const shareUiDir = import_node_path10.default.join(root, "share-ui");
45646
- const indexHtmlPath = import_node_path10.default.join(shareUiDir, "guest.html");
45647
- const assetsDir = import_node_path10.default.join(shareUiDir, "assets");
45696
+ const shareUiDir = import_node_path12.default.join(root, "share-ui");
45697
+ const indexHtmlPath = import_node_path12.default.join(shareUiDir, "guest.html");
45698
+ const assetsDir = import_node_path12.default.join(shareUiDir, "assets");
45648
45699
  try {
45649
- if (import_node_fs11.default.statSync(indexHtmlPath).isFile() && import_node_fs11.default.statSync(assetsDir).isDirectory()) {
45700
+ if (import_node_fs12.default.statSync(indexHtmlPath).isFile() && import_node_fs12.default.statSync(assetsDir).isDirectory()) {
45650
45701
  logger?.info("share-ui.assets-root.resolved", { root: shareUiDir });
45651
45702
  return createShareUiAssetLoader({ indexHtmlPath, assetsDir });
45652
45703
  }
@@ -45728,20 +45779,20 @@ function buildVisitorLogin(deps) {
45728
45779
  }
45729
45780
 
45730
45781
  // src/visitor/visitor-store.ts
45731
- var import_node_fs12 = __toESM(require("fs"), 1);
45732
- var import_node_path11 = __toESM(require("path"), 1);
45782
+ var import_node_fs13 = __toESM(require("fs"), 1);
45783
+ var import_node_path13 = __toESM(require("path"), 1);
45733
45784
  function createVisitorStore(opts) {
45734
- const file = import_node_path11.default.join(opts.dir, "visitors.json");
45785
+ const file = import_node_path13.default.join(opts.dir, "visitors.json");
45735
45786
  const read = () => {
45736
45787
  try {
45737
- return JSON.parse(import_node_fs12.default.readFileSync(file, "utf8"));
45788
+ return JSON.parse(import_node_fs13.default.readFileSync(file, "utf8"));
45738
45789
  } catch {
45739
45790
  return [];
45740
45791
  }
45741
45792
  };
45742
45793
  const write = (rows) => {
45743
- import_node_fs12.default.mkdirSync(opts.dir, { recursive: true });
45744
- import_node_fs12.default.writeFileSync(file, JSON.stringify(rows, null, 2));
45794
+ import_node_fs13.default.mkdirSync(opts.dir, { recursive: true });
45795
+ import_node_fs13.default.writeFileSync(file, JSON.stringify(rows, null, 2));
45745
45796
  };
45746
45797
  return {
45747
45798
  upsert(r) {
@@ -46023,8 +46074,8 @@ function turnStartInput(text) {
46023
46074
  const items = [];
46024
46075
  let leftover = text;
46025
46076
  for (const m2 of text.matchAll(SKILL_RE)) {
46026
- const [marker, name, path66] = m2;
46027
- items.push({ type: "skill", name, path: path66 });
46077
+ const [marker, name, path67] = m2;
46078
+ items.push({ type: "skill", name, path: path67 });
46028
46079
  leftover = leftover.replace(marker, "");
46029
46080
  }
46030
46081
  for (const m2 of text.matchAll(ATTACHMENT_RE2)) {
@@ -46257,8 +46308,8 @@ var CodexAdapter = class {
46257
46308
 
46258
46309
  // src/tools/claude-tui.ts
46259
46310
  var import_node_fs16 = __toESM(require("fs"), 1);
46260
- var import_node_os6 = __toESM(require("os"), 1);
46261
- var import_node_path13 = __toESM(require("path"), 1);
46311
+ var import_node_os7 = __toESM(require("os"), 1);
46312
+ var import_node_path14 = __toESM(require("path"), 1);
46262
46313
  var import_headless = __toESM(require_xterm_headless(), 1);
46263
46314
 
46264
46315
  // ../node_modules/.pnpm/@xterm+addon-serialize@0.14.0/node_modules/@xterm/addon-serialize/lib/addon-serialize.mjs
@@ -47391,8 +47442,8 @@ function buildTuiSpawnArgs(ctx, isResume = false) {
47391
47442
  }
47392
47443
  function jsonlExistsForCtx(ctx) {
47393
47444
  if (!ctx.toolSessionId) return false;
47394
- const home = import_node_os6.default.homedir();
47395
- const file = import_node_path13.default.join(home, ".claude", "projects", cwdToHashDir(ctx.cwd), `${ctx.toolSessionId}.jsonl`);
47445
+ const home = import_node_os7.default.homedir();
47446
+ const file = import_node_path14.default.join(home, ".claude", "projects", cwdToHashDir(ctx.cwd), `${ctx.toolSessionId}.jsonl`);
47396
47447
  try {
47397
47448
  return import_node_fs16.default.statSync(file).isFile();
47398
47449
  } catch {
@@ -47464,9 +47515,9 @@ var PersonaDispatchManager = class {
47464
47515
 
47465
47516
  // src/dispatch/mcp-config.ts
47466
47517
  var import_node_fs17 = __toESM(require("fs"), 1);
47467
- var import_node_path14 = __toESM(require("path"), 1);
47518
+ var import_node_path15 = __toESM(require("path"), 1);
47468
47519
  function dispatchMcpConfigPath(dataDir) {
47469
- return import_node_path14.default.join(dataDir, "dispatch.mcp.json");
47520
+ return import_node_path15.default.join(dataDir, "dispatch.mcp.json");
47470
47521
  }
47471
47522
  function writeDispatchMcpConfig(args) {
47472
47523
  const cfgPath = dispatchMcpConfigPath(args.dataDir);
@@ -47488,9 +47539,9 @@ function writeDispatchMcpConfig(args) {
47488
47539
 
47489
47540
  // src/ticket/mcp-config.ts
47490
47541
  var import_node_fs18 = __toESM(require("fs"), 1);
47491
- var import_node_path15 = __toESM(require("path"), 1);
47542
+ var import_node_path16 = __toESM(require("path"), 1);
47492
47543
  function ticketMcpConfigPath(dataDir) {
47493
- return import_node_path15.default.join(dataDir, "ticket.mcp.json");
47544
+ return import_node_path16.default.join(dataDir, "ticket.mcp.json");
47494
47545
  }
47495
47546
  function writeTicketMcpConfig(args) {
47496
47547
  const cfgPath = ticketMcpConfigPath(args.dataDir);
@@ -47518,9 +47569,9 @@ function writeTicketMcpConfig(args) {
47518
47569
 
47519
47570
  // src/shift/mcp-config.ts
47520
47571
  var import_node_fs19 = __toESM(require("fs"), 1);
47521
- var import_node_path16 = __toESM(require("path"), 1);
47572
+ var import_node_path17 = __toESM(require("path"), 1);
47522
47573
  function shiftMcpConfigPath(dataDir) {
47523
- return import_node_path16.default.join(dataDir, "shift.mcp.json");
47574
+ return import_node_path17.default.join(dataDir, "shift.mcp.json");
47524
47575
  }
47525
47576
  async function writeShiftMcpConfig(args) {
47526
47577
  const cfgPath = shiftMcpConfigPath(args.dataDir);
@@ -47542,7 +47593,7 @@ async function writeShiftMcpConfig(args) {
47542
47593
 
47543
47594
  // src/shift/store.ts
47544
47595
  var import_promises = __toESM(require("fs/promises"), 1);
47545
- var import_node_path17 = __toESM(require("path"), 1);
47596
+ var import_node_path18 = __toESM(require("path"), 1);
47546
47597
  var import_node_crypto5 = require("crypto");
47547
47598
 
47548
47599
  // src/shift/constants.ts
@@ -47611,7 +47662,7 @@ function createShiftStore(deps) {
47611
47662
  flushTimer = null;
47612
47663
  }
47613
47664
  const content = { version: 1, shifts };
47614
- await import_promises.default.mkdir(import_node_path17.default.dirname(deps.filePath), { recursive: true });
47665
+ await import_promises.default.mkdir(import_node_path18.default.dirname(deps.filePath), { recursive: true });
47615
47666
  const tmp = `${deps.filePath}.tmp-${deps.now()}-${Math.floor(Math.random() * 1e6)}`;
47616
47667
  await import_promises.default.writeFile(tmp, JSON.stringify(content, null, 2), "utf8");
47617
47668
  await import_promises.default.rename(tmp, deps.filePath);
@@ -48382,13 +48433,13 @@ function mapSkillsListResponse(res) {
48382
48433
  const r = s ?? {};
48383
48434
  const name = str3(r.name);
48384
48435
  if (!name) continue;
48385
- const path66 = str3(r.path);
48436
+ const path67 = str3(r.path);
48386
48437
  const description = str3(r.description);
48387
48438
  const isPlugin = name.includes(":");
48388
48439
  out.push({
48389
48440
  name,
48390
48441
  source: isPlugin ? "plugin" : "project",
48391
- ...path66 ? { path: path66 } : {},
48442
+ ...path67 ? { path: path67 } : {},
48392
48443
  ...description ? { description } : {},
48393
48444
  ...isPlugin ? { plugin: name.split(":")[0] } : {}
48394
48445
  });
@@ -48428,15 +48479,15 @@ async function listCodexSkills(cwd, deps = {}) {
48428
48479
 
48429
48480
  // src/workspace/browser.ts
48430
48481
  var import_node_fs20 = __toESM(require("fs"), 1);
48431
- var import_node_os7 = __toESM(require("os"), 1);
48432
- var import_node_path18 = __toESM(require("path"), 1);
48482
+ var import_node_os8 = __toESM(require("os"), 1);
48483
+ var import_node_path19 = __toESM(require("path"), 1);
48433
48484
  init_protocol();
48434
48485
  var MAX_FILE_BYTES = 2 * 1024 * 1024;
48435
48486
  function resolveInsideCwd(cwd, subpath) {
48436
- const absCwd = import_node_path18.default.resolve(cwd);
48437
- const joined = import_node_path18.default.resolve(absCwd, subpath ?? ".");
48438
- const rel = import_node_path18.default.relative(absCwd, joined);
48439
- if (rel.startsWith("..") || import_node_path18.default.isAbsolute(rel)) {
48487
+ const absCwd = import_node_path19.default.resolve(cwd);
48488
+ const joined = import_node_path19.default.resolve(absCwd, subpath ?? ".");
48489
+ const rel = import_node_path19.default.relative(absCwd, joined);
48490
+ if (rel.startsWith("..") || import_node_path19.default.isAbsolute(rel)) {
48440
48491
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
48441
48492
  }
48442
48493
  return joined;
@@ -48454,7 +48505,7 @@ function ensureCwd(cwd) {
48454
48505
  }
48455
48506
  var WorkspaceBrowser = class {
48456
48507
  list(args) {
48457
- const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os7.default.homedir();
48508
+ const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os8.default.homedir();
48458
48509
  ensureCwd(cwd);
48459
48510
  const full = resolveInsideCwd(cwd, args.path);
48460
48511
  const dirents = import_node_fs20.default.readdirSync(full, { withFileTypes: true });
@@ -48467,7 +48518,7 @@ var WorkspaceBrowser = class {
48467
48518
  mtime: ""
48468
48519
  };
48469
48520
  try {
48470
- const st = import_node_fs20.default.statSync(import_node_path18.default.join(full, d.name));
48521
+ const st = import_node_fs20.default.statSync(import_node_path19.default.join(full, d.name));
48471
48522
  entry.mtime = new Date(st.mtimeMs).toISOString();
48472
48523
  if (d.isFile()) entry.size = st.size;
48473
48524
  } catch {
@@ -48513,8 +48564,8 @@ var WorkspaceBrowser = class {
48513
48564
 
48514
48565
  // src/skills/agents-scanner.ts
48515
48566
  var import_node_fs21 = __toESM(require("fs"), 1);
48516
- var import_node_os8 = __toESM(require("os"), 1);
48517
- var import_node_path19 = __toESM(require("path"), 1);
48567
+ var import_node_os9 = __toESM(require("os"), 1);
48568
+ var import_node_path20 = __toESM(require("path"), 1);
48518
48569
  var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
48519
48570
  function isDirLikeSync2(p2) {
48520
48571
  try {
@@ -48552,10 +48603,10 @@ function scanAgentsDir(dir, source, seen, out) {
48552
48603
  }
48553
48604
  for (const ent of entries) {
48554
48605
  if (!ent.name.endsWith(".md")) continue;
48555
- if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path19.default.join(dir, ent.name)))) {
48606
+ if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path20.default.join(dir, ent.name)))) {
48556
48607
  continue;
48557
48608
  }
48558
- const filePath = import_node_path19.default.join(dir, ent.name);
48609
+ const filePath = import_node_path20.default.join(dir, ent.name);
48559
48610
  const baseName = ent.name.replace(/\.md$/, "");
48560
48611
  if (seen.has(baseName)) continue;
48561
48612
  seen.add(baseName);
@@ -48578,7 +48629,7 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
48578
48629
  return;
48579
48630
  }
48580
48631
  for (const ent of entries) {
48581
- const childPath = import_node_path19.default.join(dir, ent.name);
48632
+ const childPath = import_node_path20.default.join(dir, ent.name);
48582
48633
  if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
48583
48634
  walk2(childPath, [...namespaces, ent.name]);
48584
48635
  continue;
@@ -48603,9 +48654,9 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
48603
48654
  walk2(root, []);
48604
48655
  }
48605
48656
  function readInstalledPlugins2(home) {
48606
- const pluginsDir = import_node_path19.default.join(home, ".claude", "plugins");
48607
- const v2 = import_node_path19.default.join(pluginsDir, "installed_plugins_v2.json");
48608
- const v1 = import_node_path19.default.join(pluginsDir, "installed_plugins.json");
48657
+ const pluginsDir = import_node_path20.default.join(home, ".claude", "plugins");
48658
+ const v2 = import_node_path20.default.join(pluginsDir, "installed_plugins_v2.json");
48659
+ const v1 = import_node_path20.default.join(pluginsDir, "installed_plugins.json");
48609
48660
  let raw = null;
48610
48661
  for (const candidate of [v2, v1]) {
48611
48662
  try {
@@ -48634,19 +48685,19 @@ function readInstalledPlugins2(home) {
48634
48685
  return out;
48635
48686
  }
48636
48687
  function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
48637
- let cur = import_node_path19.default.resolve(startCwd);
48638
- const fsRoot = import_node_path19.default.parse(cur).root;
48688
+ let cur = import_node_path20.default.resolve(startCwd);
48689
+ const fsRoot = import_node_path20.default.parse(cur).root;
48639
48690
  while (true) {
48640
- scanAgentsDir(import_node_path19.default.join(cur, ".claude", "agents"), "project", seen, out);
48691
+ scanAgentsDir(import_node_path20.default.join(cur, ".claude", "agents"), "project", seen, out);
48641
48692
  let hasGit = false;
48642
48693
  try {
48643
- hasGit = import_node_fs21.default.existsSync(import_node_path19.default.join(cur, ".git"));
48694
+ hasGit = import_node_fs21.default.existsSync(import_node_path20.default.join(cur, ".git"));
48644
48695
  } catch {
48645
48696
  }
48646
48697
  if (hasGit) return;
48647
48698
  if (cur === home) return;
48648
48699
  if (cur === fsRoot) return;
48649
- const parent = import_node_path19.default.dirname(cur);
48700
+ const parent = import_node_path20.default.dirname(cur);
48650
48701
  if (parent === cur) return;
48651
48702
  cur = parent;
48652
48703
  }
@@ -48656,7 +48707,7 @@ var AgentsScanner = class {
48656
48707
  extraPluginRoots;
48657
48708
  policyDir;
48658
48709
  constructor(opts = {}) {
48659
- this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os8.default.homedir();
48710
+ this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os9.default.homedir();
48660
48711
  this.extraPluginRoots = opts.extraPluginRoots ?? [];
48661
48712
  if (opts.policyDir !== void 0) {
48662
48713
  this.policyDir = opts.policyDir;
@@ -48681,7 +48732,7 @@ var AgentsScanner = class {
48681
48732
  }
48682
48733
  const fsBlock = [];
48683
48734
  scanAgentsDir(
48684
- import_node_path19.default.join(this.home, ".claude", "agents"),
48735
+ import_node_path20.default.join(this.home, ".claude", "agents"),
48685
48736
  "global",
48686
48737
  seen,
48687
48738
  fsBlock
@@ -48695,7 +48746,7 @@ var AgentsScanner = class {
48695
48746
  ...this.extraPluginRoots
48696
48747
  ];
48697
48748
  for (const { name, root } of plugins) {
48698
- const agentsRoot = import_node_path19.default.join(root, "agents");
48749
+ const agentsRoot = import_node_path20.default.join(root, "agents");
48699
48750
  scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
48700
48751
  }
48701
48752
  return [...builtinBlock, ...fsBlock];
@@ -48704,27 +48755,27 @@ var AgentsScanner = class {
48704
48755
 
48705
48756
  // src/observer/session-observer.ts
48706
48757
  var import_node_fs23 = __toESM(require("fs"), 1);
48707
- var import_node_os10 = __toESM(require("os"), 1);
48708
- var import_node_path21 = __toESM(require("path"), 1);
48758
+ var import_node_os11 = __toESM(require("os"), 1);
48759
+ var import_node_path22 = __toESM(require("path"), 1);
48709
48760
  init_claude_history();
48710
48761
 
48711
48762
  // src/observer/subagent-meta-observer.ts
48712
48763
  var import_node_fs22 = __toESM(require("fs"), 1);
48713
- var import_node_os9 = __toESM(require("os"), 1);
48714
- var import_node_path20 = __toESM(require("path"), 1);
48764
+ var import_node_os10 = __toESM(require("os"), 1);
48765
+ var import_node_path21 = __toESM(require("path"), 1);
48715
48766
  init_claude_history();
48716
48767
  var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
48717
48768
  var SubagentMetaObserver = class {
48718
48769
  constructor(opts) {
48719
48770
  this.opts = opts;
48720
- this.home = opts.home ?? import_node_os9.default.homedir();
48771
+ this.home = opts.home ?? import_node_os10.default.homedir();
48721
48772
  }
48722
48773
  opts;
48723
48774
  home;
48724
48775
  watches = /* @__PURE__ */ new Map();
48725
48776
  // public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
48726
48777
  resolveSubagentDir(cwd, toolSessionId) {
48727
- return import_node_path20.default.join(
48778
+ return import_node_path21.default.join(
48728
48779
  this.home,
48729
48780
  ".claude",
48730
48781
  "projects",
@@ -48780,7 +48831,7 @@ var SubagentMetaObserver = class {
48780
48831
  if (!m2) return;
48781
48832
  const agentId = m2[1];
48782
48833
  if (w2.emitted.has(agentId)) return;
48783
- const file = import_node_path20.default.join(w2.dirPath, name);
48834
+ const file = import_node_path21.default.join(w2.dirPath, name);
48784
48835
  let raw;
48785
48836
  try {
48786
48837
  raw = import_node_fs22.default.readFileSync(file, "utf8");
@@ -48828,7 +48879,7 @@ var SubagentMetaObserver = class {
48828
48879
  var SessionObserver = class {
48829
48880
  constructor(opts) {
48830
48881
  this.opts = opts;
48831
- this.home = opts.home ?? import_node_os10.default.homedir();
48882
+ this.home = opts.home ?? import_node_os11.default.homedir();
48832
48883
  this.metaObserver = opts.enableSubagentMetaObserver ? new SubagentMetaObserver({ home: this.home, onEvent: opts.onEvent }) : null;
48833
48884
  }
48834
48885
  opts;
@@ -48840,7 +48891,7 @@ var SessionObserver = class {
48840
48891
  metaObserver;
48841
48892
  resolveJsonlPath(cwd, toolSessionId, override) {
48842
48893
  if (override) return override;
48843
- return import_node_path21.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
48894
+ return import_node_path22.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
48844
48895
  }
48845
48896
  start(args) {
48846
48897
  this.stop(args.sessionId);
@@ -48861,10 +48912,10 @@ var SessionObserver = class {
48861
48912
  prevIsRejectSentinel: false
48862
48913
  };
48863
48914
  try {
48864
- import_node_fs23.default.mkdirSync(import_node_path21.default.dirname(filePath), { recursive: true });
48915
+ import_node_fs23.default.mkdirSync(import_node_path22.default.dirname(filePath), { recursive: true });
48865
48916
  } catch {
48866
48917
  }
48867
- w2.watcher = import_node_fs23.default.watch(import_node_path21.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
48918
+ w2.watcher = import_node_fs23.default.watch(import_node_path22.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
48868
48919
  if (!changedName || !filePath.endsWith(changedName)) return;
48869
48920
  this.poll(w2);
48870
48921
  });
@@ -49744,7 +49795,7 @@ async function authenticate(token, deps) {
49744
49795
 
49745
49796
  // src/permission/capability-store.ts
49746
49797
  var fs27 = __toESM(require("fs"), 1);
49747
- var path26 = __toESM(require("path"), 1);
49798
+ var path27 = __toESM(require("path"), 1);
49748
49799
  var CAPABILITIES_FILE_NAME = "capabilities.json";
49749
49800
  var FILE_VERSION = 1;
49750
49801
  var CapabilityStore = class {
@@ -49774,7 +49825,7 @@ var CapabilityStore = class {
49774
49825
  this.flush();
49775
49826
  }
49776
49827
  filePath() {
49777
- return path26.join(this.dataDir, CAPABILITIES_FILE_NAME);
49828
+ return path27.join(this.dataDir, CAPABILITIES_FILE_NAME);
49778
49829
  }
49779
49830
  readFromDisk() {
49780
49831
  const file = this.filePath();
@@ -49921,7 +49972,7 @@ function cleanupGuestSessionsForCapability(cap, factory) {
49921
49972
 
49922
49973
  // src/inbox/inbox-store.ts
49923
49974
  var fs29 = __toESM(require("fs"), 1);
49924
- var path27 = __toESM(require("path"), 1);
49975
+ var path28 = __toESM(require("path"), 1);
49925
49976
  var INBOX_SUBDIR = "inbox";
49926
49977
  var InboxStore = class {
49927
49978
  constructor(dataDir) {
@@ -50019,10 +50070,10 @@ var InboxStore = class {
50019
50070
  }
50020
50071
  }
50021
50072
  dirPath() {
50022
- return path27.join(this.dataDir, INBOX_SUBDIR);
50073
+ return path28.join(this.dataDir, INBOX_SUBDIR);
50023
50074
  }
50024
50075
  filePath(peerDeviceId) {
50025
- return path27.join(this.dirPath(), `${peerDeviceId}.jsonl`);
50076
+ return path28.join(this.dirPath(), `${peerDeviceId}.jsonl`);
50026
50077
  }
50027
50078
  };
50028
50079
  function parseAllLines(raw) {
@@ -50110,7 +50161,7 @@ var InboxManager = class {
50110
50161
 
50111
50162
  // src/state/contact-store.ts
50112
50163
  var fs30 = __toESM(require("fs"), 1);
50113
- var path28 = __toESM(require("path"), 1);
50164
+ var path29 = __toESM(require("path"), 1);
50114
50165
  var FILE_NAME = "contacts.json";
50115
50166
  var ContactStore = class {
50116
50167
  constructor(dataDir) {
@@ -50120,7 +50171,7 @@ var ContactStore = class {
50120
50171
  contacts = /* @__PURE__ */ new Map();
50121
50172
  load() {
50122
50173
  this.contacts.clear();
50123
- const file = path28.join(this.dataDir, FILE_NAME);
50174
+ const file = path29.join(this.dataDir, FILE_NAME);
50124
50175
  let raw;
50125
50176
  try {
50126
50177
  raw = fs30.readFileSync(file, "utf8");
@@ -50166,7 +50217,7 @@ var ContactStore = class {
50166
50217
  return existed;
50167
50218
  }
50168
50219
  flush() {
50169
- const file = path28.join(this.dataDir, FILE_NAME);
50220
+ const file = path29.join(this.dataDir, FILE_NAME);
50170
50221
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
50171
50222
  const content = JSON.stringify(
50172
50223
  { contacts: Array.from(this.contacts.values()) },
@@ -50330,52 +50381,52 @@ async function autoReverseContact(args) {
50330
50381
 
50331
50382
  // src/migrations/2026-05-20-flatten-sessions.ts
50332
50383
  var fs31 = __toESM(require("fs"), 1);
50333
- var path29 = __toESM(require("path"), 1);
50384
+ var path30 = __toESM(require("path"), 1);
50334
50385
  var MIGRATION_FLAG_NAME = ".migration.v1.done";
50335
50386
  function migrateFlattenSessions(opts) {
50336
50387
  const dataDir = opts.dataDir;
50337
50388
  const now = opts.now ?? Date.now;
50338
- const sessionsDir = path29.join(dataDir, "sessions");
50339
- const flagPath = path29.join(sessionsDir, MIGRATION_FLAG_NAME);
50389
+ const sessionsDir = path30.join(dataDir, "sessions");
50390
+ const flagPath = path30.join(sessionsDir, MIGRATION_FLAG_NAME);
50340
50391
  if (existsSync3(flagPath)) {
50341
50392
  return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
50342
50393
  }
50343
50394
  let movedBare = 0;
50344
50395
  let movedVmOwner = 0;
50345
50396
  let archivedListener = 0;
50346
- const defaultDir = path29.join(sessionsDir, "default");
50397
+ const defaultDir = path30.join(sessionsDir, "default");
50347
50398
  if (existsSync3(defaultDir)) {
50348
50399
  for (const entry of readdirSafe(defaultDir)) {
50349
50400
  if (!entry.endsWith(".json")) continue;
50350
- const src = path29.join(defaultDir, entry);
50351
- const dst = path29.join(sessionsDir, entry);
50401
+ const src = path30.join(defaultDir, entry);
50402
+ const dst = path30.join(sessionsDir, entry);
50352
50403
  fs31.renameSync(src, dst);
50353
50404
  movedBare += 1;
50354
50405
  }
50355
50406
  rmdirIfEmpty(defaultDir);
50356
50407
  }
50357
50408
  for (const pid of readdirSafe(sessionsDir)) {
50358
- const personaDir = path29.join(sessionsDir, pid);
50409
+ const personaDir = path30.join(sessionsDir, pid);
50359
50410
  if (!isDir(personaDir)) continue;
50360
50411
  if (pid === "default") continue;
50361
- const ownerSrc = path29.join(personaDir, "owner");
50412
+ const ownerSrc = path30.join(personaDir, "owner");
50362
50413
  if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
50363
- const ownerDst = path29.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
50414
+ const ownerDst = path30.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
50364
50415
  fs31.mkdirSync(ownerDst, { recursive: true });
50365
50416
  for (const file of readdirSafe(ownerSrc)) {
50366
50417
  if (!file.endsWith(".json")) continue;
50367
- fs31.renameSync(path29.join(ownerSrc, file), path29.join(ownerDst, file));
50418
+ fs31.renameSync(path30.join(ownerSrc, file), path30.join(ownerDst, file));
50368
50419
  movedVmOwner += 1;
50369
50420
  }
50370
50421
  rmdirIfEmpty(ownerSrc);
50371
50422
  }
50372
- const listenerSrc = path29.join(personaDir, "listener");
50423
+ const listenerSrc = path30.join(personaDir, "listener");
50373
50424
  if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
50374
- const archiveDst = path29.join(dataDir, ".legacy", `listener-${pid}`);
50425
+ const archiveDst = path30.join(dataDir, ".legacy", `listener-${pid}`);
50375
50426
  fs31.mkdirSync(archiveDst, { recursive: true });
50376
50427
  for (const file of readdirSafe(listenerSrc)) {
50377
50428
  if (!file.endsWith(".json")) continue;
50378
- fs31.renameSync(path29.join(listenerSrc, file), path29.join(archiveDst, file));
50429
+ fs31.renameSync(path30.join(listenerSrc, file), path30.join(archiveDst, file));
50379
50430
  archivedListener += 1;
50380
50431
  }
50381
50432
  rmdirIfEmpty(listenerSrc);
@@ -50423,10 +50474,10 @@ function rmdirIfEmpty(p2) {
50423
50474
 
50424
50475
  // src/transport/http-router.ts
50425
50476
  var import_node_fs25 = __toESM(require("fs"), 1);
50426
- var import_node_path25 = __toESM(require("path"), 1);
50477
+ var import_node_path26 = __toESM(require("path"), 1);
50427
50478
 
50428
50479
  // src/attachment/mime.ts
50429
- var import_node_path22 = __toESM(require("path"), 1);
50480
+ var import_node_path23 = __toESM(require("path"), 1);
50430
50481
  var TEXT_PLAIN = "text/plain; charset=utf-8";
50431
50482
  var EXT_TO_NATIVE_MIME = {
50432
50483
  // 图片
@@ -50533,7 +50584,7 @@ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
50533
50584
  ".mk"
50534
50585
  ]);
50535
50586
  function lookupMime(filePathOrName) {
50536
- const ext = import_node_path22.default.extname(filePathOrName).toLowerCase();
50587
+ const ext = import_node_path23.default.extname(filePathOrName).toLowerCase();
50537
50588
  if (EXT_TO_NATIVE_MIME[ext]) return EXT_TO_NATIVE_MIME[ext];
50538
50589
  if (TEXT_EXTENSIONS.has(ext)) return TEXT_PLAIN;
50539
50590
  return "application/octet-stream";
@@ -50603,7 +50654,7 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
50603
50654
 
50604
50655
  // src/attachment/upload.ts
50605
50656
  var import_node_fs24 = __toESM(require("fs"), 1);
50606
- var import_node_path23 = __toESM(require("path"), 1);
50657
+ var import_node_path24 = __toESM(require("path"), 1);
50607
50658
  var import_node_crypto7 = __toESM(require("crypto"), 1);
50608
50659
  var import_promises2 = require("stream/promises");
50609
50660
  var UploadError = class extends Error {
@@ -50615,14 +50666,14 @@ var UploadError = class extends Error {
50615
50666
  code;
50616
50667
  };
50617
50668
  function assertValidFileName(fileName) {
50618
- if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path23.default.basename(fileName)) {
50669
+ if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path24.default.basename(fileName)) {
50619
50670
  throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
50620
50671
  }
50621
50672
  }
50622
50673
  var HASH_PREFIX_LEN = 16;
50623
50674
  async function writeUploadedAttachment(args) {
50624
50675
  assertValidFileName(args.fileName);
50625
- const attachmentsRoot = import_node_path23.default.join(args.sessionDir, ".attachments");
50676
+ const attachmentsRoot = import_node_path24.default.join(args.sessionDir, ".attachments");
50626
50677
  try {
50627
50678
  import_node_fs24.default.mkdirSync(attachmentsRoot, { recursive: true });
50628
50679
  } catch (err) {
@@ -50630,7 +50681,7 @@ async function writeUploadedAttachment(args) {
50630
50681
  }
50631
50682
  const hasher = import_node_crypto7.default.createHash("sha256");
50632
50683
  let actualSize = 0;
50633
- const tmpPath = import_node_path23.default.join(
50684
+ const tmpPath = import_node_path24.default.join(
50634
50685
  attachmentsRoot,
50635
50686
  `.upload-${process.pid}-${Date.now()}-${import_node_crypto7.default.randomBytes(4).toString("hex")}`
50636
50687
  );
@@ -50665,7 +50716,7 @@ async function writeUploadedAttachment(args) {
50665
50716
  );
50666
50717
  }
50667
50718
  const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
50668
- const hashDir = import_node_path23.default.join(attachmentsRoot, attachmentId);
50719
+ const hashDir = import_node_path24.default.join(attachmentsRoot, attachmentId);
50669
50720
  let finalFileName;
50670
50721
  let hashDirExists = false;
50671
50722
  try {
@@ -50683,7 +50734,7 @@ async function writeUploadedAttachment(args) {
50683
50734
  try {
50684
50735
  import_node_fs24.default.mkdirSync(hashDir, { recursive: true });
50685
50736
  finalFileName = args.fileName;
50686
- import_node_fs24.default.renameSync(tmpPath, import_node_path23.default.join(hashDir, finalFileName));
50737
+ import_node_fs24.default.renameSync(tmpPath, import_node_path24.default.join(hashDir, finalFileName));
50687
50738
  } catch (err) {
50688
50739
  try {
50689
50740
  import_node_fs24.default.unlinkSync(tmpPath);
@@ -50692,8 +50743,8 @@ async function writeUploadedAttachment(args) {
50692
50743
  throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
50693
50744
  }
50694
50745
  }
50695
- const absPath = import_node_path23.default.join(hashDir, finalFileName);
50696
- const relPath = import_node_path23.default.relative(args.sessionDir, absPath);
50746
+ const absPath = import_node_path24.default.join(hashDir, finalFileName);
50747
+ const relPath = import_node_path24.default.relative(args.sessionDir, absPath);
50697
50748
  args.groupFileStore.upsert(args.scope, args.sessionId, {
50698
50749
  relPath: absPath,
50699
50750
  // 存绝对路径,与现有 agent 入清单的形态一致(attachment.ts:144 双形态兼容)
@@ -50707,8 +50758,8 @@ async function writeUploadedAttachment(args) {
50707
50758
 
50708
50759
  // src/extension/import.ts
50709
50760
  var import_promises3 = __toESM(require("fs/promises"), 1);
50710
- var import_node_path24 = __toESM(require("path"), 1);
50711
- var import_node_os11 = __toESM(require("os"), 1);
50761
+ var import_node_path25 = __toESM(require("path"), 1);
50762
+ var import_node_os12 = __toESM(require("os"), 1);
50712
50763
  var import_jszip = __toESM(require_lib3(), 1);
50713
50764
  var ImportError = class extends Error {
50714
50765
  constructor(code, message) {
@@ -50725,7 +50776,7 @@ async function importZip(buf, root) {
50725
50776
  throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
50726
50777
  }
50727
50778
  for (const name of Object.keys(zip.files)) {
50728
- if (name.includes("..") || name.startsWith("/") || import_node_path24.default.isAbsolute(name)) {
50779
+ if (name.includes("..") || name.startsWith("/") || import_node_path25.default.isAbsolute(name)) {
50729
50780
  throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
50730
50781
  }
50731
50782
  }
@@ -50758,7 +50809,7 @@ async function importZip(buf, root) {
50758
50809
  );
50759
50810
  }
50760
50811
  }
50761
- const destDir = import_node_path24.default.join(root, manifest.id);
50812
+ const destDir = import_node_path25.default.join(root, manifest.id);
50762
50813
  let destExists = false;
50763
50814
  try {
50764
50815
  await import_promises3.default.access(destDir);
@@ -50768,15 +50819,15 @@ async function importZip(buf, root) {
50768
50819
  if (destExists) {
50769
50820
  throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
50770
50821
  }
50771
- const stage = await import_promises3.default.mkdtemp(import_node_path24.default.join(import_node_os11.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
50822
+ const stage = await import_promises3.default.mkdtemp(import_node_path25.default.join(import_node_os12.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
50772
50823
  try {
50773
50824
  for (const [name, entry] of Object.entries(zip.files)) {
50774
- const dest = import_node_path24.default.join(stage, name);
50825
+ const dest = import_node_path25.default.join(stage, name);
50775
50826
  if (entry.dir) {
50776
50827
  await import_promises3.default.mkdir(dest, { recursive: true });
50777
50828
  continue;
50778
50829
  }
50779
- await import_promises3.default.mkdir(import_node_path24.default.dirname(dest), { recursive: true });
50830
+ await import_promises3.default.mkdir(import_node_path25.default.dirname(dest), { recursive: true });
50780
50831
  const content = await entry.async("nodebuffer");
50781
50832
  await import_promises3.default.writeFile(dest, content);
50782
50833
  }
@@ -50807,7 +50858,7 @@ var SHARE_UI_ASSET_MIME = {
50807
50858
  ".wasm": "application/wasm"
50808
50859
  };
50809
50860
  function shareUiAssetMime(filePath) {
50810
- const ext = import_node_path25.default.extname(filePath).toLowerCase();
50861
+ const ext = import_node_path26.default.extname(filePath).toLowerCase();
50811
50862
  return SHARE_UI_ASSET_MIME[ext] ?? lookupMime(filePath);
50812
50863
  }
50813
50864
  var DISPATCH_HEARTBEAT_MS = 25e3;
@@ -50894,7 +50945,7 @@ function isValidUploadFileName(fileName) {
50894
50945
  if (fileName === "." || fileName === "..") return false;
50895
50946
  if (fileName.startsWith(".")) return false;
50896
50947
  if (fileName.includes("/") || fileName.includes("\\")) return false;
50897
- return fileName === import_node_path25.default.basename(fileName);
50948
+ return fileName === import_node_path26.default.basename(fileName);
50898
50949
  }
50899
50950
  function createHttpRouter(deps) {
50900
50951
  return async (req, res) => {
@@ -51190,7 +51241,7 @@ function createHttpRouter(deps) {
51190
51241
  sendHtml(res, statusByCode[r.code], loader.renderErrorHtml(r.code, msgByCode[r.code]));
51191
51242
  return true;
51192
51243
  }
51193
- sendHtml(res, 200, loader.renderViewerHtml(import_node_path25.default.basename(r.absPath)));
51244
+ sendHtml(res, 200, loader.renderViewerHtml(import_node_path26.default.basename(r.absPath)));
51194
51245
  return true;
51195
51246
  }
51196
51247
  const ctx = deps.authResolver.resolveFromHeader(
@@ -51311,7 +51362,7 @@ function createHttpRouter(deps) {
51311
51362
  return true;
51312
51363
  }
51313
51364
  let absPath;
51314
- if (import_node_path25.default.isAbsolute(pathParam)) {
51365
+ if (import_node_path26.default.isAbsolute(pathParam)) {
51315
51366
  absPath = pathParam;
51316
51367
  } else if (deps.sessionStore) {
51317
51368
  const file = deps.sessionStore.read(sid);
@@ -51319,7 +51370,7 @@ function createHttpRouter(deps) {
51319
51370
  sendJson(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
51320
51371
  return true;
51321
51372
  }
51322
- absPath = import_node_path25.default.join(file.cwd, pathParam);
51373
+ absPath = import_node_path26.default.join(file.cwd, pathParam);
51323
51374
  } else {
51324
51375
  sendJson(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
51325
51376
  return true;
@@ -51421,7 +51472,7 @@ function streamFile(res, absPath, logger) {
51421
51472
  return;
51422
51473
  }
51423
51474
  const mime = lookupMime(absPath);
51424
- const basename = import_node_path25.default.basename(absPath);
51475
+ const basename = import_node_path26.default.basename(absPath);
51425
51476
  res.writeHead(200, {
51426
51477
  "Content-Type": mime,
51427
51478
  "Content-Length": String(stat.size),
@@ -51439,7 +51490,7 @@ function streamFile(res, absPath, logger) {
51439
51490
 
51440
51491
  // src/attachment/gc.ts
51441
51492
  var import_node_fs26 = __toESM(require("fs"), 1);
51442
- var import_node_path26 = __toESM(require("path"), 1);
51493
+ var import_node_path27 = __toESM(require("path"), 1);
51443
51494
  var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
51444
51495
  function runAttachmentGc(args) {
51445
51496
  const now = (args.now ?? Date.now)();
@@ -51448,17 +51499,17 @@ function runAttachmentGc(args) {
51448
51499
  for (const { scope, sessionId } of args.sessionScopes) {
51449
51500
  for (const entry of args.groupFileStore.list(scope, sessionId)) {
51450
51501
  if (entry.stale) continue;
51451
- if (import_node_path26.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
51502
+ if (import_node_path27.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
51452
51503
  }
51453
51504
  }
51454
51505
  for (const { scope, sessionId } of args.sessionScopes) {
51455
- const sessionDir = args.getSessionCwd?.(sessionId) ?? import_node_path26.default.join(
51506
+ const sessionDir = args.getSessionCwd?.(sessionId) ?? import_node_path27.default.join(
51456
51507
  args.dataDir,
51457
51508
  "sessions",
51458
51509
  ...scopeSubPath(scope).map(safeFileName),
51459
51510
  safeFileName(sessionId)
51460
51511
  );
51461
- const attRoot = import_node_path26.default.join(sessionDir, ".attachments");
51512
+ const attRoot = import_node_path27.default.join(sessionDir, ".attachments");
51462
51513
  let hashDirs;
51463
51514
  try {
51464
51515
  hashDirs = import_node_fs26.default.readdirSync(attRoot);
@@ -51468,7 +51519,7 @@ function runAttachmentGc(args) {
51468
51519
  continue;
51469
51520
  }
51470
51521
  for (const hashDir of hashDirs) {
51471
- const hashDirAbs = import_node_path26.default.join(attRoot, hashDir);
51522
+ const hashDirAbs = import_node_path27.default.join(attRoot, hashDir);
51472
51523
  let files;
51473
51524
  try {
51474
51525
  files = import_node_fs26.default.readdirSync(hashDirAbs);
@@ -51476,7 +51527,7 @@ function runAttachmentGc(args) {
51476
51527
  continue;
51477
51528
  }
51478
51529
  for (const name of files) {
51479
- const file = import_node_path26.default.join(hashDirAbs, name);
51530
+ const file = import_node_path27.default.join(hashDirAbs, name);
51480
51531
  let stat;
51481
51532
  try {
51482
51533
  stat = import_node_fs26.default.statSync(file);
@@ -51507,7 +51558,7 @@ function runAttachmentGc(args) {
51507
51558
 
51508
51559
  // src/attachment/group.ts
51509
51560
  var import_node_fs27 = __toESM(require("fs"), 1);
51510
- var import_node_path27 = __toESM(require("path"), 1);
51561
+ var import_node_path28 = __toESM(require("path"), 1);
51511
51562
  var import_node_crypto8 = __toESM(require("crypto"), 1);
51512
51563
  init_protocol();
51513
51564
  var GroupFileStore = class {
@@ -51519,11 +51570,11 @@ var GroupFileStore = class {
51519
51570
  this.logger = opts.logger;
51520
51571
  }
51521
51572
  rootForScope(scope) {
51522
- return import_node_path27.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
51573
+ return import_node_path28.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
51523
51574
  }
51524
51575
  /** 与 SessionStore.filePath 平级,扩展名 .group-files.json */
51525
51576
  filePath(scope, sessionId) {
51526
- return import_node_path27.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
51577
+ return import_node_path28.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
51527
51578
  }
51528
51579
  cacheKey(scope, sessionId) {
51529
51580
  return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
@@ -51558,7 +51609,7 @@ var GroupFileStore = class {
51558
51609
  }
51559
51610
  writeFile(scope, sessionId, entries) {
51560
51611
  const file = this.filePath(scope, sessionId);
51561
- import_node_fs27.default.mkdirSync(import_node_path27.default.dirname(file), { recursive: true });
51612
+ import_node_fs27.default.mkdirSync(import_node_path28.default.dirname(file), { recursive: true });
51562
51613
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
51563
51614
  import_node_fs27.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
51564
51615
  import_node_fs27.default.renameSync(tmp, file);
@@ -51648,9 +51699,9 @@ var GroupFileStore = class {
51648
51699
 
51649
51700
  // src/discovery/state-file.ts
51650
51701
  var import_node_fs28 = __toESM(require("fs"), 1);
51651
- var import_node_path28 = __toESM(require("path"), 1);
51702
+ var import_node_path29 = __toESM(require("path"), 1);
51652
51703
  function defaultStateFilePath(dataDir) {
51653
- return import_node_path28.default.join(dataDir, "state.json");
51704
+ return import_node_path29.default.join(dataDir, "state.json");
51654
51705
  }
51655
51706
  function isPidAlive(pid) {
51656
51707
  if (!Number.isFinite(pid) || pid <= 0) return false;
@@ -51686,7 +51737,7 @@ var StateFileManager = class {
51686
51737
  return { status: "stale", existing };
51687
51738
  }
51688
51739
  write(state) {
51689
- import_node_fs28.default.mkdirSync(import_node_path28.default.dirname(this.file), { recursive: true });
51740
+ import_node_fs28.default.mkdirSync(import_node_path29.default.dirname(this.file), { recursive: true });
51690
51741
  const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
51691
51742
  import_node_fs28.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
51692
51743
  import_node_fs28.default.renameSync(tmp, this.file);
@@ -51715,13 +51766,13 @@ function readDaemonSourceFromEnv(env = process.env) {
51715
51766
 
51716
51767
  // src/tunnel/tunnel-manager.ts
51717
51768
  var import_node_fs32 = __toESM(require("fs"), 1);
51718
- var import_node_path32 = __toESM(require("path"), 1);
51769
+ var import_node_path33 = __toESM(require("path"), 1);
51719
51770
  var import_node_crypto9 = __toESM(require("crypto"), 1);
51720
51771
  var import_node_child_process9 = require("child_process");
51721
51772
 
51722
51773
  // src/tunnel/tunnel-store.ts
51723
51774
  var import_node_fs29 = __toESM(require("fs"), 1);
51724
- var import_node_path29 = __toESM(require("path"), 1);
51775
+ var import_node_path30 = __toESM(require("path"), 1);
51725
51776
  var TunnelStore = class {
51726
51777
  constructor(filePath) {
51727
51778
  this.filePath = filePath;
@@ -51740,7 +51791,7 @@ var TunnelStore = class {
51740
51791
  }
51741
51792
  }
51742
51793
  async set(v2) {
51743
- const dir = import_node_path29.default.dirname(this.filePath);
51794
+ const dir = import_node_path30.default.dirname(this.filePath);
51744
51795
  await import_node_fs29.default.promises.mkdir(dir, { recursive: true });
51745
51796
  const data = JSON.stringify(v2, null, 2);
51746
51797
  const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
@@ -51851,8 +51902,8 @@ function escape(v2) {
51851
51902
 
51852
51903
  // src/tunnel/frpc-binary.ts
51853
51904
  var import_node_fs30 = __toESM(require("fs"), 1);
51854
- var import_node_os12 = __toESM(require("os"), 1);
51855
- var import_node_path30 = __toESM(require("path"), 1);
51905
+ var import_node_os13 = __toESM(require("os"), 1);
51906
+ var import_node_path31 = __toESM(require("path"), 1);
51856
51907
  var import_node_child_process7 = require("child_process");
51857
51908
  var import_node_stream3 = require("stream");
51858
51909
  var import_promises4 = require("stream/promises");
@@ -51891,13 +51942,13 @@ async function ensureFrpcBinary(opts) {
51891
51942
  }
51892
51943
  const version2 = opts.version ?? FRPC_VERSION;
51893
51944
  const platform = opts.platform ?? detectPlatform();
51894
- const binDir = import_node_path30.default.join(opts.dataDir, "bin");
51945
+ const binDir = import_node_path31.default.join(opts.dataDir, "bin");
51895
51946
  import_node_fs30.default.mkdirSync(binDir, { recursive: true });
51896
51947
  cleanupStaleArtifacts(binDir);
51897
- const stableBin = import_node_path30.default.join(binDir, "frpc");
51948
+ const stableBin = import_node_path31.default.join(binDir, "frpc");
51898
51949
  if (import_node_fs30.default.existsSync(stableBin)) return stableBin;
51899
51950
  const partialBin = `${stableBin}.partial`;
51900
- const tarballPath = import_node_path30.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
51951
+ const tarballPath = import_node_path31.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
51901
51952
  try {
51902
51953
  const url = frpcDownloadUrl(version2, platform);
51903
51954
  await downloadToFile(url, tarballPath, opts.fetchImpl);
@@ -51923,7 +51974,7 @@ function cleanupStaleArtifacts(binDir) {
51923
51974
  }
51924
51975
  for (const name of entries) {
51925
51976
  if (name.endsWith(".partial") || name.startsWith("extract-")) {
51926
- const full = import_node_path30.default.join(binDir, name);
51977
+ const full = import_node_path31.default.join(binDir, name);
51927
51978
  try {
51928
51979
  import_node_fs30.default.rmSync(full, { recursive: true, force: true });
51929
51980
  } catch {
@@ -51949,7 +52000,7 @@ async function downloadToFile(url, dest, fetchImpl) {
51949
52000
  await (0, import_promises4.pipeline)(nodeStream, out);
51950
52001
  }
51951
52002
  async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
51952
- const work = import_node_path30.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
52003
+ const work = import_node_path31.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
51953
52004
  import_node_fs30.default.mkdirSync(work, { recursive: true });
51954
52005
  try {
51955
52006
  await new Promise((resolve6, reject) => {
@@ -51958,7 +52009,7 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
51958
52009
  proc.on("exit", (code) => code === 0 ? resolve6() : reject(new Error(`tar exited ${code}`)));
51959
52010
  });
51960
52011
  const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
51961
- const src = import_node_path30.default.join(work, dirName, "frpc");
52012
+ const src = import_node_path31.default.join(work, dirName, "frpc");
51962
52013
  if (!import_node_fs30.default.existsSync(src)) {
51963
52014
  throw new Error(`frpc not found inside tarball at ${src}`);
51964
52015
  }
@@ -51970,10 +52021,10 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
51970
52021
 
51971
52022
  // src/tunnel/frpc-process.ts
51972
52023
  var import_node_fs31 = __toESM(require("fs"), 1);
51973
- var import_node_path31 = __toESM(require("path"), 1);
52024
+ var import_node_path32 = __toESM(require("path"), 1);
51974
52025
  var import_node_child_process8 = require("child_process");
51975
52026
  function frpcPidFilePath(dataDir) {
51976
- return import_node_path31.default.join(dataDir, "frpc.pid");
52027
+ return import_node_path32.default.join(dataDir, "frpc.pid");
51977
52028
  }
51978
52029
  function writeFrpcPid(dataDir, pid) {
51979
52030
  try {
@@ -52015,7 +52066,7 @@ function defaultSleep(ms) {
52015
52066
  }
52016
52067
  async function killStaleFrpc(deps) {
52017
52068
  const pidFile = frpcPidFilePath(deps.dataDir);
52018
- const tomlPath = import_node_path31.default.join(deps.dataDir, "frpc.toml");
52069
+ const tomlPath = import_node_path32.default.join(deps.dataDir, "frpc.toml");
52019
52070
  const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
52020
52071
  const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
52021
52072
  const killPid = deps.killPidImpl ?? defaultKillPid;
@@ -52087,7 +52138,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
52087
52138
  var TunnelManager = class {
52088
52139
  constructor(deps) {
52089
52140
  this.deps = deps;
52090
- this.store = deps.store ?? new TunnelStore(import_node_path32.default.join(deps.dataDir, "tunnel.json"));
52141
+ this.store = deps.store ?? new TunnelStore(import_node_path33.default.join(deps.dataDir, "tunnel.json"));
52091
52142
  this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
52092
52143
  this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
52093
52144
  }
@@ -52214,7 +52265,7 @@ var TunnelManager = class {
52214
52265
  dataDir: this.deps.dataDir,
52215
52266
  override: this.deps.frpcBinaryOverride ?? void 0
52216
52267
  });
52217
- const tomlPath = import_node_path32.default.join(this.deps.dataDir, "frpc.toml");
52268
+ const tomlPath = import_node_path33.default.join(this.deps.dataDir, "frpc.toml");
52218
52269
  const proxyName = `clawd-${t.subdomain}-${localPort}-${import_node_crypto9.default.randomBytes(3).toString("hex")}`;
52219
52270
  const toml = buildFrpcToml({
52220
52271
  serverAddr: t.frpsHost,
@@ -52229,7 +52280,7 @@ var TunnelManager = class {
52229
52280
  const proc = (this.deps.spawnImpl ?? import_node_child_process9.spawn)(frpcBin, ["-c", tomlPath], {
52230
52281
  stdio: ["ignore", "pipe", "pipe"]
52231
52282
  });
52232
- const logFilePath = import_node_path32.default.join(this.deps.dataDir, "frpc.log");
52283
+ const logFilePath = import_node_path33.default.join(this.deps.dataDir, "frpc.log");
52233
52284
  const logStream = import_node_fs32.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
52234
52285
  logStream.on("error", () => {
52235
52286
  });
@@ -52312,16 +52363,16 @@ async function waitForFrpcReady(proc, timeoutMs) {
52312
52363
  }
52313
52364
 
52314
52365
  // src/tunnel/device-key.ts
52315
- var import_node_os13 = __toESM(require("os"), 1);
52316
- var import_node_path33 = __toESM(require("path"), 1);
52366
+ var import_node_os14 = __toESM(require("os"), 1);
52367
+ var import_node_path34 = __toESM(require("path"), 1);
52317
52368
  var import_node_crypto10 = __toESM(require("crypto"), 1);
52318
52369
  var DERIVE_SALT = "clawd-tunnel-device-v1";
52319
52370
  function deriveStableDeviceKey(opts = {}) {
52320
- const hostname = opts.hostname ?? import_node_os13.default.hostname();
52321
- const uid = opts.uid ?? (typeof import_node_os13.default.userInfo === "function" ? import_node_os13.default.userInfo().uid : 0);
52322
- const home = opts.home ?? import_node_os13.default.homedir();
52323
- const defaultDataDir = import_node_path33.default.resolve(import_node_path33.default.join(home, ".clawd"));
52324
- const normalizedDataDir = opts.dataDir ? import_node_path33.default.resolve(opts.dataDir) : null;
52371
+ const hostname = opts.hostname ?? import_node_os14.default.hostname();
52372
+ const uid = opts.uid ?? (typeof import_node_os14.default.userInfo === "function" ? import_node_os14.default.userInfo().uid : 0);
52373
+ const home = opts.home ?? import_node_os14.default.homedir();
52374
+ const defaultDataDir = import_node_path34.default.resolve(import_node_path34.default.join(home, ".clawd"));
52375
+ const normalizedDataDir = opts.dataDir ? import_node_path34.default.resolve(opts.dataDir) : null;
52325
52376
  const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
52326
52377
  const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
52327
52378
  return import_node_crypto10.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
@@ -52329,11 +52380,11 @@ function deriveStableDeviceKey(opts = {}) {
52329
52380
 
52330
52381
  // src/auth-store.ts
52331
52382
  var import_node_fs33 = __toESM(require("fs"), 1);
52332
- var import_node_path34 = __toESM(require("path"), 1);
52383
+ var import_node_path35 = __toESM(require("path"), 1);
52333
52384
  var import_node_crypto11 = __toESM(require("crypto"), 1);
52334
52385
  var AUTH_FILE_NAME = "auth.json";
52335
52386
  function authFilePath(dataDir) {
52336
- return import_node_path34.default.join(dataDir, AUTH_FILE_NAME);
52387
+ return import_node_path35.default.join(dataDir, AUTH_FILE_NAME);
52337
52388
  }
52338
52389
  function loadOrCreateAuthFile(opts) {
52339
52390
  const file = authFilePath(opts.dataDir);
@@ -52389,7 +52440,7 @@ function readAuthFile(file) {
52389
52440
  }
52390
52441
  }
52391
52442
  function writeAuthFile(file, content) {
52392
- import_node_fs33.default.mkdirSync(import_node_path34.default.dirname(file), { recursive: true });
52443
+ import_node_fs33.default.mkdirSync(import_node_path35.default.dirname(file), { recursive: true });
52393
52444
  import_node_fs33.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
52394
52445
  try {
52395
52446
  import_node_fs33.default.chmodSync(file, 384);
@@ -52399,12 +52450,12 @@ function writeAuthFile(file, content) {
52399
52450
 
52400
52451
  // src/owner-profile.ts
52401
52452
  var import_node_fs34 = __toESM(require("fs"), 1);
52402
- var import_node_os14 = __toESM(require("os"), 1);
52403
- var import_node_path35 = __toESM(require("path"), 1);
52453
+ var import_node_os15 = __toESM(require("os"), 1);
52454
+ var import_node_path36 = __toESM(require("path"), 1);
52404
52455
  var PROFILE_FILENAME = "profile.json";
52405
52456
  function loadOwnerDisplayName(dataDir) {
52406
- const fallback = import_node_os14.default.userInfo().username;
52407
- const profilePath = import_node_path35.default.join(dataDir, PROFILE_FILENAME);
52457
+ const fallback = import_node_os15.default.userInfo().username;
52458
+ const profilePath = import_node_path36.default.join(dataDir, PROFILE_FILENAME);
52408
52459
  let raw;
52409
52460
  try {
52410
52461
  raw = import_node_fs34.default.readFileSync(profilePath, "utf8");
@@ -52431,12 +52482,12 @@ function loadOwnerDisplayName(dataDir) {
52431
52482
 
52432
52483
  // src/feishu-auth/owner-identity-store.ts
52433
52484
  var import_node_fs35 = __toESM(require("fs"), 1);
52434
- var import_node_path36 = __toESM(require("path"), 1);
52485
+ var import_node_path37 = __toESM(require("path"), 1);
52435
52486
  var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
52436
52487
  var OwnerIdentityStore = class {
52437
52488
  file;
52438
52489
  constructor(dataDir) {
52439
- this.file = import_node_path36.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
52490
+ this.file = import_node_path37.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
52440
52491
  }
52441
52492
  read() {
52442
52493
  let raw;
@@ -52469,7 +52520,7 @@ var OwnerIdentityStore = class {
52469
52520
  };
52470
52521
  }
52471
52522
  write(record) {
52472
- import_node_fs35.default.mkdirSync(import_node_path36.default.dirname(this.file), { recursive: true });
52523
+ import_node_fs35.default.mkdirSync(import_node_path37.default.dirname(this.file), { recursive: true });
52473
52524
  import_node_fs35.default.writeFileSync(this.file, JSON.stringify(record, null, 2), { mode: 384 });
52474
52525
  try {
52475
52526
  import_node_fs35.default.chmodSync(this.file, 384);
@@ -52599,9 +52650,9 @@ var CentralClientError = class extends Error {
52599
52650
  code;
52600
52651
  cause;
52601
52652
  };
52602
- async function centralRequest(opts, path66, init) {
52653
+ async function centralRequest(opts, path67, init) {
52603
52654
  const f = opts.fetchImpl ?? globalThis.fetch;
52604
- const url = `${opts.api.replace(/\/+$/, "")}${path66}`;
52655
+ const url = `${opts.api.replace(/\/+$/, "")}${path67}`;
52605
52656
  const ctrl = new AbortController();
52606
52657
  const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
52607
52658
  let res;
@@ -52744,7 +52795,7 @@ function verifyConnectToken(args) {
52744
52795
 
52745
52796
  // src/feishu-auth/server-key.ts
52746
52797
  var fs45 = __toESM(require("fs"), 1);
52747
- var path45 = __toESM(require("path"), 1);
52798
+ var path46 = __toESM(require("path"), 1);
52748
52799
  var FILE_NAME2 = "server-signing-key.json";
52749
52800
  var ServerKeyStore = class {
52750
52801
  constructor(dataDir) {
@@ -52752,7 +52803,7 @@ var ServerKeyStore = class {
52752
52803
  }
52753
52804
  dataDir;
52754
52805
  filePath() {
52755
- return path45.join(this.dataDir, FILE_NAME2);
52806
+ return path46.join(this.dataDir, FILE_NAME2);
52756
52807
  }
52757
52808
  /** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
52758
52809
  read() {
@@ -52791,8 +52842,8 @@ init_protocol();
52791
52842
 
52792
52843
  // src/session/fork.ts
52793
52844
  var import_node_fs36 = __toESM(require("fs"), 1);
52794
- var import_node_os15 = __toESM(require("os"), 1);
52795
- var import_node_path37 = __toESM(require("path"), 1);
52845
+ var import_node_os16 = __toESM(require("os"), 1);
52846
+ var import_node_path38 = __toESM(require("path"), 1);
52796
52847
  init_claude_history();
52797
52848
  function readJsonlEntries(file) {
52798
52849
  const raw = import_node_fs36.default.readFileSync(file, "utf8");
@@ -52808,9 +52859,9 @@ function readJsonlEntries(file) {
52808
52859
  return out;
52809
52860
  }
52810
52861
  function forkSession(input) {
52811
- const baseDir = input.baseDir ?? import_node_path37.default.join(import_node_os15.default.homedir(), ".claude");
52812
- const projectDir = import_node_path37.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
52813
- const sourceFile = import_node_path37.default.join(projectDir, `${input.toolSessionId}.jsonl`);
52862
+ const baseDir = input.baseDir ?? import_node_path38.default.join(import_node_os16.default.homedir(), ".claude");
52863
+ const projectDir = import_node_path38.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
52864
+ const sourceFile = import_node_path38.default.join(projectDir, `${input.toolSessionId}.jsonl`);
52814
52865
  if (!import_node_fs36.default.existsSync(sourceFile)) {
52815
52866
  throw new Error(`fork: source transcript not found: ${sourceFile}`);
52816
52867
  }
@@ -52841,7 +52892,7 @@ function forkSession(input) {
52841
52892
  }
52842
52893
  forkedLines.push(JSON.stringify(forked));
52843
52894
  }
52844
- const forkedFilePath = import_node_path37.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
52895
+ const forkedFilePath = import_node_path38.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
52845
52896
  import_node_fs36.default.mkdirSync(projectDir, { recursive: true });
52846
52897
  import_node_fs36.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
52847
52898
  return { forkedToolSessionId, forkedFilePath };
@@ -53195,7 +53246,7 @@ function buildPermissionHandlers(deps) {
53195
53246
  }
53196
53247
 
53197
53248
  // src/handlers/history.ts
53198
- var path48 = __toESM(require("path"), 1);
53249
+ var path49 = __toESM(require("path"), 1);
53199
53250
  init_protocol();
53200
53251
 
53201
53252
  // src/session/recent-dirs.ts
@@ -53213,7 +53264,7 @@ function listRecentDirs(store, limit = 50) {
53213
53264
  }
53214
53265
 
53215
53266
  // src/permission/persona-paths.ts
53216
- var path47 = __toESM(require("path"), 1);
53267
+ var path48 = __toESM(require("path"), 1);
53217
53268
  function getAllowedPersonaIds(grants, action) {
53218
53269
  const ids = /* @__PURE__ */ new Set();
53219
53270
  for (const g2 of grants) {
@@ -53226,42 +53277,42 @@ function getAllowedPersonaIds(grants, action) {
53226
53277
  return ids;
53227
53278
  }
53228
53279
  function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
53229
- const target = path47.resolve(absPath);
53280
+ const target = path48.resolve(absPath);
53230
53281
  if (userWorkDir) {
53231
- const u = path47.resolve(userWorkDir);
53232
- const usep = u.endsWith(path47.sep) ? "" : path47.sep;
53282
+ const u = path48.resolve(userWorkDir);
53283
+ const usep = u.endsWith(path48.sep) ? "" : path48.sep;
53233
53284
  if (target === u || target.startsWith(u + usep)) return true;
53234
53285
  }
53235
- const root = path47.resolve(personaRoot);
53236
- const sep3 = root.endsWith(path47.sep) ? "" : path47.sep;
53286
+ const root = path48.resolve(personaRoot);
53287
+ const sep3 = root.endsWith(path48.sep) ? "" : path48.sep;
53237
53288
  if (!target.startsWith(root + sep3)) return false;
53238
- const rel = path47.relative(root, target);
53289
+ const rel = path48.relative(root, target);
53239
53290
  if (!rel || rel.startsWith("..")) return false;
53240
- const personaId = rel.split(path47.sep)[0];
53291
+ const personaId = rel.split(path48.sep)[0];
53241
53292
  if (!personaId) return false;
53242
53293
  const allowed = getAllowedPersonaIds(grants, action);
53243
53294
  if (allowed === "*") return true;
53244
53295
  return allowed.has(personaId);
53245
53296
  }
53246
53297
  function personaIdFromPath(absPath, personaRoot) {
53247
- const root = path47.resolve(personaRoot);
53248
- const target = path47.resolve(absPath);
53249
- const sep3 = root.endsWith(path47.sep) ? "" : path47.sep;
53298
+ const root = path48.resolve(personaRoot);
53299
+ const target = path48.resolve(absPath);
53300
+ const sep3 = root.endsWith(path48.sep) ? "" : path48.sep;
53250
53301
  if (!target.startsWith(root + sep3)) return null;
53251
- const rel = path47.relative(root, target);
53302
+ const rel = path48.relative(root, target);
53252
53303
  if (!rel || rel.startsWith("..")) return null;
53253
- const id = rel.split(path47.sep)[0];
53304
+ const id = rel.split(path48.sep)[0];
53254
53305
  return id || null;
53255
53306
  }
53256
53307
  function isPathWithin(dir, absPath) {
53257
- const d = path47.resolve(dir);
53258
- const t = path47.resolve(absPath);
53259
- const sep3 = d.endsWith(path47.sep) ? "" : path47.sep;
53308
+ const d = path48.resolve(dir);
53309
+ const t = path48.resolve(absPath);
53310
+ const sep3 = d.endsWith(path48.sep) ? "" : path48.sep;
53260
53311
  return t === d || t.startsWith(d + sep3);
53261
53312
  }
53262
53313
  function isPathInGuestBoundary(personaRoot, personaId, userWorkDir, absPath) {
53263
53314
  if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
53264
- return personaIdFromPath(path47.resolve(absPath), personaRoot) === personaId;
53315
+ return personaIdFromPath(path48.resolve(absPath), personaRoot) === personaId;
53265
53316
  }
53266
53317
 
53267
53318
  // src/handlers/history.ts
@@ -53287,7 +53338,7 @@ function buildHistoryHandlers(deps) {
53287
53338
  if (!pid) return false;
53288
53339
  return isGuestPathAllowed(
53289
53340
  ctx.grants,
53290
- path48.join(personaRoot, pid),
53341
+ path49.join(personaRoot, pid),
53291
53342
  personaRoot,
53292
53343
  "read",
53293
53344
  userWorkDir
@@ -53299,7 +53350,7 @@ function buildHistoryHandlers(deps) {
53299
53350
  };
53300
53351
  const list = async (frame, _client, ctx) => {
53301
53352
  const args = HistoryListArgs.parse(frame);
53302
- assertGuestPath(ctx, path48.resolve(args.projectPath), personaRoot, "history:list");
53353
+ assertGuestPath(ctx, path49.resolve(args.projectPath), personaRoot, "history:list");
53303
53354
  const sessions = await history.listSessions(args);
53304
53355
  return { response: { type: "history:list", sessions } };
53305
53356
  };
@@ -53331,13 +53382,13 @@ function buildHistoryHandlers(deps) {
53331
53382
  };
53332
53383
  const subagents = async (frame, _client, ctx) => {
53333
53384
  const args = HistorySubagentsArgs.parse(frame);
53334
- assertGuestPath(ctx, path48.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
53385
+ assertGuestPath(ctx, path49.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
53335
53386
  const subs = await history.listSubagents(args);
53336
53387
  return { response: { type: "history:subagents", subagents: subs } };
53337
53388
  };
53338
53389
  const subagentRead = async (frame, _client, ctx) => {
53339
53390
  const args = HistorySubagentReadArgs.parse(frame);
53340
- assertGuestPath(ctx, path48.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
53391
+ assertGuestPath(ctx, path49.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
53341
53392
  const res = await history.readSubagent(args);
53342
53393
  return { response: { type: "history:subagent-read", ...res } };
53343
53394
  };
@@ -53346,7 +53397,7 @@ function buildHistoryHandlers(deps) {
53346
53397
  if (ctx?.principal.kind === "guest" && personaRoot) {
53347
53398
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
53348
53399
  const filtered = dirs.filter(
53349
- (d) => isGuestPathAllowed(ctx.grants, path48.resolve(d.cwd), personaRoot, "read", userWorkDir)
53400
+ (d) => isGuestPathAllowed(ctx.grants, path49.resolve(d.cwd), personaRoot, "read", userWorkDir)
53350
53401
  );
53351
53402
  return { response: { type: "history:recentDirs", dirs: filtered } };
53352
53403
  }
@@ -53363,8 +53414,8 @@ function buildHistoryHandlers(deps) {
53363
53414
  }
53364
53415
 
53365
53416
  // src/handlers/workspace.ts
53366
- var path49 = __toESM(require("path"), 1);
53367
- var os15 = __toESM(require("os"), 1);
53417
+ var path50 = __toESM(require("path"), 1);
53418
+ var os16 = __toESM(require("os"), 1);
53368
53419
  init_protocol();
53369
53420
  init_protocol();
53370
53421
  function buildEnabledPluginNames(personaManager, personaId) {
@@ -53404,23 +53455,23 @@ function buildWorkspaceHandlers(deps) {
53404
53455
  const list = async (frame, _client, ctx) => {
53405
53456
  const args = WorkspaceListArgs.parse(frame);
53406
53457
  const isGuest = ctx?.principal.kind === "guest";
53407
- const fallbackCwd = isGuest && personaRoot ? personaRoot : os15.homedir();
53408
- const resolvedCwd = path49.resolve(args.cwd ?? fallbackCwd);
53409
- const target = args.path ? path49.resolve(resolvedCwd, args.path) : resolvedCwd;
53458
+ const fallbackCwd = isGuest && personaRoot ? personaRoot : os16.homedir();
53459
+ const resolvedCwd = path50.resolve(args.cwd ?? fallbackCwd);
53460
+ const target = args.path ? path50.resolve(resolvedCwd, args.path) : resolvedCwd;
53410
53461
  assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
53411
53462
  const res = workspace.list({ ...args, cwd: resolvedCwd });
53412
53463
  return { response: { type: "workspace:list", ...res } };
53413
53464
  };
53414
53465
  const read = async (frame, _client, ctx) => {
53415
53466
  const args = WorkspaceReadArgs.parse(frame);
53416
- const target = path49.isAbsolute(args.path) ? path49.resolve(args.path) : path49.resolve(args.cwd, args.path);
53467
+ const target = path50.isAbsolute(args.path) ? path50.resolve(args.path) : path50.resolve(args.cwd, args.path);
53417
53468
  assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
53418
53469
  const res = workspace.read(args);
53419
53470
  return { response: { type: "workspace:read", ...res } };
53420
53471
  };
53421
53472
  const skillsList = async (frame, _client, ctx) => {
53422
53473
  const args = SkillsListArgs.parse(frame);
53423
- const cwdAbs = path49.resolve(args.cwd);
53474
+ const cwdAbs = path50.resolve(args.cwd);
53424
53475
  assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
53425
53476
  const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
53426
53477
  if (ctx?.principal.kind === "guest" && personaRoot) {
@@ -53432,7 +53483,7 @@ function buildWorkspaceHandlers(deps) {
53432
53483
  };
53433
53484
  const agentsList = async (frame, _client, ctx) => {
53434
53485
  const args = AgentsListArgs.parse(frame);
53435
- const cwdAbs = path49.resolve(args.cwd);
53486
+ const cwdAbs = path50.resolve(args.cwd);
53436
53487
  assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
53437
53488
  if (args.tool === "codex") {
53438
53489
  return { response: { type: "agents:list", agents: [] } };
@@ -53454,18 +53505,18 @@ function buildWorkspaceHandlers(deps) {
53454
53505
  }
53455
53506
 
53456
53507
  // src/handlers/git.ts
53457
- var path51 = __toESM(require("path"), 1);
53508
+ var path52 = __toESM(require("path"), 1);
53458
53509
  init_protocol();
53459
53510
  init_protocol();
53460
53511
 
53461
53512
  // src/workspace/git.ts
53462
53513
  var import_node_child_process10 = require("child_process");
53463
53514
  var import_node_fs37 = __toESM(require("fs"), 1);
53464
- var import_node_path38 = __toESM(require("path"), 1);
53515
+ var import_node_path39 = __toESM(require("path"), 1);
53465
53516
  var import_node_util = require("util");
53466
53517
  var pexec = (0, import_node_util.promisify)(import_node_child_process10.execFile);
53467
53518
  function normalizePath(p2) {
53468
- const resolved = import_node_path38.default.resolve(p2);
53519
+ const resolved = import_node_path39.default.resolve(p2);
53469
53520
  try {
53470
53521
  return import_node_fs37.default.realpathSync(resolved);
53471
53522
  } catch {
@@ -53541,7 +53592,7 @@ async function listGitBranches(cwd) {
53541
53592
  function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
53542
53593
  if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
53543
53594
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
53544
- if (!isGuestPathAllowed(ctx.grants, path51.resolve(cwd), personaRoot, "read", userWorkDir)) {
53595
+ if (!isGuestPathAllowed(ctx.grants, path52.resolve(cwd), personaRoot, "read", userWorkDir)) {
53545
53596
  throw new ClawdError(
53546
53597
  ERROR_CODES.UNAUTHORIZED,
53547
53598
  `guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
@@ -53930,7 +53981,7 @@ function buildDeviceHandlers(deps) {
53930
53981
  }
53931
53982
 
53932
53983
  // src/handlers/meta.ts
53933
- var import_node_os16 = __toESM(require("os"), 1);
53984
+ var import_node_os17 = __toESM(require("os"), 1);
53934
53985
  init_protocol();
53935
53986
 
53936
53987
  // src/version.ts
@@ -53962,7 +54013,7 @@ function buildReadyFrame(deps, client) {
53962
54013
  return {
53963
54014
  version,
53964
54015
  protocolVersion: PROTOCOL_VERSION,
53965
- hostname: import_node_os16.default.hostname(),
54016
+ hostname: import_node_os17.default.hostname(),
53966
54017
  os: process.platform,
53967
54018
  tools,
53968
54019
  runningSessions: info.runningSessions,
@@ -54059,7 +54110,7 @@ function buildPersonaHandlers(deps) {
54059
54110
  }
54060
54111
 
54061
54112
  // src/handlers/attachment.ts
54062
- var import_node_path39 = __toESM(require("path"), 1);
54113
+ var import_node_path40 = __toESM(require("path"), 1);
54063
54114
  init_protocol();
54064
54115
  init_protocol();
54065
54116
  var DEFAULT_TTL_SECONDS = 24 * 3600;
@@ -54139,12 +54190,12 @@ function buildAttachmentHandlers(deps) {
54139
54190
  `session ${args.sessionId} scope unresolved`
54140
54191
  );
54141
54192
  }
54142
- const cwdAbs = import_node_path39.default.resolve(sessionFile.cwd);
54143
- const candidateAbs = import_node_path39.default.isAbsolute(args.relPath) ? import_node_path39.default.resolve(args.relPath) : import_node_path39.default.resolve(cwdAbs, args.relPath);
54193
+ const cwdAbs = import_node_path40.default.resolve(sessionFile.cwd);
54194
+ const candidateAbs = import_node_path40.default.isAbsolute(args.relPath) ? import_node_path40.default.resolve(args.relPath) : import_node_path40.default.resolve(cwdAbs, args.relPath);
54144
54195
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
54145
54196
  const entries = deps.groupFileStore.list(scope, args.sessionId);
54146
54197
  const entry = entries.find((e) => {
54147
- const storedAbs = import_node_path39.default.isAbsolute(e.relPath) ? import_node_path39.default.resolve(e.relPath) : import_node_path39.default.resolve(cwdAbs, e.relPath);
54198
+ const storedAbs = import_node_path40.default.isAbsolute(e.relPath) ? import_node_path40.default.resolve(e.relPath) : import_node_path40.default.resolve(cwdAbs, e.relPath);
54148
54199
  return storedAbs === candidateAbs && !e.stale;
54149
54200
  });
54150
54201
  if (!entry) {
@@ -54169,7 +54220,7 @@ function buildAttachmentHandlers(deps) {
54169
54220
  if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
54170
54221
  const f = deps.sessionStore.read(sessionId);
54171
54222
  if (!f) return;
54172
- assertGuestAttachmentPath(ctx, import_node_path39.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
54223
+ assertGuestAttachmentPath(ctx, import_node_path40.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
54173
54224
  }
54174
54225
  const groupAdd = async (frame, _client, ctx) => {
54175
54226
  if (!deps.groupFileStore || !deps.getSessionScope) {
@@ -54184,8 +54235,8 @@ function buildAttachmentHandlers(deps) {
54184
54235
  if (!scope) {
54185
54236
  throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
54186
54237
  }
54187
- const cwdAbs = import_node_path39.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
54188
- const candidateAbs = import_node_path39.default.isAbsolute(args.relPath) ? import_node_path39.default.resolve(args.relPath) : import_node_path39.default.resolve(cwdAbs, args.relPath);
54238
+ const cwdAbs = import_node_path40.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
54239
+ const candidateAbs = import_node_path40.default.isAbsolute(args.relPath) ? import_node_path40.default.resolve(args.relPath) : import_node_path40.default.resolve(cwdAbs, args.relPath);
54189
54240
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
54190
54241
  const from = ctx?.principal.kind === "owner" ? "owner" : "agent";
54191
54242
  const size = 0;
@@ -54244,19 +54295,19 @@ function buildAttachmentHandlers(deps) {
54244
54295
 
54245
54296
  // src/handlers/extension.ts
54246
54297
  var import_promises8 = __toESM(require("fs/promises"), 1);
54247
- var import_node_path44 = __toESM(require("path"), 1);
54298
+ var import_node_path45 = __toESM(require("path"), 1);
54248
54299
  init_protocol();
54249
54300
 
54250
54301
  // src/extension/bundle-zip.ts
54251
54302
  var import_promises5 = __toESM(require("fs/promises"), 1);
54252
- var import_node_path40 = __toESM(require("path"), 1);
54303
+ var import_node_path41 = __toESM(require("path"), 1);
54253
54304
  var import_node_crypto13 = __toESM(require("crypto"), 1);
54254
54305
  var import_jszip2 = __toESM(require_lib3(), 1);
54255
54306
  async function bundleExtensionDir(dir) {
54256
54307
  const entries = await listFilesSorted(dir);
54257
54308
  const zip = new import_jszip2.default();
54258
54309
  for (const rel of entries) {
54259
- const abs = import_node_path40.default.join(dir, rel);
54310
+ const abs = import_node_path41.default.join(dir, rel);
54260
54311
  const content = await import_promises5.default.readFile(abs);
54261
54312
  zip.file(rel, content, { date: FIXED_DATE });
54262
54313
  }
@@ -54277,7 +54328,7 @@ async function listFilesSorted(rootDir) {
54277
54328
  return out;
54278
54329
  }
54279
54330
  async function walk(absRoot, relPrefix, out) {
54280
- const dirAbs = import_node_path40.default.join(absRoot, relPrefix);
54331
+ const dirAbs = import_node_path41.default.join(absRoot, relPrefix);
54281
54332
  const entries = await import_promises5.default.readdir(dirAbs, { withFileTypes: true });
54282
54333
  for (const e of entries) {
54283
54334
  if (IGNORE_BASENAMES.has(e.name)) continue;
@@ -54331,25 +54382,25 @@ function computePublishCheck(args) {
54331
54382
 
54332
54383
  // src/extension/install-flow.ts
54333
54384
  var import_promises6 = __toESM(require("fs/promises"), 1);
54334
- var import_node_path42 = __toESM(require("path"), 1);
54335
- var import_node_os18 = __toESM(require("os"), 1);
54385
+ var import_node_path43 = __toESM(require("path"), 1);
54386
+ var import_node_os19 = __toESM(require("os"), 1);
54336
54387
  var import_node_crypto14 = __toESM(require("crypto"), 1);
54337
54388
  var import_jszip3 = __toESM(require_lib3(), 1);
54338
54389
 
54339
54390
  // src/extension/paths.ts
54340
- var import_node_os17 = __toESM(require("os"), 1);
54341
- var import_node_path41 = __toESM(require("path"), 1);
54391
+ var import_node_os18 = __toESM(require("os"), 1);
54392
+ var import_node_path42 = __toESM(require("path"), 1);
54342
54393
  function clawdHomeRoot(override) {
54343
- return override ?? process.env.CLAWD_HOME ?? import_node_path41.default.join(import_node_os17.default.homedir(), ".clawd");
54394
+ return override ?? process.env.CLAWD_HOME ?? import_node_path42.default.join(import_node_os18.default.homedir(), ".clawd");
54344
54395
  }
54345
54396
  function extensionsRoot(override) {
54346
- return import_node_path41.default.join(clawdHomeRoot(override), "extensions");
54397
+ return import_node_path42.default.join(clawdHomeRoot(override), "extensions");
54347
54398
  }
54348
54399
  function publishedChannelsFile(override) {
54349
- return import_node_path41.default.join(clawdHomeRoot(override), "extensions-published.json");
54400
+ return import_node_path42.default.join(clawdHomeRoot(override), "extensions-published.json");
54350
54401
  }
54351
54402
  function bundleCacheRoot(override) {
54352
- return import_node_path41.default.join(clawdHomeRoot(override), "extension-bundles");
54403
+ return import_node_path42.default.join(clawdHomeRoot(override), "extension-bundles");
54353
54404
  }
54354
54405
 
54355
54406
  // src/extension/install-flow.ts
@@ -54376,7 +54427,7 @@ async function installFromChannel(args, deps) {
54376
54427
  throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
54377
54428
  }
54378
54429
  for (const name of Object.keys(zip.files)) {
54379
- if (name.includes("..") || name.startsWith("/") || import_node_path42.default.isAbsolute(name)) {
54430
+ if (name.includes("..") || name.startsWith("/") || import_node_path43.default.isAbsolute(name)) {
54380
54431
  throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
54381
54432
  }
54382
54433
  }
@@ -54408,7 +54459,7 @@ async function installFromChannel(args, deps) {
54408
54459
  );
54409
54460
  }
54410
54461
  const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
54411
- const destDir = import_node_path42.default.join(deps.extensionsRoot, localExtId);
54462
+ const destDir = import_node_path43.default.join(deps.extensionsRoot, localExtId);
54412
54463
  let destExists = false;
54413
54464
  try {
54414
54465
  await import_promises6.default.access(destDir);
@@ -54422,16 +54473,16 @@ async function installFromChannel(args, deps) {
54422
54473
  );
54423
54474
  }
54424
54475
  const stage = await import_promises6.default.mkdtemp(
54425
- import_node_path42.default.join(import_node_os18.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
54476
+ import_node_path43.default.join(import_node_os19.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
54426
54477
  );
54427
54478
  try {
54428
54479
  for (const [name, entry] of Object.entries(zip.files)) {
54429
- const dest = import_node_path42.default.join(stage, name);
54480
+ const dest = import_node_path43.default.join(stage, name);
54430
54481
  if (entry.dir) {
54431
54482
  await import_promises6.default.mkdir(dest, { recursive: true });
54432
54483
  continue;
54433
54484
  }
54434
- await import_promises6.default.mkdir(import_node_path42.default.dirname(dest), { recursive: true });
54485
+ await import_promises6.default.mkdir(import_node_path43.default.dirname(dest), { recursive: true });
54435
54486
  if (name === "manifest.json") {
54436
54487
  const rewritten = { ...parsed.data, id: localExtId };
54437
54488
  await import_promises6.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -54452,8 +54503,8 @@ async function installFromChannel(args, deps) {
54452
54503
 
54453
54504
  // src/extension/update-flow.ts
54454
54505
  var import_promises7 = __toESM(require("fs/promises"), 1);
54455
- var import_node_path43 = __toESM(require("path"), 1);
54456
- var import_node_os19 = __toESM(require("os"), 1);
54506
+ var import_node_path44 = __toESM(require("path"), 1);
54507
+ var import_node_os20 = __toESM(require("os"), 1);
54457
54508
  var import_node_crypto15 = __toESM(require("crypto"), 1);
54458
54509
  var import_jszip4 = __toESM(require_lib3(), 1);
54459
54510
  var UpdateError = class extends Error {
@@ -54469,11 +54520,11 @@ async function updateFromChannel(args, deps) {
54469
54520
  channelRef.extId,
54470
54521
  channelRef.ownerPrincipalId
54471
54522
  );
54472
- const liveDir = import_node_path43.default.join(deps.extensionsRoot, localExtId);
54523
+ const liveDir = import_node_path44.default.join(deps.extensionsRoot, localExtId);
54473
54524
  const prevDir = `${liveDir}.prev`;
54474
54525
  let existingVersion;
54475
54526
  try {
54476
- const raw = await import_promises7.default.readFile(import_node_path43.default.join(liveDir, "manifest.json"), "utf8");
54527
+ const raw = await import_promises7.default.readFile(import_node_path44.default.join(liveDir, "manifest.json"), "utf8");
54477
54528
  const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
54478
54529
  if (!parsed2.success) {
54479
54530
  throw new UpdateError(
@@ -54506,7 +54557,7 @@ async function updateFromChannel(args, deps) {
54506
54557
  throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
54507
54558
  }
54508
54559
  for (const name of Object.keys(zip.files)) {
54509
- if (name.includes("..") || name.startsWith("/") || import_node_path43.default.isAbsolute(name)) {
54560
+ if (name.includes("..") || name.startsWith("/") || import_node_path44.default.isAbsolute(name)) {
54510
54561
  throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
54511
54562
  }
54512
54563
  }
@@ -54541,16 +54592,16 @@ async function updateFromChannel(args, deps) {
54541
54592
  await import_promises7.default.rm(prevDir, { recursive: true, force: true });
54542
54593
  await import_promises7.default.rename(liveDir, prevDir);
54543
54594
  const stage = await import_promises7.default.mkdtemp(
54544
- import_node_path43.default.join(import_node_os19.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
54595
+ import_node_path44.default.join(import_node_os20.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
54545
54596
  );
54546
54597
  try {
54547
54598
  for (const [name, entry] of Object.entries(zip.files)) {
54548
- const dest = import_node_path43.default.join(stage, name);
54599
+ const dest = import_node_path44.default.join(stage, name);
54549
54600
  if (entry.dir) {
54550
54601
  await import_promises7.default.mkdir(dest, { recursive: true });
54551
54602
  continue;
54552
54603
  }
54553
- await import_promises7.default.mkdir(import_node_path43.default.dirname(dest), { recursive: true });
54604
+ await import_promises7.default.mkdir(import_node_path44.default.dirname(dest), { recursive: true });
54554
54605
  if (name === "manifest.json") {
54555
54606
  const rewritten = { ...parsed.data, id: localExtId };
54556
54607
  await import_promises7.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -54643,7 +54694,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
54643
54694
  );
54644
54695
  }
54645
54696
  }
54646
- const manifestPath = import_node_path44.default.join(root, extId, "manifest.json");
54697
+ const manifestPath = import_node_path45.default.join(root, extId, "manifest.json");
54647
54698
  const manifest = await readManifest(root, extId);
54648
54699
  const next = { ...manifest, version: newVersion };
54649
54700
  const tmp = `${manifestPath}.tmp`;
@@ -54651,7 +54702,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
54651
54702
  await import_promises8.default.rename(tmp, manifestPath);
54652
54703
  }
54653
54704
  async function readManifest(root, extId) {
54654
- const file = import_node_path44.default.join(root, extId, "manifest.json");
54705
+ const file = import_node_path45.default.join(root, extId, "manifest.json");
54655
54706
  let raw;
54656
54707
  try {
54657
54708
  raw = await import_promises8.default.readFile(file, "utf8");
@@ -54742,7 +54793,7 @@ function buildExtensionHandlers(deps) {
54742
54793
  };
54743
54794
  async function buildSnapshotMeta(extId) {
54744
54795
  const manifest = await readManifest(deps.root, extId);
54745
- const { sha256, buffer } = await bundleExtensionDir(import_node_path44.default.join(deps.root, extId));
54796
+ const { sha256, buffer } = await bundleExtensionDir(import_node_path45.default.join(deps.root, extId));
54746
54797
  return { manifest, contentHash: sha256, buffer };
54747
54798
  }
54748
54799
  const publish = async (frame, _client, ctx) => {
@@ -54925,7 +54976,7 @@ function buildExtensionHandlers(deps) {
54925
54976
  // src/app-builder/project-store.ts
54926
54977
  var import_node_fs38 = require("fs");
54927
54978
  var import_node_child_process11 = require("child_process");
54928
- var import_node_path45 = require("path");
54979
+ var import_node_path46 = require("path");
54929
54980
  init_protocol();
54930
54981
  var PROJECTS_DIR = "projects";
54931
54982
  var META_FILE = ".clawd-project.json";
@@ -54939,14 +54990,14 @@ var ProjectStore = class {
54939
54990
  root;
54940
54991
  /** projects/<name>/.clawd-project.json 路径 */
54941
54992
  metaPath(name) {
54942
- return (0, import_node_path45.join)(this.projectsRoot(), name, META_FILE);
54993
+ return (0, import_node_path46.join)(this.projectsRoot(), name, META_FILE);
54943
54994
  }
54944
54995
  /** projects/<name>/ 目录路径(cwd 用) */
54945
54996
  projectDir(name) {
54946
- return (0, import_node_path45.join)(this.projectsRoot(), name);
54997
+ return (0, import_node_path46.join)(this.projectsRoot(), name);
54947
54998
  }
54948
54999
  projectsRoot() {
54949
- return (0, import_node_path45.join)(this.root, PROJECTS_DIR);
55000
+ return (0, import_node_path46.join)(this.root, PROJECTS_DIR);
54950
55001
  }
54951
55002
  async list() {
54952
55003
  let entries;
@@ -55249,7 +55300,7 @@ var PublishJobRegistry = class {
55249
55300
  // src/app-builder/publish-job-runner.ts
55250
55301
  var import_node_child_process13 = require("child_process");
55251
55302
  var import_node_fs39 = require("fs");
55252
- var import_node_path46 = require("path");
55303
+ var import_node_path47 = require("path");
55253
55304
 
55254
55305
  // src/app-builder/publish-stage-parser.ts
55255
55306
  var STAGE_RE = /^\s*::stage::(build|deploy|verify)\s*$/;
@@ -55281,7 +55332,7 @@ async function startPublishJob(deps, args) {
55281
55332
  return { jobId: registry2.get(args.name).jobId, status: "already-publishing" };
55282
55333
  }
55283
55334
  const projDir = projectDir(args.name);
55284
- const logPath = (0, import_node_path46.join)(projDir, ".publish.log");
55335
+ const logPath = (0, import_node_path47.join)(projDir, ".publish.log");
55285
55336
  let logStream = null;
55286
55337
  try {
55287
55338
  logStream = (0, import_node_fs39.createWriteStream)(logPath, { flags: "w" });
@@ -55541,7 +55592,7 @@ async function recoverInterruptedJobs(deps) {
55541
55592
 
55542
55593
  // src/handlers/app-builder.ts
55543
55594
  init_protocol();
55544
- var import_node_path47 = require("path");
55595
+ var import_node_path48 = require("path");
55545
55596
  var import_node_fs40 = require("fs");
55546
55597
  var APP_BUILDER_PERSONAS = ["persona-app-builder", "persona-dataclaw-builder"];
55547
55598
  var DEV_SERVER_READY_TIMEOUT_MS = 3e4;
@@ -55699,8 +55750,8 @@ function buildAppBuilderHandlers(deps) {
55699
55750
  const project = await userStore.create(f.name, reservedPorts);
55700
55751
  try {
55701
55752
  const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(session.ownerPersonaId ?? "") : deps.personaRoot;
55702
- const templateSrcDir = (0, import_node_path47.join)(personaRoot, "extension-kit", "examples", DEFAULT_TEMPLATE);
55703
- const scaffoldScript = (0, import_node_path47.join)(deps.deployKitRoot, "scripts", "new-extension.sh");
55753
+ const templateSrcDir = (0, import_node_path48.join)(personaRoot, "extension-kit", "examples", DEFAULT_TEMPLATE);
55754
+ const scaffoldScript = (0, import_node_path48.join)(deps.deployKitRoot, "scripts", "new-extension.sh");
55704
55755
  const scaffoldResult = await userStore.scaffold(project.name, templateSrcDir, scaffoldScript);
55705
55756
  deps.logger?.info("app-builder.scaffold.done", {
55706
55757
  name: project.name,
@@ -55921,7 +55972,7 @@ function buildAppBuilderHandlers(deps) {
55921
55972
  await userStore.clearPublishJob(args.name);
55922
55973
  }
55923
55974
  const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(boundSession.ownerPersonaId ?? "") : deps.personaRoot;
55924
- const scriptPath = (0, import_node_path47.join)(deps.deployKitRoot, "scripts", "publish.sh");
55975
+ const scriptPath = (0, import_node_path48.join)(deps.deployKitRoot, "scripts", "publish.sh");
55925
55976
  deps.logger?.info("app-builder.publish.start", {
55926
55977
  name: args.name,
55927
55978
  sessionId: boundSession.sessionId,
@@ -56090,7 +56141,7 @@ function buildVisitorHandlers(deps) {
56090
56141
 
56091
56142
  // src/extension/registry.ts
56092
56143
  var import_promises9 = __toESM(require("fs/promises"), 1);
56093
- var import_node_path48 = __toESM(require("path"), 1);
56144
+ var import_node_path49 = __toESM(require("path"), 1);
56094
56145
  async function loadAll(root) {
56095
56146
  let entries;
56096
56147
  try {
@@ -56103,13 +56154,13 @@ async function loadAll(root) {
56103
56154
  for (const ent of entries) {
56104
56155
  if (!ent.isDirectory()) continue;
56105
56156
  if (ent.name.startsWith(".")) continue;
56106
- records.push(await loadOne(import_node_path48.default.join(root, ent.name), ent.name));
56157
+ records.push(await loadOne(import_node_path49.default.join(root, ent.name), ent.name));
56107
56158
  }
56108
56159
  records.sort((a, b2) => a.extId < b2.extId ? -1 : a.extId > b2.extId ? 1 : 0);
56109
56160
  return records;
56110
56161
  }
56111
56162
  async function loadOne(dir, dirName) {
56112
- const manifestPath = import_node_path48.default.join(dir, "manifest.json");
56163
+ const manifestPath = import_node_path49.default.join(dir, "manifest.json");
56113
56164
  let raw;
56114
56165
  try {
56115
56166
  raw = await import_promises9.default.readFile(manifestPath, "utf8");
@@ -56154,7 +56205,7 @@ async function loadOne(dir, dirName) {
56154
56205
 
56155
56206
  // src/extension/uninstall.ts
56156
56207
  var import_promises10 = __toESM(require("fs/promises"), 1);
56157
- var import_node_path49 = __toESM(require("path"), 1);
56208
+ var import_node_path50 = __toESM(require("path"), 1);
56158
56209
  var UninstallError = class extends Error {
56159
56210
  constructor(code, message) {
56160
56211
  super(message);
@@ -56163,7 +56214,7 @@ var UninstallError = class extends Error {
56163
56214
  code;
56164
56215
  };
56165
56216
  async function uninstall(deps) {
56166
- const dir = import_node_path49.default.join(deps.root, deps.extId);
56217
+ const dir = import_node_path50.default.join(deps.root, deps.extId);
56167
56218
  try {
56168
56219
  await import_promises10.default.access(dir);
56169
56220
  } catch {
@@ -56719,7 +56770,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
56719
56770
 
56720
56771
  // src/extension/runtime.ts
56721
56772
  var import_node_child_process15 = require("child_process");
56722
- var import_node_path50 = __toESM(require("path"), 1);
56773
+ var import_node_path51 = __toESM(require("path"), 1);
56723
56774
  var import_promises11 = require("timers/promises");
56724
56775
 
56725
56776
  // src/extension/port-allocator.ts
@@ -56820,7 +56871,7 @@ var Runtime = class {
56820
56871
  /\$CLAWOS_EXT_PORT/g,
56821
56872
  String(port)
56822
56873
  );
56823
- const dir = import_node_path50.default.join(this.root, extId);
56874
+ const dir = import_node_path51.default.join(this.root, extId);
56824
56875
  const env = {
56825
56876
  ...process.env,
56826
56877
  CLAWOS_EXT_PORT: String(port),
@@ -56932,7 +56983,7 @@ ${handle.stderrTail}`
56932
56983
 
56933
56984
  // src/extension/published-channels.ts
56934
56985
  var import_promises12 = __toESM(require("fs/promises"), 1);
56935
- var import_node_path51 = __toESM(require("path"), 1);
56986
+ var import_node_path52 = __toESM(require("path"), 1);
56936
56987
  init_zod();
56937
56988
  var PublishedChannelsError = class extends Error {
56938
56989
  constructor(code, message) {
@@ -57031,7 +57082,7 @@ var PublishedChannelStore = class {
57031
57082
  )
57032
57083
  };
57033
57084
  const tmp = `${this.filePath}.tmp`;
57034
- await import_promises12.default.mkdir(import_node_path51.default.dirname(this.filePath), { recursive: true });
57085
+ await import_promises12.default.mkdir(import_node_path52.default.dirname(this.filePath), { recursive: true });
57035
57086
  await import_promises12.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
57036
57087
  await import_promises12.default.rename(tmp, this.filePath);
57037
57088
  }
@@ -57039,7 +57090,7 @@ var PublishedChannelStore = class {
57039
57090
 
57040
57091
  // src/extension/bundle-cache.ts
57041
57092
  var import_promises13 = __toESM(require("fs/promises"), 1);
57042
- var import_node_path52 = __toESM(require("path"), 1);
57093
+ var import_node_path53 = __toESM(require("path"), 1);
57043
57094
  var BundleCache = class {
57044
57095
  constructor(rootDir) {
57045
57096
  this.rootDir = rootDir;
@@ -57048,14 +57099,14 @@ var BundleCache = class {
57048
57099
  /** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
57049
57100
  async write(snapshotHash, buffer) {
57050
57101
  await import_promises13.default.mkdir(this.rootDir, { recursive: true });
57051
- const file = import_node_path52.default.join(this.rootDir, `${snapshotHash}.zip`);
57102
+ const file = import_node_path53.default.join(this.rootDir, `${snapshotHash}.zip`);
57052
57103
  const tmp = `${file}.tmp`;
57053
57104
  await import_promises13.default.writeFile(tmp, buffer, { mode: 384 });
57054
57105
  await import_promises13.default.rename(tmp, file);
57055
57106
  }
57056
57107
  /** Returns the bundle bytes, or null when the file doesn't exist. */
57057
57108
  async read(snapshotHash) {
57058
- const file = import_node_path52.default.join(this.rootDir, `${snapshotHash}.zip`);
57109
+ const file = import_node_path53.default.join(this.rootDir, `${snapshotHash}.zip`);
57059
57110
  try {
57060
57111
  return await import_promises13.default.readFile(file);
57061
57112
  } catch (e) {
@@ -57065,7 +57116,7 @@ var BundleCache = class {
57065
57116
  }
57066
57117
  /** Idempotent — missing file is not an error. */
57067
57118
  async delete(snapshotHash) {
57068
- const file = import_node_path52.default.join(this.rootDir, `${snapshotHash}.zip`);
57119
+ const file = import_node_path53.default.join(this.rootDir, `${snapshotHash}.zip`);
57069
57120
  await import_promises13.default.rm(file, { force: true });
57070
57121
  }
57071
57122
  };
@@ -57086,11 +57137,11 @@ async function startDaemon(config) {
57086
57137
  },
57087
57138
  source: "daemon",
57088
57139
  sampling: logShippingCfg.sampling,
57089
- homeDir: import_node_os20.default.homedir()
57140
+ homeDir: import_node_os21.default.homedir()
57090
57141
  });
57091
57142
  const logger = createLogger({
57092
57143
  level: config.logLevel,
57093
- file: import_node_path53.default.join(config.dataDir, "clawd.log"),
57144
+ file: import_node_path54.default.join(config.dataDir, "clawd.log"),
57094
57145
  logClient
57095
57146
  });
57096
57147
  logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
@@ -57230,8 +57281,8 @@ async function startDaemon(config) {
57230
57281
  const agents = new AgentsScanner();
57231
57282
  const history = new ClaudeHistoryReader();
57232
57283
  let transport = null;
57233
- const personaStore = new PersonaStore(import_node_path53.default.join(config.dataDir, "personas"));
57234
- const usersRoot = import_node_path53.default.join(config.dataDir, "users");
57284
+ const personaStore = new PersonaStore(import_node_path54.default.join(config.dataDir, "personas"));
57285
+ const usersRoot = import_node_path54.default.join(config.dataDir, "users");
57235
57286
  const defaultsRoot = findDefaultsRoot(logger);
57236
57287
  if (defaultsRoot) {
57237
57288
  seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
@@ -57251,17 +57302,17 @@ async function startDaemon(config) {
57251
57302
  migrateCodexSandbox({ store: personaStore, logger });
57252
57303
  const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
57253
57304
  const personaDispatchManager = new PersonaDispatchManager({ genId: () => v4_default() });
57254
- const here = typeof __dirname === "string" ? __dirname : import_node_path53.default.dirname((0, import_node_url4.fileURLToPath)(import_meta6.url));
57305
+ const here = typeof __dirname === "string" ? __dirname : import_node_path54.default.dirname((0, import_node_url4.fileURLToPath)(import_meta6.url));
57255
57306
  const dispatchServerCandidates = [
57256
- import_node_path53.default.join(here, "dispatch", "mcp-server.cjs"),
57307
+ import_node_path54.default.join(here, "dispatch", "mcp-server.cjs"),
57257
57308
  // 生产 dist/index → dist/dispatch/mcp-server.cjs
57258
- import_node_path53.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
57309
+ import_node_path54.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
57259
57310
  // dev tsx src/index → ../dist/dispatch/mcp-server.cjs
57260
57311
  ];
57261
57312
  const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs41.default.existsSync(p2));
57262
57313
  let dispatchMcpConfigPath2;
57263
57314
  if (dispatchServerScriptPath) {
57264
- const dispatchLogPath = import_node_path53.default.join(config.dataDir, "dispatch-mcp-server.log");
57315
+ const dispatchLogPath = import_node_path54.default.join(config.dataDir, "dispatch-mcp-server.log");
57265
57316
  dispatchMcpConfigPath2 = writeDispatchMcpConfig({
57266
57317
  dataDir: config.dataDir,
57267
57318
  serverScriptPath: dispatchServerScriptPath,
@@ -57278,15 +57329,15 @@ async function startDaemon(config) {
57278
57329
  });
57279
57330
  }
57280
57331
  const ticketServerCandidates = [
57281
- import_node_path53.default.join(here, "ticket", "mcp-server.cjs"),
57282
- import_node_path53.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
57332
+ import_node_path54.default.join(here, "ticket", "mcp-server.cjs"),
57333
+ import_node_path54.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
57283
57334
  ];
57284
57335
  const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs41.default.existsSync(p2));
57285
57336
  const ticketOwnerUnionId = feishuIdentity?.identity.unionId ?? "";
57286
57337
  const ticketOwnerName = feishuIdentity?.identity.displayName ?? "";
57287
57338
  let ticketMcpConfigPath2;
57288
57339
  if (ticketServerScriptPath && ticketOwnerUnionId) {
57289
- const ticketLogPath = import_node_path53.default.join(config.dataDir, "ticket-mcp-server.log");
57340
+ const ticketLogPath = import_node_path54.default.join(config.dataDir, "ticket-mcp-server.log");
57290
57341
  ticketMcpConfigPath2 = writeTicketMcpConfig({
57291
57342
  dataDir: config.dataDir,
57292
57343
  serverScriptPath: ticketServerScriptPath,
@@ -57307,13 +57358,13 @@ async function startDaemon(config) {
57307
57358
  });
57308
57359
  }
57309
57360
  const shiftServerCandidates = [
57310
- import_node_path53.default.join(here, "shift", "mcp-server.cjs"),
57311
- import_node_path53.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
57361
+ import_node_path54.default.join(here, "shift", "mcp-server.cjs"),
57362
+ import_node_path54.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
57312
57363
  ];
57313
57364
  const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs41.default.existsSync(p2));
57314
57365
  let shiftMcpConfigPath2;
57315
57366
  if (shiftServerScriptPath) {
57316
- const shiftLogPath = import_node_path53.default.join(config.dataDir, "shift-mcp-server.log");
57367
+ const shiftLogPath = import_node_path54.default.join(config.dataDir, "shift-mcp-server.log");
57317
57368
  shiftMcpConfigPath2 = await writeShiftMcpConfig({
57318
57369
  dataDir: config.dataDir,
57319
57370
  serverScriptPath: shiftServerScriptPath,
@@ -57331,7 +57382,7 @@ async function startDaemon(config) {
57331
57382
  );
57332
57383
  }
57333
57384
  const shiftStore = createShiftStore({
57334
- filePath: import_node_path53.default.join(config.dataDir, "shift.json"),
57385
+ filePath: import_node_path54.default.join(config.dataDir, "shift.json"),
57335
57386
  ownerIdProvider: () => ownerPrincipalId,
57336
57387
  now: () => Date.now()
57337
57388
  });
@@ -57349,7 +57400,7 @@ async function startDaemon(config) {
57349
57400
  getAdapter,
57350
57401
  historyReader: history,
57351
57402
  dataDir: config.dataDir,
57352
- personaRoot: import_node_path53.default.join(config.dataDir, "personas"),
57403
+ personaRoot: import_node_path54.default.join(config.dataDir, "personas"),
57353
57404
  usersRoot,
57354
57405
  personaStore,
57355
57406
  ownerDisplayName,
@@ -57390,7 +57441,7 @@ async function startDaemon(config) {
57390
57441
  // 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
57391
57442
  attachmentGroup: {
57392
57443
  onFileEdit: (input) => {
57393
- const absPath = import_node_path53.default.isAbsolute(input.relPath) ? input.relPath : import_node_path53.default.join(input.cwd, input.relPath);
57444
+ const absPath = import_node_path54.default.isAbsolute(input.relPath) ? input.relPath : import_node_path54.default.join(input.cwd, input.relPath);
57394
57445
  let size = 0;
57395
57446
  try {
57396
57447
  size = import_node_fs41.default.statSync(absPath).size;
@@ -57591,11 +57642,11 @@ async function startDaemon(config) {
57591
57642
  // 'persona/<pid>/owner',default 走 'default'。
57592
57643
  getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
57593
57644
  // guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
57594
- personaRoot: import_node_path53.default.join(config.dataDir, "personas"),
57645
+ personaRoot: import_node_path54.default.join(config.dataDir, "personas"),
57595
57646
  usersRoot
57596
57647
  },
57597
57648
  // workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
57598
- personaRoot: import_node_path53.default.join(config.dataDir, "personas"),
57649
+ personaRoot: import_node_path54.default.join(config.dataDir, "personas"),
57599
57650
  // v2 多人 persona 隔离:handler 派生 guest user-dir 放行
57600
57651
  usersRoot,
57601
57652
  // capability:list / delete handler 依赖
@@ -57702,11 +57753,11 @@ async function startDaemon(config) {
57702
57753
  // 发布上线脚手架化 (spec 2026-06-03 §5.2):
57703
57754
  // appBuilderPersonaRoot 用于拼 publish.sh 绝对路径(persona-app-builder 安装在
57704
57755
  // dataDir/personas/persona-app-builder 之下,extension-kit/scripts/publish.sh 是相对路径)。
57705
- appBuilderPersonaRoot: import_node_path53.default.join(config.dataDir, "personas", "persona-app-builder"),
57756
+ appBuilderPersonaRoot: import_node_path54.default.join(config.dataDir, "personas", "persona-app-builder"),
57706
57757
  // 共享 deploy-kit 根:scaffold/publish 脚本骨架 + 阿里云凭证单一真源。
57707
- deployKitRoot: import_node_path53.default.join(config.dataDir, "deploy-kit"),
57758
+ deployKitRoot: import_node_path54.default.join(config.dataDir, "deploy-kit"),
57708
57759
  // scaffold/publish 按当前 session 的 persona 解析其安装根,让每个 persona 用自己的模板/注入配置。
57709
- resolvePersonaRoot: (personaId) => import_node_path53.default.join(config.dataDir, "personas", personaId),
57760
+ resolvePersonaRoot: (personaId) => import_node_path54.default.join(config.dataDir, "personas", personaId),
57710
57761
  // 发布上线脚手架化 (spec 2026-06-03 §5.2.2):
57711
57762
  // 复用 SessionManagerDeps.broadcastFrame 同款 dispatch 逻辑 —— runner 调 manager.send
57712
57763
  // 取回 broadcast 帧后逐帧 push 到 transport,跟 manager 自身的 deps 一致。
@@ -57749,8 +57800,8 @@ async function startDaemon(config) {
57749
57800
  }
57750
57801
  let sourceJsonlPath = "(no transcript yet \u2014 operate from the task description alone)";
57751
57802
  if (sourceFile && sourceFile.toolSessionId) {
57752
- sourceJsonlPath = import_node_path53.default.join(
57753
- import_node_os20.default.homedir(),
57803
+ sourceJsonlPath = import_node_path54.default.join(
57804
+ import_node_os21.default.homedir(),
57754
57805
  ".claude",
57755
57806
  "projects",
57756
57807
  cwdToHashDir(sourceFile.cwd),
@@ -58049,8 +58100,8 @@ async function startDaemon(config) {
58049
58100
  const lines = [
58050
58101
  `Tunnel: ${r.url}`,
58051
58102
  ...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
58052
- `Frpc config: ${import_node_path53.default.join(config.dataDir, "frpc.toml")}`,
58053
- `Frpc log: ${import_node_path53.default.join(config.dataDir, "frpc.log")}`
58103
+ `Frpc config: ${import_node_path54.default.join(config.dataDir, "frpc.toml")}`,
58104
+ `Frpc log: ${import_node_path54.default.join(config.dataDir, "frpc.log")}`
58054
58105
  ];
58055
58106
  const width = Math.max(...lines.map((l) => l.length));
58056
58107
  const bar = "\u2550".repeat(width + 4);
@@ -58063,7 +58114,7 @@ ${bar}
58063
58114
 
58064
58115
  `);
58065
58116
  try {
58066
- const connectPath = import_node_path53.default.join(config.dataDir, "connect.txt");
58117
+ const connectPath = import_node_path54.default.join(config.dataDir, "connect.txt");
58067
58118
  import_node_fs41.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
58068
58119
  } catch {
58069
58120
  }
@@ -58136,7 +58187,7 @@ ${bar}
58136
58187
  };
58137
58188
  }
58138
58189
  function migrateDropPersonsDir(dataDir) {
58139
- const dir = import_node_path53.default.join(dataDir, "persons");
58190
+ const dir = import_node_path54.default.join(dataDir, "persons");
58140
58191
  try {
58141
58192
  import_node_fs41.default.rmSync(dir, { recursive: true, force: true });
58142
58193
  } catch {