@clawos-dev/clawd 0.2.188 → 0.2.189-beta.377.bb861eb

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 +588 -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,7 @@ 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 = 6e5;
41462
41486
  function tryFlushPending(state, deps) {
41463
41487
  if (!state.readyForSend || state.pendingSend.length === 0) return [];
41464
41488
  const text = state.pendingSend.shift();
@@ -42127,6 +42151,18 @@ function reduceSession(state, input, deps) {
42127
42151
  if (state.status !== "running-idle") {
42128
42152
  return { state, effects: [] };
42129
42153
  }
42154
+ if (input.subagentActive) {
42155
+ return {
42156
+ state,
42157
+ effects: [
42158
+ {
42159
+ kind: "schedule-idle-kill",
42160
+ sessionId: state.file.sessionId,
42161
+ ms: IDLE_KILL_DELAY_MS
42162
+ }
42163
+ ]
42164
+ };
42165
+ }
42130
42166
  const next = cloneState(state);
42131
42167
  next.status = "stopping";
42132
42168
  return {
@@ -42183,10 +42219,11 @@ function reduceSession(state, input, deps) {
42183
42219
  // src/session/runner.ts
42184
42220
  init_stdout_splitter();
42185
42221
  init_permission_stdio();
42222
+ init_claude_history();
42186
42223
 
42187
42224
  // src/ipc-recorder.ts
42188
- var import_node_fs4 = __toESM(require("fs"), 1);
42189
- var import_node_path4 = __toESM(require("path"), 1);
42225
+ var import_node_fs5 = __toESM(require("fs"), 1);
42226
+ var import_node_path5 = __toESM(require("path"), 1);
42190
42227
  function tsForFilename(ms) {
42191
42228
  return new Date(ms).toISOString().replace(/[:.]/g, "-");
42192
42229
  }
@@ -42197,8 +42234,8 @@ function startRecorder(opts) {
42197
42234
  return null;
42198
42235
  }
42199
42236
  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`);
42237
+ const dir = import_node_path5.default.join(opts.dataDir, "ipc-recordings", opts.sessionId);
42238
+ const filePath = import_node_path5.default.join(dir, `${tsForFilename(now())}.jsonl`);
42202
42239
  let stream = null;
42203
42240
  let closedResolve;
42204
42241
  const closed = new Promise((resolve6) => {
@@ -42207,8 +42244,8 @@ function startRecorder(opts) {
42207
42244
  let exited = false;
42208
42245
  const ensureStream = () => {
42209
42246
  if (stream) return stream;
42210
- import_node_fs4.default.mkdirSync(dir, { recursive: true });
42211
- stream = import_node_fs4.default.createWriteStream(filePath, { flags: "a" });
42247
+ import_node_fs5.default.mkdirSync(dir, { recursive: true });
42248
+ stream = import_node_fs5.default.createWriteStream(filePath, { flags: "a" });
42212
42249
  stream.on("close", () => closedResolve());
42213
42250
  return stream;
42214
42251
  };
@@ -42253,6 +42290,7 @@ function encodeAllowWithInputControlResponse(requestId, updatedInput) {
42253
42290
  return JSON.stringify(payload) + "\n";
42254
42291
  }
42255
42292
  var DEFAULT_WAIT_STOP_TIMEOUT_MS = 3e3;
42293
+ var SUBAGENT_ACTIVE_WINDOW_MS = 3e5;
42256
42294
  var SessionRunner = class {
42257
42295
  constructor(initial, hooks) {
42258
42296
  this.hooks = hooks;
@@ -42564,7 +42602,7 @@ var SessionRunner = class {
42564
42602
  if (existing) clearTimeout(existing);
42565
42603
  const timer = setTimeout(() => {
42566
42604
  this.idleKillTimers.delete(effect.sessionId);
42567
- this.input({ kind: "idle-kill-fired" });
42605
+ this.input({ kind: "idle-kill-fired", subagentActive: this.isSubagentActive() });
42568
42606
  }, effect.ms);
42569
42607
  timer.unref?.();
42570
42608
  this.idleKillTimers.set(effect.sessionId, timer);
@@ -42580,6 +42618,18 @@ var SessionRunner = class {
42580
42618
  }
42581
42619
  }
42582
42620
  }
42621
+ // idle-kill 到点判定:本 session 的 subagents/ 里是否还有 agent-*.jsonl 在近期写盘。
42622
+ // 新鲜(近 SUBAGENT_ACTIVE_WINDOW_MS 内有写)= 后台 subagent 还在干活 → 不该杀。
42623
+ // 没有 toolSessionId(SDK 模式 CC 内生 id)/ 无目录 / 无 agent 文件 → false(照常回收)。
42624
+ isSubagentActive() {
42625
+ const toolSessionId = this.state.file.toolSessionId;
42626
+ if (!toolSessionId) return false;
42627
+ const projectsRoot = import_node_path6.default.join(this.hooks.home ?? import_node_os4.default.homedir(), ".claude", "projects");
42628
+ const mtime = newestSubagentMtimeMs(projectsRoot, this.state.file.cwd, toolSessionId);
42629
+ if (mtime === null) return false;
42630
+ const now = (this.hooks.now ?? Date.now)();
42631
+ return now - mtime < SUBAGENT_ACTIVE_WINDOW_MS;
42632
+ }
42583
42633
  // 清空所有 idle-kill timer(runner dispose / proc 永久退出时调用)。
42584
42634
  // 不喂 idle-kill-fired —— dispose 路径不再翻 reducer 状态
42585
42635
  clearIdleKillTimers() {
@@ -42662,15 +42712,15 @@ function extractEditPath(input) {
42662
42712
  }
42663
42713
 
42664
42714
  // src/debug/pty-probe.ts
42665
- var import_node_fs5 = __toESM(require("fs"), 1);
42666
- var import_node_path5 = __toESM(require("path"), 1);
42715
+ var import_node_fs6 = __toESM(require("fs"), 1);
42716
+ var import_node_path7 = __toESM(require("path"), 1);
42667
42717
  var PROBE_DIR = "/tmp/clawd-probe";
42668
- var EVENTS_FILE = import_node_path5.default.join(PROBE_DIR, "events.jsonl");
42718
+ var EVENTS_FILE = import_node_path7.default.join(PROBE_DIR, "events.jsonl");
42669
42719
  var inited = false;
42670
42720
  function ensureDir() {
42671
42721
  if (inited) return true;
42672
42722
  try {
42673
- import_node_fs5.default.mkdirSync(PROBE_DIR, { recursive: true });
42723
+ import_node_fs6.default.mkdirSync(PROBE_DIR, { recursive: true });
42674
42724
  inited = true;
42675
42725
  return true;
42676
42726
  } catch {
@@ -42681,15 +42731,15 @@ function probeEvent(event, data = {}) {
42681
42731
  try {
42682
42732
  if (!ensureDir()) return;
42683
42733
  const line = JSON.stringify({ ts: Date.now(), event, ...data }) + "\n";
42684
- import_node_fs5.default.appendFileSync(EVENTS_FILE, line);
42734
+ import_node_fs6.default.appendFileSync(EVENTS_FILE, line);
42685
42735
  } catch {
42686
42736
  }
42687
42737
  }
42688
42738
  function probeDumpReplay(sessionId, payload) {
42689
42739
  try {
42690
42740
  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");
42741
+ const file = import_node_path7.default.join(PROBE_DIR, `replay-${sessionId}-${Date.now()}.ans`);
42742
+ import_node_fs6.default.writeFileSync(file, payload, "utf8");
42693
42743
  return file;
42694
42744
  } catch {
42695
42745
  return "";
@@ -42796,7 +42846,7 @@ function derivePersonaSpawnCwd(file, personaRoot) {
42796
42846
  `derivePersonaSpawnCwd: personaRoot missing for owner session ${file.sessionId} (ownerPersonaId=${personaId})`
42797
42847
  );
42798
42848
  }
42799
- return import_node_path6.default.join(personaRoot, safeFileName(personaId));
42849
+ return import_node_path8.default.join(personaRoot, safeFileName(personaId));
42800
42850
  }
42801
42851
  function makeInitialState(file, subSessionMeta) {
42802
42852
  return {
@@ -42921,10 +42971,10 @@ var SessionManager = class {
42921
42971
  // <dataDir>/sessions/ 列子目录 (排除 'default').
42922
42972
  listPersonaIdsOnDisk() {
42923
42973
  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");
42974
+ const root = this.deps.storeFactory ? import_node_path8.default.join(this.deps.dataDir, "personas") : import_node_path8.default.join(this.deps.dataDir, "sessions");
42925
42975
  let entries;
42926
42976
  try {
42927
- entries = import_node_fs6.default.readdirSync(root, { withFileTypes: true });
42977
+ entries = import_node_fs7.default.readdirSync(root, { withFileTypes: true });
42928
42978
  } catch (err) {
42929
42979
  const code = err?.code;
42930
42980
  if (code === "ENOENT") return [];
@@ -42937,7 +42987,7 @@ var SessionManager = class {
42937
42987
  // 只在 storeFactory 注入 (新布局) 下生效, 老布局无 guest 目录.
42938
42988
  listGuestCapIdsForPersona(personaId) {
42939
42989
  if (!this.deps.dataDir || !this.deps.storeFactory) return [];
42940
- const root = import_node_path6.default.join(
42990
+ const root = import_node_path8.default.join(
42941
42991
  this.deps.dataDir,
42942
42992
  "personas",
42943
42993
  personaId,
@@ -42947,7 +42997,7 @@ var SessionManager = class {
42947
42997
  );
42948
42998
  let entries;
42949
42999
  try {
42950
- entries = import_node_fs6.default.readdirSync(root, { withFileTypes: true });
43000
+ entries = import_node_fs7.default.readdirSync(root, { withFileTypes: true });
42951
43001
  } catch (err) {
42952
43002
  const code = err?.code;
42953
43003
  if (code === "ENOENT") return [];
@@ -43066,7 +43116,7 @@ var SessionManager = class {
43066
43116
  callerDisplayName
43067
43117
  );
43068
43118
  if (subSessionMeta?.userWorkDir) {
43069
- import_node_fs6.default.mkdirSync(subSessionMeta.userWorkDir, { recursive: true });
43119
+ import_node_fs7.default.mkdirSync(subSessionMeta.userWorkDir, { recursive: true });
43070
43120
  }
43071
43121
  if (scope.kind === "persona" && scope.mode === "guest") {
43072
43122
  if (!this.deps.personaRoot || !subSessionMeta?.userWorkDir) {
@@ -43077,8 +43127,8 @@ var SessionManager = class {
43077
43127
  const base = this.deps.personaStore?.readSandboxSettings(scope.personaId) ?? null;
43078
43128
  const settings = composeGuestSandbox(base, subSessionMeta.userWorkDir, file.cwd);
43079
43129
  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;
43130
+ const home = import_node_os5.default.homedir();
43131
+ const expand = (p2) => p2 === "~" ? home : p2.startsWith("~/") ? import_node_path8.default.join(home, p2.slice(2)) : p2;
43082
43132
  const codexCfg = this.deps.personaStore?.readCodexSandboxSettings(scope.personaId) ?? null;
43083
43133
  subSessionMeta.codexSandbox = {
43084
43134
  writableRoots: [subSessionMeta.userWorkDir, ...(codexCfg?.writableRoots ?? []).map(expand)],
@@ -43230,7 +43280,7 @@ var SessionManager = class {
43230
43280
  throw new ClawdError(ERROR_CODES.INVALID_CWD, "cwd required when ownerPersonaId is absent");
43231
43281
  }
43232
43282
  try {
43233
- const stat = import_node_fs6.default.statSync(cwd);
43283
+ const stat = import_node_fs7.default.statSync(cwd);
43234
43284
  if (!stat.isDirectory()) throw new Error("not dir");
43235
43285
  } catch {
43236
43286
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${cwd}`);
@@ -43761,7 +43811,7 @@ var SessionManager = class {
43761
43811
  */
43762
43812
  createForScope(args) {
43763
43813
  try {
43764
- const stat = import_node_fs6.default.statSync(args.cwd);
43814
+ const stat = import_node_fs7.default.statSync(args.cwd);
43765
43815
  if (!stat.isDirectory()) throw new Error("not dir");
43766
43816
  } catch {
43767
43817
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${args.cwd}`);
@@ -43977,7 +44027,7 @@ var SessionManager = class {
43977
44027
  personaId: args.targetPersona,
43978
44028
  mode: "owner"
43979
44029
  };
43980
- const cwd = import_node_path6.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
44030
+ const cwd = import_node_path8.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
43981
44031
  const now = (/* @__PURE__ */ new Date()).toISOString();
43982
44032
  const file = {
43983
44033
  sessionId,
@@ -44042,7 +44092,7 @@ var SessionManager = class {
44042
44092
  personaId: args.targetPersona,
44043
44093
  mode: "owner"
44044
44094
  };
44045
- const cwd = import_node_path6.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
44095
+ const cwd = import_node_path8.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
44046
44096
  const now = (/* @__PURE__ */ new Date()).toISOString();
44047
44097
  const file = {
44048
44098
  sessionId,
@@ -44524,28 +44574,28 @@ var SessionManager = class {
44524
44574
  };
44525
44575
 
44526
44576
  // src/persona/store.ts
44527
- var fs7 = __toESM(require("fs"), 1);
44528
- var path9 = __toESM(require("path"), 1);
44577
+ var fs8 = __toESM(require("fs"), 1);
44578
+ var path11 = __toESM(require("path"), 1);
44529
44579
  init_protocol();
44530
44580
  var PersonaStore = class {
44531
44581
  constructor(root) {
44532
44582
  this.root = root;
44533
- fs7.mkdirSync(root, { recursive: true });
44583
+ fs8.mkdirSync(root, { recursive: true });
44534
44584
  }
44535
44585
  root;
44536
44586
  personaDir(personaId) {
44537
- return path9.join(this.root, safeFileName(personaId));
44587
+ return path11.join(this.root, safeFileName(personaId));
44538
44588
  }
44539
44589
  metaPath(personaId) {
44540
- return path9.join(this.personaDir(personaId), ".clawd", "persona.json");
44590
+ return path11.join(this.personaDir(personaId), ".clawd", "persona.json");
44541
44591
  }
44542
44592
  claudeMdPath(personaId) {
44543
- return path9.join(this.personaDir(personaId), "CLAUDE.md");
44593
+ return path11.join(this.personaDir(personaId), "CLAUDE.md");
44544
44594
  }
44545
44595
  // codex 原生读 cwd 的 AGENTS.md。人格双写镜像:claude 读 CLAUDE.md、codex 读 AGENTS.md,
44546
44596
  // 两份内容恒一致,persona 切 tool 零迁移。
44547
44597
  agentsMdPath(personaId) {
44548
- return path9.join(this.personaDir(personaId), "AGENTS.md");
44598
+ return path11.join(this.personaDir(personaId), "AGENTS.md");
44549
44599
  }
44550
44600
  /**
44551
44601
  * persona 级 sandbox base 落盘路径 —— 故意放 `.clawd/` 而非 `.claude/`,让 CC 的 project
@@ -44554,11 +44604,11 @@ var PersonaStore = class {
44554
44604
  * spawn 前 per-guest 动态拼到各自 session 目录的那份(base + 强制底座 + 本 guest userWorkDir carve)。
44555
44605
  */
44556
44606
  sandboxSettingsPath(personaId) {
44557
- return path9.join(this.personaDir(personaId), ".clawd", "sandbox-settings.json");
44607
+ return path11.join(this.personaDir(personaId), ".clawd", "sandbox-settings.json");
44558
44608
  }
44559
44609
  write(persona, personality) {
44560
44610
  const dir = this.personaDir(persona.personaId);
44561
- fs7.mkdirSync(path9.join(dir, ".clawd"), { recursive: true });
44611
+ fs8.mkdirSync(path11.join(dir, ".clawd"), { recursive: true });
44562
44612
  this.atomicWrite(this.claudeMdPath(persona.personaId), personality);
44563
44613
  this.atomicWrite(this.agentsMdPath(persona.personaId), personality);
44564
44614
  this.writeSandboxSettings(persona.personaId, buildGuestSettingsV1());
@@ -44577,9 +44627,9 @@ var PersonaStore = class {
44577
44627
  ensureAgentsMirror(personaId) {
44578
44628
  const claudeMd = this.claudeMdPath(personaId);
44579
44629
  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"));
44630
+ if (!fs8.existsSync(claudeMd)) return false;
44631
+ if (fs8.existsSync(agentsMd)) return false;
44632
+ this.atomicWrite(agentsMd, fs8.readFileSync(claudeMd, "utf8"));
44583
44633
  return true;
44584
44634
  }
44585
44635
  /**
@@ -44603,22 +44653,22 @@ var PersonaStore = class {
44603
44653
  return { ...s, permissions: { ...s.permissions ?? {}, deny: [...prev, rule] } };
44604
44654
  }
44605
44655
  codexSandboxSettingsPath(personaId) {
44606
- return path9.join(this.personaDir(personaId), ".clawd", "codex-sandbox.json");
44656
+ return path11.join(this.personaDir(personaId), ".clawd", "codex-sandbox.json");
44607
44657
  }
44608
44658
  /** 读 codex-sandbox.json;不存在/损坏 → null。 */
44609
44659
  readCodexSandboxSettings(personaId) {
44610
44660
  const p2 = this.codexSandboxSettingsPath(personaId);
44611
- if (!fs7.existsSync(p2)) return null;
44661
+ if (!fs8.existsSync(p2)) return null;
44612
44662
  try {
44613
- return CodexSandboxSettingsSchema.parse(JSON.parse(fs7.readFileSync(p2, "utf8")));
44663
+ return CodexSandboxSettingsSchema.parse(JSON.parse(fs8.readFileSync(p2, "utf8")));
44614
44664
  } catch {
44615
44665
  return null;
44616
44666
  }
44617
44667
  }
44618
44668
  /** 覆盖写 codex-sandbox.json(seed/migrate 用)。 */
44619
44669
  writeCodexSandboxSettings(personaId, settings) {
44620
- const dir = path9.join(this.personaDir(personaId), ".clawd");
44621
- fs7.mkdirSync(dir, { recursive: true });
44670
+ const dir = path11.join(this.personaDir(personaId), ".clawd");
44671
+ fs8.mkdirSync(dir, { recursive: true });
44622
44672
  this.atomicWrite(this.codexSandboxSettingsPath(personaId), JSON.stringify(settings, null, 2));
44623
44673
  }
44624
44674
  writeMeta(persona) {
@@ -44626,8 +44676,8 @@ var PersonaStore = class {
44626
44676
  }
44627
44677
  read(personaId) {
44628
44678
  const p2 = this.metaPath(personaId);
44629
- if (!fs7.existsSync(p2)) return null;
44630
- const raw = JSON.parse(fs7.readFileSync(p2, "utf8"));
44679
+ if (!fs8.existsSync(p2)) return null;
44680
+ const raw = JSON.parse(fs8.readFileSync(p2, "utf8"));
44631
44681
  if (raw && typeof raw === "object" && "tokenMap" in raw) {
44632
44682
  delete raw.tokenMap;
44633
44683
  this.atomicWrite(p2, JSON.stringify(raw, null, 2));
@@ -44635,13 +44685,13 @@ var PersonaStore = class {
44635
44685
  return PersonaFileSchema.parse(raw);
44636
44686
  }
44637
44687
  has(personaId) {
44638
- return fs7.existsSync(this.metaPath(personaId));
44688
+ return fs8.existsSync(this.metaPath(personaId));
44639
44689
  }
44640
44690
  readPersonality(personaId) {
44641
44691
  const claudeMd = this.claudeMdPath(personaId);
44642
- if (fs7.existsSync(claudeMd)) return fs7.readFileSync(claudeMd, "utf8");
44692
+ if (fs8.existsSync(claudeMd)) return fs8.readFileSync(claudeMd, "utf8");
44643
44693
  const agentsMd = this.agentsMdPath(personaId);
44644
- if (fs7.existsSync(agentsMd)) return fs7.readFileSync(agentsMd, "utf8");
44694
+ if (fs8.existsSync(agentsMd)) return fs8.readFileSync(agentsMd, "utf8");
44645
44695
  return null;
44646
44696
  }
44647
44697
  /**
@@ -44650,23 +44700,23 @@ var PersonaStore = class {
44650
44700
  */
44651
44701
  readSandboxSettings(personaId) {
44652
44702
  const p2 = this.sandboxSettingsPath(personaId);
44653
- if (!fs7.existsSync(p2)) return null;
44703
+ if (!fs8.existsSync(p2)) return null;
44654
44704
  try {
44655
- return JSON.parse(fs7.readFileSync(p2, "utf8"));
44705
+ return JSON.parse(fs8.readFileSync(p2, "utf8"));
44656
44706
  } catch {
44657
44707
  return null;
44658
44708
  }
44659
44709
  }
44660
44710
  /** Persona 私有 skills 目录路径:<personaDir>/.claude/skills */
44661
44711
  skillsDir(personaId) {
44662
- return path9.join(this.personaDir(personaId), ".claude", "skills");
44712
+ return path11.join(this.personaDir(personaId), ".claude", "skills");
44663
44713
  }
44664
44714
  /**
44665
44715
  * Claude Code 项目级 settings 路径:`<personaDir>/.claude/settings.json`。
44666
44716
  * 这里只读 `enabledPlugins` 字段,由 owner 通过 CC `/plugin` 之类命令维护,daemon 不写。
44667
44717
  */
44668
44718
  claudeSettingsPath(personaId) {
44669
- return path9.join(this.personaDir(personaId), ".claude", "settings.json");
44719
+ return path11.join(this.personaDir(personaId), ".claude", "settings.json");
44670
44720
  }
44671
44721
  /**
44672
44722
  * 读取 persona 的 `.claude/settings.json` 中 `enabledPlugins` map,把 value === true
@@ -44681,10 +44731,10 @@ var PersonaStore = class {
44681
44731
  */
44682
44732
  readEnabledPlugins(personaId) {
44683
44733
  const p2 = this.claudeSettingsPath(personaId);
44684
- if (!fs7.existsSync(p2)) return [];
44734
+ if (!fs8.existsSync(p2)) return [];
44685
44735
  let raw;
44686
44736
  try {
44687
- raw = JSON.parse(fs7.readFileSync(p2, "utf8"));
44737
+ raw = JSON.parse(fs8.readFileSync(p2, "utf8"));
44688
44738
  } catch {
44689
44739
  return [];
44690
44740
  }
@@ -44698,22 +44748,22 @@ var PersonaStore = class {
44698
44748
  return out;
44699
44749
  }
44700
44750
  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"));
44751
+ if (!fs8.existsSync(this.root)) return [];
44752
+ return fs8.readdirSync(this.root).filter((name) => {
44753
+ return fs8.existsSync(path11.join(this.root, name, ".clawd", "persona.json"));
44704
44754
  });
44705
44755
  }
44706
44756
  remove(personaId) {
44707
44757
  const dir = this.personaDir(personaId);
44708
- if (fs7.existsSync(dir)) fs7.rmSync(dir, { recursive: true, force: true });
44758
+ if (fs8.existsSync(dir)) fs8.rmSync(dir, { recursive: true, force: true });
44709
44759
  }
44710
44760
  personaDirPath(personaId) {
44711
44761
  return this.personaDir(personaId);
44712
44762
  }
44713
44763
  atomicWrite(file, content) {
44714
44764
  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);
44765
+ fs8.writeFileSync(tmp, content, { mode: 384 });
44766
+ fs8.renameSync(tmp, file);
44717
44767
  }
44718
44768
  };
44719
44769
 
@@ -44759,9 +44809,9 @@ var PersonaRegistry = class {
44759
44809
  var import_node_crypto3 = __toESM(require("crypto"), 1);
44760
44810
 
44761
44811
  // 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);
44812
+ var import_node_fs8 = __toESM(require("fs"), 1);
44813
+ var import_node_os6 = __toESM(require("os"), 1);
44814
+ var import_node_path9 = __toESM(require("path"), 1);
44765
44815
 
44766
44816
  // src/skills/frontmatter.ts
44767
44817
  var STRIP_QUOTES = /^["']|["']$/g;
@@ -44870,7 +44920,7 @@ function parseDescription(content) {
44870
44920
  }
44871
44921
  function isDirLikeSync(p2) {
44872
44922
  try {
44873
- return import_node_fs7.default.statSync(p2).isDirectory();
44923
+ return import_node_fs8.default.statSync(p2).isDirectory();
44874
44924
  } catch {
44875
44925
  return false;
44876
44926
  }
@@ -44878,19 +44928,19 @@ function isDirLikeSync(p2) {
44878
44928
  function scanSkillDir(dir, source, seen, out, pluginName) {
44879
44929
  let entries;
44880
44930
  try {
44881
- entries = import_node_fs7.default.readdirSync(dir, { withFileTypes: true });
44931
+ entries = import_node_fs8.default.readdirSync(dir, { withFileTypes: true });
44882
44932
  } catch {
44883
44933
  return;
44884
44934
  }
44885
44935
  for (const ent of entries) {
44886
- const entryPath = import_node_path7.default.join(dir, ent.name);
44936
+ const entryPath = import_node_path9.default.join(dir, ent.name);
44887
44937
  if (!ent.isDirectory() && !(ent.isSymbolicLink() && isDirLikeSync(entryPath))) continue;
44888
44938
  let content;
44889
44939
  try {
44890
- content = import_node_fs7.default.readFileSync(import_node_path7.default.join(entryPath, "SKILL.md"), "utf8");
44940
+ content = import_node_fs8.default.readFileSync(import_node_path9.default.join(entryPath, "SKILL.md"), "utf8");
44891
44941
  } catch {
44892
44942
  try {
44893
- content = import_node_fs7.default.readFileSync(import_node_path7.default.join(entryPath, "skill.md"), "utf8");
44943
+ content = import_node_fs8.default.readFileSync(import_node_path9.default.join(entryPath, "skill.md"), "utf8");
44894
44944
  } catch {
44895
44945
  continue;
44896
44946
  }
@@ -44914,26 +44964,26 @@ function listSkillsForDir(dir, source) {
44914
44964
  function scanCommandDir(dir, source, seen, out, pluginName) {
44915
44965
  let entries;
44916
44966
  try {
44917
- entries = import_node_fs7.default.readdirSync(dir, { withFileTypes: true });
44967
+ entries = import_node_fs8.default.readdirSync(dir, { withFileTypes: true });
44918
44968
  } catch {
44919
44969
  return;
44920
44970
  }
44921
44971
  for (const ent of entries) {
44922
- const entryPath = import_node_path7.default.join(dir, ent.name);
44972
+ const entryPath = import_node_path9.default.join(dir, ent.name);
44923
44973
  if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync(entryPath)) {
44924
44974
  const ns = ent.name;
44925
44975
  let subEntries;
44926
44976
  try {
44927
- subEntries = import_node_fs7.default.readdirSync(entryPath, { withFileTypes: true });
44977
+ subEntries = import_node_fs8.default.readdirSync(entryPath, { withFileTypes: true });
44928
44978
  } catch {
44929
44979
  continue;
44930
44980
  }
44931
44981
  for (const se of subEntries) {
44932
44982
  if (!se.name.endsWith(".md")) continue;
44933
- const sePath = import_node_path7.default.join(entryPath, se.name);
44983
+ const sePath = import_node_path9.default.join(entryPath, se.name);
44934
44984
  let content;
44935
44985
  try {
44936
- content = import_node_fs7.default.readFileSync(sePath, "utf8");
44986
+ content = import_node_fs8.default.readFileSync(sePath, "utf8");
44937
44987
  } catch {
44938
44988
  continue;
44939
44989
  }
@@ -44950,7 +45000,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
44950
45000
  } else if (ent.name.endsWith(".md")) {
44951
45001
  let content;
44952
45002
  try {
44953
- content = import_node_fs7.default.readFileSync(entryPath, "utf8");
45003
+ content = import_node_fs8.default.readFileSync(entryPath, "utf8");
44954
45004
  } catch {
44955
45005
  continue;
44956
45006
  }
@@ -44966,10 +45016,10 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
44966
45016
  }
44967
45017
  }
44968
45018
  function readInstalledPlugins(home) {
44969
- const file = import_node_path7.default.join(home, ".claude", "plugins", "installed_plugins.json");
45019
+ const file = import_node_path9.default.join(home, ".claude", "plugins", "installed_plugins.json");
44970
45020
  let raw;
44971
45021
  try {
44972
- raw = import_node_fs7.default.readFileSync(file, "utf8");
45022
+ raw = import_node_fs8.default.readFileSync(file, "utf8");
44973
45023
  } catch {
44974
45024
  return [];
44975
45025
  }
@@ -44994,7 +45044,7 @@ var SkillsScanner = class {
44994
45044
  home;
44995
45045
  extraPluginRoots;
44996
45046
  constructor(opts = {}) {
44997
- this.home = opts.home ?? import_node_os4.default.homedir();
45047
+ this.home = opts.home ?? import_node_os6.default.homedir();
44998
45048
  this.extraPluginRoots = opts.extraPluginRoots ?? [];
44999
45049
  }
45000
45050
  /**
@@ -45017,14 +45067,14 @@ var SkillsScanner = class {
45017
45067
  });
45018
45068
  }
45019
45069
  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);
45070
+ scanSkillDir(import_node_path9.default.join(this.home, ".claude", "skills"), "global", seen, fsBlock);
45071
+ scanCommandDir(import_node_path9.default.join(this.home, ".claude", "commands"), "global", seen, fsBlock);
45072
+ scanSkillDir(import_node_path9.default.join(args.cwd, ".claude", "skills"), "project", seen, fsBlock);
45073
+ scanCommandDir(import_node_path9.default.join(args.cwd, ".claude", "commands"), "project", seen, fsBlock);
45024
45074
  const plugins = [...readInstalledPlugins(this.home), ...this.extraPluginRoots];
45025
45075
  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);
45076
+ scanSkillDir(import_node_path9.default.join(root, "skills"), "plugin", seen, fsBlock, name);
45077
+ scanCommandDir(import_node_path9.default.join(root, "commands"), "plugin", seen, fsBlock, name);
45028
45078
  }
45029
45079
  fsBlock.sort((a, b2) => a.name < b2.name ? -1 : a.name > b2.name ? 1 : 0);
45030
45080
  return [...builtinBlock, ...fsBlock];
@@ -45130,8 +45180,8 @@ var PersonaManager = class {
45130
45180
  };
45131
45181
 
45132
45182
  // src/persona/seed.ts
45133
- var fs9 = __toESM(require("fs"), 1);
45134
- var path11 = __toESM(require("path"), 1);
45183
+ var fs10 = __toESM(require("fs"), 1);
45184
+ var path13 = __toESM(require("path"), 1);
45135
45185
  var import_node_url = require("url");
45136
45186
  var import_meta = {};
45137
45187
  var DEFAULT_BYPASS_PROFILE = {
@@ -45301,24 +45351,24 @@ function bundleSiblingFromArgv(argv1, sibling) {
45301
45351
  if (!argv1) return null;
45302
45352
  let real = argv1;
45303
45353
  try {
45304
- real = fs9.realpathSync(argv1);
45354
+ real = fs10.realpathSync(argv1);
45305
45355
  } catch {
45306
45356
  }
45307
- return path11.resolve(path11.dirname(real), sibling);
45357
+ return path13.resolve(path13.dirname(real), sibling);
45308
45358
  }
45309
45359
  function findDefaultsRoot(logger) {
45310
45360
  const candidates = [];
45311
45361
  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"));
45362
+ const here = path13.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
45363
+ candidates.push(path13.resolve(here, "defaults"));
45364
+ candidates.push(path13.resolve(here, "persona-defaults"));
45315
45365
  } catch {
45316
45366
  }
45317
45367
  const fromArgv = bundleSiblingFromArgv(process.argv[1], "persona-defaults");
45318
45368
  if (fromArgv) candidates.push(fromArgv);
45319
45369
  for (const c of candidates) {
45320
45370
  try {
45321
- if (fs9.statSync(c).isDirectory()) {
45371
+ if (fs10.statSync(c).isDirectory()) {
45322
45372
  logger?.info("persona.defaults-root.resolved", { root: c });
45323
45373
  return c;
45324
45374
  }
@@ -45335,8 +45385,8 @@ function seedDefaultPersonas(args) {
45335
45385
  args.logger.info("persona.seed.skip", { personaId: entry.personaId, reason: "exists" });
45336
45386
  continue;
45337
45387
  }
45338
- const bundleDir = path11.join(args.defaultsRoot, entry.personaId);
45339
- if (!fs9.existsSync(bundleDir)) {
45388
+ const bundleDir = path13.join(args.defaultsRoot, entry.personaId);
45389
+ if (!fs10.existsSync(bundleDir)) {
45340
45390
  args.logger.warn("persona.seed.skip", {
45341
45391
  personaId: entry.personaId,
45342
45392
  reason: "bundle-missing",
@@ -45344,8 +45394,8 @@ function seedDefaultPersonas(args) {
45344
45394
  });
45345
45395
  continue;
45346
45396
  }
45347
- const claudeMdPath = path11.join(bundleDir, "CLAUDE.md");
45348
- if (!fs9.existsSync(claudeMdPath)) {
45397
+ const claudeMdPath = path13.join(bundleDir, "CLAUDE.md");
45398
+ if (!fs10.existsSync(claudeMdPath)) {
45349
45399
  args.logger.warn("persona.seed.skip", {
45350
45400
  personaId: entry.personaId,
45351
45401
  reason: "no-CLAUDE.md",
@@ -45353,7 +45403,7 @@ function seedDefaultPersonas(args) {
45353
45403
  });
45354
45404
  continue;
45355
45405
  }
45356
- const personality = fs9.readFileSync(claudeMdPath, "utf8");
45406
+ const personality = fs10.readFileSync(claudeMdPath, "utf8");
45357
45407
  const now = Date.now();
45358
45408
  const persona = {
45359
45409
  personaId: entry.personaId,
@@ -45379,17 +45429,17 @@ function seedDefaultPersonas(args) {
45379
45429
  }
45380
45430
  }
45381
45431
  function skipNodeModulesUnder(srcRoot) {
45382
- return (src) => !path11.relative(srcRoot, src).split(path11.sep).includes("node_modules");
45432
+ return (src) => !path13.relative(srcRoot, src).split(path13.sep).includes("node_modules");
45383
45433
  }
45384
45434
  function copyBundleExtras(srcDir, dstDir) {
45385
- for (const entry of fs9.readdirSync(srcDir, { withFileTypes: true })) {
45435
+ for (const entry of fs10.readdirSync(srcDir, { withFileTypes: true })) {
45386
45436
  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);
45437
+ const srcPath = path13.join(srcDir, entry.name);
45438
+ const dstPath = path13.join(dstDir, entry.name);
45389
45439
  if (entry.isDirectory()) {
45390
- fs9.cpSync(srcPath, dstPath, { recursive: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
45440
+ fs10.cpSync(srcPath, dstPath, { recursive: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
45391
45441
  } else if (entry.isFile()) {
45392
- fs9.copyFileSync(srcPath, dstPath);
45442
+ fs10.copyFileSync(srcPath, dstPath);
45393
45443
  }
45394
45444
  }
45395
45445
  }
@@ -45397,16 +45447,16 @@ var DAEMON_MANAGED_PATHS = ["extension-kit", "CLAUDE.md", ".mcp.json"];
45397
45447
  function refreshDaemonManagedDirs(args) {
45398
45448
  const entries = args.entries ?? DEFAULT_PERSONAS;
45399
45449
  for (const entry of entries) {
45400
- const bundleDir = path11.join(args.defaultsRoot, entry.personaId);
45401
- if (!fs9.existsSync(bundleDir)) continue;
45450
+ const bundleDir = path13.join(args.defaultsRoot, entry.personaId);
45451
+ if (!fs10.existsSync(bundleDir)) continue;
45402
45452
  const personaDir = args.store.personaDirPath(entry.personaId);
45403
- if (!fs9.existsSync(personaDir)) continue;
45453
+ if (!fs10.existsSync(personaDir)) continue;
45404
45454
  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);
45455
+ const srcPath = path13.join(bundleDir, relPath);
45456
+ if (!fs10.existsSync(srcPath)) continue;
45457
+ const dstPath = path13.join(personaDir, relPath);
45408
45458
  try {
45409
- fs9.cpSync(srcPath, dstPath, { recursive: true, force: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
45459
+ fs10.cpSync(srcPath, dstPath, { recursive: true, force: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
45410
45460
  args.logger.info("persona.refresh.synced", {
45411
45461
  personaId: entry.personaId,
45412
45462
  path: relPath
@@ -45466,15 +45516,15 @@ function migrateCodexSandbox(args) {
45466
45516
  function findDeployKitRoot(logger) {
45467
45517
  const candidates = [];
45468
45518
  try {
45469
- const here = path11.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
45470
- candidates.push(path11.resolve(here, "..", "deploy-kit"));
45519
+ const here = path13.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
45520
+ candidates.push(path13.resolve(here, "..", "deploy-kit"));
45471
45521
  } catch {
45472
45522
  }
45473
45523
  const fromArgv = bundleSiblingFromArgv(process.argv[1], "deploy-kit");
45474
45524
  if (fromArgv) candidates.push(fromArgv);
45475
45525
  for (const c of candidates) {
45476
45526
  try {
45477
- if (fs9.statSync(c).isDirectory()) {
45527
+ if (fs10.statSync(c).isDirectory()) {
45478
45528
  logger?.info("persona.deploy-kit-root.resolved", { root: c });
45479
45529
  return c;
45480
45530
  }
@@ -45485,8 +45535,8 @@ function findDeployKitRoot(logger) {
45485
45535
  return null;
45486
45536
  }
45487
45537
  function seedDeployKit(args) {
45488
- const dst = path11.join(args.dataDir, "deploy-kit");
45489
- fs9.cpSync(args.deployKitBundleRoot, dst, {
45538
+ const dst = path13.join(args.dataDir, "deploy-kit");
45539
+ fs10.cpSync(args.deployKitBundleRoot, dst, {
45490
45540
  recursive: true,
45491
45541
  dereference: true,
45492
45542
  force: false,
@@ -45495,35 +45545,35 @@ function seedDeployKit(args) {
45495
45545
  args.logger.info("deploy-kit.seed.done", { dst });
45496
45546
  }
45497
45547
  function refreshDeployKit(args) {
45498
- const dst = path11.join(args.dataDir, "deploy-kit");
45499
- if (!fs9.existsSync(dst)) {
45548
+ const dst = path13.join(args.dataDir, "deploy-kit");
45549
+ if (!fs10.existsSync(dst)) {
45500
45550
  seedDeployKit(args);
45501
45551
  return;
45502
45552
  }
45503
45553
  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 });
45554
+ const s = path13.join(args.deployKitBundleRoot, sub);
45555
+ if (fs10.existsSync(s)) {
45556
+ fs10.cpSync(s, path13.join(dst, sub), { recursive: true, force: true, dereference: true });
45507
45557
  }
45508
45558
  }
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)) {
45559
+ const secretsSrc = path13.join(args.deployKitBundleRoot, ".secrets");
45560
+ if (fs10.existsSync(secretsSrc)) {
45561
+ fs10.mkdirSync(path13.join(dst, ".secrets"), { recursive: true });
45562
+ for (const f of fs10.readdirSync(secretsSrc)) {
45513
45563
  if (!f.endsWith(".example")) continue;
45514
- fs9.copyFileSync(path11.join(secretsSrc, f), path11.join(dst, ".secrets", f));
45564
+ fs10.copyFileSync(path13.join(secretsSrc, f), path13.join(dst, ".secrets", f));
45515
45565
  }
45516
45566
  }
45517
45567
  args.logger.info("deploy-kit.refresh.done", { dst });
45518
45568
  }
45519
45569
 
45520
45570
  // src/share-md-viewer/load.ts
45521
- var import_node_fs9 = __toESM(require("fs"), 1);
45522
- var import_node_path8 = __toESM(require("path"), 1);
45571
+ var import_node_fs10 = __toESM(require("fs"), 1);
45572
+ var import_node_path10 = __toESM(require("path"), 1);
45523
45573
  var import_node_url2 = require("url");
45524
45574
 
45525
45575
  // src/share-md-viewer/asset-loader.ts
45526
- var import_node_fs8 = __toESM(require("fs"), 1);
45576
+ var import_node_fs9 = __toESM(require("fs"), 1);
45527
45577
  function htmlEscape(s) {
45528
45578
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
45529
45579
  }
@@ -45531,12 +45581,12 @@ function createViewerAssetLoader(opts) {
45531
45581
  let viewerTemplate;
45532
45582
  let errorTemplate;
45533
45583
  try {
45534
- viewerTemplate = import_node_fs8.default.readFileSync(opts.viewerHtmlPath, "utf8");
45584
+ viewerTemplate = import_node_fs9.default.readFileSync(opts.viewerHtmlPath, "utf8");
45535
45585
  } catch (err) {
45536
45586
  throw new Error(`viewer asset not found at ${opts.viewerHtmlPath}: ${err.message}`);
45537
45587
  }
45538
45588
  try {
45539
- errorTemplate = import_node_fs8.default.readFileSync(opts.errorHtmlPath, "utf8");
45589
+ errorTemplate = import_node_fs9.default.readFileSync(opts.errorHtmlPath, "utf8");
45540
45590
  } catch (err) {
45541
45591
  throw new Error(`viewer error asset not found at ${opts.errorHtmlPath}: ${err.message}`);
45542
45592
  }
@@ -45555,25 +45605,25 @@ var import_meta2 = {};
45555
45605
  function tryLoadViewerAssets(logger) {
45556
45606
  const candidates = [];
45557
45607
  try {
45558
- const here = import_node_path8.default.dirname((0, import_node_url2.fileURLToPath)(import_meta2.url));
45608
+ const here = import_node_path10.default.dirname((0, import_node_url2.fileURLToPath)(import_meta2.url));
45559
45609
  candidates.push(here);
45560
- candidates.push(import_node_path8.default.resolve(here, ".."));
45561
- candidates.push(import_node_path8.default.resolve(here, "..", "..", "dist"));
45610
+ candidates.push(import_node_path10.default.resolve(here, ".."));
45611
+ candidates.push(import_node_path10.default.resolve(here, "..", "..", "dist"));
45562
45612
  } catch {
45563
45613
  }
45564
45614
  if (process.argv[1]) {
45565
45615
  let real = process.argv[1];
45566
45616
  try {
45567
- real = import_node_fs9.default.realpathSync(process.argv[1]);
45617
+ real = import_node_fs10.default.realpathSync(process.argv[1]);
45568
45618
  } catch {
45569
45619
  }
45570
- candidates.push(import_node_path8.default.dirname(real));
45620
+ candidates.push(import_node_path10.default.dirname(real));
45571
45621
  }
45572
45622
  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");
45623
+ const viewerHtmlPath = import_node_path10.default.join(root, "share-md-viewer.html");
45624
+ const errorHtmlPath = import_node_path10.default.join(root, "share-md-viewer-error.html");
45575
45625
  try {
45576
- if (import_node_fs9.default.statSync(viewerHtmlPath).isFile() && import_node_fs9.default.statSync(errorHtmlPath).isFile()) {
45626
+ if (import_node_fs10.default.statSync(viewerHtmlPath).isFile() && import_node_fs10.default.statSync(errorHtmlPath).isFile()) {
45577
45627
  logger?.info("share-md-viewer.assets-root.resolved", { root });
45578
45628
  return createViewerAssetLoader({ viewerHtmlPath, errorHtmlPath });
45579
45629
  }
@@ -45588,30 +45638,30 @@ function tryLoadViewerAssets(logger) {
45588
45638
  }
45589
45639
 
45590
45640
  // src/share-ui/load.ts
45591
- var import_node_fs11 = __toESM(require("fs"), 1);
45592
- var import_node_path10 = __toESM(require("path"), 1);
45641
+ var import_node_fs12 = __toESM(require("fs"), 1);
45642
+ var import_node_path12 = __toESM(require("path"), 1);
45593
45643
  var import_node_url3 = require("url");
45594
45644
 
45595
45645
  // src/share-ui/asset-loader.ts
45596
- var import_node_fs10 = __toESM(require("fs"), 1);
45597
- var import_node_path9 = __toESM(require("path"), 1);
45646
+ var import_node_fs11 = __toESM(require("fs"), 1);
45647
+ var import_node_path11 = __toESM(require("path"), 1);
45598
45648
  function createShareUiAssetLoader(opts) {
45599
45649
  let indexHtml;
45600
45650
  try {
45601
- indexHtml = import_node_fs10.default.readFileSync(opts.indexHtmlPath, "utf8");
45651
+ indexHtml = import_node_fs11.default.readFileSync(opts.indexHtmlPath, "utf8");
45602
45652
  } catch (err) {
45603
45653
  throw new Error(`share-ui index.html not found at ${opts.indexHtmlPath}: ${err.message}`);
45604
45654
  }
45605
- const assetsDir = import_node_path9.default.resolve(opts.assetsDir);
45655
+ const assetsDir = import_node_path11.default.resolve(opts.assetsDir);
45606
45656
  return {
45607
45657
  renderIndexHtml() {
45608
45658
  return indexHtml;
45609
45659
  },
45610
45660
  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;
45661
+ const resolved = import_node_path11.default.resolve(assetsDir, rel);
45662
+ if (resolved !== assetsDir && !resolved.startsWith(assetsDir + import_node_path11.default.sep)) return null;
45613
45663
  try {
45614
- if (import_node_fs10.default.statSync(resolved).isFile()) return resolved;
45664
+ if (import_node_fs11.default.statSync(resolved).isFile()) return resolved;
45615
45665
  } catch {
45616
45666
  }
45617
45667
  return null;
@@ -45625,28 +45675,28 @@ function bundleDirFromArgv(argv1) {
45625
45675
  if (!argv1) return null;
45626
45676
  let real = argv1;
45627
45677
  try {
45628
- real = import_node_fs11.default.realpathSync(argv1);
45678
+ real = import_node_fs12.default.realpathSync(argv1);
45629
45679
  } catch {
45630
45680
  }
45631
- return import_node_path10.default.dirname(real);
45681
+ return import_node_path12.default.dirname(real);
45632
45682
  }
45633
45683
  function tryLoadShareUi(logger) {
45634
45684
  const candidates = [];
45635
45685
  try {
45636
- const here = import_node_path10.default.dirname((0, import_node_url3.fileURLToPath)(import_meta3.url));
45686
+ const here = import_node_path12.default.dirname((0, import_node_url3.fileURLToPath)(import_meta3.url));
45637
45687
  candidates.push(here);
45638
- candidates.push(import_node_path10.default.resolve(here, ".."));
45639
- candidates.push(import_node_path10.default.resolve(here, "..", "..", "dist"));
45688
+ candidates.push(import_node_path12.default.resolve(here, ".."));
45689
+ candidates.push(import_node_path12.default.resolve(here, "..", "..", "dist"));
45640
45690
  } catch {
45641
45691
  }
45642
45692
  const argvDir = bundleDirFromArgv(process.argv[1]);
45643
45693
  if (argvDir) candidates.push(argvDir);
45644
45694
  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");
45695
+ const shareUiDir = import_node_path12.default.join(root, "share-ui");
45696
+ const indexHtmlPath = import_node_path12.default.join(shareUiDir, "guest.html");
45697
+ const assetsDir = import_node_path12.default.join(shareUiDir, "assets");
45648
45698
  try {
45649
- if (import_node_fs11.default.statSync(indexHtmlPath).isFile() && import_node_fs11.default.statSync(assetsDir).isDirectory()) {
45699
+ if (import_node_fs12.default.statSync(indexHtmlPath).isFile() && import_node_fs12.default.statSync(assetsDir).isDirectory()) {
45650
45700
  logger?.info("share-ui.assets-root.resolved", { root: shareUiDir });
45651
45701
  return createShareUiAssetLoader({ indexHtmlPath, assetsDir });
45652
45702
  }
@@ -45728,20 +45778,20 @@ function buildVisitorLogin(deps) {
45728
45778
  }
45729
45779
 
45730
45780
  // src/visitor/visitor-store.ts
45731
- var import_node_fs12 = __toESM(require("fs"), 1);
45732
- var import_node_path11 = __toESM(require("path"), 1);
45781
+ var import_node_fs13 = __toESM(require("fs"), 1);
45782
+ var import_node_path13 = __toESM(require("path"), 1);
45733
45783
  function createVisitorStore(opts) {
45734
- const file = import_node_path11.default.join(opts.dir, "visitors.json");
45784
+ const file = import_node_path13.default.join(opts.dir, "visitors.json");
45735
45785
  const read = () => {
45736
45786
  try {
45737
- return JSON.parse(import_node_fs12.default.readFileSync(file, "utf8"));
45787
+ return JSON.parse(import_node_fs13.default.readFileSync(file, "utf8"));
45738
45788
  } catch {
45739
45789
  return [];
45740
45790
  }
45741
45791
  };
45742
45792
  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));
45793
+ import_node_fs13.default.mkdirSync(opts.dir, { recursive: true });
45794
+ import_node_fs13.default.writeFileSync(file, JSON.stringify(rows, null, 2));
45745
45795
  };
45746
45796
  return {
45747
45797
  upsert(r) {
@@ -46023,8 +46073,8 @@ function turnStartInput(text) {
46023
46073
  const items = [];
46024
46074
  let leftover = text;
46025
46075
  for (const m2 of text.matchAll(SKILL_RE)) {
46026
- const [marker, name, path66] = m2;
46027
- items.push({ type: "skill", name, path: path66 });
46076
+ const [marker, name, path67] = m2;
46077
+ items.push({ type: "skill", name, path: path67 });
46028
46078
  leftover = leftover.replace(marker, "");
46029
46079
  }
46030
46080
  for (const m2 of text.matchAll(ATTACHMENT_RE2)) {
@@ -46257,8 +46307,8 @@ var CodexAdapter = class {
46257
46307
 
46258
46308
  // src/tools/claude-tui.ts
46259
46309
  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);
46310
+ var import_node_os7 = __toESM(require("os"), 1);
46311
+ var import_node_path14 = __toESM(require("path"), 1);
46262
46312
  var import_headless = __toESM(require_xterm_headless(), 1);
46263
46313
 
46264
46314
  // ../node_modules/.pnpm/@xterm+addon-serialize@0.14.0/node_modules/@xterm/addon-serialize/lib/addon-serialize.mjs
@@ -47391,8 +47441,8 @@ function buildTuiSpawnArgs(ctx, isResume = false) {
47391
47441
  }
47392
47442
  function jsonlExistsForCtx(ctx) {
47393
47443
  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`);
47444
+ const home = import_node_os7.default.homedir();
47445
+ const file = import_node_path14.default.join(home, ".claude", "projects", cwdToHashDir(ctx.cwd), `${ctx.toolSessionId}.jsonl`);
47396
47446
  try {
47397
47447
  return import_node_fs16.default.statSync(file).isFile();
47398
47448
  } catch {
@@ -47464,9 +47514,9 @@ var PersonaDispatchManager = class {
47464
47514
 
47465
47515
  // src/dispatch/mcp-config.ts
47466
47516
  var import_node_fs17 = __toESM(require("fs"), 1);
47467
- var import_node_path14 = __toESM(require("path"), 1);
47517
+ var import_node_path15 = __toESM(require("path"), 1);
47468
47518
  function dispatchMcpConfigPath(dataDir) {
47469
- return import_node_path14.default.join(dataDir, "dispatch.mcp.json");
47519
+ return import_node_path15.default.join(dataDir, "dispatch.mcp.json");
47470
47520
  }
47471
47521
  function writeDispatchMcpConfig(args) {
47472
47522
  const cfgPath = dispatchMcpConfigPath(args.dataDir);
@@ -47488,9 +47538,9 @@ function writeDispatchMcpConfig(args) {
47488
47538
 
47489
47539
  // src/ticket/mcp-config.ts
47490
47540
  var import_node_fs18 = __toESM(require("fs"), 1);
47491
- var import_node_path15 = __toESM(require("path"), 1);
47541
+ var import_node_path16 = __toESM(require("path"), 1);
47492
47542
  function ticketMcpConfigPath(dataDir) {
47493
- return import_node_path15.default.join(dataDir, "ticket.mcp.json");
47543
+ return import_node_path16.default.join(dataDir, "ticket.mcp.json");
47494
47544
  }
47495
47545
  function writeTicketMcpConfig(args) {
47496
47546
  const cfgPath = ticketMcpConfigPath(args.dataDir);
@@ -47518,9 +47568,9 @@ function writeTicketMcpConfig(args) {
47518
47568
 
47519
47569
  // src/shift/mcp-config.ts
47520
47570
  var import_node_fs19 = __toESM(require("fs"), 1);
47521
- var import_node_path16 = __toESM(require("path"), 1);
47571
+ var import_node_path17 = __toESM(require("path"), 1);
47522
47572
  function shiftMcpConfigPath(dataDir) {
47523
- return import_node_path16.default.join(dataDir, "shift.mcp.json");
47573
+ return import_node_path17.default.join(dataDir, "shift.mcp.json");
47524
47574
  }
47525
47575
  async function writeShiftMcpConfig(args) {
47526
47576
  const cfgPath = shiftMcpConfigPath(args.dataDir);
@@ -47542,7 +47592,7 @@ async function writeShiftMcpConfig(args) {
47542
47592
 
47543
47593
  // src/shift/store.ts
47544
47594
  var import_promises = __toESM(require("fs/promises"), 1);
47545
- var import_node_path17 = __toESM(require("path"), 1);
47595
+ var import_node_path18 = __toESM(require("path"), 1);
47546
47596
  var import_node_crypto5 = require("crypto");
47547
47597
 
47548
47598
  // src/shift/constants.ts
@@ -47611,7 +47661,7 @@ function createShiftStore(deps) {
47611
47661
  flushTimer = null;
47612
47662
  }
47613
47663
  const content = { version: 1, shifts };
47614
- await import_promises.default.mkdir(import_node_path17.default.dirname(deps.filePath), { recursive: true });
47664
+ await import_promises.default.mkdir(import_node_path18.default.dirname(deps.filePath), { recursive: true });
47615
47665
  const tmp = `${deps.filePath}.tmp-${deps.now()}-${Math.floor(Math.random() * 1e6)}`;
47616
47666
  await import_promises.default.writeFile(tmp, JSON.stringify(content, null, 2), "utf8");
47617
47667
  await import_promises.default.rename(tmp, deps.filePath);
@@ -48382,13 +48432,13 @@ function mapSkillsListResponse(res) {
48382
48432
  const r = s ?? {};
48383
48433
  const name = str3(r.name);
48384
48434
  if (!name) continue;
48385
- const path66 = str3(r.path);
48435
+ const path67 = str3(r.path);
48386
48436
  const description = str3(r.description);
48387
48437
  const isPlugin = name.includes(":");
48388
48438
  out.push({
48389
48439
  name,
48390
48440
  source: isPlugin ? "plugin" : "project",
48391
- ...path66 ? { path: path66 } : {},
48441
+ ...path67 ? { path: path67 } : {},
48392
48442
  ...description ? { description } : {},
48393
48443
  ...isPlugin ? { plugin: name.split(":")[0] } : {}
48394
48444
  });
@@ -48428,15 +48478,15 @@ async function listCodexSkills(cwd, deps = {}) {
48428
48478
 
48429
48479
  // src/workspace/browser.ts
48430
48480
  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);
48481
+ var import_node_os8 = __toESM(require("os"), 1);
48482
+ var import_node_path19 = __toESM(require("path"), 1);
48433
48483
  init_protocol();
48434
48484
  var MAX_FILE_BYTES = 2 * 1024 * 1024;
48435
48485
  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)) {
48486
+ const absCwd = import_node_path19.default.resolve(cwd);
48487
+ const joined = import_node_path19.default.resolve(absCwd, subpath ?? ".");
48488
+ const rel = import_node_path19.default.relative(absCwd, joined);
48489
+ if (rel.startsWith("..") || import_node_path19.default.isAbsolute(rel)) {
48440
48490
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
48441
48491
  }
48442
48492
  return joined;
@@ -48454,7 +48504,7 @@ function ensureCwd(cwd) {
48454
48504
  }
48455
48505
  var WorkspaceBrowser = class {
48456
48506
  list(args) {
48457
- const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os7.default.homedir();
48507
+ const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os8.default.homedir();
48458
48508
  ensureCwd(cwd);
48459
48509
  const full = resolveInsideCwd(cwd, args.path);
48460
48510
  const dirents = import_node_fs20.default.readdirSync(full, { withFileTypes: true });
@@ -48467,7 +48517,7 @@ var WorkspaceBrowser = class {
48467
48517
  mtime: ""
48468
48518
  };
48469
48519
  try {
48470
- const st = import_node_fs20.default.statSync(import_node_path18.default.join(full, d.name));
48520
+ const st = import_node_fs20.default.statSync(import_node_path19.default.join(full, d.name));
48471
48521
  entry.mtime = new Date(st.mtimeMs).toISOString();
48472
48522
  if (d.isFile()) entry.size = st.size;
48473
48523
  } catch {
@@ -48513,8 +48563,8 @@ var WorkspaceBrowser = class {
48513
48563
 
48514
48564
  // src/skills/agents-scanner.ts
48515
48565
  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);
48566
+ var import_node_os9 = __toESM(require("os"), 1);
48567
+ var import_node_path20 = __toESM(require("path"), 1);
48518
48568
  var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
48519
48569
  function isDirLikeSync2(p2) {
48520
48570
  try {
@@ -48552,10 +48602,10 @@ function scanAgentsDir(dir, source, seen, out) {
48552
48602
  }
48553
48603
  for (const ent of entries) {
48554
48604
  if (!ent.name.endsWith(".md")) continue;
48555
- if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path19.default.join(dir, ent.name)))) {
48605
+ if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path20.default.join(dir, ent.name)))) {
48556
48606
  continue;
48557
48607
  }
48558
- const filePath = import_node_path19.default.join(dir, ent.name);
48608
+ const filePath = import_node_path20.default.join(dir, ent.name);
48559
48609
  const baseName = ent.name.replace(/\.md$/, "");
48560
48610
  if (seen.has(baseName)) continue;
48561
48611
  seen.add(baseName);
@@ -48578,7 +48628,7 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
48578
48628
  return;
48579
48629
  }
48580
48630
  for (const ent of entries) {
48581
- const childPath = import_node_path19.default.join(dir, ent.name);
48631
+ const childPath = import_node_path20.default.join(dir, ent.name);
48582
48632
  if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
48583
48633
  walk2(childPath, [...namespaces, ent.name]);
48584
48634
  continue;
@@ -48603,9 +48653,9 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
48603
48653
  walk2(root, []);
48604
48654
  }
48605
48655
  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");
48656
+ const pluginsDir = import_node_path20.default.join(home, ".claude", "plugins");
48657
+ const v2 = import_node_path20.default.join(pluginsDir, "installed_plugins_v2.json");
48658
+ const v1 = import_node_path20.default.join(pluginsDir, "installed_plugins.json");
48609
48659
  let raw = null;
48610
48660
  for (const candidate of [v2, v1]) {
48611
48661
  try {
@@ -48634,19 +48684,19 @@ function readInstalledPlugins2(home) {
48634
48684
  return out;
48635
48685
  }
48636
48686
  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;
48687
+ let cur = import_node_path20.default.resolve(startCwd);
48688
+ const fsRoot = import_node_path20.default.parse(cur).root;
48639
48689
  while (true) {
48640
- scanAgentsDir(import_node_path19.default.join(cur, ".claude", "agents"), "project", seen, out);
48690
+ scanAgentsDir(import_node_path20.default.join(cur, ".claude", "agents"), "project", seen, out);
48641
48691
  let hasGit = false;
48642
48692
  try {
48643
- hasGit = import_node_fs21.default.existsSync(import_node_path19.default.join(cur, ".git"));
48693
+ hasGit = import_node_fs21.default.existsSync(import_node_path20.default.join(cur, ".git"));
48644
48694
  } catch {
48645
48695
  }
48646
48696
  if (hasGit) return;
48647
48697
  if (cur === home) return;
48648
48698
  if (cur === fsRoot) return;
48649
- const parent = import_node_path19.default.dirname(cur);
48699
+ const parent = import_node_path20.default.dirname(cur);
48650
48700
  if (parent === cur) return;
48651
48701
  cur = parent;
48652
48702
  }
@@ -48656,7 +48706,7 @@ var AgentsScanner = class {
48656
48706
  extraPluginRoots;
48657
48707
  policyDir;
48658
48708
  constructor(opts = {}) {
48659
- this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os8.default.homedir();
48709
+ this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os9.default.homedir();
48660
48710
  this.extraPluginRoots = opts.extraPluginRoots ?? [];
48661
48711
  if (opts.policyDir !== void 0) {
48662
48712
  this.policyDir = opts.policyDir;
@@ -48681,7 +48731,7 @@ var AgentsScanner = class {
48681
48731
  }
48682
48732
  const fsBlock = [];
48683
48733
  scanAgentsDir(
48684
- import_node_path19.default.join(this.home, ".claude", "agents"),
48734
+ import_node_path20.default.join(this.home, ".claude", "agents"),
48685
48735
  "global",
48686
48736
  seen,
48687
48737
  fsBlock
@@ -48695,7 +48745,7 @@ var AgentsScanner = class {
48695
48745
  ...this.extraPluginRoots
48696
48746
  ];
48697
48747
  for (const { name, root } of plugins) {
48698
- const agentsRoot = import_node_path19.default.join(root, "agents");
48748
+ const agentsRoot = import_node_path20.default.join(root, "agents");
48699
48749
  scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
48700
48750
  }
48701
48751
  return [...builtinBlock, ...fsBlock];
@@ -48704,27 +48754,27 @@ var AgentsScanner = class {
48704
48754
 
48705
48755
  // src/observer/session-observer.ts
48706
48756
  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);
48757
+ var import_node_os11 = __toESM(require("os"), 1);
48758
+ var import_node_path22 = __toESM(require("path"), 1);
48709
48759
  init_claude_history();
48710
48760
 
48711
48761
  // src/observer/subagent-meta-observer.ts
48712
48762
  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);
48763
+ var import_node_os10 = __toESM(require("os"), 1);
48764
+ var import_node_path21 = __toESM(require("path"), 1);
48715
48765
  init_claude_history();
48716
48766
  var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
48717
48767
  var SubagentMetaObserver = class {
48718
48768
  constructor(opts) {
48719
48769
  this.opts = opts;
48720
- this.home = opts.home ?? import_node_os9.default.homedir();
48770
+ this.home = opts.home ?? import_node_os10.default.homedir();
48721
48771
  }
48722
48772
  opts;
48723
48773
  home;
48724
48774
  watches = /* @__PURE__ */ new Map();
48725
48775
  // public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
48726
48776
  resolveSubagentDir(cwd, toolSessionId) {
48727
- return import_node_path20.default.join(
48777
+ return import_node_path21.default.join(
48728
48778
  this.home,
48729
48779
  ".claude",
48730
48780
  "projects",
@@ -48780,7 +48830,7 @@ var SubagentMetaObserver = class {
48780
48830
  if (!m2) return;
48781
48831
  const agentId = m2[1];
48782
48832
  if (w2.emitted.has(agentId)) return;
48783
- const file = import_node_path20.default.join(w2.dirPath, name);
48833
+ const file = import_node_path21.default.join(w2.dirPath, name);
48784
48834
  let raw;
48785
48835
  try {
48786
48836
  raw = import_node_fs22.default.readFileSync(file, "utf8");
@@ -48828,7 +48878,7 @@ var SubagentMetaObserver = class {
48828
48878
  var SessionObserver = class {
48829
48879
  constructor(opts) {
48830
48880
  this.opts = opts;
48831
- this.home = opts.home ?? import_node_os10.default.homedir();
48881
+ this.home = opts.home ?? import_node_os11.default.homedir();
48832
48882
  this.metaObserver = opts.enableSubagentMetaObserver ? new SubagentMetaObserver({ home: this.home, onEvent: opts.onEvent }) : null;
48833
48883
  }
48834
48884
  opts;
@@ -48840,7 +48890,7 @@ var SessionObserver = class {
48840
48890
  metaObserver;
48841
48891
  resolveJsonlPath(cwd, toolSessionId, override) {
48842
48892
  if (override) return override;
48843
- return import_node_path21.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
48893
+ return import_node_path22.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
48844
48894
  }
48845
48895
  start(args) {
48846
48896
  this.stop(args.sessionId);
@@ -48861,10 +48911,10 @@ var SessionObserver = class {
48861
48911
  prevIsRejectSentinel: false
48862
48912
  };
48863
48913
  try {
48864
- import_node_fs23.default.mkdirSync(import_node_path21.default.dirname(filePath), { recursive: true });
48914
+ import_node_fs23.default.mkdirSync(import_node_path22.default.dirname(filePath), { recursive: true });
48865
48915
  } catch {
48866
48916
  }
48867
- w2.watcher = import_node_fs23.default.watch(import_node_path21.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
48917
+ w2.watcher = import_node_fs23.default.watch(import_node_path22.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
48868
48918
  if (!changedName || !filePath.endsWith(changedName)) return;
48869
48919
  this.poll(w2);
48870
48920
  });
@@ -49744,7 +49794,7 @@ async function authenticate(token, deps) {
49744
49794
 
49745
49795
  // src/permission/capability-store.ts
49746
49796
  var fs27 = __toESM(require("fs"), 1);
49747
- var path26 = __toESM(require("path"), 1);
49797
+ var path27 = __toESM(require("path"), 1);
49748
49798
  var CAPABILITIES_FILE_NAME = "capabilities.json";
49749
49799
  var FILE_VERSION = 1;
49750
49800
  var CapabilityStore = class {
@@ -49774,7 +49824,7 @@ var CapabilityStore = class {
49774
49824
  this.flush();
49775
49825
  }
49776
49826
  filePath() {
49777
- return path26.join(this.dataDir, CAPABILITIES_FILE_NAME);
49827
+ return path27.join(this.dataDir, CAPABILITIES_FILE_NAME);
49778
49828
  }
49779
49829
  readFromDisk() {
49780
49830
  const file = this.filePath();
@@ -49921,7 +49971,7 @@ function cleanupGuestSessionsForCapability(cap, factory) {
49921
49971
 
49922
49972
  // src/inbox/inbox-store.ts
49923
49973
  var fs29 = __toESM(require("fs"), 1);
49924
- var path27 = __toESM(require("path"), 1);
49974
+ var path28 = __toESM(require("path"), 1);
49925
49975
  var INBOX_SUBDIR = "inbox";
49926
49976
  var InboxStore = class {
49927
49977
  constructor(dataDir) {
@@ -50019,10 +50069,10 @@ var InboxStore = class {
50019
50069
  }
50020
50070
  }
50021
50071
  dirPath() {
50022
- return path27.join(this.dataDir, INBOX_SUBDIR);
50072
+ return path28.join(this.dataDir, INBOX_SUBDIR);
50023
50073
  }
50024
50074
  filePath(peerDeviceId) {
50025
- return path27.join(this.dirPath(), `${peerDeviceId}.jsonl`);
50075
+ return path28.join(this.dirPath(), `${peerDeviceId}.jsonl`);
50026
50076
  }
50027
50077
  };
50028
50078
  function parseAllLines(raw) {
@@ -50110,7 +50160,7 @@ var InboxManager = class {
50110
50160
 
50111
50161
  // src/state/contact-store.ts
50112
50162
  var fs30 = __toESM(require("fs"), 1);
50113
- var path28 = __toESM(require("path"), 1);
50163
+ var path29 = __toESM(require("path"), 1);
50114
50164
  var FILE_NAME = "contacts.json";
50115
50165
  var ContactStore = class {
50116
50166
  constructor(dataDir) {
@@ -50120,7 +50170,7 @@ var ContactStore = class {
50120
50170
  contacts = /* @__PURE__ */ new Map();
50121
50171
  load() {
50122
50172
  this.contacts.clear();
50123
- const file = path28.join(this.dataDir, FILE_NAME);
50173
+ const file = path29.join(this.dataDir, FILE_NAME);
50124
50174
  let raw;
50125
50175
  try {
50126
50176
  raw = fs30.readFileSync(file, "utf8");
@@ -50166,7 +50216,7 @@ var ContactStore = class {
50166
50216
  return existed;
50167
50217
  }
50168
50218
  flush() {
50169
- const file = path28.join(this.dataDir, FILE_NAME);
50219
+ const file = path29.join(this.dataDir, FILE_NAME);
50170
50220
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
50171
50221
  const content = JSON.stringify(
50172
50222
  { contacts: Array.from(this.contacts.values()) },
@@ -50330,52 +50380,52 @@ async function autoReverseContact(args) {
50330
50380
 
50331
50381
  // src/migrations/2026-05-20-flatten-sessions.ts
50332
50382
  var fs31 = __toESM(require("fs"), 1);
50333
- var path29 = __toESM(require("path"), 1);
50383
+ var path30 = __toESM(require("path"), 1);
50334
50384
  var MIGRATION_FLAG_NAME = ".migration.v1.done";
50335
50385
  function migrateFlattenSessions(opts) {
50336
50386
  const dataDir = opts.dataDir;
50337
50387
  const now = opts.now ?? Date.now;
50338
- const sessionsDir = path29.join(dataDir, "sessions");
50339
- const flagPath = path29.join(sessionsDir, MIGRATION_FLAG_NAME);
50388
+ const sessionsDir = path30.join(dataDir, "sessions");
50389
+ const flagPath = path30.join(sessionsDir, MIGRATION_FLAG_NAME);
50340
50390
  if (existsSync3(flagPath)) {
50341
50391
  return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
50342
50392
  }
50343
50393
  let movedBare = 0;
50344
50394
  let movedVmOwner = 0;
50345
50395
  let archivedListener = 0;
50346
- const defaultDir = path29.join(sessionsDir, "default");
50396
+ const defaultDir = path30.join(sessionsDir, "default");
50347
50397
  if (existsSync3(defaultDir)) {
50348
50398
  for (const entry of readdirSafe(defaultDir)) {
50349
50399
  if (!entry.endsWith(".json")) continue;
50350
- const src = path29.join(defaultDir, entry);
50351
- const dst = path29.join(sessionsDir, entry);
50400
+ const src = path30.join(defaultDir, entry);
50401
+ const dst = path30.join(sessionsDir, entry);
50352
50402
  fs31.renameSync(src, dst);
50353
50403
  movedBare += 1;
50354
50404
  }
50355
50405
  rmdirIfEmpty(defaultDir);
50356
50406
  }
50357
50407
  for (const pid of readdirSafe(sessionsDir)) {
50358
- const personaDir = path29.join(sessionsDir, pid);
50408
+ const personaDir = path30.join(sessionsDir, pid);
50359
50409
  if (!isDir(personaDir)) continue;
50360
50410
  if (pid === "default") continue;
50361
- const ownerSrc = path29.join(personaDir, "owner");
50411
+ const ownerSrc = path30.join(personaDir, "owner");
50362
50412
  if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
50363
- const ownerDst = path29.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
50413
+ const ownerDst = path30.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
50364
50414
  fs31.mkdirSync(ownerDst, { recursive: true });
50365
50415
  for (const file of readdirSafe(ownerSrc)) {
50366
50416
  if (!file.endsWith(".json")) continue;
50367
- fs31.renameSync(path29.join(ownerSrc, file), path29.join(ownerDst, file));
50417
+ fs31.renameSync(path30.join(ownerSrc, file), path30.join(ownerDst, file));
50368
50418
  movedVmOwner += 1;
50369
50419
  }
50370
50420
  rmdirIfEmpty(ownerSrc);
50371
50421
  }
50372
- const listenerSrc = path29.join(personaDir, "listener");
50422
+ const listenerSrc = path30.join(personaDir, "listener");
50373
50423
  if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
50374
- const archiveDst = path29.join(dataDir, ".legacy", `listener-${pid}`);
50424
+ const archiveDst = path30.join(dataDir, ".legacy", `listener-${pid}`);
50375
50425
  fs31.mkdirSync(archiveDst, { recursive: true });
50376
50426
  for (const file of readdirSafe(listenerSrc)) {
50377
50427
  if (!file.endsWith(".json")) continue;
50378
- fs31.renameSync(path29.join(listenerSrc, file), path29.join(archiveDst, file));
50428
+ fs31.renameSync(path30.join(listenerSrc, file), path30.join(archiveDst, file));
50379
50429
  archivedListener += 1;
50380
50430
  }
50381
50431
  rmdirIfEmpty(listenerSrc);
@@ -50423,10 +50473,10 @@ function rmdirIfEmpty(p2) {
50423
50473
 
50424
50474
  // src/transport/http-router.ts
50425
50475
  var import_node_fs25 = __toESM(require("fs"), 1);
50426
- var import_node_path25 = __toESM(require("path"), 1);
50476
+ var import_node_path26 = __toESM(require("path"), 1);
50427
50477
 
50428
50478
  // src/attachment/mime.ts
50429
- var import_node_path22 = __toESM(require("path"), 1);
50479
+ var import_node_path23 = __toESM(require("path"), 1);
50430
50480
  var TEXT_PLAIN = "text/plain; charset=utf-8";
50431
50481
  var EXT_TO_NATIVE_MIME = {
50432
50482
  // 图片
@@ -50533,7 +50583,7 @@ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
50533
50583
  ".mk"
50534
50584
  ]);
50535
50585
  function lookupMime(filePathOrName) {
50536
- const ext = import_node_path22.default.extname(filePathOrName).toLowerCase();
50586
+ const ext = import_node_path23.default.extname(filePathOrName).toLowerCase();
50537
50587
  if (EXT_TO_NATIVE_MIME[ext]) return EXT_TO_NATIVE_MIME[ext];
50538
50588
  if (TEXT_EXTENSIONS.has(ext)) return TEXT_PLAIN;
50539
50589
  return "application/octet-stream";
@@ -50603,7 +50653,7 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
50603
50653
 
50604
50654
  // src/attachment/upload.ts
50605
50655
  var import_node_fs24 = __toESM(require("fs"), 1);
50606
- var import_node_path23 = __toESM(require("path"), 1);
50656
+ var import_node_path24 = __toESM(require("path"), 1);
50607
50657
  var import_node_crypto7 = __toESM(require("crypto"), 1);
50608
50658
  var import_promises2 = require("stream/promises");
50609
50659
  var UploadError = class extends Error {
@@ -50615,14 +50665,14 @@ var UploadError = class extends Error {
50615
50665
  code;
50616
50666
  };
50617
50667
  function assertValidFileName(fileName) {
50618
- if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path23.default.basename(fileName)) {
50668
+ if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path24.default.basename(fileName)) {
50619
50669
  throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
50620
50670
  }
50621
50671
  }
50622
50672
  var HASH_PREFIX_LEN = 16;
50623
50673
  async function writeUploadedAttachment(args) {
50624
50674
  assertValidFileName(args.fileName);
50625
- const attachmentsRoot = import_node_path23.default.join(args.sessionDir, ".attachments");
50675
+ const attachmentsRoot = import_node_path24.default.join(args.sessionDir, ".attachments");
50626
50676
  try {
50627
50677
  import_node_fs24.default.mkdirSync(attachmentsRoot, { recursive: true });
50628
50678
  } catch (err) {
@@ -50630,7 +50680,7 @@ async function writeUploadedAttachment(args) {
50630
50680
  }
50631
50681
  const hasher = import_node_crypto7.default.createHash("sha256");
50632
50682
  let actualSize = 0;
50633
- const tmpPath = import_node_path23.default.join(
50683
+ const tmpPath = import_node_path24.default.join(
50634
50684
  attachmentsRoot,
50635
50685
  `.upload-${process.pid}-${Date.now()}-${import_node_crypto7.default.randomBytes(4).toString("hex")}`
50636
50686
  );
@@ -50665,7 +50715,7 @@ async function writeUploadedAttachment(args) {
50665
50715
  );
50666
50716
  }
50667
50717
  const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
50668
- const hashDir = import_node_path23.default.join(attachmentsRoot, attachmentId);
50718
+ const hashDir = import_node_path24.default.join(attachmentsRoot, attachmentId);
50669
50719
  let finalFileName;
50670
50720
  let hashDirExists = false;
50671
50721
  try {
@@ -50683,7 +50733,7 @@ async function writeUploadedAttachment(args) {
50683
50733
  try {
50684
50734
  import_node_fs24.default.mkdirSync(hashDir, { recursive: true });
50685
50735
  finalFileName = args.fileName;
50686
- import_node_fs24.default.renameSync(tmpPath, import_node_path23.default.join(hashDir, finalFileName));
50736
+ import_node_fs24.default.renameSync(tmpPath, import_node_path24.default.join(hashDir, finalFileName));
50687
50737
  } catch (err) {
50688
50738
  try {
50689
50739
  import_node_fs24.default.unlinkSync(tmpPath);
@@ -50692,8 +50742,8 @@ async function writeUploadedAttachment(args) {
50692
50742
  throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
50693
50743
  }
50694
50744
  }
50695
- const absPath = import_node_path23.default.join(hashDir, finalFileName);
50696
- const relPath = import_node_path23.default.relative(args.sessionDir, absPath);
50745
+ const absPath = import_node_path24.default.join(hashDir, finalFileName);
50746
+ const relPath = import_node_path24.default.relative(args.sessionDir, absPath);
50697
50747
  args.groupFileStore.upsert(args.scope, args.sessionId, {
50698
50748
  relPath: absPath,
50699
50749
  // 存绝对路径,与现有 agent 入清单的形态一致(attachment.ts:144 双形态兼容)
@@ -50707,8 +50757,8 @@ async function writeUploadedAttachment(args) {
50707
50757
 
50708
50758
  // src/extension/import.ts
50709
50759
  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);
50760
+ var import_node_path25 = __toESM(require("path"), 1);
50761
+ var import_node_os12 = __toESM(require("os"), 1);
50712
50762
  var import_jszip = __toESM(require_lib3(), 1);
50713
50763
  var ImportError = class extends Error {
50714
50764
  constructor(code, message) {
@@ -50725,7 +50775,7 @@ async function importZip(buf, root) {
50725
50775
  throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
50726
50776
  }
50727
50777
  for (const name of Object.keys(zip.files)) {
50728
- if (name.includes("..") || name.startsWith("/") || import_node_path24.default.isAbsolute(name)) {
50778
+ if (name.includes("..") || name.startsWith("/") || import_node_path25.default.isAbsolute(name)) {
50729
50779
  throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
50730
50780
  }
50731
50781
  }
@@ -50758,7 +50808,7 @@ async function importZip(buf, root) {
50758
50808
  );
50759
50809
  }
50760
50810
  }
50761
- const destDir = import_node_path24.default.join(root, manifest.id);
50811
+ const destDir = import_node_path25.default.join(root, manifest.id);
50762
50812
  let destExists = false;
50763
50813
  try {
50764
50814
  await import_promises3.default.access(destDir);
@@ -50768,15 +50818,15 @@ async function importZip(buf, root) {
50768
50818
  if (destExists) {
50769
50819
  throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
50770
50820
  }
50771
- const stage = await import_promises3.default.mkdtemp(import_node_path24.default.join(import_node_os11.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
50821
+ const stage = await import_promises3.default.mkdtemp(import_node_path25.default.join(import_node_os12.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
50772
50822
  try {
50773
50823
  for (const [name, entry] of Object.entries(zip.files)) {
50774
- const dest = import_node_path24.default.join(stage, name);
50824
+ const dest = import_node_path25.default.join(stage, name);
50775
50825
  if (entry.dir) {
50776
50826
  await import_promises3.default.mkdir(dest, { recursive: true });
50777
50827
  continue;
50778
50828
  }
50779
- await import_promises3.default.mkdir(import_node_path24.default.dirname(dest), { recursive: true });
50829
+ await import_promises3.default.mkdir(import_node_path25.default.dirname(dest), { recursive: true });
50780
50830
  const content = await entry.async("nodebuffer");
50781
50831
  await import_promises3.default.writeFile(dest, content);
50782
50832
  }
@@ -50807,7 +50857,7 @@ var SHARE_UI_ASSET_MIME = {
50807
50857
  ".wasm": "application/wasm"
50808
50858
  };
50809
50859
  function shareUiAssetMime(filePath) {
50810
- const ext = import_node_path25.default.extname(filePath).toLowerCase();
50860
+ const ext = import_node_path26.default.extname(filePath).toLowerCase();
50811
50861
  return SHARE_UI_ASSET_MIME[ext] ?? lookupMime(filePath);
50812
50862
  }
50813
50863
  var DISPATCH_HEARTBEAT_MS = 25e3;
@@ -50894,7 +50944,7 @@ function isValidUploadFileName(fileName) {
50894
50944
  if (fileName === "." || fileName === "..") return false;
50895
50945
  if (fileName.startsWith(".")) return false;
50896
50946
  if (fileName.includes("/") || fileName.includes("\\")) return false;
50897
- return fileName === import_node_path25.default.basename(fileName);
50947
+ return fileName === import_node_path26.default.basename(fileName);
50898
50948
  }
50899
50949
  function createHttpRouter(deps) {
50900
50950
  return async (req, res) => {
@@ -51190,7 +51240,7 @@ function createHttpRouter(deps) {
51190
51240
  sendHtml(res, statusByCode[r.code], loader.renderErrorHtml(r.code, msgByCode[r.code]));
51191
51241
  return true;
51192
51242
  }
51193
- sendHtml(res, 200, loader.renderViewerHtml(import_node_path25.default.basename(r.absPath)));
51243
+ sendHtml(res, 200, loader.renderViewerHtml(import_node_path26.default.basename(r.absPath)));
51194
51244
  return true;
51195
51245
  }
51196
51246
  const ctx = deps.authResolver.resolveFromHeader(
@@ -51311,7 +51361,7 @@ function createHttpRouter(deps) {
51311
51361
  return true;
51312
51362
  }
51313
51363
  let absPath;
51314
- if (import_node_path25.default.isAbsolute(pathParam)) {
51364
+ if (import_node_path26.default.isAbsolute(pathParam)) {
51315
51365
  absPath = pathParam;
51316
51366
  } else if (deps.sessionStore) {
51317
51367
  const file = deps.sessionStore.read(sid);
@@ -51319,7 +51369,7 @@ function createHttpRouter(deps) {
51319
51369
  sendJson(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
51320
51370
  return true;
51321
51371
  }
51322
- absPath = import_node_path25.default.join(file.cwd, pathParam);
51372
+ absPath = import_node_path26.default.join(file.cwd, pathParam);
51323
51373
  } else {
51324
51374
  sendJson(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
51325
51375
  return true;
@@ -51421,7 +51471,7 @@ function streamFile(res, absPath, logger) {
51421
51471
  return;
51422
51472
  }
51423
51473
  const mime = lookupMime(absPath);
51424
- const basename = import_node_path25.default.basename(absPath);
51474
+ const basename = import_node_path26.default.basename(absPath);
51425
51475
  res.writeHead(200, {
51426
51476
  "Content-Type": mime,
51427
51477
  "Content-Length": String(stat.size),
@@ -51439,7 +51489,7 @@ function streamFile(res, absPath, logger) {
51439
51489
 
51440
51490
  // src/attachment/gc.ts
51441
51491
  var import_node_fs26 = __toESM(require("fs"), 1);
51442
- var import_node_path26 = __toESM(require("path"), 1);
51492
+ var import_node_path27 = __toESM(require("path"), 1);
51443
51493
  var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
51444
51494
  function runAttachmentGc(args) {
51445
51495
  const now = (args.now ?? Date.now)();
@@ -51448,17 +51498,17 @@ function runAttachmentGc(args) {
51448
51498
  for (const { scope, sessionId } of args.sessionScopes) {
51449
51499
  for (const entry of args.groupFileStore.list(scope, sessionId)) {
51450
51500
  if (entry.stale) continue;
51451
- if (import_node_path26.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
51501
+ if (import_node_path27.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
51452
51502
  }
51453
51503
  }
51454
51504
  for (const { scope, sessionId } of args.sessionScopes) {
51455
- const sessionDir = args.getSessionCwd?.(sessionId) ?? import_node_path26.default.join(
51505
+ const sessionDir = args.getSessionCwd?.(sessionId) ?? import_node_path27.default.join(
51456
51506
  args.dataDir,
51457
51507
  "sessions",
51458
51508
  ...scopeSubPath(scope).map(safeFileName),
51459
51509
  safeFileName(sessionId)
51460
51510
  );
51461
- const attRoot = import_node_path26.default.join(sessionDir, ".attachments");
51511
+ const attRoot = import_node_path27.default.join(sessionDir, ".attachments");
51462
51512
  let hashDirs;
51463
51513
  try {
51464
51514
  hashDirs = import_node_fs26.default.readdirSync(attRoot);
@@ -51468,7 +51518,7 @@ function runAttachmentGc(args) {
51468
51518
  continue;
51469
51519
  }
51470
51520
  for (const hashDir of hashDirs) {
51471
- const hashDirAbs = import_node_path26.default.join(attRoot, hashDir);
51521
+ const hashDirAbs = import_node_path27.default.join(attRoot, hashDir);
51472
51522
  let files;
51473
51523
  try {
51474
51524
  files = import_node_fs26.default.readdirSync(hashDirAbs);
@@ -51476,7 +51526,7 @@ function runAttachmentGc(args) {
51476
51526
  continue;
51477
51527
  }
51478
51528
  for (const name of files) {
51479
- const file = import_node_path26.default.join(hashDirAbs, name);
51529
+ const file = import_node_path27.default.join(hashDirAbs, name);
51480
51530
  let stat;
51481
51531
  try {
51482
51532
  stat = import_node_fs26.default.statSync(file);
@@ -51507,7 +51557,7 @@ function runAttachmentGc(args) {
51507
51557
 
51508
51558
  // src/attachment/group.ts
51509
51559
  var import_node_fs27 = __toESM(require("fs"), 1);
51510
- var import_node_path27 = __toESM(require("path"), 1);
51560
+ var import_node_path28 = __toESM(require("path"), 1);
51511
51561
  var import_node_crypto8 = __toESM(require("crypto"), 1);
51512
51562
  init_protocol();
51513
51563
  var GroupFileStore = class {
@@ -51519,11 +51569,11 @@ var GroupFileStore = class {
51519
51569
  this.logger = opts.logger;
51520
51570
  }
51521
51571
  rootForScope(scope) {
51522
- return import_node_path27.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
51572
+ return import_node_path28.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
51523
51573
  }
51524
51574
  /** 与 SessionStore.filePath 平级,扩展名 .group-files.json */
51525
51575
  filePath(scope, sessionId) {
51526
- return import_node_path27.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
51576
+ return import_node_path28.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
51527
51577
  }
51528
51578
  cacheKey(scope, sessionId) {
51529
51579
  return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
@@ -51558,7 +51608,7 @@ var GroupFileStore = class {
51558
51608
  }
51559
51609
  writeFile(scope, sessionId, entries) {
51560
51610
  const file = this.filePath(scope, sessionId);
51561
- import_node_fs27.default.mkdirSync(import_node_path27.default.dirname(file), { recursive: true });
51611
+ import_node_fs27.default.mkdirSync(import_node_path28.default.dirname(file), { recursive: true });
51562
51612
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
51563
51613
  import_node_fs27.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
51564
51614
  import_node_fs27.default.renameSync(tmp, file);
@@ -51648,9 +51698,9 @@ var GroupFileStore = class {
51648
51698
 
51649
51699
  // src/discovery/state-file.ts
51650
51700
  var import_node_fs28 = __toESM(require("fs"), 1);
51651
- var import_node_path28 = __toESM(require("path"), 1);
51701
+ var import_node_path29 = __toESM(require("path"), 1);
51652
51702
  function defaultStateFilePath(dataDir) {
51653
- return import_node_path28.default.join(dataDir, "state.json");
51703
+ return import_node_path29.default.join(dataDir, "state.json");
51654
51704
  }
51655
51705
  function isPidAlive(pid) {
51656
51706
  if (!Number.isFinite(pid) || pid <= 0) return false;
@@ -51686,7 +51736,7 @@ var StateFileManager = class {
51686
51736
  return { status: "stale", existing };
51687
51737
  }
51688
51738
  write(state) {
51689
- import_node_fs28.default.mkdirSync(import_node_path28.default.dirname(this.file), { recursive: true });
51739
+ import_node_fs28.default.mkdirSync(import_node_path29.default.dirname(this.file), { recursive: true });
51690
51740
  const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
51691
51741
  import_node_fs28.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
51692
51742
  import_node_fs28.default.renameSync(tmp, this.file);
@@ -51715,13 +51765,13 @@ function readDaemonSourceFromEnv(env = process.env) {
51715
51765
 
51716
51766
  // src/tunnel/tunnel-manager.ts
51717
51767
  var import_node_fs32 = __toESM(require("fs"), 1);
51718
- var import_node_path32 = __toESM(require("path"), 1);
51768
+ var import_node_path33 = __toESM(require("path"), 1);
51719
51769
  var import_node_crypto9 = __toESM(require("crypto"), 1);
51720
51770
  var import_node_child_process9 = require("child_process");
51721
51771
 
51722
51772
  // src/tunnel/tunnel-store.ts
51723
51773
  var import_node_fs29 = __toESM(require("fs"), 1);
51724
- var import_node_path29 = __toESM(require("path"), 1);
51774
+ var import_node_path30 = __toESM(require("path"), 1);
51725
51775
  var TunnelStore = class {
51726
51776
  constructor(filePath) {
51727
51777
  this.filePath = filePath;
@@ -51740,7 +51790,7 @@ var TunnelStore = class {
51740
51790
  }
51741
51791
  }
51742
51792
  async set(v2) {
51743
- const dir = import_node_path29.default.dirname(this.filePath);
51793
+ const dir = import_node_path30.default.dirname(this.filePath);
51744
51794
  await import_node_fs29.default.promises.mkdir(dir, { recursive: true });
51745
51795
  const data = JSON.stringify(v2, null, 2);
51746
51796
  const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
@@ -51851,8 +51901,8 @@ function escape(v2) {
51851
51901
 
51852
51902
  // src/tunnel/frpc-binary.ts
51853
51903
  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);
51904
+ var import_node_os13 = __toESM(require("os"), 1);
51905
+ var import_node_path31 = __toESM(require("path"), 1);
51856
51906
  var import_node_child_process7 = require("child_process");
51857
51907
  var import_node_stream3 = require("stream");
51858
51908
  var import_promises4 = require("stream/promises");
@@ -51891,13 +51941,13 @@ async function ensureFrpcBinary(opts) {
51891
51941
  }
51892
51942
  const version2 = opts.version ?? FRPC_VERSION;
51893
51943
  const platform = opts.platform ?? detectPlatform();
51894
- const binDir = import_node_path30.default.join(opts.dataDir, "bin");
51944
+ const binDir = import_node_path31.default.join(opts.dataDir, "bin");
51895
51945
  import_node_fs30.default.mkdirSync(binDir, { recursive: true });
51896
51946
  cleanupStaleArtifacts(binDir);
51897
- const stableBin = import_node_path30.default.join(binDir, "frpc");
51947
+ const stableBin = import_node_path31.default.join(binDir, "frpc");
51898
51948
  if (import_node_fs30.default.existsSync(stableBin)) return stableBin;
51899
51949
  const partialBin = `${stableBin}.partial`;
51900
- const tarballPath = import_node_path30.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
51950
+ const tarballPath = import_node_path31.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
51901
51951
  try {
51902
51952
  const url = frpcDownloadUrl(version2, platform);
51903
51953
  await downloadToFile(url, tarballPath, opts.fetchImpl);
@@ -51923,7 +51973,7 @@ function cleanupStaleArtifacts(binDir) {
51923
51973
  }
51924
51974
  for (const name of entries) {
51925
51975
  if (name.endsWith(".partial") || name.startsWith("extract-")) {
51926
- const full = import_node_path30.default.join(binDir, name);
51976
+ const full = import_node_path31.default.join(binDir, name);
51927
51977
  try {
51928
51978
  import_node_fs30.default.rmSync(full, { recursive: true, force: true });
51929
51979
  } catch {
@@ -51949,7 +51999,7 @@ async function downloadToFile(url, dest, fetchImpl) {
51949
51999
  await (0, import_promises4.pipeline)(nodeStream, out);
51950
52000
  }
51951
52001
  async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
51952
- const work = import_node_path30.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
52002
+ const work = import_node_path31.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
51953
52003
  import_node_fs30.default.mkdirSync(work, { recursive: true });
51954
52004
  try {
51955
52005
  await new Promise((resolve6, reject) => {
@@ -51958,7 +52008,7 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
51958
52008
  proc.on("exit", (code) => code === 0 ? resolve6() : reject(new Error(`tar exited ${code}`)));
51959
52009
  });
51960
52010
  const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
51961
- const src = import_node_path30.default.join(work, dirName, "frpc");
52011
+ const src = import_node_path31.default.join(work, dirName, "frpc");
51962
52012
  if (!import_node_fs30.default.existsSync(src)) {
51963
52013
  throw new Error(`frpc not found inside tarball at ${src}`);
51964
52014
  }
@@ -51970,10 +52020,10 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
51970
52020
 
51971
52021
  // src/tunnel/frpc-process.ts
51972
52022
  var import_node_fs31 = __toESM(require("fs"), 1);
51973
- var import_node_path31 = __toESM(require("path"), 1);
52023
+ var import_node_path32 = __toESM(require("path"), 1);
51974
52024
  var import_node_child_process8 = require("child_process");
51975
52025
  function frpcPidFilePath(dataDir) {
51976
- return import_node_path31.default.join(dataDir, "frpc.pid");
52026
+ return import_node_path32.default.join(dataDir, "frpc.pid");
51977
52027
  }
51978
52028
  function writeFrpcPid(dataDir, pid) {
51979
52029
  try {
@@ -52015,7 +52065,7 @@ function defaultSleep(ms) {
52015
52065
  }
52016
52066
  async function killStaleFrpc(deps) {
52017
52067
  const pidFile = frpcPidFilePath(deps.dataDir);
52018
- const tomlPath = import_node_path31.default.join(deps.dataDir, "frpc.toml");
52068
+ const tomlPath = import_node_path32.default.join(deps.dataDir, "frpc.toml");
52019
52069
  const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
52020
52070
  const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
52021
52071
  const killPid = deps.killPidImpl ?? defaultKillPid;
@@ -52087,7 +52137,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
52087
52137
  var TunnelManager = class {
52088
52138
  constructor(deps) {
52089
52139
  this.deps = deps;
52090
- this.store = deps.store ?? new TunnelStore(import_node_path32.default.join(deps.dataDir, "tunnel.json"));
52140
+ this.store = deps.store ?? new TunnelStore(import_node_path33.default.join(deps.dataDir, "tunnel.json"));
52091
52141
  this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
52092
52142
  this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
52093
52143
  }
@@ -52214,7 +52264,7 @@ var TunnelManager = class {
52214
52264
  dataDir: this.deps.dataDir,
52215
52265
  override: this.deps.frpcBinaryOverride ?? void 0
52216
52266
  });
52217
- const tomlPath = import_node_path32.default.join(this.deps.dataDir, "frpc.toml");
52267
+ const tomlPath = import_node_path33.default.join(this.deps.dataDir, "frpc.toml");
52218
52268
  const proxyName = `clawd-${t.subdomain}-${localPort}-${import_node_crypto9.default.randomBytes(3).toString("hex")}`;
52219
52269
  const toml = buildFrpcToml({
52220
52270
  serverAddr: t.frpsHost,
@@ -52229,7 +52279,7 @@ var TunnelManager = class {
52229
52279
  const proc = (this.deps.spawnImpl ?? import_node_child_process9.spawn)(frpcBin, ["-c", tomlPath], {
52230
52280
  stdio: ["ignore", "pipe", "pipe"]
52231
52281
  });
52232
- const logFilePath = import_node_path32.default.join(this.deps.dataDir, "frpc.log");
52282
+ const logFilePath = import_node_path33.default.join(this.deps.dataDir, "frpc.log");
52233
52283
  const logStream = import_node_fs32.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
52234
52284
  logStream.on("error", () => {
52235
52285
  });
@@ -52312,16 +52362,16 @@ async function waitForFrpcReady(proc, timeoutMs) {
52312
52362
  }
52313
52363
 
52314
52364
  // src/tunnel/device-key.ts
52315
- var import_node_os13 = __toESM(require("os"), 1);
52316
- var import_node_path33 = __toESM(require("path"), 1);
52365
+ var import_node_os14 = __toESM(require("os"), 1);
52366
+ var import_node_path34 = __toESM(require("path"), 1);
52317
52367
  var import_node_crypto10 = __toESM(require("crypto"), 1);
52318
52368
  var DERIVE_SALT = "clawd-tunnel-device-v1";
52319
52369
  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;
52370
+ const hostname = opts.hostname ?? import_node_os14.default.hostname();
52371
+ const uid = opts.uid ?? (typeof import_node_os14.default.userInfo === "function" ? import_node_os14.default.userInfo().uid : 0);
52372
+ const home = opts.home ?? import_node_os14.default.homedir();
52373
+ const defaultDataDir = import_node_path34.default.resolve(import_node_path34.default.join(home, ".clawd"));
52374
+ const normalizedDataDir = opts.dataDir ? import_node_path34.default.resolve(opts.dataDir) : null;
52325
52375
  const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
52326
52376
  const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
52327
52377
  return import_node_crypto10.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
@@ -52329,11 +52379,11 @@ function deriveStableDeviceKey(opts = {}) {
52329
52379
 
52330
52380
  // src/auth-store.ts
52331
52381
  var import_node_fs33 = __toESM(require("fs"), 1);
52332
- var import_node_path34 = __toESM(require("path"), 1);
52382
+ var import_node_path35 = __toESM(require("path"), 1);
52333
52383
  var import_node_crypto11 = __toESM(require("crypto"), 1);
52334
52384
  var AUTH_FILE_NAME = "auth.json";
52335
52385
  function authFilePath(dataDir) {
52336
- return import_node_path34.default.join(dataDir, AUTH_FILE_NAME);
52386
+ return import_node_path35.default.join(dataDir, AUTH_FILE_NAME);
52337
52387
  }
52338
52388
  function loadOrCreateAuthFile(opts) {
52339
52389
  const file = authFilePath(opts.dataDir);
@@ -52389,7 +52439,7 @@ function readAuthFile(file) {
52389
52439
  }
52390
52440
  }
52391
52441
  function writeAuthFile(file, content) {
52392
- import_node_fs33.default.mkdirSync(import_node_path34.default.dirname(file), { recursive: true });
52442
+ import_node_fs33.default.mkdirSync(import_node_path35.default.dirname(file), { recursive: true });
52393
52443
  import_node_fs33.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
52394
52444
  try {
52395
52445
  import_node_fs33.default.chmodSync(file, 384);
@@ -52399,12 +52449,12 @@ function writeAuthFile(file, content) {
52399
52449
 
52400
52450
  // src/owner-profile.ts
52401
52451
  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);
52452
+ var import_node_os15 = __toESM(require("os"), 1);
52453
+ var import_node_path36 = __toESM(require("path"), 1);
52404
52454
  var PROFILE_FILENAME = "profile.json";
52405
52455
  function loadOwnerDisplayName(dataDir) {
52406
- const fallback = import_node_os14.default.userInfo().username;
52407
- const profilePath = import_node_path35.default.join(dataDir, PROFILE_FILENAME);
52456
+ const fallback = import_node_os15.default.userInfo().username;
52457
+ const profilePath = import_node_path36.default.join(dataDir, PROFILE_FILENAME);
52408
52458
  let raw;
52409
52459
  try {
52410
52460
  raw = import_node_fs34.default.readFileSync(profilePath, "utf8");
@@ -52431,12 +52481,12 @@ function loadOwnerDisplayName(dataDir) {
52431
52481
 
52432
52482
  // src/feishu-auth/owner-identity-store.ts
52433
52483
  var import_node_fs35 = __toESM(require("fs"), 1);
52434
- var import_node_path36 = __toESM(require("path"), 1);
52484
+ var import_node_path37 = __toESM(require("path"), 1);
52435
52485
  var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
52436
52486
  var OwnerIdentityStore = class {
52437
52487
  file;
52438
52488
  constructor(dataDir) {
52439
- this.file = import_node_path36.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
52489
+ this.file = import_node_path37.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
52440
52490
  }
52441
52491
  read() {
52442
52492
  let raw;
@@ -52469,7 +52519,7 @@ var OwnerIdentityStore = class {
52469
52519
  };
52470
52520
  }
52471
52521
  write(record) {
52472
- import_node_fs35.default.mkdirSync(import_node_path36.default.dirname(this.file), { recursive: true });
52522
+ import_node_fs35.default.mkdirSync(import_node_path37.default.dirname(this.file), { recursive: true });
52473
52523
  import_node_fs35.default.writeFileSync(this.file, JSON.stringify(record, null, 2), { mode: 384 });
52474
52524
  try {
52475
52525
  import_node_fs35.default.chmodSync(this.file, 384);
@@ -52599,9 +52649,9 @@ var CentralClientError = class extends Error {
52599
52649
  code;
52600
52650
  cause;
52601
52651
  };
52602
- async function centralRequest(opts, path66, init) {
52652
+ async function centralRequest(opts, path67, init) {
52603
52653
  const f = opts.fetchImpl ?? globalThis.fetch;
52604
- const url = `${opts.api.replace(/\/+$/, "")}${path66}`;
52654
+ const url = `${opts.api.replace(/\/+$/, "")}${path67}`;
52605
52655
  const ctrl = new AbortController();
52606
52656
  const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
52607
52657
  let res;
@@ -52744,7 +52794,7 @@ function verifyConnectToken(args) {
52744
52794
 
52745
52795
  // src/feishu-auth/server-key.ts
52746
52796
  var fs45 = __toESM(require("fs"), 1);
52747
- var path45 = __toESM(require("path"), 1);
52797
+ var path46 = __toESM(require("path"), 1);
52748
52798
  var FILE_NAME2 = "server-signing-key.json";
52749
52799
  var ServerKeyStore = class {
52750
52800
  constructor(dataDir) {
@@ -52752,7 +52802,7 @@ var ServerKeyStore = class {
52752
52802
  }
52753
52803
  dataDir;
52754
52804
  filePath() {
52755
- return path45.join(this.dataDir, FILE_NAME2);
52805
+ return path46.join(this.dataDir, FILE_NAME2);
52756
52806
  }
52757
52807
  /** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
52758
52808
  read() {
@@ -52791,8 +52841,8 @@ init_protocol();
52791
52841
 
52792
52842
  // src/session/fork.ts
52793
52843
  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);
52844
+ var import_node_os16 = __toESM(require("os"), 1);
52845
+ var import_node_path38 = __toESM(require("path"), 1);
52796
52846
  init_claude_history();
52797
52847
  function readJsonlEntries(file) {
52798
52848
  const raw = import_node_fs36.default.readFileSync(file, "utf8");
@@ -52808,9 +52858,9 @@ function readJsonlEntries(file) {
52808
52858
  return out;
52809
52859
  }
52810
52860
  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`);
52861
+ const baseDir = input.baseDir ?? import_node_path38.default.join(import_node_os16.default.homedir(), ".claude");
52862
+ const projectDir = import_node_path38.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
52863
+ const sourceFile = import_node_path38.default.join(projectDir, `${input.toolSessionId}.jsonl`);
52814
52864
  if (!import_node_fs36.default.existsSync(sourceFile)) {
52815
52865
  throw new Error(`fork: source transcript not found: ${sourceFile}`);
52816
52866
  }
@@ -52841,7 +52891,7 @@ function forkSession(input) {
52841
52891
  }
52842
52892
  forkedLines.push(JSON.stringify(forked));
52843
52893
  }
52844
- const forkedFilePath = import_node_path37.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
52894
+ const forkedFilePath = import_node_path38.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
52845
52895
  import_node_fs36.default.mkdirSync(projectDir, { recursive: true });
52846
52896
  import_node_fs36.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
52847
52897
  return { forkedToolSessionId, forkedFilePath };
@@ -53195,7 +53245,7 @@ function buildPermissionHandlers(deps) {
53195
53245
  }
53196
53246
 
53197
53247
  // src/handlers/history.ts
53198
- var path48 = __toESM(require("path"), 1);
53248
+ var path49 = __toESM(require("path"), 1);
53199
53249
  init_protocol();
53200
53250
 
53201
53251
  // src/session/recent-dirs.ts
@@ -53213,7 +53263,7 @@ function listRecentDirs(store, limit = 50) {
53213
53263
  }
53214
53264
 
53215
53265
  // src/permission/persona-paths.ts
53216
- var path47 = __toESM(require("path"), 1);
53266
+ var path48 = __toESM(require("path"), 1);
53217
53267
  function getAllowedPersonaIds(grants, action) {
53218
53268
  const ids = /* @__PURE__ */ new Set();
53219
53269
  for (const g2 of grants) {
@@ -53226,42 +53276,42 @@ function getAllowedPersonaIds(grants, action) {
53226
53276
  return ids;
53227
53277
  }
53228
53278
  function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
53229
- const target = path47.resolve(absPath);
53279
+ const target = path48.resolve(absPath);
53230
53280
  if (userWorkDir) {
53231
- const u = path47.resolve(userWorkDir);
53232
- const usep = u.endsWith(path47.sep) ? "" : path47.sep;
53281
+ const u = path48.resolve(userWorkDir);
53282
+ const usep = u.endsWith(path48.sep) ? "" : path48.sep;
53233
53283
  if (target === u || target.startsWith(u + usep)) return true;
53234
53284
  }
53235
- const root = path47.resolve(personaRoot);
53236
- const sep3 = root.endsWith(path47.sep) ? "" : path47.sep;
53285
+ const root = path48.resolve(personaRoot);
53286
+ const sep3 = root.endsWith(path48.sep) ? "" : path48.sep;
53237
53287
  if (!target.startsWith(root + sep3)) return false;
53238
- const rel = path47.relative(root, target);
53288
+ const rel = path48.relative(root, target);
53239
53289
  if (!rel || rel.startsWith("..")) return false;
53240
- const personaId = rel.split(path47.sep)[0];
53290
+ const personaId = rel.split(path48.sep)[0];
53241
53291
  if (!personaId) return false;
53242
53292
  const allowed = getAllowedPersonaIds(grants, action);
53243
53293
  if (allowed === "*") return true;
53244
53294
  return allowed.has(personaId);
53245
53295
  }
53246
53296
  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;
53297
+ const root = path48.resolve(personaRoot);
53298
+ const target = path48.resolve(absPath);
53299
+ const sep3 = root.endsWith(path48.sep) ? "" : path48.sep;
53250
53300
  if (!target.startsWith(root + sep3)) return null;
53251
- const rel = path47.relative(root, target);
53301
+ const rel = path48.relative(root, target);
53252
53302
  if (!rel || rel.startsWith("..")) return null;
53253
- const id = rel.split(path47.sep)[0];
53303
+ const id = rel.split(path48.sep)[0];
53254
53304
  return id || null;
53255
53305
  }
53256
53306
  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;
53307
+ const d = path48.resolve(dir);
53308
+ const t = path48.resolve(absPath);
53309
+ const sep3 = d.endsWith(path48.sep) ? "" : path48.sep;
53260
53310
  return t === d || t.startsWith(d + sep3);
53261
53311
  }
53262
53312
  function isPathInGuestBoundary(personaRoot, personaId, userWorkDir, absPath) {
53263
53313
  if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
53264
- return personaIdFromPath(path47.resolve(absPath), personaRoot) === personaId;
53314
+ return personaIdFromPath(path48.resolve(absPath), personaRoot) === personaId;
53265
53315
  }
53266
53316
 
53267
53317
  // src/handlers/history.ts
@@ -53287,7 +53337,7 @@ function buildHistoryHandlers(deps) {
53287
53337
  if (!pid) return false;
53288
53338
  return isGuestPathAllowed(
53289
53339
  ctx.grants,
53290
- path48.join(personaRoot, pid),
53340
+ path49.join(personaRoot, pid),
53291
53341
  personaRoot,
53292
53342
  "read",
53293
53343
  userWorkDir
@@ -53299,7 +53349,7 @@ function buildHistoryHandlers(deps) {
53299
53349
  };
53300
53350
  const list = async (frame, _client, ctx) => {
53301
53351
  const args = HistoryListArgs.parse(frame);
53302
- assertGuestPath(ctx, path48.resolve(args.projectPath), personaRoot, "history:list");
53352
+ assertGuestPath(ctx, path49.resolve(args.projectPath), personaRoot, "history:list");
53303
53353
  const sessions = await history.listSessions(args);
53304
53354
  return { response: { type: "history:list", sessions } };
53305
53355
  };
@@ -53331,13 +53381,13 @@ function buildHistoryHandlers(deps) {
53331
53381
  };
53332
53382
  const subagents = async (frame, _client, ctx) => {
53333
53383
  const args = HistorySubagentsArgs.parse(frame);
53334
- assertGuestPath(ctx, path48.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
53384
+ assertGuestPath(ctx, path49.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
53335
53385
  const subs = await history.listSubagents(args);
53336
53386
  return { response: { type: "history:subagents", subagents: subs } };
53337
53387
  };
53338
53388
  const subagentRead = async (frame, _client, ctx) => {
53339
53389
  const args = HistorySubagentReadArgs.parse(frame);
53340
- assertGuestPath(ctx, path48.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
53390
+ assertGuestPath(ctx, path49.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
53341
53391
  const res = await history.readSubagent(args);
53342
53392
  return { response: { type: "history:subagent-read", ...res } };
53343
53393
  };
@@ -53346,7 +53396,7 @@ function buildHistoryHandlers(deps) {
53346
53396
  if (ctx?.principal.kind === "guest" && personaRoot) {
53347
53397
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
53348
53398
  const filtered = dirs.filter(
53349
- (d) => isGuestPathAllowed(ctx.grants, path48.resolve(d.cwd), personaRoot, "read", userWorkDir)
53399
+ (d) => isGuestPathAllowed(ctx.grants, path49.resolve(d.cwd), personaRoot, "read", userWorkDir)
53350
53400
  );
53351
53401
  return { response: { type: "history:recentDirs", dirs: filtered } };
53352
53402
  }
@@ -53363,8 +53413,8 @@ function buildHistoryHandlers(deps) {
53363
53413
  }
53364
53414
 
53365
53415
  // src/handlers/workspace.ts
53366
- var path49 = __toESM(require("path"), 1);
53367
- var os15 = __toESM(require("os"), 1);
53416
+ var path50 = __toESM(require("path"), 1);
53417
+ var os16 = __toESM(require("os"), 1);
53368
53418
  init_protocol();
53369
53419
  init_protocol();
53370
53420
  function buildEnabledPluginNames(personaManager, personaId) {
@@ -53404,23 +53454,23 @@ function buildWorkspaceHandlers(deps) {
53404
53454
  const list = async (frame, _client, ctx) => {
53405
53455
  const args = WorkspaceListArgs.parse(frame);
53406
53456
  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;
53457
+ const fallbackCwd = isGuest && personaRoot ? personaRoot : os16.homedir();
53458
+ const resolvedCwd = path50.resolve(args.cwd ?? fallbackCwd);
53459
+ const target = args.path ? path50.resolve(resolvedCwd, args.path) : resolvedCwd;
53410
53460
  assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
53411
53461
  const res = workspace.list({ ...args, cwd: resolvedCwd });
53412
53462
  return { response: { type: "workspace:list", ...res } };
53413
53463
  };
53414
53464
  const read = async (frame, _client, ctx) => {
53415
53465
  const args = WorkspaceReadArgs.parse(frame);
53416
- const target = path49.isAbsolute(args.path) ? path49.resolve(args.path) : path49.resolve(args.cwd, args.path);
53466
+ const target = path50.isAbsolute(args.path) ? path50.resolve(args.path) : path50.resolve(args.cwd, args.path);
53417
53467
  assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
53418
53468
  const res = workspace.read(args);
53419
53469
  return { response: { type: "workspace:read", ...res } };
53420
53470
  };
53421
53471
  const skillsList = async (frame, _client, ctx) => {
53422
53472
  const args = SkillsListArgs.parse(frame);
53423
- const cwdAbs = path49.resolve(args.cwd);
53473
+ const cwdAbs = path50.resolve(args.cwd);
53424
53474
  assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
53425
53475
  const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
53426
53476
  if (ctx?.principal.kind === "guest" && personaRoot) {
@@ -53432,7 +53482,7 @@ function buildWorkspaceHandlers(deps) {
53432
53482
  };
53433
53483
  const agentsList = async (frame, _client, ctx) => {
53434
53484
  const args = AgentsListArgs.parse(frame);
53435
- const cwdAbs = path49.resolve(args.cwd);
53485
+ const cwdAbs = path50.resolve(args.cwd);
53436
53486
  assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
53437
53487
  if (args.tool === "codex") {
53438
53488
  return { response: { type: "agents:list", agents: [] } };
@@ -53454,18 +53504,18 @@ function buildWorkspaceHandlers(deps) {
53454
53504
  }
53455
53505
 
53456
53506
  // src/handlers/git.ts
53457
- var path51 = __toESM(require("path"), 1);
53507
+ var path52 = __toESM(require("path"), 1);
53458
53508
  init_protocol();
53459
53509
  init_protocol();
53460
53510
 
53461
53511
  // src/workspace/git.ts
53462
53512
  var import_node_child_process10 = require("child_process");
53463
53513
  var import_node_fs37 = __toESM(require("fs"), 1);
53464
- var import_node_path38 = __toESM(require("path"), 1);
53514
+ var import_node_path39 = __toESM(require("path"), 1);
53465
53515
  var import_node_util = require("util");
53466
53516
  var pexec = (0, import_node_util.promisify)(import_node_child_process10.execFile);
53467
53517
  function normalizePath(p2) {
53468
- const resolved = import_node_path38.default.resolve(p2);
53518
+ const resolved = import_node_path39.default.resolve(p2);
53469
53519
  try {
53470
53520
  return import_node_fs37.default.realpathSync(resolved);
53471
53521
  } catch {
@@ -53541,7 +53591,7 @@ async function listGitBranches(cwd) {
53541
53591
  function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
53542
53592
  if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
53543
53593
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
53544
- if (!isGuestPathAllowed(ctx.grants, path51.resolve(cwd), personaRoot, "read", userWorkDir)) {
53594
+ if (!isGuestPathAllowed(ctx.grants, path52.resolve(cwd), personaRoot, "read", userWorkDir)) {
53545
53595
  throw new ClawdError(
53546
53596
  ERROR_CODES.UNAUTHORIZED,
53547
53597
  `guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
@@ -53930,7 +53980,7 @@ function buildDeviceHandlers(deps) {
53930
53980
  }
53931
53981
 
53932
53982
  // src/handlers/meta.ts
53933
- var import_node_os16 = __toESM(require("os"), 1);
53983
+ var import_node_os17 = __toESM(require("os"), 1);
53934
53984
  init_protocol();
53935
53985
 
53936
53986
  // src/version.ts
@@ -53962,7 +54012,7 @@ function buildReadyFrame(deps, client) {
53962
54012
  return {
53963
54013
  version,
53964
54014
  protocolVersion: PROTOCOL_VERSION,
53965
- hostname: import_node_os16.default.hostname(),
54015
+ hostname: import_node_os17.default.hostname(),
53966
54016
  os: process.platform,
53967
54017
  tools,
53968
54018
  runningSessions: info.runningSessions,
@@ -54059,7 +54109,7 @@ function buildPersonaHandlers(deps) {
54059
54109
  }
54060
54110
 
54061
54111
  // src/handlers/attachment.ts
54062
- var import_node_path39 = __toESM(require("path"), 1);
54112
+ var import_node_path40 = __toESM(require("path"), 1);
54063
54113
  init_protocol();
54064
54114
  init_protocol();
54065
54115
  var DEFAULT_TTL_SECONDS = 24 * 3600;
@@ -54139,12 +54189,12 @@ function buildAttachmentHandlers(deps) {
54139
54189
  `session ${args.sessionId} scope unresolved`
54140
54190
  );
54141
54191
  }
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);
54192
+ const cwdAbs = import_node_path40.default.resolve(sessionFile.cwd);
54193
+ 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
54194
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
54145
54195
  const entries = deps.groupFileStore.list(scope, args.sessionId);
54146
54196
  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);
54197
+ 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
54198
  return storedAbs === candidateAbs && !e.stale;
54149
54199
  });
54150
54200
  if (!entry) {
@@ -54169,7 +54219,7 @@ function buildAttachmentHandlers(deps) {
54169
54219
  if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
54170
54220
  const f = deps.sessionStore.read(sessionId);
54171
54221
  if (!f) return;
54172
- assertGuestAttachmentPath(ctx, import_node_path39.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
54222
+ assertGuestAttachmentPath(ctx, import_node_path40.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
54173
54223
  }
54174
54224
  const groupAdd = async (frame, _client, ctx) => {
54175
54225
  if (!deps.groupFileStore || !deps.getSessionScope) {
@@ -54184,8 +54234,8 @@ function buildAttachmentHandlers(deps) {
54184
54234
  if (!scope) {
54185
54235
  throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
54186
54236
  }
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);
54237
+ const cwdAbs = import_node_path40.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
54238
+ 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
54239
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
54190
54240
  const from = ctx?.principal.kind === "owner" ? "owner" : "agent";
54191
54241
  const size = 0;
@@ -54244,19 +54294,19 @@ function buildAttachmentHandlers(deps) {
54244
54294
 
54245
54295
  // src/handlers/extension.ts
54246
54296
  var import_promises8 = __toESM(require("fs/promises"), 1);
54247
- var import_node_path44 = __toESM(require("path"), 1);
54297
+ var import_node_path45 = __toESM(require("path"), 1);
54248
54298
  init_protocol();
54249
54299
 
54250
54300
  // src/extension/bundle-zip.ts
54251
54301
  var import_promises5 = __toESM(require("fs/promises"), 1);
54252
- var import_node_path40 = __toESM(require("path"), 1);
54302
+ var import_node_path41 = __toESM(require("path"), 1);
54253
54303
  var import_node_crypto13 = __toESM(require("crypto"), 1);
54254
54304
  var import_jszip2 = __toESM(require_lib3(), 1);
54255
54305
  async function bundleExtensionDir(dir) {
54256
54306
  const entries = await listFilesSorted(dir);
54257
54307
  const zip = new import_jszip2.default();
54258
54308
  for (const rel of entries) {
54259
- const abs = import_node_path40.default.join(dir, rel);
54309
+ const abs = import_node_path41.default.join(dir, rel);
54260
54310
  const content = await import_promises5.default.readFile(abs);
54261
54311
  zip.file(rel, content, { date: FIXED_DATE });
54262
54312
  }
@@ -54277,7 +54327,7 @@ async function listFilesSorted(rootDir) {
54277
54327
  return out;
54278
54328
  }
54279
54329
  async function walk(absRoot, relPrefix, out) {
54280
- const dirAbs = import_node_path40.default.join(absRoot, relPrefix);
54330
+ const dirAbs = import_node_path41.default.join(absRoot, relPrefix);
54281
54331
  const entries = await import_promises5.default.readdir(dirAbs, { withFileTypes: true });
54282
54332
  for (const e of entries) {
54283
54333
  if (IGNORE_BASENAMES.has(e.name)) continue;
@@ -54331,25 +54381,25 @@ function computePublishCheck(args) {
54331
54381
 
54332
54382
  // src/extension/install-flow.ts
54333
54383
  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);
54384
+ var import_node_path43 = __toESM(require("path"), 1);
54385
+ var import_node_os19 = __toESM(require("os"), 1);
54336
54386
  var import_node_crypto14 = __toESM(require("crypto"), 1);
54337
54387
  var import_jszip3 = __toESM(require_lib3(), 1);
54338
54388
 
54339
54389
  // src/extension/paths.ts
54340
- var import_node_os17 = __toESM(require("os"), 1);
54341
- var import_node_path41 = __toESM(require("path"), 1);
54390
+ var import_node_os18 = __toESM(require("os"), 1);
54391
+ var import_node_path42 = __toESM(require("path"), 1);
54342
54392
  function clawdHomeRoot(override) {
54343
- return override ?? process.env.CLAWD_HOME ?? import_node_path41.default.join(import_node_os17.default.homedir(), ".clawd");
54393
+ return override ?? process.env.CLAWD_HOME ?? import_node_path42.default.join(import_node_os18.default.homedir(), ".clawd");
54344
54394
  }
54345
54395
  function extensionsRoot(override) {
54346
- return import_node_path41.default.join(clawdHomeRoot(override), "extensions");
54396
+ return import_node_path42.default.join(clawdHomeRoot(override), "extensions");
54347
54397
  }
54348
54398
  function publishedChannelsFile(override) {
54349
- return import_node_path41.default.join(clawdHomeRoot(override), "extensions-published.json");
54399
+ return import_node_path42.default.join(clawdHomeRoot(override), "extensions-published.json");
54350
54400
  }
54351
54401
  function bundleCacheRoot(override) {
54352
- return import_node_path41.default.join(clawdHomeRoot(override), "extension-bundles");
54402
+ return import_node_path42.default.join(clawdHomeRoot(override), "extension-bundles");
54353
54403
  }
54354
54404
 
54355
54405
  // src/extension/install-flow.ts
@@ -54376,7 +54426,7 @@ async function installFromChannel(args, deps) {
54376
54426
  throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
54377
54427
  }
54378
54428
  for (const name of Object.keys(zip.files)) {
54379
- if (name.includes("..") || name.startsWith("/") || import_node_path42.default.isAbsolute(name)) {
54429
+ if (name.includes("..") || name.startsWith("/") || import_node_path43.default.isAbsolute(name)) {
54380
54430
  throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
54381
54431
  }
54382
54432
  }
@@ -54408,7 +54458,7 @@ async function installFromChannel(args, deps) {
54408
54458
  );
54409
54459
  }
54410
54460
  const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
54411
- const destDir = import_node_path42.default.join(deps.extensionsRoot, localExtId);
54461
+ const destDir = import_node_path43.default.join(deps.extensionsRoot, localExtId);
54412
54462
  let destExists = false;
54413
54463
  try {
54414
54464
  await import_promises6.default.access(destDir);
@@ -54422,16 +54472,16 @@ async function installFromChannel(args, deps) {
54422
54472
  );
54423
54473
  }
54424
54474
  const stage = await import_promises6.default.mkdtemp(
54425
- import_node_path42.default.join(import_node_os18.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
54475
+ import_node_path43.default.join(import_node_os19.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
54426
54476
  );
54427
54477
  try {
54428
54478
  for (const [name, entry] of Object.entries(zip.files)) {
54429
- const dest = import_node_path42.default.join(stage, name);
54479
+ const dest = import_node_path43.default.join(stage, name);
54430
54480
  if (entry.dir) {
54431
54481
  await import_promises6.default.mkdir(dest, { recursive: true });
54432
54482
  continue;
54433
54483
  }
54434
- await import_promises6.default.mkdir(import_node_path42.default.dirname(dest), { recursive: true });
54484
+ await import_promises6.default.mkdir(import_node_path43.default.dirname(dest), { recursive: true });
54435
54485
  if (name === "manifest.json") {
54436
54486
  const rewritten = { ...parsed.data, id: localExtId };
54437
54487
  await import_promises6.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -54452,8 +54502,8 @@ async function installFromChannel(args, deps) {
54452
54502
 
54453
54503
  // src/extension/update-flow.ts
54454
54504
  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);
54505
+ var import_node_path44 = __toESM(require("path"), 1);
54506
+ var import_node_os20 = __toESM(require("os"), 1);
54457
54507
  var import_node_crypto15 = __toESM(require("crypto"), 1);
54458
54508
  var import_jszip4 = __toESM(require_lib3(), 1);
54459
54509
  var UpdateError = class extends Error {
@@ -54469,11 +54519,11 @@ async function updateFromChannel(args, deps) {
54469
54519
  channelRef.extId,
54470
54520
  channelRef.ownerPrincipalId
54471
54521
  );
54472
- const liveDir = import_node_path43.default.join(deps.extensionsRoot, localExtId);
54522
+ const liveDir = import_node_path44.default.join(deps.extensionsRoot, localExtId);
54473
54523
  const prevDir = `${liveDir}.prev`;
54474
54524
  let existingVersion;
54475
54525
  try {
54476
- const raw = await import_promises7.default.readFile(import_node_path43.default.join(liveDir, "manifest.json"), "utf8");
54526
+ const raw = await import_promises7.default.readFile(import_node_path44.default.join(liveDir, "manifest.json"), "utf8");
54477
54527
  const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
54478
54528
  if (!parsed2.success) {
54479
54529
  throw new UpdateError(
@@ -54506,7 +54556,7 @@ async function updateFromChannel(args, deps) {
54506
54556
  throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
54507
54557
  }
54508
54558
  for (const name of Object.keys(zip.files)) {
54509
- if (name.includes("..") || name.startsWith("/") || import_node_path43.default.isAbsolute(name)) {
54559
+ if (name.includes("..") || name.startsWith("/") || import_node_path44.default.isAbsolute(name)) {
54510
54560
  throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
54511
54561
  }
54512
54562
  }
@@ -54541,16 +54591,16 @@ async function updateFromChannel(args, deps) {
54541
54591
  await import_promises7.default.rm(prevDir, { recursive: true, force: true });
54542
54592
  await import_promises7.default.rename(liveDir, prevDir);
54543
54593
  const stage = await import_promises7.default.mkdtemp(
54544
- import_node_path43.default.join(import_node_os19.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
54594
+ import_node_path44.default.join(import_node_os20.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
54545
54595
  );
54546
54596
  try {
54547
54597
  for (const [name, entry] of Object.entries(zip.files)) {
54548
- const dest = import_node_path43.default.join(stage, name);
54598
+ const dest = import_node_path44.default.join(stage, name);
54549
54599
  if (entry.dir) {
54550
54600
  await import_promises7.default.mkdir(dest, { recursive: true });
54551
54601
  continue;
54552
54602
  }
54553
- await import_promises7.default.mkdir(import_node_path43.default.dirname(dest), { recursive: true });
54603
+ await import_promises7.default.mkdir(import_node_path44.default.dirname(dest), { recursive: true });
54554
54604
  if (name === "manifest.json") {
54555
54605
  const rewritten = { ...parsed.data, id: localExtId };
54556
54606
  await import_promises7.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -54643,7 +54693,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
54643
54693
  );
54644
54694
  }
54645
54695
  }
54646
- const manifestPath = import_node_path44.default.join(root, extId, "manifest.json");
54696
+ const manifestPath = import_node_path45.default.join(root, extId, "manifest.json");
54647
54697
  const manifest = await readManifest(root, extId);
54648
54698
  const next = { ...manifest, version: newVersion };
54649
54699
  const tmp = `${manifestPath}.tmp`;
@@ -54651,7 +54701,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
54651
54701
  await import_promises8.default.rename(tmp, manifestPath);
54652
54702
  }
54653
54703
  async function readManifest(root, extId) {
54654
- const file = import_node_path44.default.join(root, extId, "manifest.json");
54704
+ const file = import_node_path45.default.join(root, extId, "manifest.json");
54655
54705
  let raw;
54656
54706
  try {
54657
54707
  raw = await import_promises8.default.readFile(file, "utf8");
@@ -54742,7 +54792,7 @@ function buildExtensionHandlers(deps) {
54742
54792
  };
54743
54793
  async function buildSnapshotMeta(extId) {
54744
54794
  const manifest = await readManifest(deps.root, extId);
54745
- const { sha256, buffer } = await bundleExtensionDir(import_node_path44.default.join(deps.root, extId));
54795
+ const { sha256, buffer } = await bundleExtensionDir(import_node_path45.default.join(deps.root, extId));
54746
54796
  return { manifest, contentHash: sha256, buffer };
54747
54797
  }
54748
54798
  const publish = async (frame, _client, ctx) => {
@@ -54925,7 +54975,7 @@ function buildExtensionHandlers(deps) {
54925
54975
  // src/app-builder/project-store.ts
54926
54976
  var import_node_fs38 = require("fs");
54927
54977
  var import_node_child_process11 = require("child_process");
54928
- var import_node_path45 = require("path");
54978
+ var import_node_path46 = require("path");
54929
54979
  init_protocol();
54930
54980
  var PROJECTS_DIR = "projects";
54931
54981
  var META_FILE = ".clawd-project.json";
@@ -54939,14 +54989,14 @@ var ProjectStore = class {
54939
54989
  root;
54940
54990
  /** projects/<name>/.clawd-project.json 路径 */
54941
54991
  metaPath(name) {
54942
- return (0, import_node_path45.join)(this.projectsRoot(), name, META_FILE);
54992
+ return (0, import_node_path46.join)(this.projectsRoot(), name, META_FILE);
54943
54993
  }
54944
54994
  /** projects/<name>/ 目录路径(cwd 用) */
54945
54995
  projectDir(name) {
54946
- return (0, import_node_path45.join)(this.projectsRoot(), name);
54996
+ return (0, import_node_path46.join)(this.projectsRoot(), name);
54947
54997
  }
54948
54998
  projectsRoot() {
54949
- return (0, import_node_path45.join)(this.root, PROJECTS_DIR);
54999
+ return (0, import_node_path46.join)(this.root, PROJECTS_DIR);
54950
55000
  }
54951
55001
  async list() {
54952
55002
  let entries;
@@ -55249,7 +55299,7 @@ var PublishJobRegistry = class {
55249
55299
  // src/app-builder/publish-job-runner.ts
55250
55300
  var import_node_child_process13 = require("child_process");
55251
55301
  var import_node_fs39 = require("fs");
55252
- var import_node_path46 = require("path");
55302
+ var import_node_path47 = require("path");
55253
55303
 
55254
55304
  // src/app-builder/publish-stage-parser.ts
55255
55305
  var STAGE_RE = /^\s*::stage::(build|deploy|verify)\s*$/;
@@ -55281,7 +55331,7 @@ async function startPublishJob(deps, args) {
55281
55331
  return { jobId: registry2.get(args.name).jobId, status: "already-publishing" };
55282
55332
  }
55283
55333
  const projDir = projectDir(args.name);
55284
- const logPath = (0, import_node_path46.join)(projDir, ".publish.log");
55334
+ const logPath = (0, import_node_path47.join)(projDir, ".publish.log");
55285
55335
  let logStream = null;
55286
55336
  try {
55287
55337
  logStream = (0, import_node_fs39.createWriteStream)(logPath, { flags: "w" });
@@ -55541,7 +55591,7 @@ async function recoverInterruptedJobs(deps) {
55541
55591
 
55542
55592
  // src/handlers/app-builder.ts
55543
55593
  init_protocol();
55544
- var import_node_path47 = require("path");
55594
+ var import_node_path48 = require("path");
55545
55595
  var import_node_fs40 = require("fs");
55546
55596
  var APP_BUILDER_PERSONAS = ["persona-app-builder", "persona-dataclaw-builder"];
55547
55597
  var DEV_SERVER_READY_TIMEOUT_MS = 3e4;
@@ -55699,8 +55749,8 @@ function buildAppBuilderHandlers(deps) {
55699
55749
  const project = await userStore.create(f.name, reservedPorts);
55700
55750
  try {
55701
55751
  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");
55752
+ const templateSrcDir = (0, import_node_path48.join)(personaRoot, "extension-kit", "examples", DEFAULT_TEMPLATE);
55753
+ const scaffoldScript = (0, import_node_path48.join)(deps.deployKitRoot, "scripts", "new-extension.sh");
55704
55754
  const scaffoldResult = await userStore.scaffold(project.name, templateSrcDir, scaffoldScript);
55705
55755
  deps.logger?.info("app-builder.scaffold.done", {
55706
55756
  name: project.name,
@@ -55921,7 +55971,7 @@ function buildAppBuilderHandlers(deps) {
55921
55971
  await userStore.clearPublishJob(args.name);
55922
55972
  }
55923
55973
  const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(boundSession.ownerPersonaId ?? "") : deps.personaRoot;
55924
- const scriptPath = (0, import_node_path47.join)(deps.deployKitRoot, "scripts", "publish.sh");
55974
+ const scriptPath = (0, import_node_path48.join)(deps.deployKitRoot, "scripts", "publish.sh");
55925
55975
  deps.logger?.info("app-builder.publish.start", {
55926
55976
  name: args.name,
55927
55977
  sessionId: boundSession.sessionId,
@@ -56090,7 +56140,7 @@ function buildVisitorHandlers(deps) {
56090
56140
 
56091
56141
  // src/extension/registry.ts
56092
56142
  var import_promises9 = __toESM(require("fs/promises"), 1);
56093
- var import_node_path48 = __toESM(require("path"), 1);
56143
+ var import_node_path49 = __toESM(require("path"), 1);
56094
56144
  async function loadAll(root) {
56095
56145
  let entries;
56096
56146
  try {
@@ -56103,13 +56153,13 @@ async function loadAll(root) {
56103
56153
  for (const ent of entries) {
56104
56154
  if (!ent.isDirectory()) continue;
56105
56155
  if (ent.name.startsWith(".")) continue;
56106
- records.push(await loadOne(import_node_path48.default.join(root, ent.name), ent.name));
56156
+ records.push(await loadOne(import_node_path49.default.join(root, ent.name), ent.name));
56107
56157
  }
56108
56158
  records.sort((a, b2) => a.extId < b2.extId ? -1 : a.extId > b2.extId ? 1 : 0);
56109
56159
  return records;
56110
56160
  }
56111
56161
  async function loadOne(dir, dirName) {
56112
- const manifestPath = import_node_path48.default.join(dir, "manifest.json");
56162
+ const manifestPath = import_node_path49.default.join(dir, "manifest.json");
56113
56163
  let raw;
56114
56164
  try {
56115
56165
  raw = await import_promises9.default.readFile(manifestPath, "utf8");
@@ -56154,7 +56204,7 @@ async function loadOne(dir, dirName) {
56154
56204
 
56155
56205
  // src/extension/uninstall.ts
56156
56206
  var import_promises10 = __toESM(require("fs/promises"), 1);
56157
- var import_node_path49 = __toESM(require("path"), 1);
56207
+ var import_node_path50 = __toESM(require("path"), 1);
56158
56208
  var UninstallError = class extends Error {
56159
56209
  constructor(code, message) {
56160
56210
  super(message);
@@ -56163,7 +56213,7 @@ var UninstallError = class extends Error {
56163
56213
  code;
56164
56214
  };
56165
56215
  async function uninstall(deps) {
56166
- const dir = import_node_path49.default.join(deps.root, deps.extId);
56216
+ const dir = import_node_path50.default.join(deps.root, deps.extId);
56167
56217
  try {
56168
56218
  await import_promises10.default.access(dir);
56169
56219
  } catch {
@@ -56719,7 +56769,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
56719
56769
 
56720
56770
  // src/extension/runtime.ts
56721
56771
  var import_node_child_process15 = require("child_process");
56722
- var import_node_path50 = __toESM(require("path"), 1);
56772
+ var import_node_path51 = __toESM(require("path"), 1);
56723
56773
  var import_promises11 = require("timers/promises");
56724
56774
 
56725
56775
  // src/extension/port-allocator.ts
@@ -56820,7 +56870,7 @@ var Runtime = class {
56820
56870
  /\$CLAWOS_EXT_PORT/g,
56821
56871
  String(port)
56822
56872
  );
56823
- const dir = import_node_path50.default.join(this.root, extId);
56873
+ const dir = import_node_path51.default.join(this.root, extId);
56824
56874
  const env = {
56825
56875
  ...process.env,
56826
56876
  CLAWOS_EXT_PORT: String(port),
@@ -56932,7 +56982,7 @@ ${handle.stderrTail}`
56932
56982
 
56933
56983
  // src/extension/published-channels.ts
56934
56984
  var import_promises12 = __toESM(require("fs/promises"), 1);
56935
- var import_node_path51 = __toESM(require("path"), 1);
56985
+ var import_node_path52 = __toESM(require("path"), 1);
56936
56986
  init_zod();
56937
56987
  var PublishedChannelsError = class extends Error {
56938
56988
  constructor(code, message) {
@@ -57031,7 +57081,7 @@ var PublishedChannelStore = class {
57031
57081
  )
57032
57082
  };
57033
57083
  const tmp = `${this.filePath}.tmp`;
57034
- await import_promises12.default.mkdir(import_node_path51.default.dirname(this.filePath), { recursive: true });
57084
+ await import_promises12.default.mkdir(import_node_path52.default.dirname(this.filePath), { recursive: true });
57035
57085
  await import_promises12.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
57036
57086
  await import_promises12.default.rename(tmp, this.filePath);
57037
57087
  }
@@ -57039,7 +57089,7 @@ var PublishedChannelStore = class {
57039
57089
 
57040
57090
  // src/extension/bundle-cache.ts
57041
57091
  var import_promises13 = __toESM(require("fs/promises"), 1);
57042
- var import_node_path52 = __toESM(require("path"), 1);
57092
+ var import_node_path53 = __toESM(require("path"), 1);
57043
57093
  var BundleCache = class {
57044
57094
  constructor(rootDir) {
57045
57095
  this.rootDir = rootDir;
@@ -57048,14 +57098,14 @@ var BundleCache = class {
57048
57098
  /** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
57049
57099
  async write(snapshotHash, buffer) {
57050
57100
  await import_promises13.default.mkdir(this.rootDir, { recursive: true });
57051
- const file = import_node_path52.default.join(this.rootDir, `${snapshotHash}.zip`);
57101
+ const file = import_node_path53.default.join(this.rootDir, `${snapshotHash}.zip`);
57052
57102
  const tmp = `${file}.tmp`;
57053
57103
  await import_promises13.default.writeFile(tmp, buffer, { mode: 384 });
57054
57104
  await import_promises13.default.rename(tmp, file);
57055
57105
  }
57056
57106
  /** Returns the bundle bytes, or null when the file doesn't exist. */
57057
57107
  async read(snapshotHash) {
57058
- const file = import_node_path52.default.join(this.rootDir, `${snapshotHash}.zip`);
57108
+ const file = import_node_path53.default.join(this.rootDir, `${snapshotHash}.zip`);
57059
57109
  try {
57060
57110
  return await import_promises13.default.readFile(file);
57061
57111
  } catch (e) {
@@ -57065,7 +57115,7 @@ var BundleCache = class {
57065
57115
  }
57066
57116
  /** Idempotent — missing file is not an error. */
57067
57117
  async delete(snapshotHash) {
57068
- const file = import_node_path52.default.join(this.rootDir, `${snapshotHash}.zip`);
57118
+ const file = import_node_path53.default.join(this.rootDir, `${snapshotHash}.zip`);
57069
57119
  await import_promises13.default.rm(file, { force: true });
57070
57120
  }
57071
57121
  };
@@ -57086,11 +57136,11 @@ async function startDaemon(config) {
57086
57136
  },
57087
57137
  source: "daemon",
57088
57138
  sampling: logShippingCfg.sampling,
57089
- homeDir: import_node_os20.default.homedir()
57139
+ homeDir: import_node_os21.default.homedir()
57090
57140
  });
57091
57141
  const logger = createLogger({
57092
57142
  level: config.logLevel,
57093
- file: import_node_path53.default.join(config.dataDir, "clawd.log"),
57143
+ file: import_node_path54.default.join(config.dataDir, "clawd.log"),
57094
57144
  logClient
57095
57145
  });
57096
57146
  logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
@@ -57230,8 +57280,8 @@ async function startDaemon(config) {
57230
57280
  const agents = new AgentsScanner();
57231
57281
  const history = new ClaudeHistoryReader();
57232
57282
  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");
57283
+ const personaStore = new PersonaStore(import_node_path54.default.join(config.dataDir, "personas"));
57284
+ const usersRoot = import_node_path54.default.join(config.dataDir, "users");
57235
57285
  const defaultsRoot = findDefaultsRoot(logger);
57236
57286
  if (defaultsRoot) {
57237
57287
  seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
@@ -57251,17 +57301,17 @@ async function startDaemon(config) {
57251
57301
  migrateCodexSandbox({ store: personaStore, logger });
57252
57302
  const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
57253
57303
  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));
57304
+ const here = typeof __dirname === "string" ? __dirname : import_node_path54.default.dirname((0, import_node_url4.fileURLToPath)(import_meta6.url));
57255
57305
  const dispatchServerCandidates = [
57256
- import_node_path53.default.join(here, "dispatch", "mcp-server.cjs"),
57306
+ import_node_path54.default.join(here, "dispatch", "mcp-server.cjs"),
57257
57307
  // 生产 dist/index → dist/dispatch/mcp-server.cjs
57258
- import_node_path53.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
57308
+ import_node_path54.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
57259
57309
  // dev tsx src/index → ../dist/dispatch/mcp-server.cjs
57260
57310
  ];
57261
57311
  const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs41.default.existsSync(p2));
57262
57312
  let dispatchMcpConfigPath2;
57263
57313
  if (dispatchServerScriptPath) {
57264
- const dispatchLogPath = import_node_path53.default.join(config.dataDir, "dispatch-mcp-server.log");
57314
+ const dispatchLogPath = import_node_path54.default.join(config.dataDir, "dispatch-mcp-server.log");
57265
57315
  dispatchMcpConfigPath2 = writeDispatchMcpConfig({
57266
57316
  dataDir: config.dataDir,
57267
57317
  serverScriptPath: dispatchServerScriptPath,
@@ -57278,15 +57328,15 @@ async function startDaemon(config) {
57278
57328
  });
57279
57329
  }
57280
57330
  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")
57331
+ import_node_path54.default.join(here, "ticket", "mcp-server.cjs"),
57332
+ import_node_path54.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
57283
57333
  ];
57284
57334
  const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs41.default.existsSync(p2));
57285
57335
  const ticketOwnerUnionId = feishuIdentity?.identity.unionId ?? "";
57286
57336
  const ticketOwnerName = feishuIdentity?.identity.displayName ?? "";
57287
57337
  let ticketMcpConfigPath2;
57288
57338
  if (ticketServerScriptPath && ticketOwnerUnionId) {
57289
- const ticketLogPath = import_node_path53.default.join(config.dataDir, "ticket-mcp-server.log");
57339
+ const ticketLogPath = import_node_path54.default.join(config.dataDir, "ticket-mcp-server.log");
57290
57340
  ticketMcpConfigPath2 = writeTicketMcpConfig({
57291
57341
  dataDir: config.dataDir,
57292
57342
  serverScriptPath: ticketServerScriptPath,
@@ -57307,13 +57357,13 @@ async function startDaemon(config) {
57307
57357
  });
57308
57358
  }
57309
57359
  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")
57360
+ import_node_path54.default.join(here, "shift", "mcp-server.cjs"),
57361
+ import_node_path54.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
57312
57362
  ];
57313
57363
  const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs41.default.existsSync(p2));
57314
57364
  let shiftMcpConfigPath2;
57315
57365
  if (shiftServerScriptPath) {
57316
- const shiftLogPath = import_node_path53.default.join(config.dataDir, "shift-mcp-server.log");
57366
+ const shiftLogPath = import_node_path54.default.join(config.dataDir, "shift-mcp-server.log");
57317
57367
  shiftMcpConfigPath2 = await writeShiftMcpConfig({
57318
57368
  dataDir: config.dataDir,
57319
57369
  serverScriptPath: shiftServerScriptPath,
@@ -57331,7 +57381,7 @@ async function startDaemon(config) {
57331
57381
  );
57332
57382
  }
57333
57383
  const shiftStore = createShiftStore({
57334
- filePath: import_node_path53.default.join(config.dataDir, "shift.json"),
57384
+ filePath: import_node_path54.default.join(config.dataDir, "shift.json"),
57335
57385
  ownerIdProvider: () => ownerPrincipalId,
57336
57386
  now: () => Date.now()
57337
57387
  });
@@ -57349,7 +57399,7 @@ async function startDaemon(config) {
57349
57399
  getAdapter,
57350
57400
  historyReader: history,
57351
57401
  dataDir: config.dataDir,
57352
- personaRoot: import_node_path53.default.join(config.dataDir, "personas"),
57402
+ personaRoot: import_node_path54.default.join(config.dataDir, "personas"),
57353
57403
  usersRoot,
57354
57404
  personaStore,
57355
57405
  ownerDisplayName,
@@ -57390,7 +57440,7 @@ async function startDaemon(config) {
57390
57440
  // 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
57391
57441
  attachmentGroup: {
57392
57442
  onFileEdit: (input) => {
57393
- const absPath = import_node_path53.default.isAbsolute(input.relPath) ? input.relPath : import_node_path53.default.join(input.cwd, input.relPath);
57443
+ const absPath = import_node_path54.default.isAbsolute(input.relPath) ? input.relPath : import_node_path54.default.join(input.cwd, input.relPath);
57394
57444
  let size = 0;
57395
57445
  try {
57396
57446
  size = import_node_fs41.default.statSync(absPath).size;
@@ -57591,11 +57641,11 @@ async function startDaemon(config) {
57591
57641
  // 'persona/<pid>/owner',default 走 'default'。
57592
57642
  getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
57593
57643
  // guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
57594
- personaRoot: import_node_path53.default.join(config.dataDir, "personas"),
57644
+ personaRoot: import_node_path54.default.join(config.dataDir, "personas"),
57595
57645
  usersRoot
57596
57646
  },
57597
57647
  // workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
57598
- personaRoot: import_node_path53.default.join(config.dataDir, "personas"),
57648
+ personaRoot: import_node_path54.default.join(config.dataDir, "personas"),
57599
57649
  // v2 多人 persona 隔离:handler 派生 guest user-dir 放行
57600
57650
  usersRoot,
57601
57651
  // capability:list / delete handler 依赖
@@ -57702,11 +57752,11 @@ async function startDaemon(config) {
57702
57752
  // 发布上线脚手架化 (spec 2026-06-03 §5.2):
57703
57753
  // appBuilderPersonaRoot 用于拼 publish.sh 绝对路径(persona-app-builder 安装在
57704
57754
  // dataDir/personas/persona-app-builder 之下,extension-kit/scripts/publish.sh 是相对路径)。
57705
- appBuilderPersonaRoot: import_node_path53.default.join(config.dataDir, "personas", "persona-app-builder"),
57755
+ appBuilderPersonaRoot: import_node_path54.default.join(config.dataDir, "personas", "persona-app-builder"),
57706
57756
  // 共享 deploy-kit 根:scaffold/publish 脚本骨架 + 阿里云凭证单一真源。
57707
- deployKitRoot: import_node_path53.default.join(config.dataDir, "deploy-kit"),
57757
+ deployKitRoot: import_node_path54.default.join(config.dataDir, "deploy-kit"),
57708
57758
  // scaffold/publish 按当前 session 的 persona 解析其安装根,让每个 persona 用自己的模板/注入配置。
57709
- resolvePersonaRoot: (personaId) => import_node_path53.default.join(config.dataDir, "personas", personaId),
57759
+ resolvePersonaRoot: (personaId) => import_node_path54.default.join(config.dataDir, "personas", personaId),
57710
57760
  // 发布上线脚手架化 (spec 2026-06-03 §5.2.2):
57711
57761
  // 复用 SessionManagerDeps.broadcastFrame 同款 dispatch 逻辑 —— runner 调 manager.send
57712
57762
  // 取回 broadcast 帧后逐帧 push 到 transport,跟 manager 自身的 deps 一致。
@@ -57749,8 +57799,8 @@ async function startDaemon(config) {
57749
57799
  }
57750
57800
  let sourceJsonlPath = "(no transcript yet \u2014 operate from the task description alone)";
57751
57801
  if (sourceFile && sourceFile.toolSessionId) {
57752
- sourceJsonlPath = import_node_path53.default.join(
57753
- import_node_os20.default.homedir(),
57802
+ sourceJsonlPath = import_node_path54.default.join(
57803
+ import_node_os21.default.homedir(),
57754
57804
  ".claude",
57755
57805
  "projects",
57756
57806
  cwdToHashDir(sourceFile.cwd),
@@ -58049,8 +58099,8 @@ async function startDaemon(config) {
58049
58099
  const lines = [
58050
58100
  `Tunnel: ${r.url}`,
58051
58101
  ...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")}`
58102
+ `Frpc config: ${import_node_path54.default.join(config.dataDir, "frpc.toml")}`,
58103
+ `Frpc log: ${import_node_path54.default.join(config.dataDir, "frpc.log")}`
58054
58104
  ];
58055
58105
  const width = Math.max(...lines.map((l) => l.length));
58056
58106
  const bar = "\u2550".repeat(width + 4);
@@ -58063,7 +58113,7 @@ ${bar}
58063
58113
 
58064
58114
  `);
58065
58115
  try {
58066
- const connectPath = import_node_path53.default.join(config.dataDir, "connect.txt");
58116
+ const connectPath = import_node_path54.default.join(config.dataDir, "connect.txt");
58067
58117
  import_node_fs41.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
58068
58118
  } catch {
58069
58119
  }
@@ -58136,7 +58186,7 @@ ${bar}
58136
58186
  };
58137
58187
  }
58138
58188
  function migrateDropPersonsDir(dataDir) {
58139
- const dir = import_node_path53.default.join(dataDir, "persons");
58189
+ const dir = import_node_path54.default.join(dataDir, "persons");
58140
58190
  try {
58141
58191
  import_node_fs41.default.rmSync(dir, { recursive: true, force: true });
58142
58192
  } catch {