@clawos-dev/clawd 0.2.190-beta.380.a359b26 → 0.2.191-beta.381.2ccc9ac

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs CHANGED
@@ -5599,7 +5599,7 @@ var init_capability = __esm({
5599
5599
  });
5600
5600
 
5601
5601
  // ../protocol/src/inbox.ts
5602
- var InboxMessageSchema, InboxPostMessageArgsSchema, InboxListArgsSchema, InboxMarkReadArgsSchema;
5602
+ var InboxMessageSchema, InboxPostMessageArgsSchema, InboxListArgsSchema, InboxMarkReadArgsSchema, InboxSendDmArgsSchema;
5603
5603
  var init_inbox = __esm({
5604
5604
  "../protocol/src/inbox.ts"() {
5605
5605
  "use strict";
@@ -5610,13 +5610,18 @@ var init_inbox = __esm({
5610
5610
  senderDeviceId: external_exports.string().min(1),
5611
5611
  text: external_exports.string().min(1),
5612
5612
  createdAt: external_exports.number().int().nonnegative(),
5613
- readBy: external_exports.record(external_exports.string().min(1), external_exports.number().int().positive()).default({})
5613
+ readBy: external_exports.record(external_exports.string().min(1), external_exports.number().int().positive()).default({}),
5614
+ // persona 代发署名(B 版设计):非空 = 该消息由某 persona 代发,非真人手打。
5615
+ // 缺省 = 真人。routing 身份仍看 senderDeviceId;origin 只用于末端 UI 渲染来源。
5616
+ origin: external_exports.object({ kind: external_exports.literal("persona"), personaId: external_exports.string().min(1) }).optional()
5614
5617
  }).strict();
5615
5618
  InboxPostMessageArgsSchema = external_exports.object({
5616
5619
  peerDeviceId: external_exports.string().min(1).optional(),
5617
5620
  id: external_exports.string().min(1),
5618
5621
  text: external_exports.string().min(1),
5619
- createdAt: external_exports.number().int().nonnegative()
5622
+ createdAt: external_exports.number().int().nonnegative(),
5623
+ // persona 代发署名(跨 daemon forward 时随远程腿透传;真人发缺省)。
5624
+ origin: external_exports.object({ kind: external_exports.literal("persona"), personaId: external_exports.string().min(1) }).optional()
5620
5625
  }).strict();
5621
5626
  InboxListArgsSchema = external_exports.object({
5622
5627
  peerDeviceId: external_exports.string().min(1),
@@ -5626,6 +5631,10 @@ var init_inbox = __esm({
5626
5631
  peerDeviceId: external_exports.string().min(1),
5627
5632
  upToCreatedAt: external_exports.number().int().nonnegative()
5628
5633
  }).strict();
5634
+ InboxSendDmArgsSchema = external_exports.object({
5635
+ peerDeviceId: external_exports.string().min(1).optional(),
5636
+ text: external_exports.string().min(1)
5637
+ });
5629
5638
  }
5630
5639
  });
5631
5640
 
@@ -7276,7 +7285,7 @@ var require_atomic_sleep = __commonJS({
7276
7285
  var require_sonic_boom = __commonJS({
7277
7286
  "../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
7278
7287
  "use strict";
7279
- var fs60 = require("fs");
7288
+ var fs61 = require("fs");
7280
7289
  var EventEmitter3 = require("events");
7281
7290
  var inherits = require("util").inherits;
7282
7291
  var path67 = require("path");
@@ -7333,20 +7342,20 @@ var require_sonic_boom = __commonJS({
7333
7342
  const mode = sonic.mode;
7334
7343
  if (sonic.sync) {
7335
7344
  try {
7336
- if (sonic.mkdir) fs60.mkdirSync(path67.dirname(file), { recursive: true });
7337
- const fd = fs60.openSync(file, flags, mode);
7345
+ if (sonic.mkdir) fs61.mkdirSync(path67.dirname(file), { recursive: true });
7346
+ const fd = fs61.openSync(file, flags, mode);
7338
7347
  fileOpened(null, fd);
7339
7348
  } catch (err) {
7340
7349
  fileOpened(err);
7341
7350
  throw err;
7342
7351
  }
7343
7352
  } else if (sonic.mkdir) {
7344
- fs60.mkdir(path67.dirname(file), { recursive: true }, (err) => {
7353
+ fs61.mkdir(path67.dirname(file), { recursive: true }, (err) => {
7345
7354
  if (err) return fileOpened(err);
7346
- fs60.open(file, flags, mode, fileOpened);
7355
+ fs61.open(file, flags, mode, fileOpened);
7347
7356
  });
7348
7357
  } else {
7349
- fs60.open(file, flags, mode, fileOpened);
7358
+ fs61.open(file, flags, mode, fileOpened);
7350
7359
  }
7351
7360
  }
7352
7361
  function SonicBoom(opts) {
@@ -7387,8 +7396,8 @@ var require_sonic_boom = __commonJS({
7387
7396
  this.flush = flushBuffer;
7388
7397
  this.flushSync = flushBufferSync;
7389
7398
  this._actualWrite = actualWriteBuffer;
7390
- fsWriteSync = () => fs60.writeSync(this.fd, this._writingBuf);
7391
- fsWrite = () => fs60.write(this.fd, this._writingBuf, this.release);
7399
+ fsWriteSync = () => fs61.writeSync(this.fd, this._writingBuf);
7400
+ fsWrite = () => fs61.write(this.fd, this._writingBuf, this.release);
7392
7401
  } else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
7393
7402
  this._writingBuf = "";
7394
7403
  this.write = write;
@@ -7397,15 +7406,15 @@ var require_sonic_boom = __commonJS({
7397
7406
  this._actualWrite = actualWrite;
7398
7407
  fsWriteSync = () => {
7399
7408
  if (Buffer.isBuffer(this._writingBuf)) {
7400
- return fs60.writeSync(this.fd, this._writingBuf);
7409
+ return fs61.writeSync(this.fd, this._writingBuf);
7401
7410
  }
7402
- return fs60.writeSync(this.fd, this._writingBuf, "utf8");
7411
+ return fs61.writeSync(this.fd, this._writingBuf, "utf8");
7403
7412
  };
7404
7413
  fsWrite = () => {
7405
7414
  if (Buffer.isBuffer(this._writingBuf)) {
7406
- return fs60.write(this.fd, this._writingBuf, this.release);
7415
+ return fs61.write(this.fd, this._writingBuf, this.release);
7407
7416
  }
7408
- return fs60.write(this.fd, this._writingBuf, "utf8", this.release);
7417
+ return fs61.write(this.fd, this._writingBuf, "utf8", this.release);
7409
7418
  };
7410
7419
  } else {
7411
7420
  throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
@@ -7462,7 +7471,7 @@ var require_sonic_boom = __commonJS({
7462
7471
  }
7463
7472
  }
7464
7473
  if (this._fsync) {
7465
- fs60.fsyncSync(this.fd);
7474
+ fs61.fsyncSync(this.fd);
7466
7475
  }
7467
7476
  const len = this._len;
7468
7477
  if (this._reopening) {
@@ -7576,7 +7585,7 @@ var require_sonic_boom = __commonJS({
7576
7585
  const onDrain = () => {
7577
7586
  if (!this._fsync) {
7578
7587
  try {
7579
- fs60.fsync(this.fd, (err) => {
7588
+ fs61.fsync(this.fd, (err) => {
7580
7589
  this._flushPending = false;
7581
7590
  cb(err);
7582
7591
  });
@@ -7678,7 +7687,7 @@ var require_sonic_boom = __commonJS({
7678
7687
  const fd = this.fd;
7679
7688
  this.once("ready", () => {
7680
7689
  if (fd !== this.fd) {
7681
- fs60.close(fd, (err) => {
7690
+ fs61.close(fd, (err) => {
7682
7691
  if (err) {
7683
7692
  return this.emit("error", err);
7684
7693
  }
@@ -7727,7 +7736,7 @@ var require_sonic_boom = __commonJS({
7727
7736
  buf = this._bufs[0];
7728
7737
  }
7729
7738
  try {
7730
- const n = Buffer.isBuffer(buf) ? fs60.writeSync(this.fd, buf) : fs60.writeSync(this.fd, buf, "utf8");
7739
+ const n = Buffer.isBuffer(buf) ? fs61.writeSync(this.fd, buf) : fs61.writeSync(this.fd, buf, "utf8");
7731
7740
  const releasedBufObj = releaseWritingBuf(buf, this._len, n);
7732
7741
  buf = releasedBufObj.writingBuf;
7733
7742
  this._len = releasedBufObj.len;
@@ -7743,7 +7752,7 @@ var require_sonic_boom = __commonJS({
7743
7752
  }
7744
7753
  }
7745
7754
  try {
7746
- fs60.fsyncSync(this.fd);
7755
+ fs61.fsyncSync(this.fd);
7747
7756
  } catch {
7748
7757
  }
7749
7758
  }
@@ -7764,7 +7773,7 @@ var require_sonic_boom = __commonJS({
7764
7773
  buf = mergeBuf(this._bufs[0], this._lens[0]);
7765
7774
  }
7766
7775
  try {
7767
- const n = fs60.writeSync(this.fd, buf);
7776
+ const n = fs61.writeSync(this.fd, buf);
7768
7777
  buf = buf.subarray(n);
7769
7778
  this._len = Math.max(this._len - n, 0);
7770
7779
  if (buf.length <= 0) {
@@ -7792,13 +7801,13 @@ var require_sonic_boom = __commonJS({
7792
7801
  this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
7793
7802
  if (this.sync) {
7794
7803
  try {
7795
- const written = Buffer.isBuffer(this._writingBuf) ? fs60.writeSync(this.fd, this._writingBuf) : fs60.writeSync(this.fd, this._writingBuf, "utf8");
7804
+ const written = Buffer.isBuffer(this._writingBuf) ? fs61.writeSync(this.fd, this._writingBuf) : fs61.writeSync(this.fd, this._writingBuf, "utf8");
7796
7805
  release(null, written);
7797
7806
  } catch (err) {
7798
7807
  release(err);
7799
7808
  }
7800
7809
  } else {
7801
- fs60.write(this.fd, this._writingBuf, release);
7810
+ fs61.write(this.fd, this._writingBuf, release);
7802
7811
  }
7803
7812
  }
7804
7813
  function actualWriteBuffer() {
@@ -7807,7 +7816,7 @@ var require_sonic_boom = __commonJS({
7807
7816
  this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
7808
7817
  if (this.sync) {
7809
7818
  try {
7810
- const written = fs60.writeSync(this.fd, this._writingBuf);
7819
+ const written = fs61.writeSync(this.fd, this._writingBuf);
7811
7820
  release(null, written);
7812
7821
  } catch (err) {
7813
7822
  release(err);
@@ -7816,7 +7825,7 @@ var require_sonic_boom = __commonJS({
7816
7825
  if (kCopyBuffer) {
7817
7826
  this._writingBuf = Buffer.from(this._writingBuf);
7818
7827
  }
7819
- fs60.write(this.fd, this._writingBuf, release);
7828
+ fs61.write(this.fd, this._writingBuf, release);
7820
7829
  }
7821
7830
  }
7822
7831
  function actualClose(sonic) {
@@ -7832,12 +7841,12 @@ var require_sonic_boom = __commonJS({
7832
7841
  sonic._lens = [];
7833
7842
  assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
7834
7843
  try {
7835
- fs60.fsync(sonic.fd, closeWrapped);
7844
+ fs61.fsync(sonic.fd, closeWrapped);
7836
7845
  } catch {
7837
7846
  }
7838
7847
  function closeWrapped() {
7839
7848
  if (sonic.fd !== 1 && sonic.fd !== 2) {
7840
- fs60.close(sonic.fd, done);
7849
+ fs61.close(sonic.fd, done);
7841
7850
  } else {
7842
7851
  done();
7843
7852
  }
@@ -10201,7 +10210,7 @@ var require_multistream = __commonJS({
10201
10210
  var require_pino = __commonJS({
10202
10211
  "../node_modules/.pnpm/pino@9.14.0/node_modules/pino/pino.js"(exports2, module2) {
10203
10212
  "use strict";
10204
- var os23 = require("os");
10213
+ var os22 = require("os");
10205
10214
  var stdSerializers = require_pino_std_serializers();
10206
10215
  var caller = require_caller();
10207
10216
  var redaction = require_redaction();
@@ -10248,7 +10257,7 @@ var require_pino = __commonJS({
10248
10257
  } = symbols;
10249
10258
  var { epochTime, nullTime } = time;
10250
10259
  var { pid } = process;
10251
- var hostname = os23.hostname();
10260
+ var hostname = os22.hostname();
10252
10261
  var defaultErrorSerializer = stdSerializers.err;
10253
10262
  var defaultOptions = {
10254
10263
  level: "info",
@@ -11044,7 +11053,7 @@ var init_lib = __esm({
11044
11053
  tokenize: function tokenize(value) {
11045
11054
  return Array.from(value);
11046
11055
  },
11047
- join: function join3(chars) {
11056
+ join: function join5(chars) {
11048
11057
  return chars.join("");
11049
11058
  },
11050
11059
  postProcess: function postProcess(changeObjects) {
@@ -11226,33 +11235,13 @@ var init_tool_result_extra = __esm({
11226
11235
  function cwdToHashDir(cwd) {
11227
11236
  return cwd.replace(/[^a-zA-Z0-9]/g, "-");
11228
11237
  }
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
- }
11249
11238
  function hashDirToCwd(hash) {
11250
11239
  const body = hash.startsWith("-") ? hash.slice(1) : hash;
11251
11240
  return "/" + body.replace(/-/g, "/");
11252
11241
  }
11253
11242
  function safeStatMtime(p2) {
11254
11243
  try {
11255
- return import_node_fs4.default.statSync(p2).mtimeMs;
11244
+ return import_node_fs13.default.statSync(p2).mtimeMs;
11256
11245
  } catch {
11257
11246
  return 0;
11258
11247
  }
@@ -11260,7 +11249,7 @@ function safeStatMtime(p2) {
11260
11249
  function readJsonlLines(file) {
11261
11250
  let raw;
11262
11251
  try {
11263
- raw = import_node_fs4.default.readFileSync(file, "utf8");
11252
+ raw = import_node_fs13.default.readFileSync(file, "utf8");
11264
11253
  } catch (err) {
11265
11254
  if (err.code === "ENOENT") return [];
11266
11255
  throw err;
@@ -11491,8 +11480,8 @@ function attachmentDeferredToolsText(a) {
11491
11480
  function readBackupContent(fileHistoryRoot, toolSessionId, backupFileName) {
11492
11481
  if (backupFileName === null) return null;
11493
11482
  try {
11494
- return import_node_fs4.default.readFileSync(
11495
- import_node_path4.default.join(fileHistoryRoot, toolSessionId, backupFileName),
11483
+ return import_node_fs13.default.readFileSync(
11484
+ import_node_path12.default.join(fileHistoryRoot, toolSessionId, backupFileName),
11496
11485
  "utf8"
11497
11486
  );
11498
11487
  } catch {
@@ -11501,19 +11490,19 @@ function readBackupContent(fileHistoryRoot, toolSessionId, backupFileName) {
11501
11490
  }
11502
11491
  function readCurrentContent(filePath) {
11503
11492
  try {
11504
- return import_node_fs4.default.readFileSync(filePath, "utf8");
11493
+ return import_node_fs13.default.readFileSync(filePath, "utf8");
11505
11494
  } catch (err) {
11506
11495
  if (err.code === "ENOENT") return null;
11507
11496
  return null;
11508
11497
  }
11509
11498
  }
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;
11499
+ var import_node_fs13, import_node_os5, import_node_path12, TASK_NOTIFICATION_RE, TASK_ID_RE, TOOL_USE_ID_RE, SLASH_COMMAND_RE, LOCAL_COMMAND_RE, SYSTEM_REMINDER_RE, OPENSPEC_BLOCK_RE, SKILL_HINT_RE, ATTACHMENT_SILENT_SUBTYPES, ClaudeHistoryReader;
11511
11500
  var init_claude_history = __esm({
11512
11501
  "src/tools/claude-history.ts"() {
11513
11502
  "use strict";
11514
- import_node_fs4 = __toESM(require("fs"), 1);
11515
- import_node_os3 = __toESM(require("os"), 1);
11516
- import_node_path4 = __toESM(require("path"), 1);
11503
+ import_node_fs13 = __toESM(require("fs"), 1);
11504
+ import_node_os5 = __toESM(require("os"), 1);
11505
+ import_node_path12 = __toESM(require("path"), 1);
11517
11506
  init_lib();
11518
11507
  init_tool_result_extra();
11519
11508
  TASK_NOTIFICATION_RE = /<task-notification\b[\s\S]*?<\/task-notification>/i;
@@ -11537,14 +11526,14 @@ var init_claude_history = __esm({
11537
11526
  // 每次 user 提交前 trackEdit 拷一份,作为 rewind 回退目标
11538
11527
  fileHistoryRoot;
11539
11528
  constructor(opts = {}) {
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");
11529
+ const base = opts.baseDir ?? import_node_path12.default.join(import_node_os5.default.homedir(), ".claude");
11530
+ this.projectsRoot = import_node_path12.default.join(base, "projects");
11531
+ this.fileHistoryRoot = import_node_path12.default.join(base, "file-history");
11543
11532
  }
11544
11533
  async listProjects() {
11545
11534
  let entries;
11546
11535
  try {
11547
- entries = import_node_fs4.default.readdirSync(this.projectsRoot, { withFileTypes: true });
11536
+ entries = import_node_fs13.default.readdirSync(this.projectsRoot, { withFileTypes: true });
11548
11537
  } catch (err) {
11549
11538
  if (err.code === "ENOENT") return [];
11550
11539
  throw err;
@@ -11552,9 +11541,9 @@ var init_claude_history = __esm({
11552
11541
  const out = [];
11553
11542
  for (const ent of entries) {
11554
11543
  if (!ent.isDirectory()) continue;
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);
11544
+ const dir = import_node_path12.default.join(this.projectsRoot, ent.name);
11545
+ const files = import_node_fs13.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
11546
+ const updatedAtMs = files.reduce((m2, f) => Math.max(m2, safeStatMtime(import_node_path12.default.join(dir, f))), 0);
11558
11547
  out.push({
11559
11548
  projectPath: hashDirToCwd(ent.name),
11560
11549
  hashDir: ent.name,
@@ -11566,17 +11555,17 @@ var init_claude_history = __esm({
11566
11555
  return out;
11567
11556
  }
11568
11557
  async listSessions(args) {
11569
- const dir = import_node_path4.default.join(this.projectsRoot, cwdToHashDir(args.projectPath));
11558
+ const dir = import_node_path12.default.join(this.projectsRoot, cwdToHashDir(args.projectPath));
11570
11559
  let files;
11571
11560
  try {
11572
- files = import_node_fs4.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
11561
+ files = import_node_fs13.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
11573
11562
  } catch (err) {
11574
11563
  if (err.code === "ENOENT") return [];
11575
11564
  throw err;
11576
11565
  }
11577
11566
  const out = [];
11578
11567
  for (const f of files) {
11579
- const full = import_node_path4.default.join(dir, f);
11568
+ const full = import_node_path12.default.join(dir, f);
11580
11569
  const toolSessionId = f.slice(0, -".jsonl".length);
11581
11570
  const lines = readJsonlLines(full);
11582
11571
  let summary = "";
@@ -11631,7 +11620,7 @@ var init_claude_history = __esm({
11631
11620
  return out;
11632
11621
  }
11633
11622
  async read(args) {
11634
- const file = import_node_path4.default.join(
11623
+ const file = import_node_path12.default.join(
11635
11624
  this.projectsRoot,
11636
11625
  cwdToHashDir(args.cwd),
11637
11626
  `${args.toolSessionId}.jsonl`
@@ -11668,7 +11657,7 @@ var init_claude_history = __esm({
11668
11657
  // 独立目录路径:<projectsRoot>/<cwdHash>/<toolSessionId>/subagents/*.jsonl
11669
11658
  // 返回 null 表示目录不存在(调用方回退旧实现);返回空数组表示目录存在但无 jsonl
11670
11659
  listSubagentsFromDirectory(cwd, toolSessionId) {
11671
- const dir = import_node_path4.default.join(
11660
+ const dir = import_node_path12.default.join(
11672
11661
  this.projectsRoot,
11673
11662
  cwdToHashDir(cwd),
11674
11663
  toolSessionId,
@@ -11676,7 +11665,7 @@ var init_claude_history = __esm({
11676
11665
  );
11677
11666
  let entries;
11678
11667
  try {
11679
- entries = import_node_fs4.default.readdirSync(dir, { withFileTypes: true });
11668
+ entries = import_node_fs13.default.readdirSync(dir, { withFileTypes: true });
11680
11669
  } catch (err) {
11681
11670
  if (err.code === "ENOENT") return null;
11682
11671
  return null;
@@ -11686,7 +11675,7 @@ var init_claude_history = __esm({
11686
11675
  if (!e.isFile()) continue;
11687
11676
  if (!e.name.startsWith("agent-") || !e.name.endsWith(".jsonl")) continue;
11688
11677
  const subagentId = e.name.slice("agent-".length, -".jsonl".length);
11689
- const filePath = import_node_path4.default.join(dir, e.name);
11678
+ const filePath = import_node_path12.default.join(dir, e.name);
11690
11679
  const lines = readJsonlLines(filePath);
11691
11680
  let firstText = "";
11692
11681
  let messageCount = 0;
@@ -11703,7 +11692,7 @@ var init_claude_history = __esm({
11703
11692
  return out;
11704
11693
  }
11705
11694
  listSubagentsFromMainJsonl(cwd, toolSessionId) {
11706
- const file = import_node_path4.default.join(
11695
+ const file = import_node_path12.default.join(
11707
11696
  this.projectsRoot,
11708
11697
  cwdToHashDir(cwd),
11709
11698
  `${toolSessionId}.jsonl`
@@ -11738,7 +11727,7 @@ var init_claude_history = __esm({
11738
11727
  }
11739
11728
  // 独立文件路径:agent-<subagentId>.jsonl;文件不存在返回 null 让调用方回退旧实现
11740
11729
  readSubagentFromFile(cwd, toolSessionId, subagentId) {
11741
- const file = import_node_path4.default.join(
11730
+ const file = import_node_path12.default.join(
11742
11731
  this.projectsRoot,
11743
11732
  cwdToHashDir(cwd),
11744
11733
  toolSessionId,
@@ -11747,7 +11736,7 @@ var init_claude_history = __esm({
11747
11736
  );
11748
11737
  let exists = false;
11749
11738
  try {
11750
- exists = import_node_fs4.default.statSync(file).isFile();
11739
+ exists = import_node_fs13.default.statSync(file).isFile();
11751
11740
  } catch {
11752
11741
  return null;
11753
11742
  }
@@ -11766,7 +11755,7 @@ var init_claude_history = __esm({
11766
11755
  * "那一刻每个 tracked 文件对应的 backup 文件名"
11767
11756
  */
11768
11757
  readFileHistorySnapshots(args) {
11769
- const file = import_node_path4.default.join(
11758
+ const file = import_node_path12.default.join(
11770
11759
  this.projectsRoot,
11771
11760
  cwdToHashDir(args.cwd),
11772
11761
  `${args.toolSessionId}.jsonl`
@@ -11811,7 +11800,7 @@ var init_claude_history = __esm({
11811
11800
  for (const [anchorId, target] of snapshots) {
11812
11801
  let hasAny = false;
11813
11802
  for (const [rawPath, backup] of Object.entries(target)) {
11814
- const absPath = import_node_path4.default.isAbsolute(rawPath) ? rawPath : import_node_path4.default.join(args.cwd, rawPath);
11803
+ const absPath = import_node_path12.default.isAbsolute(rawPath) ? rawPath : import_node_path12.default.join(args.cwd, rawPath);
11815
11804
  const backupContent = readBackupContent(
11816
11805
  this.fileHistoryRoot,
11817
11806
  args.toolSessionId,
@@ -11851,7 +11840,7 @@ var init_claude_history = __esm({
11851
11840
  let totalInsertions = 0;
11852
11841
  let totalDeletions = 0;
11853
11842
  for (const [rawPath, backup] of Object.entries(target)) {
11854
- const absPath = import_node_path4.default.isAbsolute(rawPath) ? rawPath : import_node_path4.default.join(args.cwd, rawPath);
11843
+ const absPath = import_node_path12.default.isAbsolute(rawPath) ? rawPath : import_node_path12.default.join(args.cwd, rawPath);
11855
11844
  const backupContent = readBackupContent(
11856
11845
  this.fileHistoryRoot,
11857
11846
  args.toolSessionId,
@@ -11898,7 +11887,7 @@ var init_claude_history = __esm({
11898
11887
  };
11899
11888
  }
11900
11889
  readSubagentFromMainJsonl(cwd, toolSessionId, subagentId) {
11901
- const file = import_node_path4.default.join(
11890
+ const file = import_node_path12.default.join(
11902
11891
  this.projectsRoot,
11903
11892
  cwdToHashDir(cwd),
11904
11893
  `${toolSessionId}.jsonl`
@@ -11984,6 +11973,9 @@ function buildSpawnArgs(ctx) {
11984
11973
  if (ctx.shiftMcpConfigPath) {
11985
11974
  args.push("--mcp-config", ctx.shiftMcpConfigPath);
11986
11975
  }
11976
+ if (ctx.inboxMcpConfigPath) {
11977
+ args.push("--mcp-config", ctx.inboxMcpConfigPath);
11978
+ }
11987
11979
  args.push("--disallowed-tools", "CronCreate,CronDelete,CronList,ScheduleWakeup,RemoteTrigger");
11988
11980
  if (ctx.effort) args.push("--effort", ctx.effort);
11989
11981
  if (ctx.toolSessionId) args.push("--resume", ctx.toolSessionId);
@@ -40112,8 +40104,8 @@ function startRunCaseRecorder(opts) {
40112
40104
  });
40113
40105
  const ensureStream = () => {
40114
40106
  if (stream) return stream;
40115
- import_node_fs42.default.mkdirSync(dir, { recursive: true });
40116
- stream = import_node_fs42.default.createWriteStream(opts.recordPath, { flags: "a" });
40107
+ import_node_fs43.default.mkdirSync(dir, { recursive: true });
40108
+ stream = import_node_fs43.default.createWriteStream(opts.recordPath, { flags: "a" });
40117
40109
  stream.on("close", () => closedResolve());
40118
40110
  return stream;
40119
40111
  };
@@ -40138,11 +40130,11 @@ function startRunCaseRecorder(opts) {
40138
40130
  };
40139
40131
  return { tap, close, closed };
40140
40132
  }
40141
- var import_node_fs42, import_node_path55;
40133
+ var import_node_fs43, import_node_path55;
40142
40134
  var init_recorder = __esm({
40143
40135
  "src/run-case/recorder.ts"() {
40144
40136
  "use strict";
40145
- import_node_fs42 = __toESM(require("fs"), 1);
40137
+ import_node_fs43 = __toESM(require("fs"), 1);
40146
40138
  import_node_path55 = __toESM(require("path"), 1);
40147
40139
  }
40148
40140
  });
@@ -40186,7 +40178,7 @@ var init_wire = __esm({
40186
40178
  // src/run-case/controller.ts
40187
40179
  async function runController(opts) {
40188
40180
  const now = opts.now ?? Date.now;
40189
- const cwd = opts.cwd ?? (0, import_node_fs43.mkdtempSync)(import_node_path56.default.join(import_node_os22.default.tmpdir(), "clawd-runcase-"));
40181
+ const cwd = opts.cwd ?? (0, import_node_fs44.mkdtempSync)(import_node_path56.default.join(import_node_os21.default.tmpdir(), "clawd-runcase-"));
40190
40182
  const ownsCwd = opts.cwd === void 0;
40191
40183
  const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
40192
40184
  const spawnCtx = { cwd };
@@ -40347,18 +40339,18 @@ async function runController(opts) {
40347
40339
  if (sigintHandler) process.off("SIGINT", sigintHandler);
40348
40340
  if (ownsCwd) {
40349
40341
  try {
40350
- (0, import_node_fs43.rmSync)(cwd, { recursive: true, force: true });
40342
+ (0, import_node_fs44.rmSync)(cwd, { recursive: true, force: true });
40351
40343
  } catch {
40352
40344
  }
40353
40345
  }
40354
40346
  return exitCode ?? 0;
40355
40347
  }
40356
- var import_node_fs43, import_node_os22, import_node_path56;
40348
+ var import_node_fs44, import_node_os21, import_node_path56;
40357
40349
  var init_controller = __esm({
40358
40350
  "src/run-case/controller.ts"() {
40359
40351
  "use strict";
40360
- import_node_fs43 = require("fs");
40361
- import_node_os22 = __toESM(require("os"), 1);
40352
+ import_node_fs44 = require("fs");
40353
+ import_node_os21 = __toESM(require("os"), 1);
40362
40354
  import_node_path56 = __toESM(require("path"), 1);
40363
40355
  init_claude();
40364
40356
  init_stdout_splitter();
@@ -40622,8 +40614,8 @@ Env (advanced):
40622
40614
 
40623
40615
  // src/index.ts
40624
40616
  var import_node_path54 = __toESM(require("path"), 1);
40625
- var import_node_fs41 = __toESM(require("fs"), 1);
40626
- var import_node_os21 = __toESM(require("os"), 1);
40617
+ var import_node_fs42 = __toESM(require("fs"), 1);
40618
+ var import_node_os20 = __toESM(require("os"), 1);
40627
40619
 
40628
40620
  // ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/stringify.js
40629
40621
  var byteToHex = [];
@@ -41240,9 +41232,9 @@ var SessionStoreFactory = class {
41240
41232
  };
41241
41233
 
41242
41234
  // src/session/manager.ts
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);
41235
+ var import_node_fs6 = __toESM(require("fs"), 1);
41236
+ var import_node_path6 = __toESM(require("path"), 1);
41237
+ var import_node_os3 = __toESM(require("os"), 1);
41246
41238
  init_protocol();
41247
41239
 
41248
41240
  // src/tools/guest-settings.ts
@@ -41340,10 +41332,6 @@ function escapeAttr(v2) {
41340
41332
  return v2.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
41341
41333
  }
41342
41334
 
41343
- // src/session/runner.ts
41344
- var import_node_os4 = __toESM(require("os"), 1);
41345
- var import_node_path6 = __toESM(require("path"), 1);
41346
-
41347
41335
  // src/session/reducer.ts
41348
41336
  init_runtime();
41349
41337
 
@@ -41430,7 +41418,7 @@ var ATTACHMENT_SHARING_HINT = `## \u628A\u4EA7\u51FA\u6587\u4EF6\u5206\u4EAB\u7E
41430
41418
  // src/dispatch/system-prompt.ts
41431
41419
  var DISPATCH_SYSTEM_PROMPT_HINT = `## \u59D4\u6D3E\u7ED9\u53E6\u4E00\u4E2A persona\uFF08dispatch\uFF09
41432
41420
 
41433
- \u5F53\u7528\u6237\u6D88\u606F\u91CC\u542B \`@persona/<id>\`\uFF08\u5982 \`@persona/persona-app-builder\`\uFF09\u65F6\uFF0C**\u4F60\u5FC5\u987B**\u7ACB\u5373\u8C03 MCP tool \`mcp__clawd-dispatch__personaDispatch\` \u59D4\u6D3E\uFF0C\u4E0D\u8981\u5C1D\u8BD5\u81EA\u5DF1\u6267\u884C\uFF1A
41421
+ \u5F53\u7528\u6237\u6D88\u606F\u91CC\u542B \`@persona/<id>\`\uFF08\u5982 \`@persona/persona-bug-fixer\`\uFF09\u65F6\uFF0C**\u4F60\u5FC5\u987B**\u7ACB\u5373\u8C03 MCP tool \`mcp__clawd-dispatch__personaDispatch\` \u59D4\u6D3E\uFF0C\u4E0D\u8981\u5C1D\u8BD5\u81EA\u5DF1\u6267\u884C\uFF1A
41434
41422
 
41435
41423
  - \`targetPersona = <id>\`\uFF08@ token \u91CC\u7684 persona id\uFF09
41436
41424
  - \`prompt = \u53BB\u6389 @persona/<id> token \u7684\u7528\u6237\u539F\u6587\`
@@ -41482,7 +41470,7 @@ function cloneState(s) {
41482
41470
  pendingSend: s.pendingSend.slice()
41483
41471
  };
41484
41472
  }
41485
- var IDLE_KILL_DELAY_MS = 6e5;
41473
+ var IDLE_KILL_DELAY_MS = 6e4;
41486
41474
  function tryFlushPending(state, deps) {
41487
41475
  if (!state.readyForSend || state.pendingSend.length === 0) return [];
41488
41476
  const text = state.pendingSend.shift();
@@ -41547,6 +41535,7 @@ function buildSpawnContext(state, deps) {
41547
41535
  const ticketMcpConfigPathRaw = deps.getTicketMcpConfigPath?.() ?? null;
41548
41536
  const ticketMcpConfigPath2 = ticketMcpConfigPathRaw && file.ownerPersonaId === "persona-ticket-manager" ? ticketMcpConfigPathRaw : null;
41549
41537
  const shiftMcpConfigPath2 = deps.getShiftMcpConfigPath?.() ?? null;
41538
+ const inboxMcpConfigPath2 = deps.getInboxMcpConfigPath?.() ?? null;
41550
41539
  const ctx = {
41551
41540
  cwd: file.cwd,
41552
41541
  toolSessionId: file.toolSessionId,
@@ -41562,6 +41551,7 @@ function buildSpawnContext(state, deps) {
41562
41551
  dispatchMcpConfigPath: dispatchMcpConfigPath2 ?? void 0,
41563
41552
  ticketMcpConfigPath: ticketMcpConfigPath2 ?? void 0,
41564
41553
  shiftMcpConfigPath: shiftMcpConfigPath2 ?? void 0,
41554
+ inboxMcpConfigPath: inboxMcpConfigPath2 ?? void 0,
41565
41555
  // shift v1:把 SessionFile.ownerPersonaId 透传到 SpawnContext;buildSpawnArgs 等下游
41566
41556
  // 不直接读这个字段(只读 env),但保留显式字段方便 daemon 内部诊断/日志。
41567
41557
  personaId
@@ -42151,18 +42141,6 @@ function reduceSession(state, input, deps) {
42151
42141
  if (state.status !== "running-idle") {
42152
42142
  return { state, effects: [] };
42153
42143
  }
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
- }
42166
42144
  const next = cloneState(state);
42167
42145
  next.status = "stopping";
42168
42146
  return {
@@ -42219,11 +42197,10 @@ function reduceSession(state, input, deps) {
42219
42197
  // src/session/runner.ts
42220
42198
  init_stdout_splitter();
42221
42199
  init_permission_stdio();
42222
- init_claude_history();
42223
42200
 
42224
42201
  // src/ipc-recorder.ts
42225
- var import_node_fs5 = __toESM(require("fs"), 1);
42226
- var import_node_path5 = __toESM(require("path"), 1);
42202
+ var import_node_fs4 = __toESM(require("fs"), 1);
42203
+ var import_node_path4 = __toESM(require("path"), 1);
42227
42204
  function tsForFilename(ms) {
42228
42205
  return new Date(ms).toISOString().replace(/[:.]/g, "-");
42229
42206
  }
@@ -42234,8 +42211,8 @@ function startRecorder(opts) {
42234
42211
  return null;
42235
42212
  }
42236
42213
  const now = opts.now ?? Date.now;
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`);
42214
+ const dir = import_node_path4.default.join(opts.dataDir, "ipc-recordings", opts.sessionId);
42215
+ const filePath = import_node_path4.default.join(dir, `${tsForFilename(now())}.jsonl`);
42239
42216
  let stream = null;
42240
42217
  let closedResolve;
42241
42218
  const closed = new Promise((resolve6) => {
@@ -42244,8 +42221,8 @@ function startRecorder(opts) {
42244
42221
  let exited = false;
42245
42222
  const ensureStream = () => {
42246
42223
  if (stream) return stream;
42247
- import_node_fs5.default.mkdirSync(dir, { recursive: true });
42248
- stream = import_node_fs5.default.createWriteStream(filePath, { flags: "a" });
42224
+ import_node_fs4.default.mkdirSync(dir, { recursive: true });
42225
+ stream = import_node_fs4.default.createWriteStream(filePath, { flags: "a" });
42249
42226
  stream.on("close", () => closedResolve());
42250
42227
  return stream;
42251
42228
  };
@@ -42290,7 +42267,6 @@ function encodeAllowWithInputControlResponse(requestId, updatedInput) {
42290
42267
  return JSON.stringify(payload) + "\n";
42291
42268
  }
42292
42269
  var DEFAULT_WAIT_STOP_TIMEOUT_MS = 3e3;
42293
- var SUBAGENT_ACTIVE_WINDOW_MS = 3e5;
42294
42270
  var SessionRunner = class {
42295
42271
  constructor(initial, hooks) {
42296
42272
  this.hooks = hooks;
@@ -42348,6 +42324,7 @@ var SessionRunner = class {
42348
42324
  // 见 reducer.buildSpawnContext 注 CLAWD_DISPATCH_ID env / 派生 SpawnContext.dispatchMcpConfigPath
42349
42325
  getDispatchMcpConfigPath: this.hooks.getDispatchMcpConfigPath,
42350
42326
  getShiftMcpConfigPath: this.hooks.getShiftMcpConfigPath,
42327
+ getInboxMcpConfigPath: this.hooks.getInboxMcpConfigPath,
42351
42328
  // Ticket MCP:透传 ticket.mcp.json 路径闭包(reducer 内做 persona-ticket-manager gating)
42352
42329
  getTicketMcpConfigPath: this.hooks.getTicketMcpConfigPath,
42353
42330
  lookupDispatchByBSessionId: this.hooks.lookupDispatchByBSessionId,
@@ -42602,7 +42579,7 @@ var SessionRunner = class {
42602
42579
  if (existing) clearTimeout(existing);
42603
42580
  const timer = setTimeout(() => {
42604
42581
  this.idleKillTimers.delete(effect.sessionId);
42605
- this.input({ kind: "idle-kill-fired", subagentActive: this.isSubagentActive() });
42582
+ this.input({ kind: "idle-kill-fired" });
42606
42583
  }, effect.ms);
42607
42584
  timer.unref?.();
42608
42585
  this.idleKillTimers.set(effect.sessionId, timer);
@@ -42618,18 +42595,6 @@ var SessionRunner = class {
42618
42595
  }
42619
42596
  }
42620
42597
  }
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
- }
42633
42598
  // 清空所有 idle-kill timer(runner dispose / proc 永久退出时调用)。
42634
42599
  // 不喂 idle-kill-fired —— dispose 路径不再翻 reducer 状态
42635
42600
  clearIdleKillTimers() {
@@ -42712,15 +42677,15 @@ function extractEditPath(input) {
42712
42677
  }
42713
42678
 
42714
42679
  // src/debug/pty-probe.ts
42715
- var import_node_fs6 = __toESM(require("fs"), 1);
42716
- var import_node_path7 = __toESM(require("path"), 1);
42680
+ var import_node_fs5 = __toESM(require("fs"), 1);
42681
+ var import_node_path5 = __toESM(require("path"), 1);
42717
42682
  var PROBE_DIR = "/tmp/clawd-probe";
42718
- var EVENTS_FILE = import_node_path7.default.join(PROBE_DIR, "events.jsonl");
42683
+ var EVENTS_FILE = import_node_path5.default.join(PROBE_DIR, "events.jsonl");
42719
42684
  var inited = false;
42720
42685
  function ensureDir() {
42721
42686
  if (inited) return true;
42722
42687
  try {
42723
- import_node_fs6.default.mkdirSync(PROBE_DIR, { recursive: true });
42688
+ import_node_fs5.default.mkdirSync(PROBE_DIR, { recursive: true });
42724
42689
  inited = true;
42725
42690
  return true;
42726
42691
  } catch {
@@ -42731,15 +42696,15 @@ function probeEvent(event, data = {}) {
42731
42696
  try {
42732
42697
  if (!ensureDir()) return;
42733
42698
  const line = JSON.stringify({ ts: Date.now(), event, ...data }) + "\n";
42734
- import_node_fs6.default.appendFileSync(EVENTS_FILE, line);
42699
+ import_node_fs5.default.appendFileSync(EVENTS_FILE, line);
42735
42700
  } catch {
42736
42701
  }
42737
42702
  }
42738
42703
  function probeDumpReplay(sessionId, payload) {
42739
42704
  try {
42740
42705
  if (!ensureDir()) return "";
42741
- const file = import_node_path7.default.join(PROBE_DIR, `replay-${sessionId}-${Date.now()}.ans`);
42742
- import_node_fs6.default.writeFileSync(file, payload, "utf8");
42706
+ const file = import_node_path5.default.join(PROBE_DIR, `replay-${sessionId}-${Date.now()}.ans`);
42707
+ import_node_fs5.default.writeFileSync(file, payload, "utf8");
42743
42708
  return file;
42744
42709
  } catch {
42745
42710
  return "";
@@ -42846,7 +42811,7 @@ function derivePersonaSpawnCwd(file, personaRoot) {
42846
42811
  `derivePersonaSpawnCwd: personaRoot missing for owner session ${file.sessionId} (ownerPersonaId=${personaId})`
42847
42812
  );
42848
42813
  }
42849
- return import_node_path8.default.join(personaRoot, safeFileName(personaId));
42814
+ return import_node_path6.default.join(personaRoot, safeFileName(personaId));
42850
42815
  }
42851
42816
  function makeInitialState(file, subSessionMeta) {
42852
42817
  return {
@@ -42971,10 +42936,10 @@ var SessionManager = class {
42971
42936
  // <dataDir>/sessions/ 列子目录 (排除 'default').
42972
42937
  listPersonaIdsOnDisk() {
42973
42938
  if (!this.deps.dataDir) return [];
42974
- const root = this.deps.storeFactory ? import_node_path8.default.join(this.deps.dataDir, "personas") : import_node_path8.default.join(this.deps.dataDir, "sessions");
42939
+ const root = this.deps.storeFactory ? import_node_path6.default.join(this.deps.dataDir, "personas") : import_node_path6.default.join(this.deps.dataDir, "sessions");
42975
42940
  let entries;
42976
42941
  try {
42977
- entries = import_node_fs7.default.readdirSync(root, { withFileTypes: true });
42942
+ entries = import_node_fs6.default.readdirSync(root, { withFileTypes: true });
42978
42943
  } catch (err) {
42979
42944
  const code = err?.code;
42980
42945
  if (code === "ENOENT") return [];
@@ -42987,7 +42952,7 @@ var SessionManager = class {
42987
42952
  // 只在 storeFactory 注入 (新布局) 下生效, 老布局无 guest 目录.
42988
42953
  listGuestCapIdsForPersona(personaId) {
42989
42954
  if (!this.deps.dataDir || !this.deps.storeFactory) return [];
42990
- const root = import_node_path8.default.join(
42955
+ const root = import_node_path6.default.join(
42991
42956
  this.deps.dataDir,
42992
42957
  "personas",
42993
42958
  personaId,
@@ -42997,7 +42962,7 @@ var SessionManager = class {
42997
42962
  );
42998
42963
  let entries;
42999
42964
  try {
43000
- entries = import_node_fs7.default.readdirSync(root, { withFileTypes: true });
42965
+ entries = import_node_fs6.default.readdirSync(root, { withFileTypes: true });
43001
42966
  } catch (err) {
43002
42967
  const code = err?.code;
43003
42968
  if (code === "ENOENT") return [];
@@ -43116,7 +43081,7 @@ var SessionManager = class {
43116
43081
  callerDisplayName
43117
43082
  );
43118
43083
  if (subSessionMeta?.userWorkDir) {
43119
- import_node_fs7.default.mkdirSync(subSessionMeta.userWorkDir, { recursive: true });
43084
+ import_node_fs6.default.mkdirSync(subSessionMeta.userWorkDir, { recursive: true });
43120
43085
  }
43121
43086
  if (scope.kind === "persona" && scope.mode === "guest") {
43122
43087
  if (!this.deps.personaRoot || !subSessionMeta?.userWorkDir) {
@@ -43127,8 +43092,8 @@ var SessionManager = class {
43127
43092
  const base = this.deps.personaStore?.readSandboxSettings(scope.personaId) ?? null;
43128
43093
  const settings = composeGuestSandbox(base, subSessionMeta.userWorkDir, file.cwd);
43129
43094
  subSessionMeta.extraSettings = JSON.stringify(settings);
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;
43095
+ const home = import_node_os3.default.homedir();
43096
+ const expand = (p2) => p2 === "~" ? home : p2.startsWith("~/") ? import_node_path6.default.join(home, p2.slice(2)) : p2;
43132
43097
  const codexCfg = this.deps.personaStore?.readCodexSandboxSettings(scope.personaId) ?? null;
43133
43098
  subSessionMeta.codexSandbox = {
43134
43099
  writableRoots: [subSessionMeta.userWorkDir, ...(codexCfg?.writableRoots ?? []).map(expand)],
@@ -43162,6 +43127,7 @@ var SessionManager = class {
43162
43127
  getDispatchMcpConfigPath: this.deps.dispatchMcpConfigPath ? () => this.deps.dispatchMcpConfigPath ?? null : void 0,
43163
43128
  getTicketMcpConfigPath: this.deps.ticketMcpConfigPath ? () => this.deps.ticketMcpConfigPath ?? null : void 0,
43164
43129
  getShiftMcpConfigPath: this.deps.shiftMcpConfigPath ? () => this.deps.shiftMcpConfigPath ?? null : void 0,
43130
+ getInboxMcpConfigPath: this.deps.inboxMcpConfigPath ? () => this.deps.inboxMcpConfigPath ?? null : void 0,
43165
43131
  lookupDispatchByBSessionId: this.deps.personaDispatchManager ? (bSid) => this.deps.personaDispatchManager?.lookupDispatchByBSessionId(bSid) : void 0,
43166
43132
  // file-sharing (spec §6 PR 3):闭包 scope + sessionId,runner 只暴露 tool/relPath/cwd
43167
43133
  onFileEdit: attachmentGroup ? (input) => attachmentGroup.onFileEdit({
@@ -43280,7 +43246,7 @@ var SessionManager = class {
43280
43246
  throw new ClawdError(ERROR_CODES.INVALID_CWD, "cwd required when ownerPersonaId is absent");
43281
43247
  }
43282
43248
  try {
43283
- const stat = import_node_fs7.default.statSync(cwd);
43249
+ const stat = import_node_fs6.default.statSync(cwd);
43284
43250
  if (!stat.isDirectory()) throw new Error("not dir");
43285
43251
  } catch {
43286
43252
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${cwd}`);
@@ -43811,7 +43777,7 @@ var SessionManager = class {
43811
43777
  */
43812
43778
  createForScope(args) {
43813
43779
  try {
43814
- const stat = import_node_fs7.default.statSync(args.cwd);
43780
+ const stat = import_node_fs6.default.statSync(args.cwd);
43815
43781
  if (!stat.isDirectory()) throw new Error("not dir");
43816
43782
  } catch {
43817
43783
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${args.cwd}`);
@@ -44027,7 +43993,7 @@ var SessionManager = class {
44027
43993
  personaId: args.targetPersona,
44028
43994
  mode: "owner"
44029
43995
  };
44030
- const cwd = import_node_path8.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
43996
+ const cwd = import_node_path6.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
44031
43997
  const now = (/* @__PURE__ */ new Date()).toISOString();
44032
43998
  const file = {
44033
43999
  sessionId,
@@ -44092,7 +44058,7 @@ var SessionManager = class {
44092
44058
  personaId: args.targetPersona,
44093
44059
  mode: "owner"
44094
44060
  };
44095
- const cwd = import_node_path8.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
44061
+ const cwd = import_node_path6.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
44096
44062
  const now = (/* @__PURE__ */ new Date()).toISOString();
44097
44063
  const file = {
44098
44064
  sessionId,
@@ -44574,28 +44540,28 @@ var SessionManager = class {
44574
44540
  };
44575
44541
 
44576
44542
  // src/persona/store.ts
44577
- var fs8 = __toESM(require("fs"), 1);
44578
- var path11 = __toESM(require("path"), 1);
44543
+ var fs7 = __toESM(require("fs"), 1);
44544
+ var path9 = __toESM(require("path"), 1);
44579
44545
  init_protocol();
44580
44546
  var PersonaStore = class {
44581
44547
  constructor(root) {
44582
44548
  this.root = root;
44583
- fs8.mkdirSync(root, { recursive: true });
44549
+ fs7.mkdirSync(root, { recursive: true });
44584
44550
  }
44585
44551
  root;
44586
44552
  personaDir(personaId) {
44587
- return path11.join(this.root, safeFileName(personaId));
44553
+ return path9.join(this.root, safeFileName(personaId));
44588
44554
  }
44589
44555
  metaPath(personaId) {
44590
- return path11.join(this.personaDir(personaId), ".clawd", "persona.json");
44556
+ return path9.join(this.personaDir(personaId), ".clawd", "persona.json");
44591
44557
  }
44592
44558
  claudeMdPath(personaId) {
44593
- return path11.join(this.personaDir(personaId), "CLAUDE.md");
44559
+ return path9.join(this.personaDir(personaId), "CLAUDE.md");
44594
44560
  }
44595
44561
  // codex 原生读 cwd 的 AGENTS.md。人格双写镜像:claude 读 CLAUDE.md、codex 读 AGENTS.md,
44596
44562
  // 两份内容恒一致,persona 切 tool 零迁移。
44597
44563
  agentsMdPath(personaId) {
44598
- return path11.join(this.personaDir(personaId), "AGENTS.md");
44564
+ return path9.join(this.personaDir(personaId), "AGENTS.md");
44599
44565
  }
44600
44566
  /**
44601
44567
  * persona 级 sandbox base 落盘路径 —— 故意放 `.clawd/` 而非 `.claude/`,让 CC 的 project
@@ -44604,11 +44570,11 @@ var PersonaStore = class {
44604
44570
  * spawn 前 per-guest 动态拼到各自 session 目录的那份(base + 强制底座 + 本 guest userWorkDir carve)。
44605
44571
  */
44606
44572
  sandboxSettingsPath(personaId) {
44607
- return path11.join(this.personaDir(personaId), ".clawd", "sandbox-settings.json");
44573
+ return path9.join(this.personaDir(personaId), ".clawd", "sandbox-settings.json");
44608
44574
  }
44609
44575
  write(persona, personality) {
44610
44576
  const dir = this.personaDir(persona.personaId);
44611
- fs8.mkdirSync(path11.join(dir, ".clawd"), { recursive: true });
44577
+ fs7.mkdirSync(path9.join(dir, ".clawd"), { recursive: true });
44612
44578
  this.atomicWrite(this.claudeMdPath(persona.personaId), personality);
44613
44579
  this.atomicWrite(this.agentsMdPath(persona.personaId), personality);
44614
44580
  this.writeSandboxSettings(persona.personaId, buildGuestSettingsV1());
@@ -44627,9 +44593,9 @@ var PersonaStore = class {
44627
44593
  ensureAgentsMirror(personaId) {
44628
44594
  const claudeMd = this.claudeMdPath(personaId);
44629
44595
  const agentsMd = this.agentsMdPath(personaId);
44630
- if (!fs8.existsSync(claudeMd)) return false;
44631
- if (fs8.existsSync(agentsMd)) return false;
44632
- this.atomicWrite(agentsMd, fs8.readFileSync(claudeMd, "utf8"));
44596
+ if (!fs7.existsSync(claudeMd)) return false;
44597
+ if (fs7.existsSync(agentsMd)) return false;
44598
+ this.atomicWrite(agentsMd, fs7.readFileSync(claudeMd, "utf8"));
44633
44599
  return true;
44634
44600
  }
44635
44601
  /**
@@ -44653,22 +44619,22 @@ var PersonaStore = class {
44653
44619
  return { ...s, permissions: { ...s.permissions ?? {}, deny: [...prev, rule] } };
44654
44620
  }
44655
44621
  codexSandboxSettingsPath(personaId) {
44656
- return path11.join(this.personaDir(personaId), ".clawd", "codex-sandbox.json");
44622
+ return path9.join(this.personaDir(personaId), ".clawd", "codex-sandbox.json");
44657
44623
  }
44658
44624
  /** 读 codex-sandbox.json;不存在/损坏 → null。 */
44659
44625
  readCodexSandboxSettings(personaId) {
44660
44626
  const p2 = this.codexSandboxSettingsPath(personaId);
44661
- if (!fs8.existsSync(p2)) return null;
44627
+ if (!fs7.existsSync(p2)) return null;
44662
44628
  try {
44663
- return CodexSandboxSettingsSchema.parse(JSON.parse(fs8.readFileSync(p2, "utf8")));
44629
+ return CodexSandboxSettingsSchema.parse(JSON.parse(fs7.readFileSync(p2, "utf8")));
44664
44630
  } catch {
44665
44631
  return null;
44666
44632
  }
44667
44633
  }
44668
44634
  /** 覆盖写 codex-sandbox.json(seed/migrate 用)。 */
44669
44635
  writeCodexSandboxSettings(personaId, settings) {
44670
- const dir = path11.join(this.personaDir(personaId), ".clawd");
44671
- fs8.mkdirSync(dir, { recursive: true });
44636
+ const dir = path9.join(this.personaDir(personaId), ".clawd");
44637
+ fs7.mkdirSync(dir, { recursive: true });
44672
44638
  this.atomicWrite(this.codexSandboxSettingsPath(personaId), JSON.stringify(settings, null, 2));
44673
44639
  }
44674
44640
  writeMeta(persona) {
@@ -44676,8 +44642,8 @@ var PersonaStore = class {
44676
44642
  }
44677
44643
  read(personaId) {
44678
44644
  const p2 = this.metaPath(personaId);
44679
- if (!fs8.existsSync(p2)) return null;
44680
- const raw = JSON.parse(fs8.readFileSync(p2, "utf8"));
44645
+ if (!fs7.existsSync(p2)) return null;
44646
+ const raw = JSON.parse(fs7.readFileSync(p2, "utf8"));
44681
44647
  if (raw && typeof raw === "object" && "tokenMap" in raw) {
44682
44648
  delete raw.tokenMap;
44683
44649
  this.atomicWrite(p2, JSON.stringify(raw, null, 2));
@@ -44685,13 +44651,13 @@ var PersonaStore = class {
44685
44651
  return PersonaFileSchema.parse(raw);
44686
44652
  }
44687
44653
  has(personaId) {
44688
- return fs8.existsSync(this.metaPath(personaId));
44654
+ return fs7.existsSync(this.metaPath(personaId));
44689
44655
  }
44690
44656
  readPersonality(personaId) {
44691
44657
  const claudeMd = this.claudeMdPath(personaId);
44692
- if (fs8.existsSync(claudeMd)) return fs8.readFileSync(claudeMd, "utf8");
44658
+ if (fs7.existsSync(claudeMd)) return fs7.readFileSync(claudeMd, "utf8");
44693
44659
  const agentsMd = this.agentsMdPath(personaId);
44694
- if (fs8.existsSync(agentsMd)) return fs8.readFileSync(agentsMd, "utf8");
44660
+ if (fs7.existsSync(agentsMd)) return fs7.readFileSync(agentsMd, "utf8");
44695
44661
  return null;
44696
44662
  }
44697
44663
  /**
@@ -44700,23 +44666,23 @@ var PersonaStore = class {
44700
44666
  */
44701
44667
  readSandboxSettings(personaId) {
44702
44668
  const p2 = this.sandboxSettingsPath(personaId);
44703
- if (!fs8.existsSync(p2)) return null;
44669
+ if (!fs7.existsSync(p2)) return null;
44704
44670
  try {
44705
- return JSON.parse(fs8.readFileSync(p2, "utf8"));
44671
+ return JSON.parse(fs7.readFileSync(p2, "utf8"));
44706
44672
  } catch {
44707
44673
  return null;
44708
44674
  }
44709
44675
  }
44710
44676
  /** Persona 私有 skills 目录路径:<personaDir>/.claude/skills */
44711
44677
  skillsDir(personaId) {
44712
- return path11.join(this.personaDir(personaId), ".claude", "skills");
44678
+ return path9.join(this.personaDir(personaId), ".claude", "skills");
44713
44679
  }
44714
44680
  /**
44715
44681
  * Claude Code 项目级 settings 路径:`<personaDir>/.claude/settings.json`。
44716
44682
  * 这里只读 `enabledPlugins` 字段,由 owner 通过 CC `/plugin` 之类命令维护,daemon 不写。
44717
44683
  */
44718
44684
  claudeSettingsPath(personaId) {
44719
- return path11.join(this.personaDir(personaId), ".claude", "settings.json");
44685
+ return path9.join(this.personaDir(personaId), ".claude", "settings.json");
44720
44686
  }
44721
44687
  /**
44722
44688
  * 读取 persona 的 `.claude/settings.json` 中 `enabledPlugins` map,把 value === true
@@ -44731,10 +44697,10 @@ var PersonaStore = class {
44731
44697
  */
44732
44698
  readEnabledPlugins(personaId) {
44733
44699
  const p2 = this.claudeSettingsPath(personaId);
44734
- if (!fs8.existsSync(p2)) return [];
44700
+ if (!fs7.existsSync(p2)) return [];
44735
44701
  let raw;
44736
44702
  try {
44737
- raw = JSON.parse(fs8.readFileSync(p2, "utf8"));
44703
+ raw = JSON.parse(fs7.readFileSync(p2, "utf8"));
44738
44704
  } catch {
44739
44705
  return [];
44740
44706
  }
@@ -44748,22 +44714,22 @@ var PersonaStore = class {
44748
44714
  return out;
44749
44715
  }
44750
44716
  list() {
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"));
44717
+ if (!fs7.existsSync(this.root)) return [];
44718
+ return fs7.readdirSync(this.root).filter((name) => {
44719
+ return fs7.existsSync(path9.join(this.root, name, ".clawd", "persona.json"));
44754
44720
  });
44755
44721
  }
44756
44722
  remove(personaId) {
44757
44723
  const dir = this.personaDir(personaId);
44758
- if (fs8.existsSync(dir)) fs8.rmSync(dir, { recursive: true, force: true });
44724
+ if (fs7.existsSync(dir)) fs7.rmSync(dir, { recursive: true, force: true });
44759
44725
  }
44760
44726
  personaDirPath(personaId) {
44761
44727
  return this.personaDir(personaId);
44762
44728
  }
44763
44729
  atomicWrite(file, content) {
44764
44730
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
44765
- fs8.writeFileSync(tmp, content, { mode: 384 });
44766
- fs8.renameSync(tmp, file);
44731
+ fs7.writeFileSync(tmp, content, { mode: 384 });
44732
+ fs7.renameSync(tmp, file);
44767
44733
  }
44768
44734
  };
44769
44735
 
@@ -44809,9 +44775,9 @@ var PersonaRegistry = class {
44809
44775
  var import_node_crypto3 = __toESM(require("crypto"), 1);
44810
44776
 
44811
44777
  // src/skills/scanner.ts
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);
44778
+ var import_node_fs7 = __toESM(require("fs"), 1);
44779
+ var import_node_os4 = __toESM(require("os"), 1);
44780
+ var import_node_path7 = __toESM(require("path"), 1);
44815
44781
 
44816
44782
  // src/skills/frontmatter.ts
44817
44783
  var STRIP_QUOTES = /^["']|["']$/g;
@@ -44920,7 +44886,7 @@ function parseDescription(content) {
44920
44886
  }
44921
44887
  function isDirLikeSync(p2) {
44922
44888
  try {
44923
- return import_node_fs8.default.statSync(p2).isDirectory();
44889
+ return import_node_fs7.default.statSync(p2).isDirectory();
44924
44890
  } catch {
44925
44891
  return false;
44926
44892
  }
@@ -44928,19 +44894,19 @@ function isDirLikeSync(p2) {
44928
44894
  function scanSkillDir(dir, source, seen, out, pluginName) {
44929
44895
  let entries;
44930
44896
  try {
44931
- entries = import_node_fs8.default.readdirSync(dir, { withFileTypes: true });
44897
+ entries = import_node_fs7.default.readdirSync(dir, { withFileTypes: true });
44932
44898
  } catch {
44933
44899
  return;
44934
44900
  }
44935
44901
  for (const ent of entries) {
44936
- const entryPath = import_node_path9.default.join(dir, ent.name);
44902
+ const entryPath = import_node_path7.default.join(dir, ent.name);
44937
44903
  if (!ent.isDirectory() && !(ent.isSymbolicLink() && isDirLikeSync(entryPath))) continue;
44938
44904
  let content;
44939
44905
  try {
44940
- content = import_node_fs8.default.readFileSync(import_node_path9.default.join(entryPath, "SKILL.md"), "utf8");
44906
+ content = import_node_fs7.default.readFileSync(import_node_path7.default.join(entryPath, "SKILL.md"), "utf8");
44941
44907
  } catch {
44942
44908
  try {
44943
- content = import_node_fs8.default.readFileSync(import_node_path9.default.join(entryPath, "skill.md"), "utf8");
44909
+ content = import_node_fs7.default.readFileSync(import_node_path7.default.join(entryPath, "skill.md"), "utf8");
44944
44910
  } catch {
44945
44911
  continue;
44946
44912
  }
@@ -44964,26 +44930,26 @@ function listSkillsForDir(dir, source) {
44964
44930
  function scanCommandDir(dir, source, seen, out, pluginName) {
44965
44931
  let entries;
44966
44932
  try {
44967
- entries = import_node_fs8.default.readdirSync(dir, { withFileTypes: true });
44933
+ entries = import_node_fs7.default.readdirSync(dir, { withFileTypes: true });
44968
44934
  } catch {
44969
44935
  return;
44970
44936
  }
44971
44937
  for (const ent of entries) {
44972
- const entryPath = import_node_path9.default.join(dir, ent.name);
44938
+ const entryPath = import_node_path7.default.join(dir, ent.name);
44973
44939
  if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync(entryPath)) {
44974
44940
  const ns = ent.name;
44975
44941
  let subEntries;
44976
44942
  try {
44977
- subEntries = import_node_fs8.default.readdirSync(entryPath, { withFileTypes: true });
44943
+ subEntries = import_node_fs7.default.readdirSync(entryPath, { withFileTypes: true });
44978
44944
  } catch {
44979
44945
  continue;
44980
44946
  }
44981
44947
  for (const se of subEntries) {
44982
44948
  if (!se.name.endsWith(".md")) continue;
44983
- const sePath = import_node_path9.default.join(entryPath, se.name);
44949
+ const sePath = import_node_path7.default.join(entryPath, se.name);
44984
44950
  let content;
44985
44951
  try {
44986
- content = import_node_fs8.default.readFileSync(sePath, "utf8");
44952
+ content = import_node_fs7.default.readFileSync(sePath, "utf8");
44987
44953
  } catch {
44988
44954
  continue;
44989
44955
  }
@@ -45000,7 +44966,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
45000
44966
  } else if (ent.name.endsWith(".md")) {
45001
44967
  let content;
45002
44968
  try {
45003
- content = import_node_fs8.default.readFileSync(entryPath, "utf8");
44969
+ content = import_node_fs7.default.readFileSync(entryPath, "utf8");
45004
44970
  } catch {
45005
44971
  continue;
45006
44972
  }
@@ -45016,10 +44982,10 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
45016
44982
  }
45017
44983
  }
45018
44984
  function readInstalledPlugins(home) {
45019
- const file = import_node_path9.default.join(home, ".claude", "plugins", "installed_plugins.json");
44985
+ const file = import_node_path7.default.join(home, ".claude", "plugins", "installed_plugins.json");
45020
44986
  let raw;
45021
44987
  try {
45022
- raw = import_node_fs8.default.readFileSync(file, "utf8");
44988
+ raw = import_node_fs7.default.readFileSync(file, "utf8");
45023
44989
  } catch {
45024
44990
  return [];
45025
44991
  }
@@ -45044,7 +45010,7 @@ var SkillsScanner = class {
45044
45010
  home;
45045
45011
  extraPluginRoots;
45046
45012
  constructor(opts = {}) {
45047
- this.home = opts.home ?? import_node_os6.default.homedir();
45013
+ this.home = opts.home ?? import_node_os4.default.homedir();
45048
45014
  this.extraPluginRoots = opts.extraPluginRoots ?? [];
45049
45015
  }
45050
45016
  /**
@@ -45067,14 +45033,14 @@ var SkillsScanner = class {
45067
45033
  });
45068
45034
  }
45069
45035
  const 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);
45036
+ scanSkillDir(import_node_path7.default.join(this.home, ".claude", "skills"), "global", seen, fsBlock);
45037
+ scanCommandDir(import_node_path7.default.join(this.home, ".claude", "commands"), "global", seen, fsBlock);
45038
+ scanSkillDir(import_node_path7.default.join(args.cwd, ".claude", "skills"), "project", seen, fsBlock);
45039
+ scanCommandDir(import_node_path7.default.join(args.cwd, ".claude", "commands"), "project", seen, fsBlock);
45074
45040
  const plugins = [...readInstalledPlugins(this.home), ...this.extraPluginRoots];
45075
45041
  for (const { name, root } of plugins) {
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);
45042
+ scanSkillDir(import_node_path7.default.join(root, "skills"), "plugin", seen, fsBlock, name);
45043
+ scanCommandDir(import_node_path7.default.join(root, "commands"), "plugin", seen, fsBlock, name);
45078
45044
  }
45079
45045
  fsBlock.sort((a, b2) => a.name < b2.name ? -1 : a.name > b2.name ? 1 : 0);
45080
45046
  return [...builtinBlock, ...fsBlock];
@@ -45180,8 +45146,8 @@ var PersonaManager = class {
45180
45146
  };
45181
45147
 
45182
45148
  // src/persona/seed.ts
45183
- var fs10 = __toESM(require("fs"), 1);
45184
- var path13 = __toESM(require("path"), 1);
45149
+ var fs9 = __toESM(require("fs"), 1);
45150
+ var path11 = __toESM(require("path"), 1);
45185
45151
  var import_node_url = require("url");
45186
45152
  var import_meta = {};
45187
45153
  var DEFAULT_BYPASS_PROFILE = {
@@ -45212,6 +45178,16 @@ var DEFAULT_PERSONAS = [
45212
45178
  public: false,
45213
45179
  sandboxProfile: DEFAULT_BYPASS_PROFILE
45214
45180
  },
45181
+ {
45182
+ // 工单管理员:纯操作员,按指令调 clawd-ticket MCP 增删改查 ticket。MCP 由 daemon 全局
45183
+ // 注入(index.ts ticket-mcp wiring),persona 端不需要单独 .mcp.json。
45184
+ personaId: "persona-ticket-manager",
45185
+ label: "\u5DE5\u5355\u7BA1\u7406\u5458",
45186
+ model: "opus",
45187
+ iconKey: "assist",
45188
+ public: false,
45189
+ sandboxProfile: DEFAULT_BYPASS_PROFILE
45190
+ },
45215
45191
  {
45216
45192
  personaId: "persona-feishu-assistant",
45217
45193
  label: "\u98DE\u4E66\u52A9\u7406",
@@ -45305,6 +45281,14 @@ var DEFAULT_PERSONAS = [
45305
45281
  public: false,
45306
45282
  sandboxProfile: DEFAULT_BYPASS_PROFILE
45307
45283
  },
45284
+ {
45285
+ personaId: "persona-bug-fixer",
45286
+ label: "Bug \u4FEE\u590D\u5E08",
45287
+ model: "opus",
45288
+ iconKey: "debug",
45289
+ public: false,
45290
+ sandboxProfile: DEFAULT_BYPASS_PROFILE
45291
+ },
45308
45292
  {
45309
45293
  // HTML PPT 制作师:把想法/文字/旧 PPT 转成单文件 HTML 演示稿
45310
45294
  // bundle 含 frontend-slides skill(MIT,Zara Zhang),daemon ship 进 .claude/skills/
@@ -45351,24 +45335,24 @@ function bundleSiblingFromArgv(argv1, sibling) {
45351
45335
  if (!argv1) return null;
45352
45336
  let real = argv1;
45353
45337
  try {
45354
- real = fs10.realpathSync(argv1);
45338
+ real = fs9.realpathSync(argv1);
45355
45339
  } catch {
45356
45340
  }
45357
- return path13.resolve(path13.dirname(real), sibling);
45341
+ return path11.resolve(path11.dirname(real), sibling);
45358
45342
  }
45359
45343
  function findDefaultsRoot(logger) {
45360
45344
  const candidates = [];
45361
45345
  try {
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"));
45346
+ const here = path11.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
45347
+ candidates.push(path11.resolve(here, "defaults"));
45348
+ candidates.push(path11.resolve(here, "persona-defaults"));
45365
45349
  } catch {
45366
45350
  }
45367
45351
  const fromArgv = bundleSiblingFromArgv(process.argv[1], "persona-defaults");
45368
45352
  if (fromArgv) candidates.push(fromArgv);
45369
45353
  for (const c of candidates) {
45370
45354
  try {
45371
- if (fs10.statSync(c).isDirectory()) {
45355
+ if (fs9.statSync(c).isDirectory()) {
45372
45356
  logger?.info("persona.defaults-root.resolved", { root: c });
45373
45357
  return c;
45374
45358
  }
@@ -45385,8 +45369,8 @@ function seedDefaultPersonas(args) {
45385
45369
  args.logger.info("persona.seed.skip", { personaId: entry.personaId, reason: "exists" });
45386
45370
  continue;
45387
45371
  }
45388
- const bundleDir = path13.join(args.defaultsRoot, entry.personaId);
45389
- if (!fs10.existsSync(bundleDir)) {
45372
+ const bundleDir = path11.join(args.defaultsRoot, entry.personaId);
45373
+ if (!fs9.existsSync(bundleDir)) {
45390
45374
  args.logger.warn("persona.seed.skip", {
45391
45375
  personaId: entry.personaId,
45392
45376
  reason: "bundle-missing",
@@ -45394,8 +45378,8 @@ function seedDefaultPersonas(args) {
45394
45378
  });
45395
45379
  continue;
45396
45380
  }
45397
- const claudeMdPath = path13.join(bundleDir, "CLAUDE.md");
45398
- if (!fs10.existsSync(claudeMdPath)) {
45381
+ const claudeMdPath = path11.join(bundleDir, "CLAUDE.md");
45382
+ if (!fs9.existsSync(claudeMdPath)) {
45399
45383
  args.logger.warn("persona.seed.skip", {
45400
45384
  personaId: entry.personaId,
45401
45385
  reason: "no-CLAUDE.md",
@@ -45403,7 +45387,7 @@ function seedDefaultPersonas(args) {
45403
45387
  });
45404
45388
  continue;
45405
45389
  }
45406
- const personality = fs10.readFileSync(claudeMdPath, "utf8");
45390
+ const personality = fs9.readFileSync(claudeMdPath, "utf8");
45407
45391
  const now = Date.now();
45408
45392
  const persona = {
45409
45393
  personaId: entry.personaId,
@@ -45429,17 +45413,17 @@ function seedDefaultPersonas(args) {
45429
45413
  }
45430
45414
  }
45431
45415
  function skipNodeModulesUnder(srcRoot) {
45432
- return (src) => !path13.relative(srcRoot, src).split(path13.sep).includes("node_modules");
45416
+ return (src) => !path11.relative(srcRoot, src).split(path11.sep).includes("node_modules");
45433
45417
  }
45434
45418
  function copyBundleExtras(srcDir, dstDir) {
45435
- for (const entry of fs10.readdirSync(srcDir, { withFileTypes: true })) {
45419
+ for (const entry of fs9.readdirSync(srcDir, { withFileTypes: true })) {
45436
45420
  if (entry.name === "CLAUDE.md" || entry.name === ".clawd") continue;
45437
- const srcPath = path13.join(srcDir, entry.name);
45438
- const dstPath = path13.join(dstDir, entry.name);
45421
+ const srcPath = path11.join(srcDir, entry.name);
45422
+ const dstPath = path11.join(dstDir, entry.name);
45439
45423
  if (entry.isDirectory()) {
45440
- fs10.cpSync(srcPath, dstPath, { recursive: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
45424
+ fs9.cpSync(srcPath, dstPath, { recursive: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
45441
45425
  } else if (entry.isFile()) {
45442
- fs10.copyFileSync(srcPath, dstPath);
45426
+ fs9.copyFileSync(srcPath, dstPath);
45443
45427
  }
45444
45428
  }
45445
45429
  }
@@ -45447,16 +45431,16 @@ var DAEMON_MANAGED_PATHS = ["extension-kit", "CLAUDE.md", ".mcp.json"];
45447
45431
  function refreshDaemonManagedDirs(args) {
45448
45432
  const entries = args.entries ?? DEFAULT_PERSONAS;
45449
45433
  for (const entry of entries) {
45450
- const bundleDir = path13.join(args.defaultsRoot, entry.personaId);
45451
- if (!fs10.existsSync(bundleDir)) continue;
45434
+ const bundleDir = path11.join(args.defaultsRoot, entry.personaId);
45435
+ if (!fs9.existsSync(bundleDir)) continue;
45452
45436
  const personaDir = args.store.personaDirPath(entry.personaId);
45453
- if (!fs10.existsSync(personaDir)) continue;
45437
+ if (!fs9.existsSync(personaDir)) continue;
45454
45438
  for (const relPath of DAEMON_MANAGED_PATHS) {
45455
- const srcPath = path13.join(bundleDir, relPath);
45456
- if (!fs10.existsSync(srcPath)) continue;
45457
- const dstPath = path13.join(personaDir, relPath);
45439
+ const srcPath = path11.join(bundleDir, relPath);
45440
+ if (!fs9.existsSync(srcPath)) continue;
45441
+ const dstPath = path11.join(personaDir, relPath);
45458
45442
  try {
45459
- fs10.cpSync(srcPath, dstPath, { recursive: true, force: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
45443
+ fs9.cpSync(srcPath, dstPath, { recursive: true, force: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
45460
45444
  args.logger.info("persona.refresh.synced", {
45461
45445
  personaId: entry.personaId,
45462
45446
  path: relPath
@@ -45516,15 +45500,15 @@ function migrateCodexSandbox(args) {
45516
45500
  function findDeployKitRoot(logger) {
45517
45501
  const candidates = [];
45518
45502
  try {
45519
- const here = path13.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
45520
- candidates.push(path13.resolve(here, "..", "deploy-kit"));
45503
+ const here = path11.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
45504
+ candidates.push(path11.resolve(here, "..", "deploy-kit"));
45521
45505
  } catch {
45522
45506
  }
45523
45507
  const fromArgv = bundleSiblingFromArgv(process.argv[1], "deploy-kit");
45524
45508
  if (fromArgv) candidates.push(fromArgv);
45525
45509
  for (const c of candidates) {
45526
45510
  try {
45527
- if (fs10.statSync(c).isDirectory()) {
45511
+ if (fs9.statSync(c).isDirectory()) {
45528
45512
  logger?.info("persona.deploy-kit-root.resolved", { root: c });
45529
45513
  return c;
45530
45514
  }
@@ -45535,8 +45519,8 @@ function findDeployKitRoot(logger) {
45535
45519
  return null;
45536
45520
  }
45537
45521
  function seedDeployKit(args) {
45538
- const dst = path13.join(args.dataDir, "deploy-kit");
45539
- fs10.cpSync(args.deployKitBundleRoot, dst, {
45522
+ const dst = path11.join(args.dataDir, "deploy-kit");
45523
+ fs9.cpSync(args.deployKitBundleRoot, dst, {
45540
45524
  recursive: true,
45541
45525
  dereference: true,
45542
45526
  force: false,
@@ -45545,35 +45529,35 @@ function seedDeployKit(args) {
45545
45529
  args.logger.info("deploy-kit.seed.done", { dst });
45546
45530
  }
45547
45531
  function refreshDeployKit(args) {
45548
- const dst = path13.join(args.dataDir, "deploy-kit");
45549
- if (!fs10.existsSync(dst)) {
45532
+ const dst = path11.join(args.dataDir, "deploy-kit");
45533
+ if (!fs9.existsSync(dst)) {
45550
45534
  seedDeployKit(args);
45551
45535
  return;
45552
45536
  }
45553
45537
  for (const sub of ["scripts", "contract"]) {
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 });
45538
+ const s = path11.join(args.deployKitBundleRoot, sub);
45539
+ if (fs9.existsSync(s)) {
45540
+ fs9.cpSync(s, path11.join(dst, sub), { recursive: true, force: true, dereference: true });
45557
45541
  }
45558
45542
  }
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)) {
45543
+ const secretsSrc = path11.join(args.deployKitBundleRoot, ".secrets");
45544
+ if (fs9.existsSync(secretsSrc)) {
45545
+ fs9.mkdirSync(path11.join(dst, ".secrets"), { recursive: true });
45546
+ for (const f of fs9.readdirSync(secretsSrc)) {
45563
45547
  if (!f.endsWith(".example")) continue;
45564
- fs10.copyFileSync(path13.join(secretsSrc, f), path13.join(dst, ".secrets", f));
45548
+ fs9.copyFileSync(path11.join(secretsSrc, f), path11.join(dst, ".secrets", f));
45565
45549
  }
45566
45550
  }
45567
45551
  args.logger.info("deploy-kit.refresh.done", { dst });
45568
45552
  }
45569
45553
 
45570
45554
  // src/share-md-viewer/load.ts
45571
- var import_node_fs10 = __toESM(require("fs"), 1);
45572
- var import_node_path10 = __toESM(require("path"), 1);
45555
+ var import_node_fs9 = __toESM(require("fs"), 1);
45556
+ var import_node_path8 = __toESM(require("path"), 1);
45573
45557
  var import_node_url2 = require("url");
45574
45558
 
45575
45559
  // src/share-md-viewer/asset-loader.ts
45576
- var import_node_fs9 = __toESM(require("fs"), 1);
45560
+ var import_node_fs8 = __toESM(require("fs"), 1);
45577
45561
  function htmlEscape(s) {
45578
45562
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
45579
45563
  }
@@ -45581,12 +45565,12 @@ function createViewerAssetLoader(opts) {
45581
45565
  let viewerTemplate;
45582
45566
  let errorTemplate;
45583
45567
  try {
45584
- viewerTemplate = import_node_fs9.default.readFileSync(opts.viewerHtmlPath, "utf8");
45568
+ viewerTemplate = import_node_fs8.default.readFileSync(opts.viewerHtmlPath, "utf8");
45585
45569
  } catch (err) {
45586
45570
  throw new Error(`viewer asset not found at ${opts.viewerHtmlPath}: ${err.message}`);
45587
45571
  }
45588
45572
  try {
45589
- errorTemplate = import_node_fs9.default.readFileSync(opts.errorHtmlPath, "utf8");
45573
+ errorTemplate = import_node_fs8.default.readFileSync(opts.errorHtmlPath, "utf8");
45590
45574
  } catch (err) {
45591
45575
  throw new Error(`viewer error asset not found at ${opts.errorHtmlPath}: ${err.message}`);
45592
45576
  }
@@ -45605,25 +45589,25 @@ var import_meta2 = {};
45605
45589
  function tryLoadViewerAssets(logger) {
45606
45590
  const candidates = [];
45607
45591
  try {
45608
- const here = import_node_path10.default.dirname((0, import_node_url2.fileURLToPath)(import_meta2.url));
45592
+ const here = import_node_path8.default.dirname((0, import_node_url2.fileURLToPath)(import_meta2.url));
45609
45593
  candidates.push(here);
45610
- candidates.push(import_node_path10.default.resolve(here, ".."));
45611
- candidates.push(import_node_path10.default.resolve(here, "..", "..", "dist"));
45594
+ candidates.push(import_node_path8.default.resolve(here, ".."));
45595
+ candidates.push(import_node_path8.default.resolve(here, "..", "..", "dist"));
45612
45596
  } catch {
45613
45597
  }
45614
45598
  if (process.argv[1]) {
45615
45599
  let real = process.argv[1];
45616
45600
  try {
45617
- real = import_node_fs10.default.realpathSync(process.argv[1]);
45601
+ real = import_node_fs9.default.realpathSync(process.argv[1]);
45618
45602
  } catch {
45619
45603
  }
45620
- candidates.push(import_node_path10.default.dirname(real));
45604
+ candidates.push(import_node_path8.default.dirname(real));
45621
45605
  }
45622
45606
  for (const root of candidates) {
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");
45607
+ const viewerHtmlPath = import_node_path8.default.join(root, "share-md-viewer.html");
45608
+ const errorHtmlPath = import_node_path8.default.join(root, "share-md-viewer-error.html");
45625
45609
  try {
45626
- if (import_node_fs10.default.statSync(viewerHtmlPath).isFile() && import_node_fs10.default.statSync(errorHtmlPath).isFile()) {
45610
+ if (import_node_fs9.default.statSync(viewerHtmlPath).isFile() && import_node_fs9.default.statSync(errorHtmlPath).isFile()) {
45627
45611
  logger?.info("share-md-viewer.assets-root.resolved", { root });
45628
45612
  return createViewerAssetLoader({ viewerHtmlPath, errorHtmlPath });
45629
45613
  }
@@ -45638,30 +45622,30 @@ function tryLoadViewerAssets(logger) {
45638
45622
  }
45639
45623
 
45640
45624
  // src/share-ui/load.ts
45641
- var import_node_fs12 = __toESM(require("fs"), 1);
45642
- var import_node_path12 = __toESM(require("path"), 1);
45625
+ var import_node_fs11 = __toESM(require("fs"), 1);
45626
+ var import_node_path10 = __toESM(require("path"), 1);
45643
45627
  var import_node_url3 = require("url");
45644
45628
 
45645
45629
  // src/share-ui/asset-loader.ts
45646
- var import_node_fs11 = __toESM(require("fs"), 1);
45647
- var import_node_path11 = __toESM(require("path"), 1);
45630
+ var import_node_fs10 = __toESM(require("fs"), 1);
45631
+ var import_node_path9 = __toESM(require("path"), 1);
45648
45632
  function createShareUiAssetLoader(opts) {
45649
45633
  let indexHtml;
45650
45634
  try {
45651
- indexHtml = import_node_fs11.default.readFileSync(opts.indexHtmlPath, "utf8");
45635
+ indexHtml = import_node_fs10.default.readFileSync(opts.indexHtmlPath, "utf8");
45652
45636
  } catch (err) {
45653
45637
  throw new Error(`share-ui index.html not found at ${opts.indexHtmlPath}: ${err.message}`);
45654
45638
  }
45655
- const assetsDir = import_node_path11.default.resolve(opts.assetsDir);
45639
+ const assetsDir = import_node_path9.default.resolve(opts.assetsDir);
45656
45640
  return {
45657
45641
  renderIndexHtml() {
45658
45642
  return indexHtml;
45659
45643
  },
45660
45644
  resolveAssetPath(rel) {
45661
- const resolved = import_node_path11.default.resolve(assetsDir, rel);
45662
- if (resolved !== assetsDir && !resolved.startsWith(assetsDir + import_node_path11.default.sep)) return null;
45645
+ const resolved = import_node_path9.default.resolve(assetsDir, rel);
45646
+ if (resolved !== assetsDir && !resolved.startsWith(assetsDir + import_node_path9.default.sep)) return null;
45663
45647
  try {
45664
- if (import_node_fs11.default.statSync(resolved).isFile()) return resolved;
45648
+ if (import_node_fs10.default.statSync(resolved).isFile()) return resolved;
45665
45649
  } catch {
45666
45650
  }
45667
45651
  return null;
@@ -45675,28 +45659,28 @@ function bundleDirFromArgv(argv1) {
45675
45659
  if (!argv1) return null;
45676
45660
  let real = argv1;
45677
45661
  try {
45678
- real = import_node_fs12.default.realpathSync(argv1);
45662
+ real = import_node_fs11.default.realpathSync(argv1);
45679
45663
  } catch {
45680
45664
  }
45681
- return import_node_path12.default.dirname(real);
45665
+ return import_node_path10.default.dirname(real);
45682
45666
  }
45683
45667
  function tryLoadShareUi(logger) {
45684
45668
  const candidates = [];
45685
45669
  try {
45686
- const here = import_node_path12.default.dirname((0, import_node_url3.fileURLToPath)(import_meta3.url));
45670
+ const here = import_node_path10.default.dirname((0, import_node_url3.fileURLToPath)(import_meta3.url));
45687
45671
  candidates.push(here);
45688
- candidates.push(import_node_path12.default.resolve(here, ".."));
45689
- candidates.push(import_node_path12.default.resolve(here, "..", "..", "dist"));
45672
+ candidates.push(import_node_path10.default.resolve(here, ".."));
45673
+ candidates.push(import_node_path10.default.resolve(here, "..", "..", "dist"));
45690
45674
  } catch {
45691
45675
  }
45692
45676
  const argvDir = bundleDirFromArgv(process.argv[1]);
45693
45677
  if (argvDir) candidates.push(argvDir);
45694
45678
  for (const root of candidates) {
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");
45679
+ const shareUiDir = import_node_path10.default.join(root, "share-ui");
45680
+ const indexHtmlPath = import_node_path10.default.join(shareUiDir, "guest.html");
45681
+ const assetsDir = import_node_path10.default.join(shareUiDir, "assets");
45698
45682
  try {
45699
- if (import_node_fs12.default.statSync(indexHtmlPath).isFile() && import_node_fs12.default.statSync(assetsDir).isDirectory()) {
45683
+ if (import_node_fs11.default.statSync(indexHtmlPath).isFile() && import_node_fs11.default.statSync(assetsDir).isDirectory()) {
45700
45684
  logger?.info("share-ui.assets-root.resolved", { root: shareUiDir });
45701
45685
  return createShareUiAssetLoader({ indexHtmlPath, assetsDir });
45702
45686
  }
@@ -45778,20 +45762,20 @@ function buildVisitorLogin(deps) {
45778
45762
  }
45779
45763
 
45780
45764
  // src/visitor/visitor-store.ts
45781
- var import_node_fs13 = __toESM(require("fs"), 1);
45782
- var import_node_path13 = __toESM(require("path"), 1);
45765
+ var import_node_fs12 = __toESM(require("fs"), 1);
45766
+ var import_node_path11 = __toESM(require("path"), 1);
45783
45767
  function createVisitorStore(opts) {
45784
- const file = import_node_path13.default.join(opts.dir, "visitors.json");
45768
+ const file = import_node_path11.default.join(opts.dir, "visitors.json");
45785
45769
  const read = () => {
45786
45770
  try {
45787
- return JSON.parse(import_node_fs13.default.readFileSync(file, "utf8"));
45771
+ return JSON.parse(import_node_fs12.default.readFileSync(file, "utf8"));
45788
45772
  } catch {
45789
45773
  return [];
45790
45774
  }
45791
45775
  };
45792
45776
  const write = (rows) => {
45793
- import_node_fs13.default.mkdirSync(opts.dir, { recursive: true });
45794
- import_node_fs13.default.writeFileSync(file, JSON.stringify(rows, null, 2));
45777
+ import_node_fs12.default.mkdirSync(opts.dir, { recursive: true });
45778
+ import_node_fs12.default.writeFileSync(file, JSON.stringify(rows, null, 2));
45795
45779
  };
45796
45780
  return {
45797
45781
  upsert(r) {
@@ -46307,8 +46291,8 @@ var CodexAdapter = class {
46307
46291
 
46308
46292
  // src/tools/claude-tui.ts
46309
46293
  var import_node_fs16 = __toESM(require("fs"), 1);
46310
- var import_node_os7 = __toESM(require("os"), 1);
46311
- var import_node_path14 = __toESM(require("path"), 1);
46294
+ var import_node_os6 = __toESM(require("os"), 1);
46295
+ var import_node_path13 = __toESM(require("path"), 1);
46312
46296
  var import_headless = __toESM(require_xterm_headless(), 1);
46313
46297
 
46314
46298
  // ../node_modules/.pnpm/@xterm+addon-serialize@0.14.0/node_modules/@xterm/addon-serialize/lib/addon-serialize.mjs
@@ -47435,14 +47419,17 @@ function buildTuiSpawnArgs(ctx, isResume = false) {
47435
47419
  if (ctx.shiftMcpConfigPath) {
47436
47420
  args.push("--mcp-config", ctx.shiftMcpConfigPath);
47437
47421
  }
47422
+ if (ctx.inboxMcpConfigPath) {
47423
+ args.push("--mcp-config", ctx.inboxMcpConfigPath);
47424
+ }
47438
47425
  args.push("--disallowed-tools", "CronCreate,CronDelete,CronList,ScheduleWakeup,RemoteTrigger");
47439
47426
  if (ctx.effort) args.push("--effort", ctx.effort);
47440
47427
  return args;
47441
47428
  }
47442
47429
  function jsonlExistsForCtx(ctx) {
47443
47430
  if (!ctx.toolSessionId) return false;
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`);
47431
+ const home = import_node_os6.default.homedir();
47432
+ const file = import_node_path13.default.join(home, ".claude", "projects", cwdToHashDir(ctx.cwd), `${ctx.toolSessionId}.jsonl`);
47446
47433
  try {
47447
47434
  return import_node_fs16.default.statSync(file).isFile();
47448
47435
  } catch {
@@ -47514,9 +47501,9 @@ var PersonaDispatchManager = class {
47514
47501
 
47515
47502
  // src/dispatch/mcp-config.ts
47516
47503
  var import_node_fs17 = __toESM(require("fs"), 1);
47517
- var import_node_path15 = __toESM(require("path"), 1);
47504
+ var import_node_path14 = __toESM(require("path"), 1);
47518
47505
  function dispatchMcpConfigPath(dataDir) {
47519
- return import_node_path15.default.join(dataDir, "dispatch.mcp.json");
47506
+ return import_node_path14.default.join(dataDir, "dispatch.mcp.json");
47520
47507
  }
47521
47508
  function writeDispatchMcpConfig(args) {
47522
47509
  const cfgPath = dispatchMcpConfigPath(args.dataDir);
@@ -47538,9 +47525,9 @@ function writeDispatchMcpConfig(args) {
47538
47525
 
47539
47526
  // src/ticket/mcp-config.ts
47540
47527
  var import_node_fs18 = __toESM(require("fs"), 1);
47541
- var import_node_path16 = __toESM(require("path"), 1);
47528
+ var import_node_path15 = __toESM(require("path"), 1);
47542
47529
  function ticketMcpConfigPath(dataDir) {
47543
- return import_node_path16.default.join(dataDir, "ticket.mcp.json");
47530
+ return import_node_path15.default.join(dataDir, "ticket.mcp.json");
47544
47531
  }
47545
47532
  function writeTicketMcpConfig(args) {
47546
47533
  const cfgPath = ticketMcpConfigPath(args.dataDir);
@@ -47568,9 +47555,9 @@ function writeTicketMcpConfig(args) {
47568
47555
 
47569
47556
  // src/shift/mcp-config.ts
47570
47557
  var import_node_fs19 = __toESM(require("fs"), 1);
47571
- var import_node_path17 = __toESM(require("path"), 1);
47558
+ var import_node_path16 = __toESM(require("path"), 1);
47572
47559
  function shiftMcpConfigPath(dataDir) {
47573
- return import_node_path17.default.join(dataDir, "shift.mcp.json");
47560
+ return import_node_path16.default.join(dataDir, "shift.mcp.json");
47574
47561
  }
47575
47562
  async function writeShiftMcpConfig(args) {
47576
47563
  const cfgPath = shiftMcpConfigPath(args.dataDir);
@@ -47590,6 +47577,29 @@ async function writeShiftMcpConfig(args) {
47590
47577
  return cfgPath;
47591
47578
  }
47592
47579
 
47580
+ // src/inbox/mcp-config.ts
47581
+ var import_node_fs20 = __toESM(require("fs"), 1);
47582
+ var import_node_path17 = __toESM(require("path"), 1);
47583
+ function inboxMcpConfigPath(dataDir) {
47584
+ return import_node_path17.default.join(dataDir, "inbox.mcp.json");
47585
+ }
47586
+ async function writeInboxMcpConfig(args) {
47587
+ const cfgPath = inboxMcpConfigPath(args.dataDir);
47588
+ const content = {
47589
+ _comment: "daemon \u542F\u52A8\u65F6\u81EA\u52A8\u751F\u6210\uFF1Bcc spawn \u901A\u8FC7 --mcp-config \u6CE8\u5165\u3002inbox/mcp-server.cjs \u662F daemon \u81EA\u5E26\u7684 stdio MCP server\uFF0C\u66B4\u9732 sendDm tool\uFF08persona \u53D7\u63A7\u53D1 P2P IM DM\uFF09\u3002",
47590
+ mcpServers: {
47591
+ "clawd-inbox": {
47592
+ type: "stdio",
47593
+ command: "node",
47594
+ args: [args.serverScriptPath]
47595
+ }
47596
+ }
47597
+ };
47598
+ await import_node_fs20.default.promises.mkdir(args.dataDir, { recursive: true });
47599
+ await import_node_fs20.default.promises.writeFile(cfgPath, JSON.stringify(content, null, 2), "utf8");
47600
+ return cfgPath;
47601
+ }
47602
+
47593
47603
  // src/shift/store.ts
47594
47604
  var import_promises = __toESM(require("fs/promises"), 1);
47595
47605
  var import_node_path18 = __toESM(require("path"), 1);
@@ -48245,6 +48255,39 @@ async function forwardDispatchToPeer(args) {
48245
48255
  }
48246
48256
  return json.result.outcome;
48247
48257
  }
48258
+ async function forwardInboxPostToPeer(args) {
48259
+ const f = args.fetchImpl ?? fetch;
48260
+ const base = wsUrlToHttp(args.contact.remoteUrl).replace(/\/+$/, "");
48261
+ const url = `${base}/rpc/inbox:postMessage`;
48262
+ let res;
48263
+ try {
48264
+ res = await f(url, {
48265
+ method: "POST",
48266
+ headers: {
48267
+ "content-type": "application/json",
48268
+ authorization: `Bearer ${args.contact.connectToken}`
48269
+ },
48270
+ body: JSON.stringify({
48271
+ id: args.id,
48272
+ text: args.text,
48273
+ createdAt: args.createdAt,
48274
+ ...args.origin ? { origin: args.origin } : {}
48275
+ })
48276
+ });
48277
+ } catch (err) {
48278
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
48279
+ }
48280
+ let json = null;
48281
+ try {
48282
+ json = await res.json();
48283
+ } catch {
48284
+ return { ok: false, error: `peer non-JSON (HTTP ${res.status})` };
48285
+ }
48286
+ if (res.status < 200 || res.status >= 300 || json?.ok === false) {
48287
+ return { ok: false, error: json?.error ?? `HTTP ${res.status}` };
48288
+ }
48289
+ return { ok: true };
48290
+ }
48248
48291
 
48249
48292
  // src/tools/codex-history.ts
48250
48293
  var import_node_child_process5 = require("child_process");
@@ -48477,8 +48520,8 @@ async function listCodexSkills(cwd, deps = {}) {
48477
48520
  }
48478
48521
 
48479
48522
  // src/workspace/browser.ts
48480
- var import_node_fs20 = __toESM(require("fs"), 1);
48481
- var import_node_os8 = __toESM(require("os"), 1);
48523
+ var import_node_fs21 = __toESM(require("fs"), 1);
48524
+ var import_node_os7 = __toESM(require("os"), 1);
48482
48525
  var import_node_path19 = __toESM(require("path"), 1);
48483
48526
  init_protocol();
48484
48527
  var MAX_FILE_BYTES = 2 * 1024 * 1024;
@@ -48493,7 +48536,7 @@ function resolveInsideCwd(cwd, subpath) {
48493
48536
  }
48494
48537
  function ensureCwd(cwd) {
48495
48538
  try {
48496
- const stat = import_node_fs20.default.statSync(cwd);
48539
+ const stat = import_node_fs21.default.statSync(cwd);
48497
48540
  if (!stat.isDirectory()) {
48498
48541
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${cwd}`);
48499
48542
  }
@@ -48504,10 +48547,10 @@ function ensureCwd(cwd) {
48504
48547
  }
48505
48548
  var WorkspaceBrowser = class {
48506
48549
  list(args) {
48507
- const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os8.default.homedir();
48550
+ const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os7.default.homedir();
48508
48551
  ensureCwd(cwd);
48509
48552
  const full = resolveInsideCwd(cwd, args.path);
48510
- const dirents = import_node_fs20.default.readdirSync(full, { withFileTypes: true });
48553
+ const dirents = import_node_fs21.default.readdirSync(full, { withFileTypes: true });
48511
48554
  const entries = [];
48512
48555
  for (const d of dirents) {
48513
48556
  if (!args.showHidden && d.name.startsWith(".")) continue;
@@ -48517,7 +48560,7 @@ var WorkspaceBrowser = class {
48517
48560
  mtime: ""
48518
48561
  };
48519
48562
  try {
48520
- const st = import_node_fs20.default.statSync(import_node_path19.default.join(full, d.name));
48563
+ const st = import_node_fs21.default.statSync(import_node_path19.default.join(full, d.name));
48521
48564
  entry.mtime = new Date(st.mtimeMs).toISOString();
48522
48565
  if (d.isFile()) entry.size = st.size;
48523
48566
  } catch {
@@ -48533,14 +48576,14 @@ var WorkspaceBrowser = class {
48533
48576
  read(args) {
48534
48577
  ensureCwd(args.cwd);
48535
48578
  const full = resolveInsideCwd(args.cwd, args.path);
48536
- const st = import_node_fs20.default.statSync(full);
48579
+ const st = import_node_fs21.default.statSync(full);
48537
48580
  if (!st.isFile()) {
48538
48581
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `not a file: ${args.path}`);
48539
48582
  }
48540
48583
  if (st.size > MAX_FILE_BYTES) {
48541
48584
  throw new ClawdError(ERROR_CODES.FILE_TOO_LARGE, `file > ${MAX_FILE_BYTES} bytes`);
48542
48585
  }
48543
- const buf = import_node_fs20.default.readFileSync(full);
48586
+ const buf = import_node_fs21.default.readFileSync(full);
48544
48587
  const isBinary = buf.includes(0);
48545
48588
  if (isBinary) {
48546
48589
  return {
@@ -48562,20 +48605,20 @@ var WorkspaceBrowser = class {
48562
48605
  };
48563
48606
 
48564
48607
  // src/skills/agents-scanner.ts
48565
- var import_node_fs21 = __toESM(require("fs"), 1);
48566
- var import_node_os9 = __toESM(require("os"), 1);
48608
+ var import_node_fs22 = __toESM(require("fs"), 1);
48609
+ var import_node_os8 = __toESM(require("os"), 1);
48567
48610
  var import_node_path20 = __toESM(require("path"), 1);
48568
48611
  var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
48569
48612
  function isDirLikeSync2(p2) {
48570
48613
  try {
48571
- return import_node_fs21.default.statSync(p2).isDirectory();
48614
+ return import_node_fs22.default.statSync(p2).isDirectory();
48572
48615
  } catch {
48573
48616
  return false;
48574
48617
  }
48575
48618
  }
48576
48619
  function fileExistsSync(p2) {
48577
48620
  try {
48578
- return import_node_fs21.default.statSync(p2).isFile();
48621
+ return import_node_fs22.default.statSync(p2).isFile();
48579
48622
  } catch {
48580
48623
  return false;
48581
48624
  }
@@ -48583,7 +48626,7 @@ function fileExistsSync(p2) {
48583
48626
  function parseAgentFile(filePath) {
48584
48627
  let content;
48585
48628
  try {
48586
- content = import_node_fs21.default.readFileSync(filePath, "utf8");
48629
+ content = import_node_fs22.default.readFileSync(filePath, "utf8");
48587
48630
  } catch {
48588
48631
  return {};
48589
48632
  }
@@ -48596,7 +48639,7 @@ function parseAgentFile(filePath) {
48596
48639
  function scanAgentsDir(dir, source, seen, out) {
48597
48640
  let entries;
48598
48641
  try {
48599
- entries = import_node_fs21.default.readdirSync(dir, { withFileTypes: true });
48642
+ entries = import_node_fs22.default.readdirSync(dir, { withFileTypes: true });
48600
48643
  } catch {
48601
48644
  return;
48602
48645
  }
@@ -48623,7 +48666,7 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
48623
48666
  function walk2(dir, namespaces) {
48624
48667
  let entries;
48625
48668
  try {
48626
- entries = import_node_fs21.default.readdirSync(dir, { withFileTypes: true });
48669
+ entries = import_node_fs22.default.readdirSync(dir, { withFileTypes: true });
48627
48670
  } catch {
48628
48671
  return;
48629
48672
  }
@@ -48659,7 +48702,7 @@ function readInstalledPlugins2(home) {
48659
48702
  let raw = null;
48660
48703
  for (const candidate of [v2, v1]) {
48661
48704
  try {
48662
- raw = import_node_fs21.default.readFileSync(candidate, "utf8");
48705
+ raw = import_node_fs22.default.readFileSync(candidate, "utf8");
48663
48706
  break;
48664
48707
  } catch {
48665
48708
  }
@@ -48690,7 +48733,7 @@ function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
48690
48733
  scanAgentsDir(import_node_path20.default.join(cur, ".claude", "agents"), "project", seen, out);
48691
48734
  let hasGit = false;
48692
48735
  try {
48693
- hasGit = import_node_fs21.default.existsSync(import_node_path20.default.join(cur, ".git"));
48736
+ hasGit = import_node_fs22.default.existsSync(import_node_path20.default.join(cur, ".git"));
48694
48737
  } catch {
48695
48738
  }
48696
48739
  if (hasGit) return;
@@ -48706,7 +48749,7 @@ var AgentsScanner = class {
48706
48749
  extraPluginRoots;
48707
48750
  policyDir;
48708
48751
  constructor(opts = {}) {
48709
- this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os9.default.homedir();
48752
+ this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os8.default.homedir();
48710
48753
  this.extraPluginRoots = opts.extraPluginRoots ?? [];
48711
48754
  if (opts.policyDir !== void 0) {
48712
48755
  this.policyDir = opts.policyDir;
@@ -48753,21 +48796,21 @@ var AgentsScanner = class {
48753
48796
  };
48754
48797
 
48755
48798
  // src/observer/session-observer.ts
48756
- var import_node_fs23 = __toESM(require("fs"), 1);
48757
- var import_node_os11 = __toESM(require("os"), 1);
48799
+ var import_node_fs24 = __toESM(require("fs"), 1);
48800
+ var import_node_os10 = __toESM(require("os"), 1);
48758
48801
  var import_node_path22 = __toESM(require("path"), 1);
48759
48802
  init_claude_history();
48760
48803
 
48761
48804
  // src/observer/subagent-meta-observer.ts
48762
- var import_node_fs22 = __toESM(require("fs"), 1);
48763
- var import_node_os10 = __toESM(require("os"), 1);
48805
+ var import_node_fs23 = __toESM(require("fs"), 1);
48806
+ var import_node_os9 = __toESM(require("os"), 1);
48764
48807
  var import_node_path21 = __toESM(require("path"), 1);
48765
48808
  init_claude_history();
48766
48809
  var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
48767
48810
  var SubagentMetaObserver = class {
48768
48811
  constructor(opts) {
48769
48812
  this.opts = opts;
48770
- this.home = opts.home ?? import_node_os10.default.homedir();
48813
+ this.home = opts.home ?? import_node_os9.default.homedir();
48771
48814
  }
48772
48815
  opts;
48773
48816
  home;
@@ -48804,7 +48847,7 @@ var SubagentMetaObserver = class {
48804
48847
  attachWatcher(w2) {
48805
48848
  if (w2.watcher) return;
48806
48849
  try {
48807
- w2.watcher = import_node_fs22.default.watch(w2.dirPath, { persistent: false }, (_evt, name) => {
48850
+ w2.watcher = import_node_fs23.default.watch(w2.dirPath, { persistent: false }, (_evt, name) => {
48808
48851
  if (!name) return;
48809
48852
  const m2 = META_RE.exec(String(name));
48810
48853
  if (!m2) return;
@@ -48816,7 +48859,7 @@ var SubagentMetaObserver = class {
48816
48859
  scan(w2) {
48817
48860
  let entries;
48818
48861
  try {
48819
- entries = import_node_fs22.default.readdirSync(w2.dirPath);
48862
+ entries = import_node_fs23.default.readdirSync(w2.dirPath);
48820
48863
  } catch {
48821
48864
  return;
48822
48865
  }
@@ -48833,7 +48876,7 @@ var SubagentMetaObserver = class {
48833
48876
  const file = import_node_path21.default.join(w2.dirPath, name);
48834
48877
  let raw;
48835
48878
  try {
48836
- raw = import_node_fs22.default.readFileSync(file, "utf8");
48879
+ raw = import_node_fs23.default.readFileSync(file, "utf8");
48837
48880
  } catch {
48838
48881
  return;
48839
48882
  }
@@ -48878,7 +48921,7 @@ var SubagentMetaObserver = class {
48878
48921
  var SessionObserver = class {
48879
48922
  constructor(opts) {
48880
48923
  this.opts = opts;
48881
- this.home = opts.home ?? import_node_os11.default.homedir();
48924
+ this.home = opts.home ?? import_node_os10.default.homedir();
48882
48925
  this.metaObserver = opts.enableSubagentMetaObserver ? new SubagentMetaObserver({ home: this.home, onEvent: opts.onEvent }) : null;
48883
48926
  }
48884
48927
  opts;
@@ -48897,7 +48940,7 @@ var SessionObserver = class {
48897
48940
  const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
48898
48941
  let size = 0;
48899
48942
  try {
48900
- size = import_node_fs23.default.statSync(filePath).size;
48943
+ size = import_node_fs24.default.statSync(filePath).size;
48901
48944
  } catch {
48902
48945
  }
48903
48946
  const w2 = {
@@ -48911,10 +48954,10 @@ var SessionObserver = class {
48911
48954
  prevIsRejectSentinel: false
48912
48955
  };
48913
48956
  try {
48914
- import_node_fs23.default.mkdirSync(import_node_path22.default.dirname(filePath), { recursive: true });
48957
+ import_node_fs24.default.mkdirSync(import_node_path22.default.dirname(filePath), { recursive: true });
48915
48958
  } catch {
48916
48959
  }
48917
- w2.watcher = import_node_fs23.default.watch(import_node_path22.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
48960
+ w2.watcher = import_node_fs24.default.watch(import_node_path22.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
48918
48961
  if (!changedName || !filePath.endsWith(changedName)) return;
48919
48962
  this.poll(w2);
48920
48963
  });
@@ -48937,7 +48980,7 @@ var SessionObserver = class {
48937
48980
  // 异常静默吞,不阻塞 watcher 启动
48938
48981
  hydrateMetaTail(w2, maxLines = 200) {
48939
48982
  try {
48940
- const raw = import_node_fs23.default.readFileSync(w2.filePath, "utf8");
48983
+ const raw = import_node_fs24.default.readFileSync(w2.filePath, "utf8");
48941
48984
  if (!raw) return;
48942
48985
  const allLines = raw.split("\n").filter((l) => l.trim().length > 0);
48943
48986
  if (allLines.length === 0) return;
@@ -48961,7 +49004,7 @@ var SessionObserver = class {
48961
49004
  poll(w2) {
48962
49005
  let size = 0;
48963
49006
  try {
48964
- size = import_node_fs23.default.statSync(w2.filePath).size;
49007
+ size = import_node_fs24.default.statSync(w2.filePath).size;
48965
49008
  } catch {
48966
49009
  return;
48967
49010
  }
@@ -48970,11 +49013,11 @@ var SessionObserver = class {
48970
49013
  w2.buf = "";
48971
49014
  }
48972
49015
  if (size === w2.lastSize) return;
48973
- const fd = import_node_fs23.default.openSync(w2.filePath, "r");
49016
+ const fd = import_node_fs24.default.openSync(w2.filePath, "r");
48974
49017
  try {
48975
49018
  const len = size - w2.lastSize;
48976
49019
  const buf = Buffer.alloc(len);
48977
- import_node_fs23.default.readSync(fd, buf, 0, len, w2.lastSize);
49020
+ import_node_fs24.default.readSync(fd, buf, 0, len, w2.lastSize);
48978
49021
  w2.lastSize = size;
48979
49022
  w2.buf += buf.toString("utf8");
48980
49023
  let newlineIndex;
@@ -48997,7 +49040,7 @@ var SessionObserver = class {
48997
49040
  }
48998
49041
  }
48999
49042
  } finally {
49000
- import_node_fs23.default.closeSync(fd);
49043
+ import_node_fs24.default.closeSync(fd);
49001
49044
  }
49002
49045
  }
49003
49046
  // 解析 JSONL 单行:仅当是主链 user 文本行(非 sidechain / 非 sub-agent / message.role='user'
@@ -49557,7 +49600,9 @@ var EXPOSED_RPC_METHODS = [
49557
49600
  // file-sharing:persona guest agent 把自己工作目录内的产物入群+签名分享。
49558
49601
  // 路径越界由 handlers/attachment.ts guardAttachmentPath(scope-based)拦截。
49559
49602
  "attachment.groupAdd",
49560
- "attachment.signUrl"
49603
+ "attachment.signUrl",
49604
+ // persona 受控发 P2P IM DM(sender 由 session scope 推,driver 分级授权见 handlers/inbox.ts)
49605
+ "inbox.sendDm"
49561
49606
  ];
49562
49607
  async function handleRpcRequest(input) {
49563
49608
  const { method, body, sessionId, dispatcher } = input;
@@ -49793,14 +49838,14 @@ async function authenticate(token, deps) {
49793
49838
  }
49794
49839
 
49795
49840
  // src/permission/capability-store.ts
49796
- var fs27 = __toESM(require("fs"), 1);
49841
+ var fs28 = __toESM(require("fs"), 1);
49797
49842
  var path27 = __toESM(require("path"), 1);
49798
49843
  var CAPABILITIES_FILE_NAME = "capabilities.json";
49799
49844
  var FILE_VERSION = 1;
49800
49845
  var CapabilityStore = class {
49801
49846
  constructor(dataDir) {
49802
49847
  this.dataDir = dataDir;
49803
- fs27.mkdirSync(dataDir, { recursive: true });
49848
+ fs28.mkdirSync(dataDir, { recursive: true });
49804
49849
  this.cache = this.readFromDisk();
49805
49850
  }
49806
49851
  dataDir;
@@ -49830,7 +49875,7 @@ var CapabilityStore = class {
49830
49875
  const file = this.filePath();
49831
49876
  let raw;
49832
49877
  try {
49833
- raw = fs27.readFileSync(file, "utf8");
49878
+ raw = fs28.readFileSync(file, "utf8");
49834
49879
  } catch (err) {
49835
49880
  if (err?.code === "ENOENT") return [];
49836
49881
  return [];
@@ -49858,10 +49903,10 @@ var CapabilityStore = class {
49858
49903
  }
49859
49904
  atomicWrite(file, content) {
49860
49905
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
49861
- fs27.writeFileSync(tmp, content, { mode: 384 });
49862
- fs27.renameSync(tmp, file);
49906
+ fs28.writeFileSync(tmp, content, { mode: 384 });
49907
+ fs28.renameSync(tmp, file);
49863
49908
  try {
49864
- fs27.chmodSync(file, 384);
49909
+ fs28.chmodSync(file, 384);
49865
49910
  } catch {
49866
49911
  }
49867
49912
  }
@@ -49954,14 +49999,14 @@ var CapabilityManager = class {
49954
49999
  };
49955
50000
 
49956
50001
  // src/permission/cleanup.ts
49957
- var fs28 = __toESM(require("fs"), 1);
50002
+ var fs29 = __toESM(require("fs"), 1);
49958
50003
  function cleanupGuestSessionsForCapability(cap, factory) {
49959
50004
  const removed = [];
49960
50005
  for (const g2 of cap.grants) {
49961
50006
  if (g2.resource.type !== "persona") continue;
49962
50007
  const dir = factory.vmGuestRoot(g2.resource.id, cap.id);
49963
50008
  try {
49964
- fs28.rmSync(dir, { recursive: true, force: true });
50009
+ fs29.rmSync(dir, { recursive: true, force: true });
49965
50010
  removed.push(dir);
49966
50011
  } catch {
49967
50012
  }
@@ -49970,13 +50015,13 @@ function cleanupGuestSessionsForCapability(cap, factory) {
49970
50015
  }
49971
50016
 
49972
50017
  // src/inbox/inbox-store.ts
49973
- var fs29 = __toESM(require("fs"), 1);
50018
+ var fs30 = __toESM(require("fs"), 1);
49974
50019
  var path28 = __toESM(require("path"), 1);
49975
50020
  var INBOX_SUBDIR = "inbox";
49976
50021
  var InboxStore = class {
49977
50022
  constructor(dataDir) {
49978
50023
  this.dataDir = dataDir;
49979
- fs29.mkdirSync(this.dirPath(), { recursive: true });
50024
+ fs30.mkdirSync(this.dirPath(), { recursive: true });
49980
50025
  }
49981
50026
  dataDir;
49982
50027
  /**
@@ -49988,7 +50033,7 @@ var InboxStore = class {
49988
50033
  const file = this.filePath(peerDeviceId);
49989
50034
  let raw;
49990
50035
  try {
49991
- raw = fs29.readFileSync(file, "utf8");
50036
+ raw = fs30.readFileSync(file, "utf8");
49992
50037
  } catch (err) {
49993
50038
  if (err?.code === "ENOENT") return [];
49994
50039
  return [];
@@ -50004,7 +50049,7 @@ var InboxStore = class {
50004
50049
  const dir = this.dirPath();
50005
50050
  let entries;
50006
50051
  try {
50007
- entries = fs29.readdirSync(dir);
50052
+ entries = fs30.readdirSync(dir);
50008
50053
  } catch (err) {
50009
50054
  if (err?.code === "ENOENT") return [];
50010
50055
  return [];
@@ -50020,9 +50065,9 @@ var InboxStore = class {
50020
50065
  if (existing.some((m2) => m2.id === message.id)) return;
50021
50066
  const file = this.filePath(message.peerDeviceId);
50022
50067
  const line = JSON.stringify(message) + "\n";
50023
- fs29.appendFileSync(file, line, { mode: 384 });
50068
+ fs30.appendFileSync(file, line, { mode: 384 });
50024
50069
  try {
50025
- fs29.chmodSync(file, 384);
50070
+ fs30.chmodSync(file, 384);
50026
50071
  } catch {
50027
50072
  }
50028
50073
  }
@@ -50052,7 +50097,7 @@ var InboxStore = class {
50052
50097
  removeByPeerDeviceId(peerDeviceId) {
50053
50098
  const file = this.filePath(peerDeviceId);
50054
50099
  try {
50055
- fs29.unlinkSync(file);
50100
+ fs30.unlinkSync(file);
50056
50101
  } catch (err) {
50057
50102
  if (err?.code === "ENOENT") return;
50058
50103
  }
@@ -50061,10 +50106,10 @@ var InboxStore = class {
50061
50106
  const file = this.filePath(peerDeviceId);
50062
50107
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
50063
50108
  const content = messages.map((m2) => JSON.stringify(m2)).join("\n") + (messages.length > 0 ? "\n" : "");
50064
- fs29.writeFileSync(tmp, content, { mode: 384 });
50065
- fs29.renameSync(tmp, file);
50109
+ fs30.writeFileSync(tmp, content, { mode: 384 });
50110
+ fs30.renameSync(tmp, file);
50066
50111
  try {
50067
- fs29.chmodSync(file, 384);
50112
+ fs30.chmodSync(file, 384);
50068
50113
  } catch {
50069
50114
  }
50070
50115
  }
@@ -50115,7 +50160,8 @@ var InboxManager = class {
50115
50160
  senderDeviceId: args.senderDeviceId,
50116
50161
  text: args.text,
50117
50162
  createdAt: args.createdAt,
50118
- readBy: {}
50163
+ readBy: {},
50164
+ ...args.origin ? { origin: args.origin } : {}
50119
50165
  };
50120
50166
  this.store.append(msg);
50121
50167
  const afterLen = this.store.list(args.peerDeviceId).length;
@@ -50159,7 +50205,7 @@ var InboxManager = class {
50159
50205
  };
50160
50206
 
50161
50207
  // src/state/contact-store.ts
50162
- var fs30 = __toESM(require("fs"), 1);
50208
+ var fs31 = __toESM(require("fs"), 1);
50163
50209
  var path29 = __toESM(require("path"), 1);
50164
50210
  var FILE_NAME = "contacts.json";
50165
50211
  var ContactStore = class {
@@ -50173,7 +50219,7 @@ var ContactStore = class {
50173
50219
  const file = path29.join(this.dataDir, FILE_NAME);
50174
50220
  let raw;
50175
50221
  try {
50176
- raw = fs30.readFileSync(file, "utf8");
50222
+ raw = fs31.readFileSync(file, "utf8");
50177
50223
  } catch (err) {
50178
50224
  if (err?.code !== "ENOENT") this.renameBak(file);
50179
50225
  return;
@@ -50223,13 +50269,13 @@ var ContactStore = class {
50223
50269
  null,
50224
50270
  2
50225
50271
  );
50226
- fs30.mkdirSync(this.dataDir, { recursive: true });
50227
- fs30.writeFileSync(tmp, content, { mode: 384 });
50228
- fs30.renameSync(tmp, file);
50272
+ fs31.mkdirSync(this.dataDir, { recursive: true });
50273
+ fs31.writeFileSync(tmp, content, { mode: 384 });
50274
+ fs31.renameSync(tmp, file);
50229
50275
  }
50230
50276
  renameBak(file) {
50231
50277
  try {
50232
- fs30.renameSync(file, `${file}.bak`);
50278
+ fs31.renameSync(file, `${file}.bak`);
50233
50279
  } catch {
50234
50280
  }
50235
50281
  }
@@ -50379,7 +50425,7 @@ async function autoReverseContact(args) {
50379
50425
  }
50380
50426
 
50381
50427
  // src/migrations/2026-05-20-flatten-sessions.ts
50382
- var fs31 = __toESM(require("fs"), 1);
50428
+ var fs32 = __toESM(require("fs"), 1);
50383
50429
  var path30 = __toESM(require("path"), 1);
50384
50430
  var MIGRATION_FLAG_NAME = ".migration.v1.done";
50385
50431
  function migrateFlattenSessions(opts) {
@@ -50399,7 +50445,7 @@ function migrateFlattenSessions(opts) {
50399
50445
  if (!entry.endsWith(".json")) continue;
50400
50446
  const src = path30.join(defaultDir, entry);
50401
50447
  const dst = path30.join(sessionsDir, entry);
50402
- fs31.renameSync(src, dst);
50448
+ fs32.renameSync(src, dst);
50403
50449
  movedBare += 1;
50404
50450
  }
50405
50451
  rmdirIfEmpty(defaultDir);
@@ -50411,10 +50457,10 @@ function migrateFlattenSessions(opts) {
50411
50457
  const ownerSrc = path30.join(personaDir, "owner");
50412
50458
  if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
50413
50459
  const ownerDst = path30.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
50414
- fs31.mkdirSync(ownerDst, { recursive: true });
50460
+ fs32.mkdirSync(ownerDst, { recursive: true });
50415
50461
  for (const file of readdirSafe(ownerSrc)) {
50416
50462
  if (!file.endsWith(".json")) continue;
50417
- fs31.renameSync(path30.join(ownerSrc, file), path30.join(ownerDst, file));
50463
+ fs32.renameSync(path30.join(ownerSrc, file), path30.join(ownerDst, file));
50418
50464
  movedVmOwner += 1;
50419
50465
  }
50420
50466
  rmdirIfEmpty(ownerSrc);
@@ -50422,18 +50468,18 @@ function migrateFlattenSessions(opts) {
50422
50468
  const listenerSrc = path30.join(personaDir, "listener");
50423
50469
  if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
50424
50470
  const archiveDst = path30.join(dataDir, ".legacy", `listener-${pid}`);
50425
- fs31.mkdirSync(archiveDst, { recursive: true });
50471
+ fs32.mkdirSync(archiveDst, { recursive: true });
50426
50472
  for (const file of readdirSafe(listenerSrc)) {
50427
50473
  if (!file.endsWith(".json")) continue;
50428
- fs31.renameSync(path30.join(listenerSrc, file), path30.join(archiveDst, file));
50474
+ fs32.renameSync(path30.join(listenerSrc, file), path30.join(archiveDst, file));
50429
50475
  archivedListener += 1;
50430
50476
  }
50431
50477
  rmdirIfEmpty(listenerSrc);
50432
50478
  }
50433
50479
  rmdirIfEmpty(personaDir);
50434
50480
  }
50435
- fs31.mkdirSync(sessionsDir, { recursive: true });
50436
- fs31.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
50481
+ fs32.mkdirSync(sessionsDir, { recursive: true });
50482
+ fs32.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
50437
50483
  return {
50438
50484
  skipped: false,
50439
50485
  flagWritten: true,
@@ -50444,7 +50490,7 @@ function migrateFlattenSessions(opts) {
50444
50490
  }
50445
50491
  function existsSync3(p2) {
50446
50492
  try {
50447
- fs31.statSync(p2);
50493
+ fs32.statSync(p2);
50448
50494
  return true;
50449
50495
  } catch {
50450
50496
  return false;
@@ -50452,27 +50498,27 @@ function existsSync3(p2) {
50452
50498
  }
50453
50499
  function isDir(p2) {
50454
50500
  try {
50455
- return fs31.statSync(p2).isDirectory();
50501
+ return fs32.statSync(p2).isDirectory();
50456
50502
  } catch {
50457
50503
  return false;
50458
50504
  }
50459
50505
  }
50460
50506
  function readdirSafe(p2) {
50461
50507
  try {
50462
- return fs31.readdirSync(p2);
50508
+ return fs32.readdirSync(p2);
50463
50509
  } catch {
50464
50510
  return [];
50465
50511
  }
50466
50512
  }
50467
50513
  function rmdirIfEmpty(p2) {
50468
50514
  try {
50469
- fs31.rmdirSync(p2);
50515
+ fs32.rmdirSync(p2);
50470
50516
  } catch {
50471
50517
  }
50472
50518
  }
50473
50519
 
50474
50520
  // src/transport/http-router.ts
50475
- var import_node_fs25 = __toESM(require("fs"), 1);
50521
+ var import_node_fs26 = __toESM(require("fs"), 1);
50476
50522
  var import_node_path26 = __toESM(require("path"), 1);
50477
50523
 
50478
50524
  // src/attachment/mime.ts
@@ -50652,7 +50698,7 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
50652
50698
  }
50653
50699
 
50654
50700
  // src/attachment/upload.ts
50655
- var import_node_fs24 = __toESM(require("fs"), 1);
50701
+ var import_node_fs25 = __toESM(require("fs"), 1);
50656
50702
  var import_node_path24 = __toESM(require("path"), 1);
50657
50703
  var import_node_crypto7 = __toESM(require("crypto"), 1);
50658
50704
  var import_promises2 = require("stream/promises");
@@ -50674,7 +50720,7 @@ async function writeUploadedAttachment(args) {
50674
50720
  assertValidFileName(args.fileName);
50675
50721
  const attachmentsRoot = import_node_path24.default.join(args.sessionDir, ".attachments");
50676
50722
  try {
50677
- import_node_fs24.default.mkdirSync(attachmentsRoot, { recursive: true });
50723
+ import_node_fs25.default.mkdirSync(attachmentsRoot, { recursive: true });
50678
50724
  } catch (err) {
50679
50725
  throw new UploadError("STORAGE_ERROR", `mkdir failed: ${err.message}`);
50680
50726
  }
@@ -50695,18 +50741,18 @@ async function writeUploadedAttachment(args) {
50695
50741
  yield buf;
50696
50742
  }
50697
50743
  },
50698
- import_node_fs24.default.createWriteStream(tmpPath, { mode: 384 })
50744
+ import_node_fs25.default.createWriteStream(tmpPath, { mode: 384 })
50699
50745
  );
50700
50746
  } catch (err) {
50701
50747
  try {
50702
- import_node_fs24.default.unlinkSync(tmpPath);
50748
+ import_node_fs25.default.unlinkSync(tmpPath);
50703
50749
  } catch {
50704
50750
  }
50705
50751
  throw new UploadError("STORAGE_ERROR", `write failed: ${err.message}`);
50706
50752
  }
50707
50753
  if (actualSize !== args.contentLength) {
50708
50754
  try {
50709
- import_node_fs24.default.unlinkSync(tmpPath);
50755
+ import_node_fs25.default.unlinkSync(tmpPath);
50710
50756
  } catch {
50711
50757
  }
50712
50758
  throw new UploadError(
@@ -50719,24 +50765,24 @@ async function writeUploadedAttachment(args) {
50719
50765
  let finalFileName;
50720
50766
  let hashDirExists = false;
50721
50767
  try {
50722
- hashDirExists = import_node_fs24.default.statSync(hashDir).isDirectory();
50768
+ hashDirExists = import_node_fs25.default.statSync(hashDir).isDirectory();
50723
50769
  } catch {
50724
50770
  }
50725
50771
  if (hashDirExists) {
50726
- const existing = import_node_fs24.default.readdirSync(hashDir).filter((n) => !n.startsWith("."));
50772
+ const existing = import_node_fs25.default.readdirSync(hashDir).filter((n) => !n.startsWith("."));
50727
50773
  finalFileName = existing[0] ?? args.fileName;
50728
50774
  try {
50729
- import_node_fs24.default.unlinkSync(tmpPath);
50775
+ import_node_fs25.default.unlinkSync(tmpPath);
50730
50776
  } catch {
50731
50777
  }
50732
50778
  } else {
50733
50779
  try {
50734
- import_node_fs24.default.mkdirSync(hashDir, { recursive: true });
50780
+ import_node_fs25.default.mkdirSync(hashDir, { recursive: true });
50735
50781
  finalFileName = args.fileName;
50736
- import_node_fs24.default.renameSync(tmpPath, import_node_path24.default.join(hashDir, finalFileName));
50782
+ import_node_fs25.default.renameSync(tmpPath, import_node_path24.default.join(hashDir, finalFileName));
50737
50783
  } catch (err) {
50738
50784
  try {
50739
- import_node_fs24.default.unlinkSync(tmpPath);
50785
+ import_node_fs25.default.unlinkSync(tmpPath);
50740
50786
  } catch {
50741
50787
  }
50742
50788
  throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
@@ -50758,7 +50804,7 @@ async function writeUploadedAttachment(args) {
50758
50804
  // src/extension/import.ts
50759
50805
  var import_promises3 = __toESM(require("fs/promises"), 1);
50760
50806
  var import_node_path25 = __toESM(require("path"), 1);
50761
- var import_node_os12 = __toESM(require("os"), 1);
50807
+ var import_node_os11 = __toESM(require("os"), 1);
50762
50808
  var import_jszip = __toESM(require_lib3(), 1);
50763
50809
  var ImportError = class extends Error {
50764
50810
  constructor(code, message) {
@@ -50818,7 +50864,7 @@ async function importZip(buf, root) {
50818
50864
  if (destExists) {
50819
50865
  throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
50820
50866
  }
50821
- const stage = await import_promises3.default.mkdtemp(import_node_path25.default.join(import_node_os12.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
50867
+ const stage = await import_promises3.default.mkdtemp(import_node_path25.default.join(import_node_os11.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
50822
50868
  try {
50823
50869
  for (const [name, entry] of Object.entries(zip.files)) {
50824
50870
  const dest = import_node_path25.default.join(stage, name);
@@ -51016,7 +51062,7 @@ function createHttpRouter(deps) {
51016
51062
  }
51017
51063
  let buf;
51018
51064
  try {
51019
- buf = await import_node_fs25.default.promises.readFile(abs);
51065
+ buf = await import_node_fs26.default.promises.readFile(abs);
51020
51066
  } catch {
51021
51067
  sendJson(res, 404, { code: "NOT_FOUND", message: "asset not found" });
51022
51068
  return true;
@@ -51456,7 +51502,7 @@ function withCtx(ctx, body) {
51456
51502
  function streamFile(res, absPath, logger) {
51457
51503
  let stat;
51458
51504
  try {
51459
- stat = import_node_fs25.default.statSync(absPath);
51505
+ stat = import_node_fs26.default.statSync(absPath);
51460
51506
  } catch (err) {
51461
51507
  const code = err?.code;
51462
51508
  if (code === "ENOENT") {
@@ -51479,7 +51525,7 @@ function streamFile(res, absPath, logger) {
51479
51525
  // 防止浏览器把任意 mime 当 html 渲染
51480
51526
  "X-Content-Type-Options": "nosniff"
51481
51527
  });
51482
- const stream = import_node_fs25.default.createReadStream(absPath);
51528
+ const stream = import_node_fs26.default.createReadStream(absPath);
51483
51529
  stream.on("error", (err) => {
51484
51530
  logger?.warn("streamFile read error", { absPath, err: err.message });
51485
51531
  res.destroy();
@@ -51488,7 +51534,7 @@ function streamFile(res, absPath, logger) {
51488
51534
  }
51489
51535
 
51490
51536
  // src/attachment/gc.ts
51491
- var import_node_fs26 = __toESM(require("fs"), 1);
51537
+ var import_node_fs27 = __toESM(require("fs"), 1);
51492
51538
  var import_node_path27 = __toESM(require("path"), 1);
51493
51539
  var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
51494
51540
  function runAttachmentGc(args) {
@@ -51511,7 +51557,7 @@ function runAttachmentGc(args) {
51511
51557
  const attRoot = import_node_path27.default.join(sessionDir, ".attachments");
51512
51558
  let hashDirs;
51513
51559
  try {
51514
- hashDirs = import_node_fs26.default.readdirSync(attRoot);
51560
+ hashDirs = import_node_fs27.default.readdirSync(attRoot);
51515
51561
  } catch (err) {
51516
51562
  if (err.code === "ENOENT") continue;
51517
51563
  args.logger?.warn("attachment gc: readdir failed", { attRoot, err: err.message });
@@ -51521,7 +51567,7 @@ function runAttachmentGc(args) {
51521
51567
  const hashDirAbs = import_node_path27.default.join(attRoot, hashDir);
51522
51568
  let files;
51523
51569
  try {
51524
- files = import_node_fs26.default.readdirSync(hashDirAbs);
51570
+ files = import_node_fs27.default.readdirSync(hashDirAbs);
51525
51571
  } catch {
51526
51572
  continue;
51527
51573
  }
@@ -51529,7 +51575,7 @@ function runAttachmentGc(args) {
51529
51575
  const file = import_node_path27.default.join(hashDirAbs, name);
51530
51576
  let stat;
51531
51577
  try {
51532
- stat = import_node_fs26.default.statSync(file);
51578
+ stat = import_node_fs27.default.statSync(file);
51533
51579
  } catch {
51534
51580
  continue;
51535
51581
  }
@@ -51538,25 +51584,25 @@ function runAttachmentGc(args) {
51538
51584
  if (age < ttlMs) continue;
51539
51585
  if (liveAbs.has(file)) continue;
51540
51586
  try {
51541
- import_node_fs26.default.unlinkSync(file);
51587
+ import_node_fs27.default.unlinkSync(file);
51542
51588
  } catch (err) {
51543
51589
  args.logger?.warn("attachment gc: unlink failed", { file, err: err.message });
51544
51590
  }
51545
51591
  }
51546
51592
  try {
51547
- if (import_node_fs26.default.readdirSync(hashDirAbs).length === 0) import_node_fs26.default.rmdirSync(hashDirAbs);
51593
+ if (import_node_fs27.default.readdirSync(hashDirAbs).length === 0) import_node_fs27.default.rmdirSync(hashDirAbs);
51548
51594
  } catch {
51549
51595
  }
51550
51596
  }
51551
51597
  try {
51552
- if (import_node_fs26.default.readdirSync(attRoot).length === 0) import_node_fs26.default.rmdirSync(attRoot);
51598
+ if (import_node_fs27.default.readdirSync(attRoot).length === 0) import_node_fs27.default.rmdirSync(attRoot);
51553
51599
  } catch {
51554
51600
  }
51555
51601
  }
51556
51602
  }
51557
51603
 
51558
51604
  // src/attachment/group.ts
51559
- var import_node_fs27 = __toESM(require("fs"), 1);
51605
+ var import_node_fs28 = __toESM(require("fs"), 1);
51560
51606
  var import_node_path28 = __toESM(require("path"), 1);
51561
51607
  var import_node_crypto8 = __toESM(require("crypto"), 1);
51562
51608
  init_protocol();
@@ -51582,7 +51628,7 @@ var GroupFileStore = class {
51582
51628
  readFile(scope, sessionId) {
51583
51629
  const file = this.filePath(scope, sessionId);
51584
51630
  try {
51585
- const raw = import_node_fs27.default.readFileSync(file, "utf8");
51631
+ const raw = import_node_fs28.default.readFileSync(file, "utf8");
51586
51632
  const parsed = JSON.parse(raw);
51587
51633
  if (!Array.isArray(parsed)) {
51588
51634
  this.logger?.warn("GroupFileStore.readFile: not an array; resetting session entries", {
@@ -51608,10 +51654,10 @@ var GroupFileStore = class {
51608
51654
  }
51609
51655
  writeFile(scope, sessionId, entries) {
51610
51656
  const file = this.filePath(scope, sessionId);
51611
- import_node_fs27.default.mkdirSync(import_node_path28.default.dirname(file), { recursive: true });
51657
+ import_node_fs28.default.mkdirSync(import_node_path28.default.dirname(file), { recursive: true });
51612
51658
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
51613
- import_node_fs27.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
51614
- import_node_fs27.default.renameSync(tmp, file);
51659
+ import_node_fs28.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
51660
+ import_node_fs28.default.renameSync(tmp, file);
51615
51661
  }
51616
51662
  /** 拉一份当前 session 的清单。读盘 → cache;之后调用复用 cache */
51617
51663
  list(scope, sessionId) {
@@ -51697,7 +51743,7 @@ var GroupFileStore = class {
51697
51743
  };
51698
51744
 
51699
51745
  // src/discovery/state-file.ts
51700
- var import_node_fs28 = __toESM(require("fs"), 1);
51746
+ var import_node_fs29 = __toESM(require("fs"), 1);
51701
51747
  var import_node_path29 = __toESM(require("path"), 1);
51702
51748
  function defaultStateFilePath(dataDir) {
51703
51749
  return import_node_path29.default.join(dataDir, "state.json");
@@ -51722,7 +51768,7 @@ var StateFileManager = class {
51722
51768
  }
51723
51769
  read() {
51724
51770
  try {
51725
- const raw = import_node_fs28.default.readFileSync(this.file, "utf8");
51771
+ const raw = import_node_fs29.default.readFileSync(this.file, "utf8");
51726
51772
  const parsed = JSON.parse(raw);
51727
51773
  return parsed;
51728
51774
  } catch {
@@ -51736,20 +51782,20 @@ var StateFileManager = class {
51736
51782
  return { status: "stale", existing };
51737
51783
  }
51738
51784
  write(state) {
51739
- import_node_fs28.default.mkdirSync(import_node_path29.default.dirname(this.file), { recursive: true });
51785
+ import_node_fs29.default.mkdirSync(import_node_path29.default.dirname(this.file), { recursive: true });
51740
51786
  const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
51741
- import_node_fs28.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
51742
- import_node_fs28.default.renameSync(tmp, this.file);
51787
+ import_node_fs29.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
51788
+ import_node_fs29.default.renameSync(tmp, this.file);
51743
51789
  if (process.platform !== "win32") {
51744
51790
  try {
51745
- import_node_fs28.default.chmodSync(this.file, 384);
51791
+ import_node_fs29.default.chmodSync(this.file, 384);
51746
51792
  } catch {
51747
51793
  }
51748
51794
  }
51749
51795
  }
51750
51796
  delete() {
51751
51797
  try {
51752
- import_node_fs28.default.unlinkSync(this.file);
51798
+ import_node_fs29.default.unlinkSync(this.file);
51753
51799
  } catch {
51754
51800
  }
51755
51801
  }
@@ -51764,13 +51810,13 @@ function readDaemonSourceFromEnv(env = process.env) {
51764
51810
  }
51765
51811
 
51766
51812
  // src/tunnel/tunnel-manager.ts
51767
- var import_node_fs32 = __toESM(require("fs"), 1);
51813
+ var import_node_fs33 = __toESM(require("fs"), 1);
51768
51814
  var import_node_path33 = __toESM(require("path"), 1);
51769
51815
  var import_node_crypto9 = __toESM(require("crypto"), 1);
51770
51816
  var import_node_child_process9 = require("child_process");
51771
51817
 
51772
51818
  // src/tunnel/tunnel-store.ts
51773
- var import_node_fs29 = __toESM(require("fs"), 1);
51819
+ var import_node_fs30 = __toESM(require("fs"), 1);
51774
51820
  var import_node_path30 = __toESM(require("path"), 1);
51775
51821
  var TunnelStore = class {
51776
51822
  constructor(filePath) {
@@ -51779,7 +51825,7 @@ var TunnelStore = class {
51779
51825
  filePath;
51780
51826
  async get() {
51781
51827
  try {
51782
- const raw = await import_node_fs29.default.promises.readFile(this.filePath, "utf8");
51828
+ const raw = await import_node_fs30.default.promises.readFile(this.filePath, "utf8");
51783
51829
  const obj = JSON.parse(raw);
51784
51830
  if (!isPersistedTunnel(obj)) return null;
51785
51831
  return obj;
@@ -51791,21 +51837,21 @@ var TunnelStore = class {
51791
51837
  }
51792
51838
  async set(v2) {
51793
51839
  const dir = import_node_path30.default.dirname(this.filePath);
51794
- await import_node_fs29.default.promises.mkdir(dir, { recursive: true });
51840
+ await import_node_fs30.default.promises.mkdir(dir, { recursive: true });
51795
51841
  const data = JSON.stringify(v2, null, 2);
51796
51842
  const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
51797
- await import_node_fs29.default.promises.writeFile(tmp, data, { mode: 384 });
51843
+ await import_node_fs30.default.promises.writeFile(tmp, data, { mode: 384 });
51798
51844
  if (process.platform !== "win32") {
51799
51845
  try {
51800
- await import_node_fs29.default.promises.chmod(tmp, 384);
51846
+ await import_node_fs30.default.promises.chmod(tmp, 384);
51801
51847
  } catch {
51802
51848
  }
51803
51849
  }
51804
- await import_node_fs29.default.promises.rename(tmp, this.filePath);
51850
+ await import_node_fs30.default.promises.rename(tmp, this.filePath);
51805
51851
  }
51806
51852
  async clear() {
51807
51853
  try {
51808
- await import_node_fs29.default.promises.unlink(this.filePath);
51854
+ await import_node_fs30.default.promises.unlink(this.filePath);
51809
51855
  } catch (err) {
51810
51856
  const code = err?.code;
51811
51857
  if (code !== "ENOENT") throw err;
@@ -51900,8 +51946,8 @@ function escape(v2) {
51900
51946
  }
51901
51947
 
51902
51948
  // src/tunnel/frpc-binary.ts
51903
- var import_node_fs30 = __toESM(require("fs"), 1);
51904
- var import_node_os13 = __toESM(require("os"), 1);
51949
+ var import_node_fs31 = __toESM(require("fs"), 1);
51950
+ var import_node_os12 = __toESM(require("os"), 1);
51905
51951
  var import_node_path31 = __toESM(require("path"), 1);
51906
51952
  var import_node_child_process7 = require("child_process");
51907
51953
  var import_node_stream3 = require("stream");
@@ -51934,7 +51980,7 @@ function frpcDownloadUrl(version2, p2) {
51934
51980
  }
51935
51981
  async function ensureFrpcBinary(opts) {
51936
51982
  if (opts.override) {
51937
- if (!import_node_fs30.default.existsSync(opts.override)) {
51983
+ if (!import_node_fs31.default.existsSync(opts.override)) {
51938
51984
  throw new Error(`frpc binary not found at override path: ${opts.override}`);
51939
51985
  }
51940
51986
  return opts.override;
@@ -51942,10 +51988,10 @@ async function ensureFrpcBinary(opts) {
51942
51988
  const version2 = opts.version ?? FRPC_VERSION;
51943
51989
  const platform = opts.platform ?? detectPlatform();
51944
51990
  const binDir = import_node_path31.default.join(opts.dataDir, "bin");
51945
- import_node_fs30.default.mkdirSync(binDir, { recursive: true });
51991
+ import_node_fs31.default.mkdirSync(binDir, { recursive: true });
51946
51992
  cleanupStaleArtifacts(binDir);
51947
51993
  const stableBin = import_node_path31.default.join(binDir, "frpc");
51948
- if (import_node_fs30.default.existsSync(stableBin)) return stableBin;
51994
+ if (import_node_fs31.default.existsSync(stableBin)) return stableBin;
51949
51995
  const partialBin = `${stableBin}.partial`;
51950
51996
  const tarballPath = import_node_path31.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
51951
51997
  try {
@@ -51956,8 +52002,8 @@ async function ensureFrpcBinary(opts) {
51956
52002
  } else {
51957
52003
  await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
51958
52004
  }
51959
- import_node_fs30.default.chmodSync(partialBin, 493);
51960
- import_node_fs30.default.renameSync(partialBin, stableBin);
52005
+ import_node_fs31.default.chmodSync(partialBin, 493);
52006
+ import_node_fs31.default.renameSync(partialBin, stableBin);
51961
52007
  } finally {
51962
52008
  safeUnlink(tarballPath);
51963
52009
  safeUnlink(partialBin);
@@ -51967,7 +52013,7 @@ async function ensureFrpcBinary(opts) {
51967
52013
  function cleanupStaleArtifacts(binDir) {
51968
52014
  let entries;
51969
52015
  try {
51970
- entries = import_node_fs30.default.readdirSync(binDir);
52016
+ entries = import_node_fs31.default.readdirSync(binDir);
51971
52017
  } catch {
51972
52018
  return;
51973
52019
  }
@@ -51975,7 +52021,7 @@ function cleanupStaleArtifacts(binDir) {
51975
52021
  if (name.endsWith(".partial") || name.startsWith("extract-")) {
51976
52022
  const full = import_node_path31.default.join(binDir, name);
51977
52023
  try {
51978
- import_node_fs30.default.rmSync(full, { recursive: true, force: true });
52024
+ import_node_fs31.default.rmSync(full, { recursive: true, force: true });
51979
52025
  } catch {
51980
52026
  }
51981
52027
  }
@@ -51983,7 +52029,7 @@ function cleanupStaleArtifacts(binDir) {
51983
52029
  }
51984
52030
  function safeUnlink(p2) {
51985
52031
  try {
51986
- import_node_fs30.default.unlinkSync(p2);
52032
+ import_node_fs31.default.unlinkSync(p2);
51987
52033
  } catch {
51988
52034
  }
51989
52035
  }
@@ -51994,13 +52040,13 @@ async function downloadToFile(url, dest, fetchImpl) {
51994
52040
  if (!res.ok || !res.body) {
51995
52041
  throw new Error(`download failed: ${res.status} ${res.statusText}`);
51996
52042
  }
51997
- const out = import_node_fs30.default.createWriteStream(dest);
52043
+ const out = import_node_fs31.default.createWriteStream(dest);
51998
52044
  const nodeStream = import_node_stream3.Readable.fromWeb(res.body);
51999
52045
  await (0, import_promises4.pipeline)(nodeStream, out);
52000
52046
  }
52001
52047
  async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
52002
52048
  const work = import_node_path31.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
52003
- import_node_fs30.default.mkdirSync(work, { recursive: true });
52049
+ import_node_fs31.default.mkdirSync(work, { recursive: true });
52004
52050
  try {
52005
52051
  await new Promise((resolve6, reject) => {
52006
52052
  const proc = (0, import_node_child_process7.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
@@ -52009,17 +52055,17 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
52009
52055
  });
52010
52056
  const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
52011
52057
  const src = import_node_path31.default.join(work, dirName, "frpc");
52012
- if (!import_node_fs30.default.existsSync(src)) {
52058
+ if (!import_node_fs31.default.existsSync(src)) {
52013
52059
  throw new Error(`frpc not found inside tarball at ${src}`);
52014
52060
  }
52015
- import_node_fs30.default.copyFileSync(src, destBin);
52061
+ import_node_fs31.default.copyFileSync(src, destBin);
52016
52062
  } finally {
52017
- import_node_fs30.default.rmSync(work, { recursive: true, force: true });
52063
+ import_node_fs31.default.rmSync(work, { recursive: true, force: true });
52018
52064
  }
52019
52065
  }
52020
52066
 
52021
52067
  // src/tunnel/frpc-process.ts
52022
- var import_node_fs31 = __toESM(require("fs"), 1);
52068
+ var import_node_fs32 = __toESM(require("fs"), 1);
52023
52069
  var import_node_path32 = __toESM(require("path"), 1);
52024
52070
  var import_node_child_process8 = require("child_process");
52025
52071
  function frpcPidFilePath(dataDir) {
@@ -52027,13 +52073,13 @@ function frpcPidFilePath(dataDir) {
52027
52073
  }
52028
52074
  function writeFrpcPid(dataDir, pid) {
52029
52075
  try {
52030
- import_node_fs31.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
52076
+ import_node_fs32.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
52031
52077
  } catch {
52032
52078
  }
52033
52079
  }
52034
52080
  function clearFrpcPid(dataDir) {
52035
52081
  try {
52036
- import_node_fs31.default.unlinkSync(frpcPidFilePath(dataDir));
52082
+ import_node_fs32.default.unlinkSync(frpcPidFilePath(dataDir));
52037
52083
  } catch {
52038
52084
  }
52039
52085
  }
@@ -52049,7 +52095,7 @@ function defaultIsPidAlive(pid) {
52049
52095
  }
52050
52096
  function defaultReadPidFile(file) {
52051
52097
  try {
52052
- return import_node_fs31.default.readFileSync(file, "utf8");
52098
+ return import_node_fs32.default.readFileSync(file, "utf8");
52053
52099
  } catch {
52054
52100
  return null;
52055
52101
  }
@@ -52089,7 +52135,7 @@ async function killStaleFrpc(deps) {
52089
52135
  }
52090
52136
  if (victims.size === 0) {
52091
52137
  try {
52092
- import_node_fs31.default.unlinkSync(pidFile);
52138
+ import_node_fs32.default.unlinkSync(pidFile);
52093
52139
  } catch {
52094
52140
  }
52095
52141
  return;
@@ -52100,7 +52146,7 @@ async function killStaleFrpc(deps) {
52100
52146
  }
52101
52147
  await sleep2(deps.reapWaitMs ?? 300);
52102
52148
  try {
52103
- import_node_fs31.default.unlinkSync(pidFile);
52149
+ import_node_fs32.default.unlinkSync(pidFile);
52104
52150
  } catch {
52105
52151
  }
52106
52152
  }
@@ -52275,12 +52321,12 @@ var TunnelManager = class {
52275
52321
  localPort,
52276
52322
  logLevel: "info"
52277
52323
  });
52278
- await import_node_fs32.default.promises.writeFile(tomlPath, toml, { mode: 384 });
52324
+ await import_node_fs33.default.promises.writeFile(tomlPath, toml, { mode: 384 });
52279
52325
  const proc = (this.deps.spawnImpl ?? import_node_child_process9.spawn)(frpcBin, ["-c", tomlPath], {
52280
52326
  stdio: ["ignore", "pipe", "pipe"]
52281
52327
  });
52282
52328
  const logFilePath = import_node_path33.default.join(this.deps.dataDir, "frpc.log");
52283
- const logStream = import_node_fs32.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
52329
+ const logStream = import_node_fs33.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
52284
52330
  logStream.on("error", () => {
52285
52331
  });
52286
52332
  const tee = (chunk) => {
@@ -52362,14 +52408,14 @@ async function waitForFrpcReady(proc, timeoutMs) {
52362
52408
  }
52363
52409
 
52364
52410
  // src/tunnel/device-key.ts
52365
- var import_node_os14 = __toESM(require("os"), 1);
52411
+ var import_node_os13 = __toESM(require("os"), 1);
52366
52412
  var import_node_path34 = __toESM(require("path"), 1);
52367
52413
  var import_node_crypto10 = __toESM(require("crypto"), 1);
52368
52414
  var DERIVE_SALT = "clawd-tunnel-device-v1";
52369
52415
  function deriveStableDeviceKey(opts = {}) {
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();
52416
+ const hostname = opts.hostname ?? import_node_os13.default.hostname();
52417
+ const uid = opts.uid ?? (typeof import_node_os13.default.userInfo === "function" ? import_node_os13.default.userInfo().uid : 0);
52418
+ const home = opts.home ?? import_node_os13.default.homedir();
52373
52419
  const defaultDataDir = import_node_path34.default.resolve(import_node_path34.default.join(home, ".clawd"));
52374
52420
  const normalizedDataDir = opts.dataDir ? import_node_path34.default.resolve(opts.dataDir) : null;
52375
52421
  const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
@@ -52378,7 +52424,7 @@ function deriveStableDeviceKey(opts = {}) {
52378
52424
  }
52379
52425
 
52380
52426
  // src/auth-store.ts
52381
- var import_node_fs33 = __toESM(require("fs"), 1);
52427
+ var import_node_fs34 = __toESM(require("fs"), 1);
52382
52428
  var import_node_path35 = __toESM(require("path"), 1);
52383
52429
  var import_node_crypto11 = __toESM(require("crypto"), 1);
52384
52430
  var AUTH_FILE_NAME = "auth.json";
@@ -52419,7 +52465,7 @@ function defaultGenerateOwnerPrincipalId() {
52419
52465
  }
52420
52466
  function readAuthFile(file) {
52421
52467
  try {
52422
- const raw = import_node_fs33.default.readFileSync(file, "utf8");
52468
+ const raw = import_node_fs34.default.readFileSync(file, "utf8");
52423
52469
  const parsed = JSON.parse(raw);
52424
52470
  if (typeof parsed?.token !== "string" || parsed.token.length === 0) {
52425
52471
  return null;
@@ -52439,25 +52485,25 @@ function readAuthFile(file) {
52439
52485
  }
52440
52486
  }
52441
52487
  function writeAuthFile(file, content) {
52442
- import_node_fs33.default.mkdirSync(import_node_path35.default.dirname(file), { recursive: true });
52443
- import_node_fs33.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
52488
+ import_node_fs34.default.mkdirSync(import_node_path35.default.dirname(file), { recursive: true });
52489
+ import_node_fs34.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
52444
52490
  try {
52445
- import_node_fs33.default.chmodSync(file, 384);
52491
+ import_node_fs34.default.chmodSync(file, 384);
52446
52492
  } catch {
52447
52493
  }
52448
52494
  }
52449
52495
 
52450
52496
  // src/owner-profile.ts
52451
- var import_node_fs34 = __toESM(require("fs"), 1);
52452
- var import_node_os15 = __toESM(require("os"), 1);
52497
+ var import_node_fs35 = __toESM(require("fs"), 1);
52498
+ var import_node_os14 = __toESM(require("os"), 1);
52453
52499
  var import_node_path36 = __toESM(require("path"), 1);
52454
52500
  var PROFILE_FILENAME = "profile.json";
52455
52501
  function loadOwnerDisplayName(dataDir) {
52456
- const fallback = import_node_os15.default.userInfo().username;
52502
+ const fallback = import_node_os14.default.userInfo().username;
52457
52503
  const profilePath = import_node_path36.default.join(dataDir, PROFILE_FILENAME);
52458
52504
  let raw;
52459
52505
  try {
52460
- raw = import_node_fs34.default.readFileSync(profilePath, "utf8");
52506
+ raw = import_node_fs35.default.readFileSync(profilePath, "utf8");
52461
52507
  } catch {
52462
52508
  return fallback;
52463
52509
  }
@@ -52480,7 +52526,7 @@ function loadOwnerDisplayName(dataDir) {
52480
52526
  }
52481
52527
 
52482
52528
  // src/feishu-auth/owner-identity-store.ts
52483
- var import_node_fs35 = __toESM(require("fs"), 1);
52529
+ var import_node_fs36 = __toESM(require("fs"), 1);
52484
52530
  var import_node_path37 = __toESM(require("path"), 1);
52485
52531
  var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
52486
52532
  var OwnerIdentityStore = class {
@@ -52491,7 +52537,7 @@ var OwnerIdentityStore = class {
52491
52537
  read() {
52492
52538
  let raw;
52493
52539
  try {
52494
- raw = import_node_fs35.default.readFileSync(this.file, "utf8");
52540
+ raw = import_node_fs36.default.readFileSync(this.file, "utf8");
52495
52541
  } catch {
52496
52542
  return null;
52497
52543
  }
@@ -52519,16 +52565,16 @@ var OwnerIdentityStore = class {
52519
52565
  };
52520
52566
  }
52521
52567
  write(record) {
52522
- import_node_fs35.default.mkdirSync(import_node_path37.default.dirname(this.file), { recursive: true });
52523
- import_node_fs35.default.writeFileSync(this.file, JSON.stringify(record, null, 2), { mode: 384 });
52568
+ import_node_fs36.default.mkdirSync(import_node_path37.default.dirname(this.file), { recursive: true });
52569
+ import_node_fs36.default.writeFileSync(this.file, JSON.stringify(record, null, 2), { mode: 384 });
52524
52570
  try {
52525
- import_node_fs35.default.chmodSync(this.file, 384);
52571
+ import_node_fs36.default.chmodSync(this.file, 384);
52526
52572
  } catch {
52527
52573
  }
52528
52574
  }
52529
52575
  clear() {
52530
52576
  try {
52531
- import_node_fs35.default.unlinkSync(this.file);
52577
+ import_node_fs36.default.unlinkSync(this.file);
52532
52578
  } catch (err) {
52533
52579
  const code = err?.code;
52534
52580
  if (code !== "ENOENT") throw err;
@@ -52793,7 +52839,7 @@ function verifyConnectToken(args) {
52793
52839
  }
52794
52840
 
52795
52841
  // src/feishu-auth/server-key.ts
52796
- var fs45 = __toESM(require("fs"), 1);
52842
+ var fs46 = __toESM(require("fs"), 1);
52797
52843
  var path46 = __toESM(require("path"), 1);
52798
52844
  var FILE_NAME2 = "server-signing-key.json";
52799
52845
  var ServerKeyStore = class {
@@ -52807,7 +52853,7 @@ var ServerKeyStore = class {
52807
52853
  /** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
52808
52854
  read() {
52809
52855
  try {
52810
- const raw = fs45.readFileSync(this.filePath(), "utf8");
52856
+ const raw = fs46.readFileSync(this.filePath(), "utf8");
52811
52857
  const parsed = JSON.parse(raw);
52812
52858
  if (typeof parsed.publicKeyPem === "string" && parsed.publicKeyPem.includes("PUBLIC KEY")) {
52813
52859
  return parsed.publicKeyPem;
@@ -52822,12 +52868,12 @@ var ServerKeyStore = class {
52822
52868
  publicKeyPem,
52823
52869
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
52824
52870
  };
52825
- fs45.mkdirSync(this.dataDir, { recursive: true });
52826
- fs45.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
52871
+ fs46.mkdirSync(this.dataDir, { recursive: true });
52872
+ fs46.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
52827
52873
  }
52828
52874
  clear() {
52829
52875
  try {
52830
- fs45.unlinkSync(this.filePath());
52876
+ fs46.unlinkSync(this.filePath());
52831
52877
  } catch {
52832
52878
  }
52833
52879
  }
@@ -52840,12 +52886,12 @@ init_protocol();
52840
52886
  init_protocol();
52841
52887
 
52842
52888
  // src/session/fork.ts
52843
- var import_node_fs36 = __toESM(require("fs"), 1);
52844
- var import_node_os16 = __toESM(require("os"), 1);
52889
+ var import_node_fs37 = __toESM(require("fs"), 1);
52890
+ var import_node_os15 = __toESM(require("os"), 1);
52845
52891
  var import_node_path38 = __toESM(require("path"), 1);
52846
52892
  init_claude_history();
52847
52893
  function readJsonlEntries(file) {
52848
- const raw = import_node_fs36.default.readFileSync(file, "utf8");
52894
+ const raw = import_node_fs37.default.readFileSync(file, "utf8");
52849
52895
  const out = [];
52850
52896
  for (const line of raw.split("\n")) {
52851
52897
  const t = line.trim();
@@ -52858,10 +52904,10 @@ function readJsonlEntries(file) {
52858
52904
  return out;
52859
52905
  }
52860
52906
  function forkSession(input) {
52861
- const baseDir = input.baseDir ?? import_node_path38.default.join(import_node_os16.default.homedir(), ".claude");
52907
+ const baseDir = input.baseDir ?? import_node_path38.default.join(import_node_os15.default.homedir(), ".claude");
52862
52908
  const projectDir = import_node_path38.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
52863
52909
  const sourceFile = import_node_path38.default.join(projectDir, `${input.toolSessionId}.jsonl`);
52864
- if (!import_node_fs36.default.existsSync(sourceFile)) {
52910
+ if (!import_node_fs37.default.existsSync(sourceFile)) {
52865
52911
  throw new Error(`fork: source transcript not found: ${sourceFile}`);
52866
52912
  }
52867
52913
  const entries = readJsonlEntries(sourceFile);
@@ -52892,8 +52938,8 @@ function forkSession(input) {
52892
52938
  forkedLines.push(JSON.stringify(forked));
52893
52939
  }
52894
52940
  const forkedFilePath = import_node_path38.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
52895
- import_node_fs36.default.mkdirSync(projectDir, { recursive: true });
52896
- import_node_fs36.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
52941
+ import_node_fs37.default.mkdirSync(projectDir, { recursive: true });
52942
+ import_node_fs37.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
52897
52943
  return { forkedToolSessionId, forkedFilePath };
52898
52944
  }
52899
52945
 
@@ -53414,7 +53460,7 @@ function buildHistoryHandlers(deps) {
53414
53460
 
53415
53461
  // src/handlers/workspace.ts
53416
53462
  var path50 = __toESM(require("path"), 1);
53417
- var os16 = __toESM(require("os"), 1);
53463
+ var os15 = __toESM(require("os"), 1);
53418
53464
  init_protocol();
53419
53465
  init_protocol();
53420
53466
  function buildEnabledPluginNames(personaManager, personaId) {
@@ -53454,7 +53500,7 @@ function buildWorkspaceHandlers(deps) {
53454
53500
  const list = async (frame, _client, ctx) => {
53455
53501
  const args = WorkspaceListArgs.parse(frame);
53456
53502
  const isGuest = ctx?.principal.kind === "guest";
53457
- const fallbackCwd = isGuest && personaRoot ? personaRoot : os16.homedir();
53503
+ const fallbackCwd = isGuest && personaRoot ? personaRoot : os15.homedir();
53458
53504
  const resolvedCwd = path50.resolve(args.cwd ?? fallbackCwd);
53459
53505
  const target = args.path ? path50.resolve(resolvedCwd, args.path) : resolvedCwd;
53460
53506
  assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
@@ -53510,14 +53556,14 @@ init_protocol();
53510
53556
 
53511
53557
  // src/workspace/git.ts
53512
53558
  var import_node_child_process10 = require("child_process");
53513
- var import_node_fs37 = __toESM(require("fs"), 1);
53559
+ var import_node_fs38 = __toESM(require("fs"), 1);
53514
53560
  var import_node_path39 = __toESM(require("path"), 1);
53515
53561
  var import_node_util = require("util");
53516
53562
  var pexec = (0, import_node_util.promisify)(import_node_child_process10.execFile);
53517
53563
  function normalizePath(p2) {
53518
53564
  const resolved = import_node_path39.default.resolve(p2);
53519
53565
  try {
53520
- return import_node_fs37.default.realpathSync(resolved);
53566
+ return import_node_fs38.default.realpathSync(resolved);
53521
53567
  } catch {
53522
53568
  return resolved;
53523
53569
  }
@@ -53713,7 +53759,8 @@ function buildInboxHandlers(deps) {
53713
53759
  senderDeviceId: ctx.principal.id,
53714
53760
  text: args.text,
53715
53761
  id: args.id,
53716
- createdAt: args.createdAt
53762
+ createdAt: args.createdAt,
53763
+ origin: args.origin
53717
53764
  });
53718
53765
  return {
53719
53766
  response: { type: "inbox:postMessage:ok", message }
@@ -53752,8 +53799,66 @@ function buildInboxHandlers(deps) {
53752
53799
  }
53753
53800
  };
53754
53801
  };
53802
+ const sendDm = async (frame) => {
53803
+ const { type: _t, requestId: _r, ...rest } = frame;
53804
+ const sessionId = typeof rest.sessionId === "string" ? rest.sessionId : void 0;
53805
+ const args = InboxSendDmArgsSchema.parse(rest);
53806
+ const d = deps.sendDmDeps;
53807
+ if (!d) throw new ClawdError(ERROR_CODES.INTERNAL, "inbox:sendDm not wired");
53808
+ if (!sessionId) {
53809
+ throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, "inbox:sendDm requires sessionId");
53810
+ }
53811
+ const scope = d.getSessionScope(sessionId);
53812
+ if (!scope || scope.kind !== "persona") {
53813
+ throw new ClawdError(ERROR_CODES.UNAUTHORIZED, "inbox:sendDm requires a persona session");
53814
+ }
53815
+ const origin = { kind: "persona", personaId: scope.personaId };
53816
+ const id = d.genId();
53817
+ const createdAt = d.now();
53818
+ if (scope.mode === "guest") {
53819
+ if (args.peerDeviceId && args.peerDeviceId !== d.ownerPrincipalId) {
53820
+ throw new ClawdError(ERROR_CODES.UNAUTHORIZED, "guest-driven persona may only DM the owner");
53821
+ }
53822
+ const message2 = manager.postMessage({
53823
+ peerDeviceId: scope.capId,
53824
+ senderDeviceId: scope.capId,
53825
+ text: args.text,
53826
+ id,
53827
+ createdAt,
53828
+ origin
53829
+ });
53830
+ return { response: { type: "inbox:sendDm:ok", message: message2 } };
53831
+ }
53832
+ if (!args.peerDeviceId) {
53833
+ throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, "owner-driven sendDm requires peerDeviceId");
53834
+ }
53835
+ const contact = d.getContact(args.peerDeviceId);
53836
+ if (!contact) {
53837
+ throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `unknown contact: ${args.peerDeviceId}`);
53838
+ }
53839
+ const fwd = await d.forwardInboxPostToPeer({
53840
+ contact: { remoteUrl: contact.remoteUrl, connectToken: contact.connectToken },
53841
+ id,
53842
+ text: args.text,
53843
+ createdAt,
53844
+ origin
53845
+ });
53846
+ if (!fwd.ok) {
53847
+ throw new ClawdError(ERROR_CODES.INTERNAL, `deliver to peer failed: ${fwd.error ?? "unknown"}`);
53848
+ }
53849
+ const message = manager.postMessage({
53850
+ peerDeviceId: args.peerDeviceId,
53851
+ senderDeviceId: d.ownerPrincipalId,
53852
+ text: args.text,
53853
+ id,
53854
+ createdAt,
53855
+ origin
53856
+ });
53857
+ return { response: { type: "inbox:sendDm:ok", message } };
53858
+ };
53755
53859
  return {
53756
53860
  "inbox:postMessage": postMessage,
53861
+ "inbox:sendDm": sendDm,
53757
53862
  "inbox:list": list,
53758
53863
  "inbox:markRead": markRead
53759
53864
  };
@@ -53980,7 +54085,7 @@ function buildDeviceHandlers(deps) {
53980
54085
  }
53981
54086
 
53982
54087
  // src/handlers/meta.ts
53983
- var import_node_os17 = __toESM(require("os"), 1);
54088
+ var import_node_os16 = __toESM(require("os"), 1);
53984
54089
  init_protocol();
53985
54090
 
53986
54091
  // src/version.ts
@@ -54012,7 +54117,7 @@ function buildReadyFrame(deps, client) {
54012
54117
  return {
54013
54118
  version,
54014
54119
  protocolVersion: PROTOCOL_VERSION,
54015
- hostname: import_node_os17.default.hostname(),
54120
+ hostname: import_node_os16.default.hostname(),
54016
54121
  os: process.platform,
54017
54122
  tools,
54018
54123
  runningSessions: info.runningSessions,
@@ -54382,15 +54487,15 @@ function computePublishCheck(args) {
54382
54487
  // src/extension/install-flow.ts
54383
54488
  var import_promises6 = __toESM(require("fs/promises"), 1);
54384
54489
  var import_node_path43 = __toESM(require("path"), 1);
54385
- var import_node_os19 = __toESM(require("os"), 1);
54490
+ var import_node_os18 = __toESM(require("os"), 1);
54386
54491
  var import_node_crypto14 = __toESM(require("crypto"), 1);
54387
54492
  var import_jszip3 = __toESM(require_lib3(), 1);
54388
54493
 
54389
54494
  // src/extension/paths.ts
54390
- var import_node_os18 = __toESM(require("os"), 1);
54495
+ var import_node_os17 = __toESM(require("os"), 1);
54391
54496
  var import_node_path42 = __toESM(require("path"), 1);
54392
54497
  function clawdHomeRoot(override) {
54393
- return override ?? process.env.CLAWD_HOME ?? import_node_path42.default.join(import_node_os18.default.homedir(), ".clawd");
54498
+ return override ?? process.env.CLAWD_HOME ?? import_node_path42.default.join(import_node_os17.default.homedir(), ".clawd");
54394
54499
  }
54395
54500
  function extensionsRoot(override) {
54396
54501
  return import_node_path42.default.join(clawdHomeRoot(override), "extensions");
@@ -54472,7 +54577,7 @@ async function installFromChannel(args, deps) {
54472
54577
  );
54473
54578
  }
54474
54579
  const stage = await import_promises6.default.mkdtemp(
54475
- import_node_path43.default.join(import_node_os19.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
54580
+ import_node_path43.default.join(import_node_os18.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
54476
54581
  );
54477
54582
  try {
54478
54583
  for (const [name, entry] of Object.entries(zip.files)) {
@@ -54503,7 +54608,7 @@ async function installFromChannel(args, deps) {
54503
54608
  // src/extension/update-flow.ts
54504
54609
  var import_promises7 = __toESM(require("fs/promises"), 1);
54505
54610
  var import_node_path44 = __toESM(require("path"), 1);
54506
- var import_node_os20 = __toESM(require("os"), 1);
54611
+ var import_node_os19 = __toESM(require("os"), 1);
54507
54612
  var import_node_crypto15 = __toESM(require("crypto"), 1);
54508
54613
  var import_jszip4 = __toESM(require_lib3(), 1);
54509
54614
  var UpdateError = class extends Error {
@@ -54591,7 +54696,7 @@ async function updateFromChannel(args, deps) {
54591
54696
  await import_promises7.default.rm(prevDir, { recursive: true, force: true });
54592
54697
  await import_promises7.default.rename(liveDir, prevDir);
54593
54698
  const stage = await import_promises7.default.mkdtemp(
54594
- import_node_path44.default.join(import_node_os20.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
54699
+ import_node_path44.default.join(import_node_os19.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
54595
54700
  );
54596
54701
  try {
54597
54702
  for (const [name, entry] of Object.entries(zip.files)) {
@@ -54973,7 +55078,7 @@ function buildExtensionHandlers(deps) {
54973
55078
  }
54974
55079
 
54975
55080
  // src/app-builder/project-store.ts
54976
- var import_node_fs38 = require("fs");
55081
+ var import_node_fs39 = require("fs");
54977
55082
  var import_node_child_process11 = require("child_process");
54978
55083
  var import_node_path46 = require("path");
54979
55084
  init_protocol();
@@ -55001,7 +55106,7 @@ var ProjectStore = class {
55001
55106
  async list() {
55002
55107
  let entries;
55003
55108
  try {
55004
- entries = await import_node_fs38.promises.readdir(this.projectsRoot());
55109
+ entries = await import_node_fs39.promises.readdir(this.projectsRoot());
55005
55110
  } catch (err) {
55006
55111
  if (err.code === "ENOENT") return [];
55007
55112
  throw err;
@@ -55009,7 +55114,7 @@ var ProjectStore = class {
55009
55114
  const out = [];
55010
55115
  for (const name of entries) {
55011
55116
  try {
55012
- const raw = await import_node_fs38.promises.readFile(this.metaPath(name), "utf8");
55117
+ const raw = await import_node_fs39.promises.readFile(this.metaPath(name), "utf8");
55013
55118
  const json = JSON.parse(raw);
55014
55119
  let migrated = false;
55015
55120
  if (typeof json.devCommand !== "string" || json.devCommand.length === 0) {
@@ -55020,7 +55125,7 @@ var ProjectStore = class {
55020
55125
  if (parsed.success) {
55021
55126
  out.push(parsed.data);
55022
55127
  if (migrated) {
55023
- void import_node_fs38.promises.writeFile(this.metaPath(name), JSON.stringify(parsed.data, null, 2) + "\n", "utf8").catch(() => {
55128
+ void import_node_fs39.promises.writeFile(this.metaPath(name), JSON.stringify(parsed.data, null, 2) + "\n", "utf8").catch(() => {
55024
55129
  });
55025
55130
  }
55026
55131
  }
@@ -55064,8 +55169,8 @@ var ProjectStore = class {
55064
55169
  throw new Error(`invalid name "${name}": ${validated.error.message}`);
55065
55170
  }
55066
55171
  const dir = this.projectDir(name);
55067
- await import_node_fs38.promises.mkdir(dir, { recursive: true });
55068
- await import_node_fs38.promises.writeFile(this.metaPath(name), JSON.stringify(meta, null, 2) + "\n", "utf8");
55172
+ await import_node_fs39.promises.mkdir(dir, { recursive: true });
55173
+ await import_node_fs39.promises.writeFile(this.metaPath(name), JSON.stringify(meta, null, 2) + "\n", "utf8");
55069
55174
  return meta;
55070
55175
  }
55071
55176
  /**
@@ -55108,7 +55213,7 @@ var ProjectStore = class {
55108
55213
  }
55109
55214
  async delete(name) {
55110
55215
  const dir = this.projectDir(name);
55111
- await import_node_fs38.promises.rm(dir, { recursive: true, force: true });
55216
+ await import_node_fs39.promises.rm(dir, { recursive: true, force: true });
55112
55217
  }
55113
55218
  async updatePort(name, newPort) {
55114
55219
  if (newPort < PROJECT_PORT_MIN || newPort > PROJECT_PORT_MAX) {
@@ -55124,7 +55229,7 @@ var ProjectStore = class {
55124
55229
  throw new Error(`port ${newPort} already used / \u5DF2\u88AB project "${conflict.name}" \u5360\u7528`);
55125
55230
  }
55126
55231
  const updated = { ...target, port: newPort };
55127
- await import_node_fs38.promises.writeFile(this.metaPath(name), JSON.stringify(updated, null, 2) + "\n", "utf8");
55232
+ await import_node_fs39.promises.writeFile(this.metaPath(name), JSON.stringify(updated, null, 2) + "\n", "utf8");
55128
55233
  return updated;
55129
55234
  }
55130
55235
  /**
@@ -55141,7 +55246,7 @@ var ProjectStore = class {
55141
55246
  if (!validated.success) {
55142
55247
  throw new Error(`invalid prodUrl "${url}": ${validated.error.message}`);
55143
55248
  }
55144
- await import_node_fs38.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
55249
+ await import_node_fs39.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
55145
55250
  return validated.data;
55146
55251
  }
55147
55252
  /**
@@ -55162,7 +55267,7 @@ var ProjectStore = class {
55162
55267
  if (!validated.success) {
55163
55268
  throw new Error(`invalid publishJob: ${validated.error.message}`);
55164
55269
  }
55165
- await import_node_fs38.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
55270
+ await import_node_fs39.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
55166
55271
  return validated.data;
55167
55272
  }
55168
55273
  /** 清掉 .clawd-project.json.publishJob 字段。其他字段保持原样。 */
@@ -55177,7 +55282,7 @@ var ProjectStore = class {
55177
55282
  if (!validated.success) {
55178
55283
  throw new Error(`failed to clear publishJob: ${validated.error.message}`);
55179
55284
  }
55180
- await import_node_fs38.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
55285
+ await import_node_fs39.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
55181
55286
  return validated.data;
55182
55287
  }
55183
55288
  };
@@ -55298,7 +55403,7 @@ var PublishJobRegistry = class {
55298
55403
 
55299
55404
  // src/app-builder/publish-job-runner.ts
55300
55405
  var import_node_child_process13 = require("child_process");
55301
- var import_node_fs39 = require("fs");
55406
+ var import_node_fs40 = require("fs");
55302
55407
  var import_node_path47 = require("path");
55303
55408
 
55304
55409
  // src/app-builder/publish-stage-parser.ts
@@ -55334,7 +55439,7 @@ async function startPublishJob(deps, args) {
55334
55439
  const logPath = (0, import_node_path47.join)(projDir, ".publish.log");
55335
55440
  let logStream = null;
55336
55441
  try {
55337
- logStream = (0, import_node_fs39.createWriteStream)(logPath, { flags: "w" });
55442
+ logStream = (0, import_node_fs40.createWriteStream)(logPath, { flags: "w" });
55338
55443
  } catch {
55339
55444
  logStream = null;
55340
55445
  }
@@ -55592,7 +55697,7 @@ async function recoverInterruptedJobs(deps) {
55592
55697
  // src/handlers/app-builder.ts
55593
55698
  init_protocol();
55594
55699
  var import_node_path48 = require("path");
55595
- var import_node_fs40 = require("fs");
55700
+ var import_node_fs41 = require("fs");
55596
55701
  var APP_BUILDER_PERSONAS = ["persona-app-builder", "persona-dataclaw-builder"];
55597
55702
  var DEV_SERVER_READY_TIMEOUT_MS = 3e4;
55598
55703
  async function recoverInterruptedPublishJobs(store, logger) {
@@ -55673,7 +55778,7 @@ function buildAppBuilderHandlers(deps) {
55673
55778
  async function listAllUsersProjects() {
55674
55779
  if (!deps.usersRoot || !deps.getStore) return [];
55675
55780
  const getStore = deps.getStore;
55676
- const userIds = await import_node_fs40.promises.readdir(deps.usersRoot).catch(() => []);
55781
+ const userIds = await import_node_fs41.promises.readdir(deps.usersRoot).catch(() => []);
55677
55782
  const perUser = await Promise.all(
55678
55783
  userIds.map((uid) => getStore(uid).list().catch(() => []))
55679
55784
  );
@@ -56224,6 +56329,7 @@ async function uninstall(deps) {
56224
56329
  }
56225
56330
 
56226
56331
  // src/handlers/index.ts
56332
+ var import_node_crypto17 = require("crypto");
56227
56333
  function buildMethodHandlers(deps) {
56228
56334
  return {
56229
56335
  ...buildSessionHandlers({
@@ -56248,7 +56354,18 @@ function buildMethodHandlers(deps) {
56248
56354
  manager: deps.capabilityManager
56249
56355
  }),
56250
56356
  ...buildInboxHandlers({
56251
- manager: deps.inboxManager
56357
+ manager: deps.inboxManager,
56358
+ sendDmDeps: {
56359
+ ownerPrincipalId: deps.ownerPrincipalId,
56360
+ getSessionScope: deps.getSessionScope,
56361
+ getContact: (deviceId) => {
56362
+ const c = deps.contactStore.get(deviceId);
56363
+ return c ? { deviceId: c.deviceId, remoteUrl: c.remoteUrl, connectToken: c.connectToken } : null;
56364
+ },
56365
+ genId: () => (0, import_node_crypto17.randomUUID)(),
56366
+ now: () => Date.now(),
56367
+ forwardInboxPostToPeer
56368
+ }
56252
56369
  }),
56253
56370
  ...buildContactHandlers({
56254
56371
  store: deps.contactStore,
@@ -57136,7 +57253,7 @@ async function startDaemon(config) {
57136
57253
  },
57137
57254
  source: "daemon",
57138
57255
  sampling: logShippingCfg.sampling,
57139
- homeDir: import_node_os21.default.homedir()
57256
+ homeDir: import_node_os20.default.homedir()
57140
57257
  });
57141
57258
  const logger = createLogger({
57142
57259
  level: config.logLevel,
@@ -57308,7 +57425,7 @@ async function startDaemon(config) {
57308
57425
  import_node_path54.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
57309
57426
  // dev tsx src/index → ../dist/dispatch/mcp-server.cjs
57310
57427
  ];
57311
- const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs41.default.existsSync(p2));
57428
+ const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs42.default.existsSync(p2));
57312
57429
  let dispatchMcpConfigPath2;
57313
57430
  if (dispatchServerScriptPath) {
57314
57431
  const dispatchLogPath = import_node_path54.default.join(config.dataDir, "dispatch-mcp-server.log");
@@ -57331,7 +57448,7 @@ async function startDaemon(config) {
57331
57448
  import_node_path54.default.join(here, "ticket", "mcp-server.cjs"),
57332
57449
  import_node_path54.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
57333
57450
  ];
57334
- const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs41.default.existsSync(p2));
57451
+ const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs42.default.existsSync(p2));
57335
57452
  const ticketOwnerUnionId = feishuIdentity?.identity.unionId ?? "";
57336
57453
  const ticketOwnerName = feishuIdentity?.identity.displayName ?? "";
57337
57454
  let ticketMcpConfigPath2;
@@ -57360,7 +57477,7 @@ async function startDaemon(config) {
57360
57477
  import_node_path54.default.join(here, "shift", "mcp-server.cjs"),
57361
57478
  import_node_path54.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
57362
57479
  ];
57363
- const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs41.default.existsSync(p2));
57480
+ const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs42.default.existsSync(p2));
57364
57481
  let shiftMcpConfigPath2;
57365
57482
  if (shiftServerScriptPath) {
57366
57483
  const shiftLogPath = import_node_path54.default.join(config.dataDir, "shift-mcp-server.log");
@@ -57380,6 +57497,27 @@ async function startDaemon(config) {
57380
57497
  { tried: shiftServerCandidates }
57381
57498
  );
57382
57499
  }
57500
+ const inboxServerCandidates = [
57501
+ import_node_path54.default.join(here, "inbox", "mcp-server.cjs"),
57502
+ import_node_path54.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
57503
+ ];
57504
+ const inboxServerScriptPath = inboxServerCandidates.find((p2) => import_node_fs42.default.existsSync(p2));
57505
+ let inboxMcpConfigPath2;
57506
+ if (inboxServerScriptPath) {
57507
+ inboxMcpConfigPath2 = await writeInboxMcpConfig({
57508
+ dataDir: config.dataDir,
57509
+ serverScriptPath: inboxServerScriptPath
57510
+ });
57511
+ logger.info("inbox.mcp.json written", {
57512
+ path: inboxMcpConfigPath2,
57513
+ server: inboxServerScriptPath
57514
+ });
57515
+ } else {
57516
+ logger.warn(
57517
+ "inbox-mcp-server.cjs not found; sendDm MCP tool disabled (dev tsx \u6A21\u5F0F\u4E0B\u9700\u5148\u8DD1\u8FC7 build)",
57518
+ { tried: inboxServerCandidates }
57519
+ );
57520
+ }
57383
57521
  const shiftStore = createShiftStore({
57384
57522
  filePath: import_node_path54.default.join(config.dataDir, "shift.json"),
57385
57523
  ownerIdProvider: () => ownerPrincipalId,
@@ -57421,6 +57559,8 @@ async function startDaemon(config) {
57421
57559
  // shift v1:所有 persona session 都挂 shift.mcp.json(不做 persona gating)。
57422
57560
  // 缺省 = shift-mcp-server.cjs 没 build 出来,cc 看不到 shift tool 但 scheduler 仍跑。
57423
57561
  shiftMcpConfigPath: shiftMcpConfigPath2,
57562
+ // sendDm MCP tool:所有 persona session 都挂 inbox.mcp.json(无 gating)。
57563
+ inboxMcpConfigPath: inboxMcpConfigPath2,
57424
57564
  broadcastFrame: (frame, target) => {
57425
57565
  if (target === "all") {
57426
57566
  transport?.broadcastAll(frame);
@@ -57443,7 +57583,7 @@ async function startDaemon(config) {
57443
57583
  const absPath = import_node_path54.default.isAbsolute(input.relPath) ? input.relPath : import_node_path54.default.join(input.cwd, input.relPath);
57444
57584
  let size = 0;
57445
57585
  try {
57446
- size = import_node_fs41.default.statSync(absPath).size;
57586
+ size = import_node_fs42.default.statSync(absPath).size;
57447
57587
  } catch (err) {
57448
57588
  logger.warn("attachment.onFileEdit stat failed", {
57449
57589
  sessionId: input.sessionId,
@@ -57665,6 +57805,8 @@ async function startDaemon(config) {
57665
57805
  inboxStore,
57666
57806
  // 联系人列表 store(device:connect / 自动反向落同一 store)
57667
57807
  contactStore,
57808
+ // inbox:sendDm 用:sessionId → session 出身(复用 attachment 同款 findOwnedSessionScope)
57809
+ getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
57668
57810
  // contact:removed broadcast;复用 capability:tokenIssued 同款通路
57669
57811
  broadcastToOwners: (frame) => wsServer?.broadcastToOwners(frame),
57670
57812
  // extension runtime (v1: local-mode only). Instance owned by daemon top
@@ -57800,7 +57942,7 @@ async function startDaemon(config) {
57800
57942
  let sourceJsonlPath = "(no transcript yet \u2014 operate from the task description alone)";
57801
57943
  if (sourceFile && sourceFile.toolSessionId) {
57802
57944
  sourceJsonlPath = import_node_path54.default.join(
57803
- import_node_os21.default.homedir(),
57945
+ import_node_os20.default.homedir(),
57804
57946
  ".claude",
57805
57947
  "projects",
57806
57948
  cwdToHashDir(sourceFile.cwd),
@@ -58114,7 +58256,7 @@ ${bar}
58114
58256
  `);
58115
58257
  try {
58116
58258
  const connectPath = import_node_path54.default.join(config.dataDir, "connect.txt");
58117
- import_node_fs41.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
58259
+ import_node_fs42.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
58118
58260
  } catch {
58119
58261
  }
58120
58262
  } catch (err) {
@@ -58188,7 +58330,7 @@ ${bar}
58188
58330
  function migrateDropPersonsDir(dataDir) {
58189
58331
  const dir = import_node_path54.default.join(dataDir, "persons");
58190
58332
  try {
58191
- import_node_fs41.default.rmSync(dir, { recursive: true, force: true });
58333
+ import_node_fs42.default.rmSync(dir, { recursive: true, force: true });
58192
58334
  } catch {
58193
58335
  }
58194
58336
  }