@clawos-dev/clawd 0.2.190 → 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);
@@ -12399,9 +12391,8 @@ var init_claude = __esm({
12399
12391
  };
12400
12392
  CLAUDE_MODELS = [
12401
12393
  { id: "", label: "Default", description: "CLI default model", contextWindowSize: 2e5, default: true },
12402
- { id: "opus", label: "Opus", description: "Most capable", contextWindowSize: 1e6 },
12403
- { id: "fable", label: "Fable", contextWindowSize: 2e5 },
12404
12394
  { id: "sonnet", label: "Sonnet", description: "Fast, balanced", contextWindowSize: 2e5 },
12395
+ { id: "opus", label: "Opus", description: "Most capable", contextWindowSize: 1e6 },
12405
12396
  { id: "haiku", label: "Haiku", description: "Fastest, lightest", contextWindowSize: 2e5 }
12406
12397
  ];
12407
12398
  CLAUDE_PERMISSION_MODES = [
@@ -40113,8 +40104,8 @@ function startRunCaseRecorder(opts) {
40113
40104
  });
40114
40105
  const ensureStream = () => {
40115
40106
  if (stream) return stream;
40116
- import_node_fs42.default.mkdirSync(dir, { recursive: true });
40117
- 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" });
40118
40109
  stream.on("close", () => closedResolve());
40119
40110
  return stream;
40120
40111
  };
@@ -40139,11 +40130,11 @@ function startRunCaseRecorder(opts) {
40139
40130
  };
40140
40131
  return { tap, close, closed };
40141
40132
  }
40142
- var import_node_fs42, import_node_path55;
40133
+ var import_node_fs43, import_node_path55;
40143
40134
  var init_recorder = __esm({
40144
40135
  "src/run-case/recorder.ts"() {
40145
40136
  "use strict";
40146
- import_node_fs42 = __toESM(require("fs"), 1);
40137
+ import_node_fs43 = __toESM(require("fs"), 1);
40147
40138
  import_node_path55 = __toESM(require("path"), 1);
40148
40139
  }
40149
40140
  });
@@ -40187,7 +40178,7 @@ var init_wire = __esm({
40187
40178
  // src/run-case/controller.ts
40188
40179
  async function runController(opts) {
40189
40180
  const now = opts.now ?? Date.now;
40190
- 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-"));
40191
40182
  const ownsCwd = opts.cwd === void 0;
40192
40183
  const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
40193
40184
  const spawnCtx = { cwd };
@@ -40348,18 +40339,18 @@ async function runController(opts) {
40348
40339
  if (sigintHandler) process.off("SIGINT", sigintHandler);
40349
40340
  if (ownsCwd) {
40350
40341
  try {
40351
- (0, import_node_fs43.rmSync)(cwd, { recursive: true, force: true });
40342
+ (0, import_node_fs44.rmSync)(cwd, { recursive: true, force: true });
40352
40343
  } catch {
40353
40344
  }
40354
40345
  }
40355
40346
  return exitCode ?? 0;
40356
40347
  }
40357
- var import_node_fs43, import_node_os22, import_node_path56;
40348
+ var import_node_fs44, import_node_os21, import_node_path56;
40358
40349
  var init_controller = __esm({
40359
40350
  "src/run-case/controller.ts"() {
40360
40351
  "use strict";
40361
- import_node_fs43 = require("fs");
40362
- import_node_os22 = __toESM(require("os"), 1);
40352
+ import_node_fs44 = require("fs");
40353
+ import_node_os21 = __toESM(require("os"), 1);
40363
40354
  import_node_path56 = __toESM(require("path"), 1);
40364
40355
  init_claude();
40365
40356
  init_stdout_splitter();
@@ -40623,8 +40614,8 @@ Env (advanced):
40623
40614
 
40624
40615
  // src/index.ts
40625
40616
  var import_node_path54 = __toESM(require("path"), 1);
40626
- var import_node_fs41 = __toESM(require("fs"), 1);
40627
- 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);
40628
40619
 
40629
40620
  // ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/stringify.js
40630
40621
  var byteToHex = [];
@@ -41241,9 +41232,9 @@ var SessionStoreFactory = class {
41241
41232
  };
41242
41233
 
41243
41234
  // src/session/manager.ts
41244
- var import_node_fs7 = __toESM(require("fs"), 1);
41245
- var import_node_path8 = __toESM(require("path"), 1);
41246
- 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);
41247
41238
  init_protocol();
41248
41239
 
41249
41240
  // src/tools/guest-settings.ts
@@ -41341,10 +41332,6 @@ function escapeAttr(v2) {
41341
41332
  return v2.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
41342
41333
  }
41343
41334
 
41344
- // src/session/runner.ts
41345
- var import_node_os4 = __toESM(require("os"), 1);
41346
- var import_node_path6 = __toESM(require("path"), 1);
41347
-
41348
41335
  // src/session/reducer.ts
41349
41336
  init_runtime();
41350
41337
 
@@ -41431,7 +41418,7 @@ var ATTACHMENT_SHARING_HINT = `## \u628A\u4EA7\u51FA\u6587\u4EF6\u5206\u4EAB\u7E
41431
41418
  // src/dispatch/system-prompt.ts
41432
41419
  var DISPATCH_SYSTEM_PROMPT_HINT = `## \u59D4\u6D3E\u7ED9\u53E6\u4E00\u4E2A persona\uFF08dispatch\uFF09
41433
41420
 
41434
- \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
41435
41422
 
41436
41423
  - \`targetPersona = <id>\`\uFF08@ token \u91CC\u7684 persona id\uFF09
41437
41424
  - \`prompt = \u53BB\u6389 @persona/<id> token \u7684\u7528\u6237\u539F\u6587\`
@@ -41483,7 +41470,7 @@ function cloneState(s) {
41483
41470
  pendingSend: s.pendingSend.slice()
41484
41471
  };
41485
41472
  }
41486
- var IDLE_KILL_DELAY_MS = 6e5;
41473
+ var IDLE_KILL_DELAY_MS = 6e4;
41487
41474
  function tryFlushPending(state, deps) {
41488
41475
  if (!state.readyForSend || state.pendingSend.length === 0) return [];
41489
41476
  const text = state.pendingSend.shift();
@@ -41548,6 +41535,7 @@ function buildSpawnContext(state, deps) {
41548
41535
  const ticketMcpConfigPathRaw = deps.getTicketMcpConfigPath?.() ?? null;
41549
41536
  const ticketMcpConfigPath2 = ticketMcpConfigPathRaw && file.ownerPersonaId === "persona-ticket-manager" ? ticketMcpConfigPathRaw : null;
41550
41537
  const shiftMcpConfigPath2 = deps.getShiftMcpConfigPath?.() ?? null;
41538
+ const inboxMcpConfigPath2 = deps.getInboxMcpConfigPath?.() ?? null;
41551
41539
  const ctx = {
41552
41540
  cwd: file.cwd,
41553
41541
  toolSessionId: file.toolSessionId,
@@ -41563,6 +41551,7 @@ function buildSpawnContext(state, deps) {
41563
41551
  dispatchMcpConfigPath: dispatchMcpConfigPath2 ?? void 0,
41564
41552
  ticketMcpConfigPath: ticketMcpConfigPath2 ?? void 0,
41565
41553
  shiftMcpConfigPath: shiftMcpConfigPath2 ?? void 0,
41554
+ inboxMcpConfigPath: inboxMcpConfigPath2 ?? void 0,
41566
41555
  // shift v1:把 SessionFile.ownerPersonaId 透传到 SpawnContext;buildSpawnArgs 等下游
41567
41556
  // 不直接读这个字段(只读 env),但保留显式字段方便 daemon 内部诊断/日志。
41568
41557
  personaId
@@ -42152,18 +42141,6 @@ function reduceSession(state, input, deps) {
42152
42141
  if (state.status !== "running-idle") {
42153
42142
  return { state, effects: [] };
42154
42143
  }
42155
- if (input.subagentActive) {
42156
- return {
42157
- state,
42158
- effects: [
42159
- {
42160
- kind: "schedule-idle-kill",
42161
- sessionId: state.file.sessionId,
42162
- ms: IDLE_KILL_DELAY_MS
42163
- }
42164
- ]
42165
- };
42166
- }
42167
42144
  const next = cloneState(state);
42168
42145
  next.status = "stopping";
42169
42146
  return {
@@ -42220,11 +42197,10 @@ function reduceSession(state, input, deps) {
42220
42197
  // src/session/runner.ts
42221
42198
  init_stdout_splitter();
42222
42199
  init_permission_stdio();
42223
- init_claude_history();
42224
42200
 
42225
42201
  // src/ipc-recorder.ts
42226
- var import_node_fs5 = __toESM(require("fs"), 1);
42227
- 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);
42228
42204
  function tsForFilename(ms) {
42229
42205
  return new Date(ms).toISOString().replace(/[:.]/g, "-");
42230
42206
  }
@@ -42235,8 +42211,8 @@ function startRecorder(opts) {
42235
42211
  return null;
42236
42212
  }
42237
42213
  const now = opts.now ?? Date.now;
42238
- const dir = import_node_path5.default.join(opts.dataDir, "ipc-recordings", opts.sessionId);
42239
- const filePath = import_node_path5.default.join(dir, `${tsForFilename(now())}.jsonl`);
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`);
42240
42216
  let stream = null;
42241
42217
  let closedResolve;
42242
42218
  const closed = new Promise((resolve6) => {
@@ -42245,8 +42221,8 @@ function startRecorder(opts) {
42245
42221
  let exited = false;
42246
42222
  const ensureStream = () => {
42247
42223
  if (stream) return stream;
42248
- import_node_fs5.default.mkdirSync(dir, { recursive: true });
42249
- 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" });
42250
42226
  stream.on("close", () => closedResolve());
42251
42227
  return stream;
42252
42228
  };
@@ -42291,7 +42267,6 @@ function encodeAllowWithInputControlResponse(requestId, updatedInput) {
42291
42267
  return JSON.stringify(payload) + "\n";
42292
42268
  }
42293
42269
  var DEFAULT_WAIT_STOP_TIMEOUT_MS = 3e3;
42294
- var SUBAGENT_ACTIVE_WINDOW_MS = 3e5;
42295
42270
  var SessionRunner = class {
42296
42271
  constructor(initial, hooks) {
42297
42272
  this.hooks = hooks;
@@ -42349,6 +42324,7 @@ var SessionRunner = class {
42349
42324
  // 见 reducer.buildSpawnContext 注 CLAWD_DISPATCH_ID env / 派生 SpawnContext.dispatchMcpConfigPath
42350
42325
  getDispatchMcpConfigPath: this.hooks.getDispatchMcpConfigPath,
42351
42326
  getShiftMcpConfigPath: this.hooks.getShiftMcpConfigPath,
42327
+ getInboxMcpConfigPath: this.hooks.getInboxMcpConfigPath,
42352
42328
  // Ticket MCP:透传 ticket.mcp.json 路径闭包(reducer 内做 persona-ticket-manager gating)
42353
42329
  getTicketMcpConfigPath: this.hooks.getTicketMcpConfigPath,
42354
42330
  lookupDispatchByBSessionId: this.hooks.lookupDispatchByBSessionId,
@@ -42603,7 +42579,7 @@ var SessionRunner = class {
42603
42579
  if (existing) clearTimeout(existing);
42604
42580
  const timer = setTimeout(() => {
42605
42581
  this.idleKillTimers.delete(effect.sessionId);
42606
- this.input({ kind: "idle-kill-fired", subagentActive: this.isSubagentActive() });
42582
+ this.input({ kind: "idle-kill-fired" });
42607
42583
  }, effect.ms);
42608
42584
  timer.unref?.();
42609
42585
  this.idleKillTimers.set(effect.sessionId, timer);
@@ -42619,18 +42595,6 @@ var SessionRunner = class {
42619
42595
  }
42620
42596
  }
42621
42597
  }
42622
- // idle-kill 到点判定:本 session 的 subagents/ 里是否还有 agent-*.jsonl 在近期写盘。
42623
- // 新鲜(近 SUBAGENT_ACTIVE_WINDOW_MS 内有写)= 后台 subagent 还在干活 → 不该杀。
42624
- // 没有 toolSessionId(SDK 模式 CC 内生 id)/ 无目录 / 无 agent 文件 → false(照常回收)。
42625
- isSubagentActive() {
42626
- const toolSessionId = this.state.file.toolSessionId;
42627
- if (!toolSessionId) return false;
42628
- const projectsRoot = import_node_path6.default.join(this.hooks.home ?? import_node_os4.default.homedir(), ".claude", "projects");
42629
- const mtime = newestSubagentMtimeMs(projectsRoot, this.state.file.cwd, toolSessionId);
42630
- if (mtime === null) return false;
42631
- const now = (this.hooks.now ?? Date.now)();
42632
- return now - mtime < SUBAGENT_ACTIVE_WINDOW_MS;
42633
- }
42634
42598
  // 清空所有 idle-kill timer(runner dispose / proc 永久退出时调用)。
42635
42599
  // 不喂 idle-kill-fired —— dispose 路径不再翻 reducer 状态
42636
42600
  clearIdleKillTimers() {
@@ -42713,15 +42677,15 @@ function extractEditPath(input) {
42713
42677
  }
42714
42678
 
42715
42679
  // src/debug/pty-probe.ts
42716
- var import_node_fs6 = __toESM(require("fs"), 1);
42717
- 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);
42718
42682
  var PROBE_DIR = "/tmp/clawd-probe";
42719
- 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");
42720
42684
  var inited = false;
42721
42685
  function ensureDir() {
42722
42686
  if (inited) return true;
42723
42687
  try {
42724
- import_node_fs6.default.mkdirSync(PROBE_DIR, { recursive: true });
42688
+ import_node_fs5.default.mkdirSync(PROBE_DIR, { recursive: true });
42725
42689
  inited = true;
42726
42690
  return true;
42727
42691
  } catch {
@@ -42732,15 +42696,15 @@ function probeEvent(event, data = {}) {
42732
42696
  try {
42733
42697
  if (!ensureDir()) return;
42734
42698
  const line = JSON.stringify({ ts: Date.now(), event, ...data }) + "\n";
42735
- import_node_fs6.default.appendFileSync(EVENTS_FILE, line);
42699
+ import_node_fs5.default.appendFileSync(EVENTS_FILE, line);
42736
42700
  } catch {
42737
42701
  }
42738
42702
  }
42739
42703
  function probeDumpReplay(sessionId, payload) {
42740
42704
  try {
42741
42705
  if (!ensureDir()) return "";
42742
- const file = import_node_path7.default.join(PROBE_DIR, `replay-${sessionId}-${Date.now()}.ans`);
42743
- 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");
42744
42708
  return file;
42745
42709
  } catch {
42746
42710
  return "";
@@ -42847,7 +42811,7 @@ function derivePersonaSpawnCwd(file, personaRoot) {
42847
42811
  `derivePersonaSpawnCwd: personaRoot missing for owner session ${file.sessionId} (ownerPersonaId=${personaId})`
42848
42812
  );
42849
42813
  }
42850
- return import_node_path8.default.join(personaRoot, safeFileName(personaId));
42814
+ return import_node_path6.default.join(personaRoot, safeFileName(personaId));
42851
42815
  }
42852
42816
  function makeInitialState(file, subSessionMeta) {
42853
42817
  return {
@@ -42972,10 +42936,10 @@ var SessionManager = class {
42972
42936
  // <dataDir>/sessions/ 列子目录 (排除 'default').
42973
42937
  listPersonaIdsOnDisk() {
42974
42938
  if (!this.deps.dataDir) return [];
42975
- 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");
42976
42940
  let entries;
42977
42941
  try {
42978
- entries = import_node_fs7.default.readdirSync(root, { withFileTypes: true });
42942
+ entries = import_node_fs6.default.readdirSync(root, { withFileTypes: true });
42979
42943
  } catch (err) {
42980
42944
  const code = err?.code;
42981
42945
  if (code === "ENOENT") return [];
@@ -42988,7 +42952,7 @@ var SessionManager = class {
42988
42952
  // 只在 storeFactory 注入 (新布局) 下生效, 老布局无 guest 目录.
42989
42953
  listGuestCapIdsForPersona(personaId) {
42990
42954
  if (!this.deps.dataDir || !this.deps.storeFactory) return [];
42991
- const root = import_node_path8.default.join(
42955
+ const root = import_node_path6.default.join(
42992
42956
  this.deps.dataDir,
42993
42957
  "personas",
42994
42958
  personaId,
@@ -42998,7 +42962,7 @@ var SessionManager = class {
42998
42962
  );
42999
42963
  let entries;
43000
42964
  try {
43001
- entries = import_node_fs7.default.readdirSync(root, { withFileTypes: true });
42965
+ entries = import_node_fs6.default.readdirSync(root, { withFileTypes: true });
43002
42966
  } catch (err) {
43003
42967
  const code = err?.code;
43004
42968
  if (code === "ENOENT") return [];
@@ -43117,7 +43081,7 @@ var SessionManager = class {
43117
43081
  callerDisplayName
43118
43082
  );
43119
43083
  if (subSessionMeta?.userWorkDir) {
43120
- import_node_fs7.default.mkdirSync(subSessionMeta.userWorkDir, { recursive: true });
43084
+ import_node_fs6.default.mkdirSync(subSessionMeta.userWorkDir, { recursive: true });
43121
43085
  }
43122
43086
  if (scope.kind === "persona" && scope.mode === "guest") {
43123
43087
  if (!this.deps.personaRoot || !subSessionMeta?.userWorkDir) {
@@ -43128,8 +43092,8 @@ var SessionManager = class {
43128
43092
  const base = this.deps.personaStore?.readSandboxSettings(scope.personaId) ?? null;
43129
43093
  const settings = composeGuestSandbox(base, subSessionMeta.userWorkDir, file.cwd);
43130
43094
  subSessionMeta.extraSettings = JSON.stringify(settings);
43131
- const home = import_node_os5.default.homedir();
43132
- const expand = (p2) => p2 === "~" ? home : p2.startsWith("~/") ? import_node_path8.default.join(home, p2.slice(2)) : p2;
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;
43133
43097
  const codexCfg = this.deps.personaStore?.readCodexSandboxSettings(scope.personaId) ?? null;
43134
43098
  subSessionMeta.codexSandbox = {
43135
43099
  writableRoots: [subSessionMeta.userWorkDir, ...(codexCfg?.writableRoots ?? []).map(expand)],
@@ -43163,6 +43127,7 @@ var SessionManager = class {
43163
43127
  getDispatchMcpConfigPath: this.deps.dispatchMcpConfigPath ? () => this.deps.dispatchMcpConfigPath ?? null : void 0,
43164
43128
  getTicketMcpConfigPath: this.deps.ticketMcpConfigPath ? () => this.deps.ticketMcpConfigPath ?? null : void 0,
43165
43129
  getShiftMcpConfigPath: this.deps.shiftMcpConfigPath ? () => this.deps.shiftMcpConfigPath ?? null : void 0,
43130
+ getInboxMcpConfigPath: this.deps.inboxMcpConfigPath ? () => this.deps.inboxMcpConfigPath ?? null : void 0,
43166
43131
  lookupDispatchByBSessionId: this.deps.personaDispatchManager ? (bSid) => this.deps.personaDispatchManager?.lookupDispatchByBSessionId(bSid) : void 0,
43167
43132
  // file-sharing (spec §6 PR 3):闭包 scope + sessionId,runner 只暴露 tool/relPath/cwd
43168
43133
  onFileEdit: attachmentGroup ? (input) => attachmentGroup.onFileEdit({
@@ -43281,7 +43246,7 @@ var SessionManager = class {
43281
43246
  throw new ClawdError(ERROR_CODES.INVALID_CWD, "cwd required when ownerPersonaId is absent");
43282
43247
  }
43283
43248
  try {
43284
- const stat = import_node_fs7.default.statSync(cwd);
43249
+ const stat = import_node_fs6.default.statSync(cwd);
43285
43250
  if (!stat.isDirectory()) throw new Error("not dir");
43286
43251
  } catch {
43287
43252
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${cwd}`);
@@ -43812,7 +43777,7 @@ var SessionManager = class {
43812
43777
  */
43813
43778
  createForScope(args) {
43814
43779
  try {
43815
- const stat = import_node_fs7.default.statSync(args.cwd);
43780
+ const stat = import_node_fs6.default.statSync(args.cwd);
43816
43781
  if (!stat.isDirectory()) throw new Error("not dir");
43817
43782
  } catch {
43818
43783
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${args.cwd}`);
@@ -44028,7 +43993,7 @@ var SessionManager = class {
44028
43993
  personaId: args.targetPersona,
44029
43994
  mode: "owner"
44030
43995
  };
44031
- 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));
44032
43997
  const now = (/* @__PURE__ */ new Date()).toISOString();
44033
43998
  const file = {
44034
43999
  sessionId,
@@ -44093,7 +44058,7 @@ var SessionManager = class {
44093
44058
  personaId: args.targetPersona,
44094
44059
  mode: "owner"
44095
44060
  };
44096
- 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));
44097
44062
  const now = (/* @__PURE__ */ new Date()).toISOString();
44098
44063
  const file = {
44099
44064
  sessionId,
@@ -44575,28 +44540,28 @@ var SessionManager = class {
44575
44540
  };
44576
44541
 
44577
44542
  // src/persona/store.ts
44578
- var fs8 = __toESM(require("fs"), 1);
44579
- var path11 = __toESM(require("path"), 1);
44543
+ var fs7 = __toESM(require("fs"), 1);
44544
+ var path9 = __toESM(require("path"), 1);
44580
44545
  init_protocol();
44581
44546
  var PersonaStore = class {
44582
44547
  constructor(root) {
44583
44548
  this.root = root;
44584
- fs8.mkdirSync(root, { recursive: true });
44549
+ fs7.mkdirSync(root, { recursive: true });
44585
44550
  }
44586
44551
  root;
44587
44552
  personaDir(personaId) {
44588
- return path11.join(this.root, safeFileName(personaId));
44553
+ return path9.join(this.root, safeFileName(personaId));
44589
44554
  }
44590
44555
  metaPath(personaId) {
44591
- return path11.join(this.personaDir(personaId), ".clawd", "persona.json");
44556
+ return path9.join(this.personaDir(personaId), ".clawd", "persona.json");
44592
44557
  }
44593
44558
  claudeMdPath(personaId) {
44594
- return path11.join(this.personaDir(personaId), "CLAUDE.md");
44559
+ return path9.join(this.personaDir(personaId), "CLAUDE.md");
44595
44560
  }
44596
44561
  // codex 原生读 cwd 的 AGENTS.md。人格双写镜像:claude 读 CLAUDE.md、codex 读 AGENTS.md,
44597
44562
  // 两份内容恒一致,persona 切 tool 零迁移。
44598
44563
  agentsMdPath(personaId) {
44599
- return path11.join(this.personaDir(personaId), "AGENTS.md");
44564
+ return path9.join(this.personaDir(personaId), "AGENTS.md");
44600
44565
  }
44601
44566
  /**
44602
44567
  * persona 级 sandbox base 落盘路径 —— 故意放 `.clawd/` 而非 `.claude/`,让 CC 的 project
@@ -44605,11 +44570,11 @@ var PersonaStore = class {
44605
44570
  * spawn 前 per-guest 动态拼到各自 session 目录的那份(base + 强制底座 + 本 guest userWorkDir carve)。
44606
44571
  */
44607
44572
  sandboxSettingsPath(personaId) {
44608
- return path11.join(this.personaDir(personaId), ".clawd", "sandbox-settings.json");
44573
+ return path9.join(this.personaDir(personaId), ".clawd", "sandbox-settings.json");
44609
44574
  }
44610
44575
  write(persona, personality) {
44611
44576
  const dir = this.personaDir(persona.personaId);
44612
- fs8.mkdirSync(path11.join(dir, ".clawd"), { recursive: true });
44577
+ fs7.mkdirSync(path9.join(dir, ".clawd"), { recursive: true });
44613
44578
  this.atomicWrite(this.claudeMdPath(persona.personaId), personality);
44614
44579
  this.atomicWrite(this.agentsMdPath(persona.personaId), personality);
44615
44580
  this.writeSandboxSettings(persona.personaId, buildGuestSettingsV1());
@@ -44628,9 +44593,9 @@ var PersonaStore = class {
44628
44593
  ensureAgentsMirror(personaId) {
44629
44594
  const claudeMd = this.claudeMdPath(personaId);
44630
44595
  const agentsMd = this.agentsMdPath(personaId);
44631
- if (!fs8.existsSync(claudeMd)) return false;
44632
- if (fs8.existsSync(agentsMd)) return false;
44633
- 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"));
44634
44599
  return true;
44635
44600
  }
44636
44601
  /**
@@ -44654,22 +44619,22 @@ var PersonaStore = class {
44654
44619
  return { ...s, permissions: { ...s.permissions ?? {}, deny: [...prev, rule] } };
44655
44620
  }
44656
44621
  codexSandboxSettingsPath(personaId) {
44657
- return path11.join(this.personaDir(personaId), ".clawd", "codex-sandbox.json");
44622
+ return path9.join(this.personaDir(personaId), ".clawd", "codex-sandbox.json");
44658
44623
  }
44659
44624
  /** 读 codex-sandbox.json;不存在/损坏 → null。 */
44660
44625
  readCodexSandboxSettings(personaId) {
44661
44626
  const p2 = this.codexSandboxSettingsPath(personaId);
44662
- if (!fs8.existsSync(p2)) return null;
44627
+ if (!fs7.existsSync(p2)) return null;
44663
44628
  try {
44664
- return CodexSandboxSettingsSchema.parse(JSON.parse(fs8.readFileSync(p2, "utf8")));
44629
+ return CodexSandboxSettingsSchema.parse(JSON.parse(fs7.readFileSync(p2, "utf8")));
44665
44630
  } catch {
44666
44631
  return null;
44667
44632
  }
44668
44633
  }
44669
44634
  /** 覆盖写 codex-sandbox.json(seed/migrate 用)。 */
44670
44635
  writeCodexSandboxSettings(personaId, settings) {
44671
- const dir = path11.join(this.personaDir(personaId), ".clawd");
44672
- fs8.mkdirSync(dir, { recursive: true });
44636
+ const dir = path9.join(this.personaDir(personaId), ".clawd");
44637
+ fs7.mkdirSync(dir, { recursive: true });
44673
44638
  this.atomicWrite(this.codexSandboxSettingsPath(personaId), JSON.stringify(settings, null, 2));
44674
44639
  }
44675
44640
  writeMeta(persona) {
@@ -44677,8 +44642,8 @@ var PersonaStore = class {
44677
44642
  }
44678
44643
  read(personaId) {
44679
44644
  const p2 = this.metaPath(personaId);
44680
- if (!fs8.existsSync(p2)) return null;
44681
- const raw = JSON.parse(fs8.readFileSync(p2, "utf8"));
44645
+ if (!fs7.existsSync(p2)) return null;
44646
+ const raw = JSON.parse(fs7.readFileSync(p2, "utf8"));
44682
44647
  if (raw && typeof raw === "object" && "tokenMap" in raw) {
44683
44648
  delete raw.tokenMap;
44684
44649
  this.atomicWrite(p2, JSON.stringify(raw, null, 2));
@@ -44686,13 +44651,13 @@ var PersonaStore = class {
44686
44651
  return PersonaFileSchema.parse(raw);
44687
44652
  }
44688
44653
  has(personaId) {
44689
- return fs8.existsSync(this.metaPath(personaId));
44654
+ return fs7.existsSync(this.metaPath(personaId));
44690
44655
  }
44691
44656
  readPersonality(personaId) {
44692
44657
  const claudeMd = this.claudeMdPath(personaId);
44693
- if (fs8.existsSync(claudeMd)) return fs8.readFileSync(claudeMd, "utf8");
44658
+ if (fs7.existsSync(claudeMd)) return fs7.readFileSync(claudeMd, "utf8");
44694
44659
  const agentsMd = this.agentsMdPath(personaId);
44695
- if (fs8.existsSync(agentsMd)) return fs8.readFileSync(agentsMd, "utf8");
44660
+ if (fs7.existsSync(agentsMd)) return fs7.readFileSync(agentsMd, "utf8");
44696
44661
  return null;
44697
44662
  }
44698
44663
  /**
@@ -44701,23 +44666,23 @@ var PersonaStore = class {
44701
44666
  */
44702
44667
  readSandboxSettings(personaId) {
44703
44668
  const p2 = this.sandboxSettingsPath(personaId);
44704
- if (!fs8.existsSync(p2)) return null;
44669
+ if (!fs7.existsSync(p2)) return null;
44705
44670
  try {
44706
- return JSON.parse(fs8.readFileSync(p2, "utf8"));
44671
+ return JSON.parse(fs7.readFileSync(p2, "utf8"));
44707
44672
  } catch {
44708
44673
  return null;
44709
44674
  }
44710
44675
  }
44711
44676
  /** Persona 私有 skills 目录路径:<personaDir>/.claude/skills */
44712
44677
  skillsDir(personaId) {
44713
- return path11.join(this.personaDir(personaId), ".claude", "skills");
44678
+ return path9.join(this.personaDir(personaId), ".claude", "skills");
44714
44679
  }
44715
44680
  /**
44716
44681
  * Claude Code 项目级 settings 路径:`<personaDir>/.claude/settings.json`。
44717
44682
  * 这里只读 `enabledPlugins` 字段,由 owner 通过 CC `/plugin` 之类命令维护,daemon 不写。
44718
44683
  */
44719
44684
  claudeSettingsPath(personaId) {
44720
- return path11.join(this.personaDir(personaId), ".claude", "settings.json");
44685
+ return path9.join(this.personaDir(personaId), ".claude", "settings.json");
44721
44686
  }
44722
44687
  /**
44723
44688
  * 读取 persona 的 `.claude/settings.json` 中 `enabledPlugins` map,把 value === true
@@ -44732,10 +44697,10 @@ var PersonaStore = class {
44732
44697
  */
44733
44698
  readEnabledPlugins(personaId) {
44734
44699
  const p2 = this.claudeSettingsPath(personaId);
44735
- if (!fs8.existsSync(p2)) return [];
44700
+ if (!fs7.existsSync(p2)) return [];
44736
44701
  let raw;
44737
44702
  try {
44738
- raw = JSON.parse(fs8.readFileSync(p2, "utf8"));
44703
+ raw = JSON.parse(fs7.readFileSync(p2, "utf8"));
44739
44704
  } catch {
44740
44705
  return [];
44741
44706
  }
@@ -44749,22 +44714,22 @@ var PersonaStore = class {
44749
44714
  return out;
44750
44715
  }
44751
44716
  list() {
44752
- if (!fs8.existsSync(this.root)) return [];
44753
- return fs8.readdirSync(this.root).filter((name) => {
44754
- return fs8.existsSync(path11.join(this.root, name, ".clawd", "persona.json"));
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"));
44755
44720
  });
44756
44721
  }
44757
44722
  remove(personaId) {
44758
44723
  const dir = this.personaDir(personaId);
44759
- if (fs8.existsSync(dir)) fs8.rmSync(dir, { recursive: true, force: true });
44724
+ if (fs7.existsSync(dir)) fs7.rmSync(dir, { recursive: true, force: true });
44760
44725
  }
44761
44726
  personaDirPath(personaId) {
44762
44727
  return this.personaDir(personaId);
44763
44728
  }
44764
44729
  atomicWrite(file, content) {
44765
44730
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
44766
- fs8.writeFileSync(tmp, content, { mode: 384 });
44767
- fs8.renameSync(tmp, file);
44731
+ fs7.writeFileSync(tmp, content, { mode: 384 });
44732
+ fs7.renameSync(tmp, file);
44768
44733
  }
44769
44734
  };
44770
44735
 
@@ -44810,9 +44775,9 @@ var PersonaRegistry = class {
44810
44775
  var import_node_crypto3 = __toESM(require("crypto"), 1);
44811
44776
 
44812
44777
  // src/skills/scanner.ts
44813
- var import_node_fs8 = __toESM(require("fs"), 1);
44814
- var import_node_os6 = __toESM(require("os"), 1);
44815
- var import_node_path9 = __toESM(require("path"), 1);
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);
44816
44781
 
44817
44782
  // src/skills/frontmatter.ts
44818
44783
  var STRIP_QUOTES = /^["']|["']$/g;
@@ -44921,7 +44886,7 @@ function parseDescription(content) {
44921
44886
  }
44922
44887
  function isDirLikeSync(p2) {
44923
44888
  try {
44924
- return import_node_fs8.default.statSync(p2).isDirectory();
44889
+ return import_node_fs7.default.statSync(p2).isDirectory();
44925
44890
  } catch {
44926
44891
  return false;
44927
44892
  }
@@ -44929,19 +44894,19 @@ function isDirLikeSync(p2) {
44929
44894
  function scanSkillDir(dir, source, seen, out, pluginName) {
44930
44895
  let entries;
44931
44896
  try {
44932
- entries = import_node_fs8.default.readdirSync(dir, { withFileTypes: true });
44897
+ entries = import_node_fs7.default.readdirSync(dir, { withFileTypes: true });
44933
44898
  } catch {
44934
44899
  return;
44935
44900
  }
44936
44901
  for (const ent of entries) {
44937
- const entryPath = import_node_path9.default.join(dir, ent.name);
44902
+ const entryPath = import_node_path7.default.join(dir, ent.name);
44938
44903
  if (!ent.isDirectory() && !(ent.isSymbolicLink() && isDirLikeSync(entryPath))) continue;
44939
44904
  let content;
44940
44905
  try {
44941
- 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");
44942
44907
  } catch {
44943
44908
  try {
44944
- 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");
44945
44910
  } catch {
44946
44911
  continue;
44947
44912
  }
@@ -44965,26 +44930,26 @@ function listSkillsForDir(dir, source) {
44965
44930
  function scanCommandDir(dir, source, seen, out, pluginName) {
44966
44931
  let entries;
44967
44932
  try {
44968
- entries = import_node_fs8.default.readdirSync(dir, { withFileTypes: true });
44933
+ entries = import_node_fs7.default.readdirSync(dir, { withFileTypes: true });
44969
44934
  } catch {
44970
44935
  return;
44971
44936
  }
44972
44937
  for (const ent of entries) {
44973
- const entryPath = import_node_path9.default.join(dir, ent.name);
44938
+ const entryPath = import_node_path7.default.join(dir, ent.name);
44974
44939
  if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync(entryPath)) {
44975
44940
  const ns = ent.name;
44976
44941
  let subEntries;
44977
44942
  try {
44978
- subEntries = import_node_fs8.default.readdirSync(entryPath, { withFileTypes: true });
44943
+ subEntries = import_node_fs7.default.readdirSync(entryPath, { withFileTypes: true });
44979
44944
  } catch {
44980
44945
  continue;
44981
44946
  }
44982
44947
  for (const se of subEntries) {
44983
44948
  if (!se.name.endsWith(".md")) continue;
44984
- const sePath = import_node_path9.default.join(entryPath, se.name);
44949
+ const sePath = import_node_path7.default.join(entryPath, se.name);
44985
44950
  let content;
44986
44951
  try {
44987
- content = import_node_fs8.default.readFileSync(sePath, "utf8");
44952
+ content = import_node_fs7.default.readFileSync(sePath, "utf8");
44988
44953
  } catch {
44989
44954
  continue;
44990
44955
  }
@@ -45001,7 +44966,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
45001
44966
  } else if (ent.name.endsWith(".md")) {
45002
44967
  let content;
45003
44968
  try {
45004
- content = import_node_fs8.default.readFileSync(entryPath, "utf8");
44969
+ content = import_node_fs7.default.readFileSync(entryPath, "utf8");
45005
44970
  } catch {
45006
44971
  continue;
45007
44972
  }
@@ -45017,10 +44982,10 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
45017
44982
  }
45018
44983
  }
45019
44984
  function readInstalledPlugins(home) {
45020
- 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");
45021
44986
  let raw;
45022
44987
  try {
45023
- raw = import_node_fs8.default.readFileSync(file, "utf8");
44988
+ raw = import_node_fs7.default.readFileSync(file, "utf8");
45024
44989
  } catch {
45025
44990
  return [];
45026
44991
  }
@@ -45045,7 +45010,7 @@ var SkillsScanner = class {
45045
45010
  home;
45046
45011
  extraPluginRoots;
45047
45012
  constructor(opts = {}) {
45048
- this.home = opts.home ?? import_node_os6.default.homedir();
45013
+ this.home = opts.home ?? import_node_os4.default.homedir();
45049
45014
  this.extraPluginRoots = opts.extraPluginRoots ?? [];
45050
45015
  }
45051
45016
  /**
@@ -45068,14 +45033,14 @@ var SkillsScanner = class {
45068
45033
  });
45069
45034
  }
45070
45035
  const fsBlock = [];
45071
- scanSkillDir(import_node_path9.default.join(this.home, ".claude", "skills"), "global", seen, fsBlock);
45072
- scanCommandDir(import_node_path9.default.join(this.home, ".claude", "commands"), "global", seen, fsBlock);
45073
- scanSkillDir(import_node_path9.default.join(args.cwd, ".claude", "skills"), "project", seen, fsBlock);
45074
- scanCommandDir(import_node_path9.default.join(args.cwd, ".claude", "commands"), "project", seen, fsBlock);
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);
45075
45040
  const plugins = [...readInstalledPlugins(this.home), ...this.extraPluginRoots];
45076
45041
  for (const { name, root } of plugins) {
45077
- scanSkillDir(import_node_path9.default.join(root, "skills"), "plugin", seen, fsBlock, name);
45078
- scanCommandDir(import_node_path9.default.join(root, "commands"), "plugin", seen, fsBlock, name);
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);
45079
45044
  }
45080
45045
  fsBlock.sort((a, b2) => a.name < b2.name ? -1 : a.name > b2.name ? 1 : 0);
45081
45046
  return [...builtinBlock, ...fsBlock];
@@ -45181,8 +45146,8 @@ var PersonaManager = class {
45181
45146
  };
45182
45147
 
45183
45148
  // src/persona/seed.ts
45184
- var fs10 = __toESM(require("fs"), 1);
45185
- var path13 = __toESM(require("path"), 1);
45149
+ var fs9 = __toESM(require("fs"), 1);
45150
+ var path11 = __toESM(require("path"), 1);
45186
45151
  var import_node_url = require("url");
45187
45152
  var import_meta = {};
45188
45153
  var DEFAULT_BYPASS_PROFILE = {
@@ -45213,6 +45178,16 @@ var DEFAULT_PERSONAS = [
45213
45178
  public: false,
45214
45179
  sandboxProfile: DEFAULT_BYPASS_PROFILE
45215
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
+ },
45216
45191
  {
45217
45192
  personaId: "persona-feishu-assistant",
45218
45193
  label: "\u98DE\u4E66\u52A9\u7406",
@@ -45306,6 +45281,14 @@ var DEFAULT_PERSONAS = [
45306
45281
  public: false,
45307
45282
  sandboxProfile: DEFAULT_BYPASS_PROFILE
45308
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
+ },
45309
45292
  {
45310
45293
  // HTML PPT 制作师:把想法/文字/旧 PPT 转成单文件 HTML 演示稿
45311
45294
  // bundle 含 frontend-slides skill(MIT,Zara Zhang),daemon ship 进 .claude/skills/
@@ -45352,24 +45335,24 @@ function bundleSiblingFromArgv(argv1, sibling) {
45352
45335
  if (!argv1) return null;
45353
45336
  let real = argv1;
45354
45337
  try {
45355
- real = fs10.realpathSync(argv1);
45338
+ real = fs9.realpathSync(argv1);
45356
45339
  } catch {
45357
45340
  }
45358
- return path13.resolve(path13.dirname(real), sibling);
45341
+ return path11.resolve(path11.dirname(real), sibling);
45359
45342
  }
45360
45343
  function findDefaultsRoot(logger) {
45361
45344
  const candidates = [];
45362
45345
  try {
45363
- const here = path13.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
45364
- candidates.push(path13.resolve(here, "defaults"));
45365
- candidates.push(path13.resolve(here, "persona-defaults"));
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"));
45366
45349
  } catch {
45367
45350
  }
45368
45351
  const fromArgv = bundleSiblingFromArgv(process.argv[1], "persona-defaults");
45369
45352
  if (fromArgv) candidates.push(fromArgv);
45370
45353
  for (const c of candidates) {
45371
45354
  try {
45372
- if (fs10.statSync(c).isDirectory()) {
45355
+ if (fs9.statSync(c).isDirectory()) {
45373
45356
  logger?.info("persona.defaults-root.resolved", { root: c });
45374
45357
  return c;
45375
45358
  }
@@ -45386,8 +45369,8 @@ function seedDefaultPersonas(args) {
45386
45369
  args.logger.info("persona.seed.skip", { personaId: entry.personaId, reason: "exists" });
45387
45370
  continue;
45388
45371
  }
45389
- const bundleDir = path13.join(args.defaultsRoot, entry.personaId);
45390
- if (!fs10.existsSync(bundleDir)) {
45372
+ const bundleDir = path11.join(args.defaultsRoot, entry.personaId);
45373
+ if (!fs9.existsSync(bundleDir)) {
45391
45374
  args.logger.warn("persona.seed.skip", {
45392
45375
  personaId: entry.personaId,
45393
45376
  reason: "bundle-missing",
@@ -45395,8 +45378,8 @@ function seedDefaultPersonas(args) {
45395
45378
  });
45396
45379
  continue;
45397
45380
  }
45398
- const claudeMdPath = path13.join(bundleDir, "CLAUDE.md");
45399
- if (!fs10.existsSync(claudeMdPath)) {
45381
+ const claudeMdPath = path11.join(bundleDir, "CLAUDE.md");
45382
+ if (!fs9.existsSync(claudeMdPath)) {
45400
45383
  args.logger.warn("persona.seed.skip", {
45401
45384
  personaId: entry.personaId,
45402
45385
  reason: "no-CLAUDE.md",
@@ -45404,7 +45387,7 @@ function seedDefaultPersonas(args) {
45404
45387
  });
45405
45388
  continue;
45406
45389
  }
45407
- const personality = fs10.readFileSync(claudeMdPath, "utf8");
45390
+ const personality = fs9.readFileSync(claudeMdPath, "utf8");
45408
45391
  const now = Date.now();
45409
45392
  const persona = {
45410
45393
  personaId: entry.personaId,
@@ -45430,17 +45413,17 @@ function seedDefaultPersonas(args) {
45430
45413
  }
45431
45414
  }
45432
45415
  function skipNodeModulesUnder(srcRoot) {
45433
- 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");
45434
45417
  }
45435
45418
  function copyBundleExtras(srcDir, dstDir) {
45436
- for (const entry of fs10.readdirSync(srcDir, { withFileTypes: true })) {
45419
+ for (const entry of fs9.readdirSync(srcDir, { withFileTypes: true })) {
45437
45420
  if (entry.name === "CLAUDE.md" || entry.name === ".clawd") continue;
45438
- const srcPath = path13.join(srcDir, entry.name);
45439
- const dstPath = path13.join(dstDir, entry.name);
45421
+ const srcPath = path11.join(srcDir, entry.name);
45422
+ const dstPath = path11.join(dstDir, entry.name);
45440
45423
  if (entry.isDirectory()) {
45441
- fs10.cpSync(srcPath, dstPath, { recursive: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
45424
+ fs9.cpSync(srcPath, dstPath, { recursive: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
45442
45425
  } else if (entry.isFile()) {
45443
- fs10.copyFileSync(srcPath, dstPath);
45426
+ fs9.copyFileSync(srcPath, dstPath);
45444
45427
  }
45445
45428
  }
45446
45429
  }
@@ -45448,16 +45431,16 @@ var DAEMON_MANAGED_PATHS = ["extension-kit", "CLAUDE.md", ".mcp.json"];
45448
45431
  function refreshDaemonManagedDirs(args) {
45449
45432
  const entries = args.entries ?? DEFAULT_PERSONAS;
45450
45433
  for (const entry of entries) {
45451
- const bundleDir = path13.join(args.defaultsRoot, entry.personaId);
45452
- if (!fs10.existsSync(bundleDir)) continue;
45434
+ const bundleDir = path11.join(args.defaultsRoot, entry.personaId);
45435
+ if (!fs9.existsSync(bundleDir)) continue;
45453
45436
  const personaDir = args.store.personaDirPath(entry.personaId);
45454
- if (!fs10.existsSync(personaDir)) continue;
45437
+ if (!fs9.existsSync(personaDir)) continue;
45455
45438
  for (const relPath of DAEMON_MANAGED_PATHS) {
45456
- const srcPath = path13.join(bundleDir, relPath);
45457
- if (!fs10.existsSync(srcPath)) continue;
45458
- 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);
45459
45442
  try {
45460
- 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) });
45461
45444
  args.logger.info("persona.refresh.synced", {
45462
45445
  personaId: entry.personaId,
45463
45446
  path: relPath
@@ -45517,15 +45500,15 @@ function migrateCodexSandbox(args) {
45517
45500
  function findDeployKitRoot(logger) {
45518
45501
  const candidates = [];
45519
45502
  try {
45520
- const here = path13.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
45521
- 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"));
45522
45505
  } catch {
45523
45506
  }
45524
45507
  const fromArgv = bundleSiblingFromArgv(process.argv[1], "deploy-kit");
45525
45508
  if (fromArgv) candidates.push(fromArgv);
45526
45509
  for (const c of candidates) {
45527
45510
  try {
45528
- if (fs10.statSync(c).isDirectory()) {
45511
+ if (fs9.statSync(c).isDirectory()) {
45529
45512
  logger?.info("persona.deploy-kit-root.resolved", { root: c });
45530
45513
  return c;
45531
45514
  }
@@ -45536,8 +45519,8 @@ function findDeployKitRoot(logger) {
45536
45519
  return null;
45537
45520
  }
45538
45521
  function seedDeployKit(args) {
45539
- const dst = path13.join(args.dataDir, "deploy-kit");
45540
- fs10.cpSync(args.deployKitBundleRoot, dst, {
45522
+ const dst = path11.join(args.dataDir, "deploy-kit");
45523
+ fs9.cpSync(args.deployKitBundleRoot, dst, {
45541
45524
  recursive: true,
45542
45525
  dereference: true,
45543
45526
  force: false,
@@ -45546,35 +45529,35 @@ function seedDeployKit(args) {
45546
45529
  args.logger.info("deploy-kit.seed.done", { dst });
45547
45530
  }
45548
45531
  function refreshDeployKit(args) {
45549
- const dst = path13.join(args.dataDir, "deploy-kit");
45550
- if (!fs10.existsSync(dst)) {
45532
+ const dst = path11.join(args.dataDir, "deploy-kit");
45533
+ if (!fs9.existsSync(dst)) {
45551
45534
  seedDeployKit(args);
45552
45535
  return;
45553
45536
  }
45554
45537
  for (const sub of ["scripts", "contract"]) {
45555
- const s = path13.join(args.deployKitBundleRoot, sub);
45556
- if (fs10.existsSync(s)) {
45557
- fs10.cpSync(s, path13.join(dst, sub), { recursive: true, force: true, dereference: true });
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 });
45558
45541
  }
45559
45542
  }
45560
- const secretsSrc = path13.join(args.deployKitBundleRoot, ".secrets");
45561
- if (fs10.existsSync(secretsSrc)) {
45562
- fs10.mkdirSync(path13.join(dst, ".secrets"), { recursive: true });
45563
- for (const f of fs10.readdirSync(secretsSrc)) {
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)) {
45564
45547
  if (!f.endsWith(".example")) continue;
45565
- fs10.copyFileSync(path13.join(secretsSrc, f), path13.join(dst, ".secrets", f));
45548
+ fs9.copyFileSync(path11.join(secretsSrc, f), path11.join(dst, ".secrets", f));
45566
45549
  }
45567
45550
  }
45568
45551
  args.logger.info("deploy-kit.refresh.done", { dst });
45569
45552
  }
45570
45553
 
45571
45554
  // src/share-md-viewer/load.ts
45572
- var import_node_fs10 = __toESM(require("fs"), 1);
45573
- 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);
45574
45557
  var import_node_url2 = require("url");
45575
45558
 
45576
45559
  // src/share-md-viewer/asset-loader.ts
45577
- var import_node_fs9 = __toESM(require("fs"), 1);
45560
+ var import_node_fs8 = __toESM(require("fs"), 1);
45578
45561
  function htmlEscape(s) {
45579
45562
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
45580
45563
  }
@@ -45582,12 +45565,12 @@ function createViewerAssetLoader(opts) {
45582
45565
  let viewerTemplate;
45583
45566
  let errorTemplate;
45584
45567
  try {
45585
- viewerTemplate = import_node_fs9.default.readFileSync(opts.viewerHtmlPath, "utf8");
45568
+ viewerTemplate = import_node_fs8.default.readFileSync(opts.viewerHtmlPath, "utf8");
45586
45569
  } catch (err) {
45587
45570
  throw new Error(`viewer asset not found at ${opts.viewerHtmlPath}: ${err.message}`);
45588
45571
  }
45589
45572
  try {
45590
- errorTemplate = import_node_fs9.default.readFileSync(opts.errorHtmlPath, "utf8");
45573
+ errorTemplate = import_node_fs8.default.readFileSync(opts.errorHtmlPath, "utf8");
45591
45574
  } catch (err) {
45592
45575
  throw new Error(`viewer error asset not found at ${opts.errorHtmlPath}: ${err.message}`);
45593
45576
  }
@@ -45606,25 +45589,25 @@ var import_meta2 = {};
45606
45589
  function tryLoadViewerAssets(logger) {
45607
45590
  const candidates = [];
45608
45591
  try {
45609
- 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));
45610
45593
  candidates.push(here);
45611
- candidates.push(import_node_path10.default.resolve(here, ".."));
45612
- 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"));
45613
45596
  } catch {
45614
45597
  }
45615
45598
  if (process.argv[1]) {
45616
45599
  let real = process.argv[1];
45617
45600
  try {
45618
- real = import_node_fs10.default.realpathSync(process.argv[1]);
45601
+ real = import_node_fs9.default.realpathSync(process.argv[1]);
45619
45602
  } catch {
45620
45603
  }
45621
- candidates.push(import_node_path10.default.dirname(real));
45604
+ candidates.push(import_node_path8.default.dirname(real));
45622
45605
  }
45623
45606
  for (const root of candidates) {
45624
- const viewerHtmlPath = import_node_path10.default.join(root, "share-md-viewer.html");
45625
- const errorHtmlPath = import_node_path10.default.join(root, "share-md-viewer-error.html");
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");
45626
45609
  try {
45627
- 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()) {
45628
45611
  logger?.info("share-md-viewer.assets-root.resolved", { root });
45629
45612
  return createViewerAssetLoader({ viewerHtmlPath, errorHtmlPath });
45630
45613
  }
@@ -45639,30 +45622,30 @@ function tryLoadViewerAssets(logger) {
45639
45622
  }
45640
45623
 
45641
45624
  // src/share-ui/load.ts
45642
- var import_node_fs12 = __toESM(require("fs"), 1);
45643
- 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);
45644
45627
  var import_node_url3 = require("url");
45645
45628
 
45646
45629
  // src/share-ui/asset-loader.ts
45647
- var import_node_fs11 = __toESM(require("fs"), 1);
45648
- 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);
45649
45632
  function createShareUiAssetLoader(opts) {
45650
45633
  let indexHtml;
45651
45634
  try {
45652
- indexHtml = import_node_fs11.default.readFileSync(opts.indexHtmlPath, "utf8");
45635
+ indexHtml = import_node_fs10.default.readFileSync(opts.indexHtmlPath, "utf8");
45653
45636
  } catch (err) {
45654
45637
  throw new Error(`share-ui index.html not found at ${opts.indexHtmlPath}: ${err.message}`);
45655
45638
  }
45656
- const assetsDir = import_node_path11.default.resolve(opts.assetsDir);
45639
+ const assetsDir = import_node_path9.default.resolve(opts.assetsDir);
45657
45640
  return {
45658
45641
  renderIndexHtml() {
45659
45642
  return indexHtml;
45660
45643
  },
45661
45644
  resolveAssetPath(rel) {
45662
- const resolved = import_node_path11.default.resolve(assetsDir, rel);
45663
- 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;
45664
45647
  try {
45665
- if (import_node_fs11.default.statSync(resolved).isFile()) return resolved;
45648
+ if (import_node_fs10.default.statSync(resolved).isFile()) return resolved;
45666
45649
  } catch {
45667
45650
  }
45668
45651
  return null;
@@ -45676,28 +45659,28 @@ function bundleDirFromArgv(argv1) {
45676
45659
  if (!argv1) return null;
45677
45660
  let real = argv1;
45678
45661
  try {
45679
- real = import_node_fs12.default.realpathSync(argv1);
45662
+ real = import_node_fs11.default.realpathSync(argv1);
45680
45663
  } catch {
45681
45664
  }
45682
- return import_node_path12.default.dirname(real);
45665
+ return import_node_path10.default.dirname(real);
45683
45666
  }
45684
45667
  function tryLoadShareUi(logger) {
45685
45668
  const candidates = [];
45686
45669
  try {
45687
- 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));
45688
45671
  candidates.push(here);
45689
- candidates.push(import_node_path12.default.resolve(here, ".."));
45690
- 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"));
45691
45674
  } catch {
45692
45675
  }
45693
45676
  const argvDir = bundleDirFromArgv(process.argv[1]);
45694
45677
  if (argvDir) candidates.push(argvDir);
45695
45678
  for (const root of candidates) {
45696
- const shareUiDir = import_node_path12.default.join(root, "share-ui");
45697
- const indexHtmlPath = import_node_path12.default.join(shareUiDir, "guest.html");
45698
- const assetsDir = import_node_path12.default.join(shareUiDir, "assets");
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");
45699
45682
  try {
45700
- 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()) {
45701
45684
  logger?.info("share-ui.assets-root.resolved", { root: shareUiDir });
45702
45685
  return createShareUiAssetLoader({ indexHtmlPath, assetsDir });
45703
45686
  }
@@ -45779,20 +45762,20 @@ function buildVisitorLogin(deps) {
45779
45762
  }
45780
45763
 
45781
45764
  // src/visitor/visitor-store.ts
45782
- var import_node_fs13 = __toESM(require("fs"), 1);
45783
- 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);
45784
45767
  function createVisitorStore(opts) {
45785
- const file = import_node_path13.default.join(opts.dir, "visitors.json");
45768
+ const file = import_node_path11.default.join(opts.dir, "visitors.json");
45786
45769
  const read = () => {
45787
45770
  try {
45788
- return JSON.parse(import_node_fs13.default.readFileSync(file, "utf8"));
45771
+ return JSON.parse(import_node_fs12.default.readFileSync(file, "utf8"));
45789
45772
  } catch {
45790
45773
  return [];
45791
45774
  }
45792
45775
  };
45793
45776
  const write = (rows) => {
45794
- import_node_fs13.default.mkdirSync(opts.dir, { recursive: true });
45795
- 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));
45796
45779
  };
45797
45780
  return {
45798
45781
  upsert(r) {
@@ -46308,8 +46291,8 @@ var CodexAdapter = class {
46308
46291
 
46309
46292
  // src/tools/claude-tui.ts
46310
46293
  var import_node_fs16 = __toESM(require("fs"), 1);
46311
- var import_node_os7 = __toESM(require("os"), 1);
46312
- 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);
46313
46296
  var import_headless = __toESM(require_xterm_headless(), 1);
46314
46297
 
46315
46298
  // ../node_modules/.pnpm/@xterm+addon-serialize@0.14.0/node_modules/@xterm/addon-serialize/lib/addon-serialize.mjs
@@ -47436,14 +47419,17 @@ function buildTuiSpawnArgs(ctx, isResume = false) {
47436
47419
  if (ctx.shiftMcpConfigPath) {
47437
47420
  args.push("--mcp-config", ctx.shiftMcpConfigPath);
47438
47421
  }
47422
+ if (ctx.inboxMcpConfigPath) {
47423
+ args.push("--mcp-config", ctx.inboxMcpConfigPath);
47424
+ }
47439
47425
  args.push("--disallowed-tools", "CronCreate,CronDelete,CronList,ScheduleWakeup,RemoteTrigger");
47440
47426
  if (ctx.effort) args.push("--effort", ctx.effort);
47441
47427
  return args;
47442
47428
  }
47443
47429
  function jsonlExistsForCtx(ctx) {
47444
47430
  if (!ctx.toolSessionId) return false;
47445
- const home = import_node_os7.default.homedir();
47446
- const file = import_node_path14.default.join(home, ".claude", "projects", cwdToHashDir(ctx.cwd), `${ctx.toolSessionId}.jsonl`);
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`);
47447
47433
  try {
47448
47434
  return import_node_fs16.default.statSync(file).isFile();
47449
47435
  } catch {
@@ -47515,9 +47501,9 @@ var PersonaDispatchManager = class {
47515
47501
 
47516
47502
  // src/dispatch/mcp-config.ts
47517
47503
  var import_node_fs17 = __toESM(require("fs"), 1);
47518
- var import_node_path15 = __toESM(require("path"), 1);
47504
+ var import_node_path14 = __toESM(require("path"), 1);
47519
47505
  function dispatchMcpConfigPath(dataDir) {
47520
- return import_node_path15.default.join(dataDir, "dispatch.mcp.json");
47506
+ return import_node_path14.default.join(dataDir, "dispatch.mcp.json");
47521
47507
  }
47522
47508
  function writeDispatchMcpConfig(args) {
47523
47509
  const cfgPath = dispatchMcpConfigPath(args.dataDir);
@@ -47539,9 +47525,9 @@ function writeDispatchMcpConfig(args) {
47539
47525
 
47540
47526
  // src/ticket/mcp-config.ts
47541
47527
  var import_node_fs18 = __toESM(require("fs"), 1);
47542
- var import_node_path16 = __toESM(require("path"), 1);
47528
+ var import_node_path15 = __toESM(require("path"), 1);
47543
47529
  function ticketMcpConfigPath(dataDir) {
47544
- return import_node_path16.default.join(dataDir, "ticket.mcp.json");
47530
+ return import_node_path15.default.join(dataDir, "ticket.mcp.json");
47545
47531
  }
47546
47532
  function writeTicketMcpConfig(args) {
47547
47533
  const cfgPath = ticketMcpConfigPath(args.dataDir);
@@ -47569,9 +47555,9 @@ function writeTicketMcpConfig(args) {
47569
47555
 
47570
47556
  // src/shift/mcp-config.ts
47571
47557
  var import_node_fs19 = __toESM(require("fs"), 1);
47572
- var import_node_path17 = __toESM(require("path"), 1);
47558
+ var import_node_path16 = __toESM(require("path"), 1);
47573
47559
  function shiftMcpConfigPath(dataDir) {
47574
- return import_node_path17.default.join(dataDir, "shift.mcp.json");
47560
+ return import_node_path16.default.join(dataDir, "shift.mcp.json");
47575
47561
  }
47576
47562
  async function writeShiftMcpConfig(args) {
47577
47563
  const cfgPath = shiftMcpConfigPath(args.dataDir);
@@ -47591,6 +47577,29 @@ async function writeShiftMcpConfig(args) {
47591
47577
  return cfgPath;
47592
47578
  }
47593
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
+
47594
47603
  // src/shift/store.ts
47595
47604
  var import_promises = __toESM(require("fs/promises"), 1);
47596
47605
  var import_node_path18 = __toESM(require("path"), 1);
@@ -48246,6 +48255,39 @@ async function forwardDispatchToPeer(args) {
48246
48255
  }
48247
48256
  return json.result.outcome;
48248
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
+ }
48249
48291
 
48250
48292
  // src/tools/codex-history.ts
48251
48293
  var import_node_child_process5 = require("child_process");
@@ -48478,8 +48520,8 @@ async function listCodexSkills(cwd, deps = {}) {
48478
48520
  }
48479
48521
 
48480
48522
  // src/workspace/browser.ts
48481
- var import_node_fs20 = __toESM(require("fs"), 1);
48482
- 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);
48483
48525
  var import_node_path19 = __toESM(require("path"), 1);
48484
48526
  init_protocol();
48485
48527
  var MAX_FILE_BYTES = 2 * 1024 * 1024;
@@ -48494,7 +48536,7 @@ function resolveInsideCwd(cwd, subpath) {
48494
48536
  }
48495
48537
  function ensureCwd(cwd) {
48496
48538
  try {
48497
- const stat = import_node_fs20.default.statSync(cwd);
48539
+ const stat = import_node_fs21.default.statSync(cwd);
48498
48540
  if (!stat.isDirectory()) {
48499
48541
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${cwd}`);
48500
48542
  }
@@ -48505,10 +48547,10 @@ function ensureCwd(cwd) {
48505
48547
  }
48506
48548
  var WorkspaceBrowser = class {
48507
48549
  list(args) {
48508
- 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();
48509
48551
  ensureCwd(cwd);
48510
48552
  const full = resolveInsideCwd(cwd, args.path);
48511
- const dirents = import_node_fs20.default.readdirSync(full, { withFileTypes: true });
48553
+ const dirents = import_node_fs21.default.readdirSync(full, { withFileTypes: true });
48512
48554
  const entries = [];
48513
48555
  for (const d of dirents) {
48514
48556
  if (!args.showHidden && d.name.startsWith(".")) continue;
@@ -48518,7 +48560,7 @@ var WorkspaceBrowser = class {
48518
48560
  mtime: ""
48519
48561
  };
48520
48562
  try {
48521
- 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));
48522
48564
  entry.mtime = new Date(st.mtimeMs).toISOString();
48523
48565
  if (d.isFile()) entry.size = st.size;
48524
48566
  } catch {
@@ -48534,14 +48576,14 @@ var WorkspaceBrowser = class {
48534
48576
  read(args) {
48535
48577
  ensureCwd(args.cwd);
48536
48578
  const full = resolveInsideCwd(args.cwd, args.path);
48537
- const st = import_node_fs20.default.statSync(full);
48579
+ const st = import_node_fs21.default.statSync(full);
48538
48580
  if (!st.isFile()) {
48539
48581
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `not a file: ${args.path}`);
48540
48582
  }
48541
48583
  if (st.size > MAX_FILE_BYTES) {
48542
48584
  throw new ClawdError(ERROR_CODES.FILE_TOO_LARGE, `file > ${MAX_FILE_BYTES} bytes`);
48543
48585
  }
48544
- const buf = import_node_fs20.default.readFileSync(full);
48586
+ const buf = import_node_fs21.default.readFileSync(full);
48545
48587
  const isBinary = buf.includes(0);
48546
48588
  if (isBinary) {
48547
48589
  return {
@@ -48563,20 +48605,20 @@ var WorkspaceBrowser = class {
48563
48605
  };
48564
48606
 
48565
48607
  // src/skills/agents-scanner.ts
48566
- var import_node_fs21 = __toESM(require("fs"), 1);
48567
- 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);
48568
48610
  var import_node_path20 = __toESM(require("path"), 1);
48569
48611
  var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
48570
48612
  function isDirLikeSync2(p2) {
48571
48613
  try {
48572
- return import_node_fs21.default.statSync(p2).isDirectory();
48614
+ return import_node_fs22.default.statSync(p2).isDirectory();
48573
48615
  } catch {
48574
48616
  return false;
48575
48617
  }
48576
48618
  }
48577
48619
  function fileExistsSync(p2) {
48578
48620
  try {
48579
- return import_node_fs21.default.statSync(p2).isFile();
48621
+ return import_node_fs22.default.statSync(p2).isFile();
48580
48622
  } catch {
48581
48623
  return false;
48582
48624
  }
@@ -48584,7 +48626,7 @@ function fileExistsSync(p2) {
48584
48626
  function parseAgentFile(filePath) {
48585
48627
  let content;
48586
48628
  try {
48587
- content = import_node_fs21.default.readFileSync(filePath, "utf8");
48629
+ content = import_node_fs22.default.readFileSync(filePath, "utf8");
48588
48630
  } catch {
48589
48631
  return {};
48590
48632
  }
@@ -48597,7 +48639,7 @@ function parseAgentFile(filePath) {
48597
48639
  function scanAgentsDir(dir, source, seen, out) {
48598
48640
  let entries;
48599
48641
  try {
48600
- entries = import_node_fs21.default.readdirSync(dir, { withFileTypes: true });
48642
+ entries = import_node_fs22.default.readdirSync(dir, { withFileTypes: true });
48601
48643
  } catch {
48602
48644
  return;
48603
48645
  }
@@ -48624,7 +48666,7 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
48624
48666
  function walk2(dir, namespaces) {
48625
48667
  let entries;
48626
48668
  try {
48627
- entries = import_node_fs21.default.readdirSync(dir, { withFileTypes: true });
48669
+ entries = import_node_fs22.default.readdirSync(dir, { withFileTypes: true });
48628
48670
  } catch {
48629
48671
  return;
48630
48672
  }
@@ -48660,7 +48702,7 @@ function readInstalledPlugins2(home) {
48660
48702
  let raw = null;
48661
48703
  for (const candidate of [v2, v1]) {
48662
48704
  try {
48663
- raw = import_node_fs21.default.readFileSync(candidate, "utf8");
48705
+ raw = import_node_fs22.default.readFileSync(candidate, "utf8");
48664
48706
  break;
48665
48707
  } catch {
48666
48708
  }
@@ -48691,7 +48733,7 @@ function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
48691
48733
  scanAgentsDir(import_node_path20.default.join(cur, ".claude", "agents"), "project", seen, out);
48692
48734
  let hasGit = false;
48693
48735
  try {
48694
- 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"));
48695
48737
  } catch {
48696
48738
  }
48697
48739
  if (hasGit) return;
@@ -48707,7 +48749,7 @@ var AgentsScanner = class {
48707
48749
  extraPluginRoots;
48708
48750
  policyDir;
48709
48751
  constructor(opts = {}) {
48710
- 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();
48711
48753
  this.extraPluginRoots = opts.extraPluginRoots ?? [];
48712
48754
  if (opts.policyDir !== void 0) {
48713
48755
  this.policyDir = opts.policyDir;
@@ -48754,21 +48796,21 @@ var AgentsScanner = class {
48754
48796
  };
48755
48797
 
48756
48798
  // src/observer/session-observer.ts
48757
- var import_node_fs23 = __toESM(require("fs"), 1);
48758
- 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);
48759
48801
  var import_node_path22 = __toESM(require("path"), 1);
48760
48802
  init_claude_history();
48761
48803
 
48762
48804
  // src/observer/subagent-meta-observer.ts
48763
- var import_node_fs22 = __toESM(require("fs"), 1);
48764
- 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);
48765
48807
  var import_node_path21 = __toESM(require("path"), 1);
48766
48808
  init_claude_history();
48767
48809
  var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
48768
48810
  var SubagentMetaObserver = class {
48769
48811
  constructor(opts) {
48770
48812
  this.opts = opts;
48771
- this.home = opts.home ?? import_node_os10.default.homedir();
48813
+ this.home = opts.home ?? import_node_os9.default.homedir();
48772
48814
  }
48773
48815
  opts;
48774
48816
  home;
@@ -48805,7 +48847,7 @@ var SubagentMetaObserver = class {
48805
48847
  attachWatcher(w2) {
48806
48848
  if (w2.watcher) return;
48807
48849
  try {
48808
- 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) => {
48809
48851
  if (!name) return;
48810
48852
  const m2 = META_RE.exec(String(name));
48811
48853
  if (!m2) return;
@@ -48817,7 +48859,7 @@ var SubagentMetaObserver = class {
48817
48859
  scan(w2) {
48818
48860
  let entries;
48819
48861
  try {
48820
- entries = import_node_fs22.default.readdirSync(w2.dirPath);
48862
+ entries = import_node_fs23.default.readdirSync(w2.dirPath);
48821
48863
  } catch {
48822
48864
  return;
48823
48865
  }
@@ -48834,7 +48876,7 @@ var SubagentMetaObserver = class {
48834
48876
  const file = import_node_path21.default.join(w2.dirPath, name);
48835
48877
  let raw;
48836
48878
  try {
48837
- raw = import_node_fs22.default.readFileSync(file, "utf8");
48879
+ raw = import_node_fs23.default.readFileSync(file, "utf8");
48838
48880
  } catch {
48839
48881
  return;
48840
48882
  }
@@ -48879,7 +48921,7 @@ var SubagentMetaObserver = class {
48879
48921
  var SessionObserver = class {
48880
48922
  constructor(opts) {
48881
48923
  this.opts = opts;
48882
- this.home = opts.home ?? import_node_os11.default.homedir();
48924
+ this.home = opts.home ?? import_node_os10.default.homedir();
48883
48925
  this.metaObserver = opts.enableSubagentMetaObserver ? new SubagentMetaObserver({ home: this.home, onEvent: opts.onEvent }) : null;
48884
48926
  }
48885
48927
  opts;
@@ -48898,7 +48940,7 @@ var SessionObserver = class {
48898
48940
  const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
48899
48941
  let size = 0;
48900
48942
  try {
48901
- size = import_node_fs23.default.statSync(filePath).size;
48943
+ size = import_node_fs24.default.statSync(filePath).size;
48902
48944
  } catch {
48903
48945
  }
48904
48946
  const w2 = {
@@ -48912,10 +48954,10 @@ var SessionObserver = class {
48912
48954
  prevIsRejectSentinel: false
48913
48955
  };
48914
48956
  try {
48915
- 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 });
48916
48958
  } catch {
48917
48959
  }
48918
- 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) => {
48919
48961
  if (!changedName || !filePath.endsWith(changedName)) return;
48920
48962
  this.poll(w2);
48921
48963
  });
@@ -48938,7 +48980,7 @@ var SessionObserver = class {
48938
48980
  // 异常静默吞,不阻塞 watcher 启动
48939
48981
  hydrateMetaTail(w2, maxLines = 200) {
48940
48982
  try {
48941
- const raw = import_node_fs23.default.readFileSync(w2.filePath, "utf8");
48983
+ const raw = import_node_fs24.default.readFileSync(w2.filePath, "utf8");
48942
48984
  if (!raw) return;
48943
48985
  const allLines = raw.split("\n").filter((l) => l.trim().length > 0);
48944
48986
  if (allLines.length === 0) return;
@@ -48962,7 +49004,7 @@ var SessionObserver = class {
48962
49004
  poll(w2) {
48963
49005
  let size = 0;
48964
49006
  try {
48965
- size = import_node_fs23.default.statSync(w2.filePath).size;
49007
+ size = import_node_fs24.default.statSync(w2.filePath).size;
48966
49008
  } catch {
48967
49009
  return;
48968
49010
  }
@@ -48971,11 +49013,11 @@ var SessionObserver = class {
48971
49013
  w2.buf = "";
48972
49014
  }
48973
49015
  if (size === w2.lastSize) return;
48974
- const fd = import_node_fs23.default.openSync(w2.filePath, "r");
49016
+ const fd = import_node_fs24.default.openSync(w2.filePath, "r");
48975
49017
  try {
48976
49018
  const len = size - w2.lastSize;
48977
49019
  const buf = Buffer.alloc(len);
48978
- import_node_fs23.default.readSync(fd, buf, 0, len, w2.lastSize);
49020
+ import_node_fs24.default.readSync(fd, buf, 0, len, w2.lastSize);
48979
49021
  w2.lastSize = size;
48980
49022
  w2.buf += buf.toString("utf8");
48981
49023
  let newlineIndex;
@@ -48998,7 +49040,7 @@ var SessionObserver = class {
48998
49040
  }
48999
49041
  }
49000
49042
  } finally {
49001
- import_node_fs23.default.closeSync(fd);
49043
+ import_node_fs24.default.closeSync(fd);
49002
49044
  }
49003
49045
  }
49004
49046
  // 解析 JSONL 单行:仅当是主链 user 文本行(非 sidechain / 非 sub-agent / message.role='user'
@@ -49558,7 +49600,9 @@ var EXPOSED_RPC_METHODS = [
49558
49600
  // file-sharing:persona guest agent 把自己工作目录内的产物入群+签名分享。
49559
49601
  // 路径越界由 handlers/attachment.ts guardAttachmentPath(scope-based)拦截。
49560
49602
  "attachment.groupAdd",
49561
- "attachment.signUrl"
49603
+ "attachment.signUrl",
49604
+ // persona 受控发 P2P IM DM(sender 由 session scope 推,driver 分级授权见 handlers/inbox.ts)
49605
+ "inbox.sendDm"
49562
49606
  ];
49563
49607
  async function handleRpcRequest(input) {
49564
49608
  const { method, body, sessionId, dispatcher } = input;
@@ -49794,14 +49838,14 @@ async function authenticate(token, deps) {
49794
49838
  }
49795
49839
 
49796
49840
  // src/permission/capability-store.ts
49797
- var fs27 = __toESM(require("fs"), 1);
49841
+ var fs28 = __toESM(require("fs"), 1);
49798
49842
  var path27 = __toESM(require("path"), 1);
49799
49843
  var CAPABILITIES_FILE_NAME = "capabilities.json";
49800
49844
  var FILE_VERSION = 1;
49801
49845
  var CapabilityStore = class {
49802
49846
  constructor(dataDir) {
49803
49847
  this.dataDir = dataDir;
49804
- fs27.mkdirSync(dataDir, { recursive: true });
49848
+ fs28.mkdirSync(dataDir, { recursive: true });
49805
49849
  this.cache = this.readFromDisk();
49806
49850
  }
49807
49851
  dataDir;
@@ -49831,7 +49875,7 @@ var CapabilityStore = class {
49831
49875
  const file = this.filePath();
49832
49876
  let raw;
49833
49877
  try {
49834
- raw = fs27.readFileSync(file, "utf8");
49878
+ raw = fs28.readFileSync(file, "utf8");
49835
49879
  } catch (err) {
49836
49880
  if (err?.code === "ENOENT") return [];
49837
49881
  return [];
@@ -49859,10 +49903,10 @@ var CapabilityStore = class {
49859
49903
  }
49860
49904
  atomicWrite(file, content) {
49861
49905
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
49862
- fs27.writeFileSync(tmp, content, { mode: 384 });
49863
- fs27.renameSync(tmp, file);
49906
+ fs28.writeFileSync(tmp, content, { mode: 384 });
49907
+ fs28.renameSync(tmp, file);
49864
49908
  try {
49865
- fs27.chmodSync(file, 384);
49909
+ fs28.chmodSync(file, 384);
49866
49910
  } catch {
49867
49911
  }
49868
49912
  }
@@ -49955,14 +49999,14 @@ var CapabilityManager = class {
49955
49999
  };
49956
50000
 
49957
50001
  // src/permission/cleanup.ts
49958
- var fs28 = __toESM(require("fs"), 1);
50002
+ var fs29 = __toESM(require("fs"), 1);
49959
50003
  function cleanupGuestSessionsForCapability(cap, factory) {
49960
50004
  const removed = [];
49961
50005
  for (const g2 of cap.grants) {
49962
50006
  if (g2.resource.type !== "persona") continue;
49963
50007
  const dir = factory.vmGuestRoot(g2.resource.id, cap.id);
49964
50008
  try {
49965
- fs28.rmSync(dir, { recursive: true, force: true });
50009
+ fs29.rmSync(dir, { recursive: true, force: true });
49966
50010
  removed.push(dir);
49967
50011
  } catch {
49968
50012
  }
@@ -49971,13 +50015,13 @@ function cleanupGuestSessionsForCapability(cap, factory) {
49971
50015
  }
49972
50016
 
49973
50017
  // src/inbox/inbox-store.ts
49974
- var fs29 = __toESM(require("fs"), 1);
50018
+ var fs30 = __toESM(require("fs"), 1);
49975
50019
  var path28 = __toESM(require("path"), 1);
49976
50020
  var INBOX_SUBDIR = "inbox";
49977
50021
  var InboxStore = class {
49978
50022
  constructor(dataDir) {
49979
50023
  this.dataDir = dataDir;
49980
- fs29.mkdirSync(this.dirPath(), { recursive: true });
50024
+ fs30.mkdirSync(this.dirPath(), { recursive: true });
49981
50025
  }
49982
50026
  dataDir;
49983
50027
  /**
@@ -49989,7 +50033,7 @@ var InboxStore = class {
49989
50033
  const file = this.filePath(peerDeviceId);
49990
50034
  let raw;
49991
50035
  try {
49992
- raw = fs29.readFileSync(file, "utf8");
50036
+ raw = fs30.readFileSync(file, "utf8");
49993
50037
  } catch (err) {
49994
50038
  if (err?.code === "ENOENT") return [];
49995
50039
  return [];
@@ -50005,7 +50049,7 @@ var InboxStore = class {
50005
50049
  const dir = this.dirPath();
50006
50050
  let entries;
50007
50051
  try {
50008
- entries = fs29.readdirSync(dir);
50052
+ entries = fs30.readdirSync(dir);
50009
50053
  } catch (err) {
50010
50054
  if (err?.code === "ENOENT") return [];
50011
50055
  return [];
@@ -50021,9 +50065,9 @@ var InboxStore = class {
50021
50065
  if (existing.some((m2) => m2.id === message.id)) return;
50022
50066
  const file = this.filePath(message.peerDeviceId);
50023
50067
  const line = JSON.stringify(message) + "\n";
50024
- fs29.appendFileSync(file, line, { mode: 384 });
50068
+ fs30.appendFileSync(file, line, { mode: 384 });
50025
50069
  try {
50026
- fs29.chmodSync(file, 384);
50070
+ fs30.chmodSync(file, 384);
50027
50071
  } catch {
50028
50072
  }
50029
50073
  }
@@ -50053,7 +50097,7 @@ var InboxStore = class {
50053
50097
  removeByPeerDeviceId(peerDeviceId) {
50054
50098
  const file = this.filePath(peerDeviceId);
50055
50099
  try {
50056
- fs29.unlinkSync(file);
50100
+ fs30.unlinkSync(file);
50057
50101
  } catch (err) {
50058
50102
  if (err?.code === "ENOENT") return;
50059
50103
  }
@@ -50062,10 +50106,10 @@ var InboxStore = class {
50062
50106
  const file = this.filePath(peerDeviceId);
50063
50107
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
50064
50108
  const content = messages.map((m2) => JSON.stringify(m2)).join("\n") + (messages.length > 0 ? "\n" : "");
50065
- fs29.writeFileSync(tmp, content, { mode: 384 });
50066
- fs29.renameSync(tmp, file);
50109
+ fs30.writeFileSync(tmp, content, { mode: 384 });
50110
+ fs30.renameSync(tmp, file);
50067
50111
  try {
50068
- fs29.chmodSync(file, 384);
50112
+ fs30.chmodSync(file, 384);
50069
50113
  } catch {
50070
50114
  }
50071
50115
  }
@@ -50116,7 +50160,8 @@ var InboxManager = class {
50116
50160
  senderDeviceId: args.senderDeviceId,
50117
50161
  text: args.text,
50118
50162
  createdAt: args.createdAt,
50119
- readBy: {}
50163
+ readBy: {},
50164
+ ...args.origin ? { origin: args.origin } : {}
50120
50165
  };
50121
50166
  this.store.append(msg);
50122
50167
  const afterLen = this.store.list(args.peerDeviceId).length;
@@ -50160,7 +50205,7 @@ var InboxManager = class {
50160
50205
  };
50161
50206
 
50162
50207
  // src/state/contact-store.ts
50163
- var fs30 = __toESM(require("fs"), 1);
50208
+ var fs31 = __toESM(require("fs"), 1);
50164
50209
  var path29 = __toESM(require("path"), 1);
50165
50210
  var FILE_NAME = "contacts.json";
50166
50211
  var ContactStore = class {
@@ -50174,7 +50219,7 @@ var ContactStore = class {
50174
50219
  const file = path29.join(this.dataDir, FILE_NAME);
50175
50220
  let raw;
50176
50221
  try {
50177
- raw = fs30.readFileSync(file, "utf8");
50222
+ raw = fs31.readFileSync(file, "utf8");
50178
50223
  } catch (err) {
50179
50224
  if (err?.code !== "ENOENT") this.renameBak(file);
50180
50225
  return;
@@ -50224,13 +50269,13 @@ var ContactStore = class {
50224
50269
  null,
50225
50270
  2
50226
50271
  );
50227
- fs30.mkdirSync(this.dataDir, { recursive: true });
50228
- fs30.writeFileSync(tmp, content, { mode: 384 });
50229
- fs30.renameSync(tmp, file);
50272
+ fs31.mkdirSync(this.dataDir, { recursive: true });
50273
+ fs31.writeFileSync(tmp, content, { mode: 384 });
50274
+ fs31.renameSync(tmp, file);
50230
50275
  }
50231
50276
  renameBak(file) {
50232
50277
  try {
50233
- fs30.renameSync(file, `${file}.bak`);
50278
+ fs31.renameSync(file, `${file}.bak`);
50234
50279
  } catch {
50235
50280
  }
50236
50281
  }
@@ -50380,7 +50425,7 @@ async function autoReverseContact(args) {
50380
50425
  }
50381
50426
 
50382
50427
  // src/migrations/2026-05-20-flatten-sessions.ts
50383
- var fs31 = __toESM(require("fs"), 1);
50428
+ var fs32 = __toESM(require("fs"), 1);
50384
50429
  var path30 = __toESM(require("path"), 1);
50385
50430
  var MIGRATION_FLAG_NAME = ".migration.v1.done";
50386
50431
  function migrateFlattenSessions(opts) {
@@ -50400,7 +50445,7 @@ function migrateFlattenSessions(opts) {
50400
50445
  if (!entry.endsWith(".json")) continue;
50401
50446
  const src = path30.join(defaultDir, entry);
50402
50447
  const dst = path30.join(sessionsDir, entry);
50403
- fs31.renameSync(src, dst);
50448
+ fs32.renameSync(src, dst);
50404
50449
  movedBare += 1;
50405
50450
  }
50406
50451
  rmdirIfEmpty(defaultDir);
@@ -50412,10 +50457,10 @@ function migrateFlattenSessions(opts) {
50412
50457
  const ownerSrc = path30.join(personaDir, "owner");
50413
50458
  if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
50414
50459
  const ownerDst = path30.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
50415
- fs31.mkdirSync(ownerDst, { recursive: true });
50460
+ fs32.mkdirSync(ownerDst, { recursive: true });
50416
50461
  for (const file of readdirSafe(ownerSrc)) {
50417
50462
  if (!file.endsWith(".json")) continue;
50418
- fs31.renameSync(path30.join(ownerSrc, file), path30.join(ownerDst, file));
50463
+ fs32.renameSync(path30.join(ownerSrc, file), path30.join(ownerDst, file));
50419
50464
  movedVmOwner += 1;
50420
50465
  }
50421
50466
  rmdirIfEmpty(ownerSrc);
@@ -50423,18 +50468,18 @@ function migrateFlattenSessions(opts) {
50423
50468
  const listenerSrc = path30.join(personaDir, "listener");
50424
50469
  if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
50425
50470
  const archiveDst = path30.join(dataDir, ".legacy", `listener-${pid}`);
50426
- fs31.mkdirSync(archiveDst, { recursive: true });
50471
+ fs32.mkdirSync(archiveDst, { recursive: true });
50427
50472
  for (const file of readdirSafe(listenerSrc)) {
50428
50473
  if (!file.endsWith(".json")) continue;
50429
- fs31.renameSync(path30.join(listenerSrc, file), path30.join(archiveDst, file));
50474
+ fs32.renameSync(path30.join(listenerSrc, file), path30.join(archiveDst, file));
50430
50475
  archivedListener += 1;
50431
50476
  }
50432
50477
  rmdirIfEmpty(listenerSrc);
50433
50478
  }
50434
50479
  rmdirIfEmpty(personaDir);
50435
50480
  }
50436
- fs31.mkdirSync(sessionsDir, { recursive: true });
50437
- 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));
50438
50483
  return {
50439
50484
  skipped: false,
50440
50485
  flagWritten: true,
@@ -50445,7 +50490,7 @@ function migrateFlattenSessions(opts) {
50445
50490
  }
50446
50491
  function existsSync3(p2) {
50447
50492
  try {
50448
- fs31.statSync(p2);
50493
+ fs32.statSync(p2);
50449
50494
  return true;
50450
50495
  } catch {
50451
50496
  return false;
@@ -50453,27 +50498,27 @@ function existsSync3(p2) {
50453
50498
  }
50454
50499
  function isDir(p2) {
50455
50500
  try {
50456
- return fs31.statSync(p2).isDirectory();
50501
+ return fs32.statSync(p2).isDirectory();
50457
50502
  } catch {
50458
50503
  return false;
50459
50504
  }
50460
50505
  }
50461
50506
  function readdirSafe(p2) {
50462
50507
  try {
50463
- return fs31.readdirSync(p2);
50508
+ return fs32.readdirSync(p2);
50464
50509
  } catch {
50465
50510
  return [];
50466
50511
  }
50467
50512
  }
50468
50513
  function rmdirIfEmpty(p2) {
50469
50514
  try {
50470
- fs31.rmdirSync(p2);
50515
+ fs32.rmdirSync(p2);
50471
50516
  } catch {
50472
50517
  }
50473
50518
  }
50474
50519
 
50475
50520
  // src/transport/http-router.ts
50476
- var import_node_fs25 = __toESM(require("fs"), 1);
50521
+ var import_node_fs26 = __toESM(require("fs"), 1);
50477
50522
  var import_node_path26 = __toESM(require("path"), 1);
50478
50523
 
50479
50524
  // src/attachment/mime.ts
@@ -50653,7 +50698,7 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
50653
50698
  }
50654
50699
 
50655
50700
  // src/attachment/upload.ts
50656
- var import_node_fs24 = __toESM(require("fs"), 1);
50701
+ var import_node_fs25 = __toESM(require("fs"), 1);
50657
50702
  var import_node_path24 = __toESM(require("path"), 1);
50658
50703
  var import_node_crypto7 = __toESM(require("crypto"), 1);
50659
50704
  var import_promises2 = require("stream/promises");
@@ -50675,7 +50720,7 @@ async function writeUploadedAttachment(args) {
50675
50720
  assertValidFileName(args.fileName);
50676
50721
  const attachmentsRoot = import_node_path24.default.join(args.sessionDir, ".attachments");
50677
50722
  try {
50678
- import_node_fs24.default.mkdirSync(attachmentsRoot, { recursive: true });
50723
+ import_node_fs25.default.mkdirSync(attachmentsRoot, { recursive: true });
50679
50724
  } catch (err) {
50680
50725
  throw new UploadError("STORAGE_ERROR", `mkdir failed: ${err.message}`);
50681
50726
  }
@@ -50696,18 +50741,18 @@ async function writeUploadedAttachment(args) {
50696
50741
  yield buf;
50697
50742
  }
50698
50743
  },
50699
- import_node_fs24.default.createWriteStream(tmpPath, { mode: 384 })
50744
+ import_node_fs25.default.createWriteStream(tmpPath, { mode: 384 })
50700
50745
  );
50701
50746
  } catch (err) {
50702
50747
  try {
50703
- import_node_fs24.default.unlinkSync(tmpPath);
50748
+ import_node_fs25.default.unlinkSync(tmpPath);
50704
50749
  } catch {
50705
50750
  }
50706
50751
  throw new UploadError("STORAGE_ERROR", `write failed: ${err.message}`);
50707
50752
  }
50708
50753
  if (actualSize !== args.contentLength) {
50709
50754
  try {
50710
- import_node_fs24.default.unlinkSync(tmpPath);
50755
+ import_node_fs25.default.unlinkSync(tmpPath);
50711
50756
  } catch {
50712
50757
  }
50713
50758
  throw new UploadError(
@@ -50720,24 +50765,24 @@ async function writeUploadedAttachment(args) {
50720
50765
  let finalFileName;
50721
50766
  let hashDirExists = false;
50722
50767
  try {
50723
- hashDirExists = import_node_fs24.default.statSync(hashDir).isDirectory();
50768
+ hashDirExists = import_node_fs25.default.statSync(hashDir).isDirectory();
50724
50769
  } catch {
50725
50770
  }
50726
50771
  if (hashDirExists) {
50727
- 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("."));
50728
50773
  finalFileName = existing[0] ?? args.fileName;
50729
50774
  try {
50730
- import_node_fs24.default.unlinkSync(tmpPath);
50775
+ import_node_fs25.default.unlinkSync(tmpPath);
50731
50776
  } catch {
50732
50777
  }
50733
50778
  } else {
50734
50779
  try {
50735
- import_node_fs24.default.mkdirSync(hashDir, { recursive: true });
50780
+ import_node_fs25.default.mkdirSync(hashDir, { recursive: true });
50736
50781
  finalFileName = args.fileName;
50737
- 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));
50738
50783
  } catch (err) {
50739
50784
  try {
50740
- import_node_fs24.default.unlinkSync(tmpPath);
50785
+ import_node_fs25.default.unlinkSync(tmpPath);
50741
50786
  } catch {
50742
50787
  }
50743
50788
  throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
@@ -50759,7 +50804,7 @@ async function writeUploadedAttachment(args) {
50759
50804
  // src/extension/import.ts
50760
50805
  var import_promises3 = __toESM(require("fs/promises"), 1);
50761
50806
  var import_node_path25 = __toESM(require("path"), 1);
50762
- var import_node_os12 = __toESM(require("os"), 1);
50807
+ var import_node_os11 = __toESM(require("os"), 1);
50763
50808
  var import_jszip = __toESM(require_lib3(), 1);
50764
50809
  var ImportError = class extends Error {
50765
50810
  constructor(code, message) {
@@ -50819,7 +50864,7 @@ async function importZip(buf, root) {
50819
50864
  if (destExists) {
50820
50865
  throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
50821
50866
  }
50822
- 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}-`));
50823
50868
  try {
50824
50869
  for (const [name, entry] of Object.entries(zip.files)) {
50825
50870
  const dest = import_node_path25.default.join(stage, name);
@@ -51017,7 +51062,7 @@ function createHttpRouter(deps) {
51017
51062
  }
51018
51063
  let buf;
51019
51064
  try {
51020
- buf = await import_node_fs25.default.promises.readFile(abs);
51065
+ buf = await import_node_fs26.default.promises.readFile(abs);
51021
51066
  } catch {
51022
51067
  sendJson(res, 404, { code: "NOT_FOUND", message: "asset not found" });
51023
51068
  return true;
@@ -51457,7 +51502,7 @@ function withCtx(ctx, body) {
51457
51502
  function streamFile(res, absPath, logger) {
51458
51503
  let stat;
51459
51504
  try {
51460
- stat = import_node_fs25.default.statSync(absPath);
51505
+ stat = import_node_fs26.default.statSync(absPath);
51461
51506
  } catch (err) {
51462
51507
  const code = err?.code;
51463
51508
  if (code === "ENOENT") {
@@ -51480,7 +51525,7 @@ function streamFile(res, absPath, logger) {
51480
51525
  // 防止浏览器把任意 mime 当 html 渲染
51481
51526
  "X-Content-Type-Options": "nosniff"
51482
51527
  });
51483
- const stream = import_node_fs25.default.createReadStream(absPath);
51528
+ const stream = import_node_fs26.default.createReadStream(absPath);
51484
51529
  stream.on("error", (err) => {
51485
51530
  logger?.warn("streamFile read error", { absPath, err: err.message });
51486
51531
  res.destroy();
@@ -51489,7 +51534,7 @@ function streamFile(res, absPath, logger) {
51489
51534
  }
51490
51535
 
51491
51536
  // src/attachment/gc.ts
51492
- var import_node_fs26 = __toESM(require("fs"), 1);
51537
+ var import_node_fs27 = __toESM(require("fs"), 1);
51493
51538
  var import_node_path27 = __toESM(require("path"), 1);
51494
51539
  var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
51495
51540
  function runAttachmentGc(args) {
@@ -51512,7 +51557,7 @@ function runAttachmentGc(args) {
51512
51557
  const attRoot = import_node_path27.default.join(sessionDir, ".attachments");
51513
51558
  let hashDirs;
51514
51559
  try {
51515
- hashDirs = import_node_fs26.default.readdirSync(attRoot);
51560
+ hashDirs = import_node_fs27.default.readdirSync(attRoot);
51516
51561
  } catch (err) {
51517
51562
  if (err.code === "ENOENT") continue;
51518
51563
  args.logger?.warn("attachment gc: readdir failed", { attRoot, err: err.message });
@@ -51522,7 +51567,7 @@ function runAttachmentGc(args) {
51522
51567
  const hashDirAbs = import_node_path27.default.join(attRoot, hashDir);
51523
51568
  let files;
51524
51569
  try {
51525
- files = import_node_fs26.default.readdirSync(hashDirAbs);
51570
+ files = import_node_fs27.default.readdirSync(hashDirAbs);
51526
51571
  } catch {
51527
51572
  continue;
51528
51573
  }
@@ -51530,7 +51575,7 @@ function runAttachmentGc(args) {
51530
51575
  const file = import_node_path27.default.join(hashDirAbs, name);
51531
51576
  let stat;
51532
51577
  try {
51533
- stat = import_node_fs26.default.statSync(file);
51578
+ stat = import_node_fs27.default.statSync(file);
51534
51579
  } catch {
51535
51580
  continue;
51536
51581
  }
@@ -51539,25 +51584,25 @@ function runAttachmentGc(args) {
51539
51584
  if (age < ttlMs) continue;
51540
51585
  if (liveAbs.has(file)) continue;
51541
51586
  try {
51542
- import_node_fs26.default.unlinkSync(file);
51587
+ import_node_fs27.default.unlinkSync(file);
51543
51588
  } catch (err) {
51544
51589
  args.logger?.warn("attachment gc: unlink failed", { file, err: err.message });
51545
51590
  }
51546
51591
  }
51547
51592
  try {
51548
- 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);
51549
51594
  } catch {
51550
51595
  }
51551
51596
  }
51552
51597
  try {
51553
- 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);
51554
51599
  } catch {
51555
51600
  }
51556
51601
  }
51557
51602
  }
51558
51603
 
51559
51604
  // src/attachment/group.ts
51560
- var import_node_fs27 = __toESM(require("fs"), 1);
51605
+ var import_node_fs28 = __toESM(require("fs"), 1);
51561
51606
  var import_node_path28 = __toESM(require("path"), 1);
51562
51607
  var import_node_crypto8 = __toESM(require("crypto"), 1);
51563
51608
  init_protocol();
@@ -51583,7 +51628,7 @@ var GroupFileStore = class {
51583
51628
  readFile(scope, sessionId) {
51584
51629
  const file = this.filePath(scope, sessionId);
51585
51630
  try {
51586
- const raw = import_node_fs27.default.readFileSync(file, "utf8");
51631
+ const raw = import_node_fs28.default.readFileSync(file, "utf8");
51587
51632
  const parsed = JSON.parse(raw);
51588
51633
  if (!Array.isArray(parsed)) {
51589
51634
  this.logger?.warn("GroupFileStore.readFile: not an array; resetting session entries", {
@@ -51609,10 +51654,10 @@ var GroupFileStore = class {
51609
51654
  }
51610
51655
  writeFile(scope, sessionId, entries) {
51611
51656
  const file = this.filePath(scope, sessionId);
51612
- 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 });
51613
51658
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
51614
- import_node_fs27.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
51615
- 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);
51616
51661
  }
51617
51662
  /** 拉一份当前 session 的清单。读盘 → cache;之后调用复用 cache */
51618
51663
  list(scope, sessionId) {
@@ -51698,7 +51743,7 @@ var GroupFileStore = class {
51698
51743
  };
51699
51744
 
51700
51745
  // src/discovery/state-file.ts
51701
- var import_node_fs28 = __toESM(require("fs"), 1);
51746
+ var import_node_fs29 = __toESM(require("fs"), 1);
51702
51747
  var import_node_path29 = __toESM(require("path"), 1);
51703
51748
  function defaultStateFilePath(dataDir) {
51704
51749
  return import_node_path29.default.join(dataDir, "state.json");
@@ -51723,7 +51768,7 @@ var StateFileManager = class {
51723
51768
  }
51724
51769
  read() {
51725
51770
  try {
51726
- const raw = import_node_fs28.default.readFileSync(this.file, "utf8");
51771
+ const raw = import_node_fs29.default.readFileSync(this.file, "utf8");
51727
51772
  const parsed = JSON.parse(raw);
51728
51773
  return parsed;
51729
51774
  } catch {
@@ -51737,20 +51782,20 @@ var StateFileManager = class {
51737
51782
  return { status: "stale", existing };
51738
51783
  }
51739
51784
  write(state) {
51740
- 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 });
51741
51786
  const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
51742
- import_node_fs28.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
51743
- 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);
51744
51789
  if (process.platform !== "win32") {
51745
51790
  try {
51746
- import_node_fs28.default.chmodSync(this.file, 384);
51791
+ import_node_fs29.default.chmodSync(this.file, 384);
51747
51792
  } catch {
51748
51793
  }
51749
51794
  }
51750
51795
  }
51751
51796
  delete() {
51752
51797
  try {
51753
- import_node_fs28.default.unlinkSync(this.file);
51798
+ import_node_fs29.default.unlinkSync(this.file);
51754
51799
  } catch {
51755
51800
  }
51756
51801
  }
@@ -51765,13 +51810,13 @@ function readDaemonSourceFromEnv(env = process.env) {
51765
51810
  }
51766
51811
 
51767
51812
  // src/tunnel/tunnel-manager.ts
51768
- var import_node_fs32 = __toESM(require("fs"), 1);
51813
+ var import_node_fs33 = __toESM(require("fs"), 1);
51769
51814
  var import_node_path33 = __toESM(require("path"), 1);
51770
51815
  var import_node_crypto9 = __toESM(require("crypto"), 1);
51771
51816
  var import_node_child_process9 = require("child_process");
51772
51817
 
51773
51818
  // src/tunnel/tunnel-store.ts
51774
- var import_node_fs29 = __toESM(require("fs"), 1);
51819
+ var import_node_fs30 = __toESM(require("fs"), 1);
51775
51820
  var import_node_path30 = __toESM(require("path"), 1);
51776
51821
  var TunnelStore = class {
51777
51822
  constructor(filePath) {
@@ -51780,7 +51825,7 @@ var TunnelStore = class {
51780
51825
  filePath;
51781
51826
  async get() {
51782
51827
  try {
51783
- 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");
51784
51829
  const obj = JSON.parse(raw);
51785
51830
  if (!isPersistedTunnel(obj)) return null;
51786
51831
  return obj;
@@ -51792,21 +51837,21 @@ var TunnelStore = class {
51792
51837
  }
51793
51838
  async set(v2) {
51794
51839
  const dir = import_node_path30.default.dirname(this.filePath);
51795
- await import_node_fs29.default.promises.mkdir(dir, { recursive: true });
51840
+ await import_node_fs30.default.promises.mkdir(dir, { recursive: true });
51796
51841
  const data = JSON.stringify(v2, null, 2);
51797
51842
  const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
51798
- await import_node_fs29.default.promises.writeFile(tmp, data, { mode: 384 });
51843
+ await import_node_fs30.default.promises.writeFile(tmp, data, { mode: 384 });
51799
51844
  if (process.platform !== "win32") {
51800
51845
  try {
51801
- await import_node_fs29.default.promises.chmod(tmp, 384);
51846
+ await import_node_fs30.default.promises.chmod(tmp, 384);
51802
51847
  } catch {
51803
51848
  }
51804
51849
  }
51805
- await import_node_fs29.default.promises.rename(tmp, this.filePath);
51850
+ await import_node_fs30.default.promises.rename(tmp, this.filePath);
51806
51851
  }
51807
51852
  async clear() {
51808
51853
  try {
51809
- await import_node_fs29.default.promises.unlink(this.filePath);
51854
+ await import_node_fs30.default.promises.unlink(this.filePath);
51810
51855
  } catch (err) {
51811
51856
  const code = err?.code;
51812
51857
  if (code !== "ENOENT") throw err;
@@ -51901,8 +51946,8 @@ function escape(v2) {
51901
51946
  }
51902
51947
 
51903
51948
  // src/tunnel/frpc-binary.ts
51904
- var import_node_fs30 = __toESM(require("fs"), 1);
51905
- 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);
51906
51951
  var import_node_path31 = __toESM(require("path"), 1);
51907
51952
  var import_node_child_process7 = require("child_process");
51908
51953
  var import_node_stream3 = require("stream");
@@ -51935,7 +51980,7 @@ function frpcDownloadUrl(version2, p2) {
51935
51980
  }
51936
51981
  async function ensureFrpcBinary(opts) {
51937
51982
  if (opts.override) {
51938
- if (!import_node_fs30.default.existsSync(opts.override)) {
51983
+ if (!import_node_fs31.default.existsSync(opts.override)) {
51939
51984
  throw new Error(`frpc binary not found at override path: ${opts.override}`);
51940
51985
  }
51941
51986
  return opts.override;
@@ -51943,10 +51988,10 @@ async function ensureFrpcBinary(opts) {
51943
51988
  const version2 = opts.version ?? FRPC_VERSION;
51944
51989
  const platform = opts.platform ?? detectPlatform();
51945
51990
  const binDir = import_node_path31.default.join(opts.dataDir, "bin");
51946
- import_node_fs30.default.mkdirSync(binDir, { recursive: true });
51991
+ import_node_fs31.default.mkdirSync(binDir, { recursive: true });
51947
51992
  cleanupStaleArtifacts(binDir);
51948
51993
  const stableBin = import_node_path31.default.join(binDir, "frpc");
51949
- if (import_node_fs30.default.existsSync(stableBin)) return stableBin;
51994
+ if (import_node_fs31.default.existsSync(stableBin)) return stableBin;
51950
51995
  const partialBin = `${stableBin}.partial`;
51951
51996
  const tarballPath = import_node_path31.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
51952
51997
  try {
@@ -51957,8 +52002,8 @@ async function ensureFrpcBinary(opts) {
51957
52002
  } else {
51958
52003
  await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
51959
52004
  }
51960
- import_node_fs30.default.chmodSync(partialBin, 493);
51961
- import_node_fs30.default.renameSync(partialBin, stableBin);
52005
+ import_node_fs31.default.chmodSync(partialBin, 493);
52006
+ import_node_fs31.default.renameSync(partialBin, stableBin);
51962
52007
  } finally {
51963
52008
  safeUnlink(tarballPath);
51964
52009
  safeUnlink(partialBin);
@@ -51968,7 +52013,7 @@ async function ensureFrpcBinary(opts) {
51968
52013
  function cleanupStaleArtifacts(binDir) {
51969
52014
  let entries;
51970
52015
  try {
51971
- entries = import_node_fs30.default.readdirSync(binDir);
52016
+ entries = import_node_fs31.default.readdirSync(binDir);
51972
52017
  } catch {
51973
52018
  return;
51974
52019
  }
@@ -51976,7 +52021,7 @@ function cleanupStaleArtifacts(binDir) {
51976
52021
  if (name.endsWith(".partial") || name.startsWith("extract-")) {
51977
52022
  const full = import_node_path31.default.join(binDir, name);
51978
52023
  try {
51979
- import_node_fs30.default.rmSync(full, { recursive: true, force: true });
52024
+ import_node_fs31.default.rmSync(full, { recursive: true, force: true });
51980
52025
  } catch {
51981
52026
  }
51982
52027
  }
@@ -51984,7 +52029,7 @@ function cleanupStaleArtifacts(binDir) {
51984
52029
  }
51985
52030
  function safeUnlink(p2) {
51986
52031
  try {
51987
- import_node_fs30.default.unlinkSync(p2);
52032
+ import_node_fs31.default.unlinkSync(p2);
51988
52033
  } catch {
51989
52034
  }
51990
52035
  }
@@ -51995,13 +52040,13 @@ async function downloadToFile(url, dest, fetchImpl) {
51995
52040
  if (!res.ok || !res.body) {
51996
52041
  throw new Error(`download failed: ${res.status} ${res.statusText}`);
51997
52042
  }
51998
- const out = import_node_fs30.default.createWriteStream(dest);
52043
+ const out = import_node_fs31.default.createWriteStream(dest);
51999
52044
  const nodeStream = import_node_stream3.Readable.fromWeb(res.body);
52000
52045
  await (0, import_promises4.pipeline)(nodeStream, out);
52001
52046
  }
52002
52047
  async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
52003
52048
  const work = import_node_path31.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
52004
- import_node_fs30.default.mkdirSync(work, { recursive: true });
52049
+ import_node_fs31.default.mkdirSync(work, { recursive: true });
52005
52050
  try {
52006
52051
  await new Promise((resolve6, reject) => {
52007
52052
  const proc = (0, import_node_child_process7.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
@@ -52010,17 +52055,17 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
52010
52055
  });
52011
52056
  const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
52012
52057
  const src = import_node_path31.default.join(work, dirName, "frpc");
52013
- if (!import_node_fs30.default.existsSync(src)) {
52058
+ if (!import_node_fs31.default.existsSync(src)) {
52014
52059
  throw new Error(`frpc not found inside tarball at ${src}`);
52015
52060
  }
52016
- import_node_fs30.default.copyFileSync(src, destBin);
52061
+ import_node_fs31.default.copyFileSync(src, destBin);
52017
52062
  } finally {
52018
- import_node_fs30.default.rmSync(work, { recursive: true, force: true });
52063
+ import_node_fs31.default.rmSync(work, { recursive: true, force: true });
52019
52064
  }
52020
52065
  }
52021
52066
 
52022
52067
  // src/tunnel/frpc-process.ts
52023
- var import_node_fs31 = __toESM(require("fs"), 1);
52068
+ var import_node_fs32 = __toESM(require("fs"), 1);
52024
52069
  var import_node_path32 = __toESM(require("path"), 1);
52025
52070
  var import_node_child_process8 = require("child_process");
52026
52071
  function frpcPidFilePath(dataDir) {
@@ -52028,13 +52073,13 @@ function frpcPidFilePath(dataDir) {
52028
52073
  }
52029
52074
  function writeFrpcPid(dataDir, pid) {
52030
52075
  try {
52031
- import_node_fs31.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
52076
+ import_node_fs32.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
52032
52077
  } catch {
52033
52078
  }
52034
52079
  }
52035
52080
  function clearFrpcPid(dataDir) {
52036
52081
  try {
52037
- import_node_fs31.default.unlinkSync(frpcPidFilePath(dataDir));
52082
+ import_node_fs32.default.unlinkSync(frpcPidFilePath(dataDir));
52038
52083
  } catch {
52039
52084
  }
52040
52085
  }
@@ -52050,7 +52095,7 @@ function defaultIsPidAlive(pid) {
52050
52095
  }
52051
52096
  function defaultReadPidFile(file) {
52052
52097
  try {
52053
- return import_node_fs31.default.readFileSync(file, "utf8");
52098
+ return import_node_fs32.default.readFileSync(file, "utf8");
52054
52099
  } catch {
52055
52100
  return null;
52056
52101
  }
@@ -52090,7 +52135,7 @@ async function killStaleFrpc(deps) {
52090
52135
  }
52091
52136
  if (victims.size === 0) {
52092
52137
  try {
52093
- import_node_fs31.default.unlinkSync(pidFile);
52138
+ import_node_fs32.default.unlinkSync(pidFile);
52094
52139
  } catch {
52095
52140
  }
52096
52141
  return;
@@ -52101,7 +52146,7 @@ async function killStaleFrpc(deps) {
52101
52146
  }
52102
52147
  await sleep2(deps.reapWaitMs ?? 300);
52103
52148
  try {
52104
- import_node_fs31.default.unlinkSync(pidFile);
52149
+ import_node_fs32.default.unlinkSync(pidFile);
52105
52150
  } catch {
52106
52151
  }
52107
52152
  }
@@ -52276,12 +52321,12 @@ var TunnelManager = class {
52276
52321
  localPort,
52277
52322
  logLevel: "info"
52278
52323
  });
52279
- await import_node_fs32.default.promises.writeFile(tomlPath, toml, { mode: 384 });
52324
+ await import_node_fs33.default.promises.writeFile(tomlPath, toml, { mode: 384 });
52280
52325
  const proc = (this.deps.spawnImpl ?? import_node_child_process9.spawn)(frpcBin, ["-c", tomlPath], {
52281
52326
  stdio: ["ignore", "pipe", "pipe"]
52282
52327
  });
52283
52328
  const logFilePath = import_node_path33.default.join(this.deps.dataDir, "frpc.log");
52284
- 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 });
52285
52330
  logStream.on("error", () => {
52286
52331
  });
52287
52332
  const tee = (chunk) => {
@@ -52363,14 +52408,14 @@ async function waitForFrpcReady(proc, timeoutMs) {
52363
52408
  }
52364
52409
 
52365
52410
  // src/tunnel/device-key.ts
52366
- var import_node_os14 = __toESM(require("os"), 1);
52411
+ var import_node_os13 = __toESM(require("os"), 1);
52367
52412
  var import_node_path34 = __toESM(require("path"), 1);
52368
52413
  var import_node_crypto10 = __toESM(require("crypto"), 1);
52369
52414
  var DERIVE_SALT = "clawd-tunnel-device-v1";
52370
52415
  function deriveStableDeviceKey(opts = {}) {
52371
- const hostname = opts.hostname ?? import_node_os14.default.hostname();
52372
- const uid = opts.uid ?? (typeof import_node_os14.default.userInfo === "function" ? import_node_os14.default.userInfo().uid : 0);
52373
- const home = opts.home ?? import_node_os14.default.homedir();
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();
52374
52419
  const defaultDataDir = import_node_path34.default.resolve(import_node_path34.default.join(home, ".clawd"));
52375
52420
  const normalizedDataDir = opts.dataDir ? import_node_path34.default.resolve(opts.dataDir) : null;
52376
52421
  const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
@@ -52379,7 +52424,7 @@ function deriveStableDeviceKey(opts = {}) {
52379
52424
  }
52380
52425
 
52381
52426
  // src/auth-store.ts
52382
- var import_node_fs33 = __toESM(require("fs"), 1);
52427
+ var import_node_fs34 = __toESM(require("fs"), 1);
52383
52428
  var import_node_path35 = __toESM(require("path"), 1);
52384
52429
  var import_node_crypto11 = __toESM(require("crypto"), 1);
52385
52430
  var AUTH_FILE_NAME = "auth.json";
@@ -52420,7 +52465,7 @@ function defaultGenerateOwnerPrincipalId() {
52420
52465
  }
52421
52466
  function readAuthFile(file) {
52422
52467
  try {
52423
- const raw = import_node_fs33.default.readFileSync(file, "utf8");
52468
+ const raw = import_node_fs34.default.readFileSync(file, "utf8");
52424
52469
  const parsed = JSON.parse(raw);
52425
52470
  if (typeof parsed?.token !== "string" || parsed.token.length === 0) {
52426
52471
  return null;
@@ -52440,25 +52485,25 @@ function readAuthFile(file) {
52440
52485
  }
52441
52486
  }
52442
52487
  function writeAuthFile(file, content) {
52443
- import_node_fs33.default.mkdirSync(import_node_path35.default.dirname(file), { recursive: true });
52444
- 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 });
52445
52490
  try {
52446
- import_node_fs33.default.chmodSync(file, 384);
52491
+ import_node_fs34.default.chmodSync(file, 384);
52447
52492
  } catch {
52448
52493
  }
52449
52494
  }
52450
52495
 
52451
52496
  // src/owner-profile.ts
52452
- var import_node_fs34 = __toESM(require("fs"), 1);
52453
- 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);
52454
52499
  var import_node_path36 = __toESM(require("path"), 1);
52455
52500
  var PROFILE_FILENAME = "profile.json";
52456
52501
  function loadOwnerDisplayName(dataDir) {
52457
- const fallback = import_node_os15.default.userInfo().username;
52502
+ const fallback = import_node_os14.default.userInfo().username;
52458
52503
  const profilePath = import_node_path36.default.join(dataDir, PROFILE_FILENAME);
52459
52504
  let raw;
52460
52505
  try {
52461
- raw = import_node_fs34.default.readFileSync(profilePath, "utf8");
52506
+ raw = import_node_fs35.default.readFileSync(profilePath, "utf8");
52462
52507
  } catch {
52463
52508
  return fallback;
52464
52509
  }
@@ -52481,7 +52526,7 @@ function loadOwnerDisplayName(dataDir) {
52481
52526
  }
52482
52527
 
52483
52528
  // src/feishu-auth/owner-identity-store.ts
52484
- var import_node_fs35 = __toESM(require("fs"), 1);
52529
+ var import_node_fs36 = __toESM(require("fs"), 1);
52485
52530
  var import_node_path37 = __toESM(require("path"), 1);
52486
52531
  var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
52487
52532
  var OwnerIdentityStore = class {
@@ -52492,7 +52537,7 @@ var OwnerIdentityStore = class {
52492
52537
  read() {
52493
52538
  let raw;
52494
52539
  try {
52495
- raw = import_node_fs35.default.readFileSync(this.file, "utf8");
52540
+ raw = import_node_fs36.default.readFileSync(this.file, "utf8");
52496
52541
  } catch {
52497
52542
  return null;
52498
52543
  }
@@ -52520,16 +52565,16 @@ var OwnerIdentityStore = class {
52520
52565
  };
52521
52566
  }
52522
52567
  write(record) {
52523
- import_node_fs35.default.mkdirSync(import_node_path37.default.dirname(this.file), { recursive: true });
52524
- 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 });
52525
52570
  try {
52526
- import_node_fs35.default.chmodSync(this.file, 384);
52571
+ import_node_fs36.default.chmodSync(this.file, 384);
52527
52572
  } catch {
52528
52573
  }
52529
52574
  }
52530
52575
  clear() {
52531
52576
  try {
52532
- import_node_fs35.default.unlinkSync(this.file);
52577
+ import_node_fs36.default.unlinkSync(this.file);
52533
52578
  } catch (err) {
52534
52579
  const code = err?.code;
52535
52580
  if (code !== "ENOENT") throw err;
@@ -52794,7 +52839,7 @@ function verifyConnectToken(args) {
52794
52839
  }
52795
52840
 
52796
52841
  // src/feishu-auth/server-key.ts
52797
- var fs45 = __toESM(require("fs"), 1);
52842
+ var fs46 = __toESM(require("fs"), 1);
52798
52843
  var path46 = __toESM(require("path"), 1);
52799
52844
  var FILE_NAME2 = "server-signing-key.json";
52800
52845
  var ServerKeyStore = class {
@@ -52808,7 +52853,7 @@ var ServerKeyStore = class {
52808
52853
  /** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
52809
52854
  read() {
52810
52855
  try {
52811
- const raw = fs45.readFileSync(this.filePath(), "utf8");
52856
+ const raw = fs46.readFileSync(this.filePath(), "utf8");
52812
52857
  const parsed = JSON.parse(raw);
52813
52858
  if (typeof parsed.publicKeyPem === "string" && parsed.publicKeyPem.includes("PUBLIC KEY")) {
52814
52859
  return parsed.publicKeyPem;
@@ -52823,12 +52868,12 @@ var ServerKeyStore = class {
52823
52868
  publicKeyPem,
52824
52869
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
52825
52870
  };
52826
- fs45.mkdirSync(this.dataDir, { recursive: true });
52827
- 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 });
52828
52873
  }
52829
52874
  clear() {
52830
52875
  try {
52831
- fs45.unlinkSync(this.filePath());
52876
+ fs46.unlinkSync(this.filePath());
52832
52877
  } catch {
52833
52878
  }
52834
52879
  }
@@ -52841,12 +52886,12 @@ init_protocol();
52841
52886
  init_protocol();
52842
52887
 
52843
52888
  // src/session/fork.ts
52844
- var import_node_fs36 = __toESM(require("fs"), 1);
52845
- 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);
52846
52891
  var import_node_path38 = __toESM(require("path"), 1);
52847
52892
  init_claude_history();
52848
52893
  function readJsonlEntries(file) {
52849
- const raw = import_node_fs36.default.readFileSync(file, "utf8");
52894
+ const raw = import_node_fs37.default.readFileSync(file, "utf8");
52850
52895
  const out = [];
52851
52896
  for (const line of raw.split("\n")) {
52852
52897
  const t = line.trim();
@@ -52859,10 +52904,10 @@ function readJsonlEntries(file) {
52859
52904
  return out;
52860
52905
  }
52861
52906
  function forkSession(input) {
52862
- 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");
52863
52908
  const projectDir = import_node_path38.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
52864
52909
  const sourceFile = import_node_path38.default.join(projectDir, `${input.toolSessionId}.jsonl`);
52865
- if (!import_node_fs36.default.existsSync(sourceFile)) {
52910
+ if (!import_node_fs37.default.existsSync(sourceFile)) {
52866
52911
  throw new Error(`fork: source transcript not found: ${sourceFile}`);
52867
52912
  }
52868
52913
  const entries = readJsonlEntries(sourceFile);
@@ -52893,8 +52938,8 @@ function forkSession(input) {
52893
52938
  forkedLines.push(JSON.stringify(forked));
52894
52939
  }
52895
52940
  const forkedFilePath = import_node_path38.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
52896
- import_node_fs36.default.mkdirSync(projectDir, { recursive: true });
52897
- 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 });
52898
52943
  return { forkedToolSessionId, forkedFilePath };
52899
52944
  }
52900
52945
 
@@ -53415,7 +53460,7 @@ function buildHistoryHandlers(deps) {
53415
53460
 
53416
53461
  // src/handlers/workspace.ts
53417
53462
  var path50 = __toESM(require("path"), 1);
53418
- var os16 = __toESM(require("os"), 1);
53463
+ var os15 = __toESM(require("os"), 1);
53419
53464
  init_protocol();
53420
53465
  init_protocol();
53421
53466
  function buildEnabledPluginNames(personaManager, personaId) {
@@ -53455,7 +53500,7 @@ function buildWorkspaceHandlers(deps) {
53455
53500
  const list = async (frame, _client, ctx) => {
53456
53501
  const args = WorkspaceListArgs.parse(frame);
53457
53502
  const isGuest = ctx?.principal.kind === "guest";
53458
- const fallbackCwd = isGuest && personaRoot ? personaRoot : os16.homedir();
53503
+ const fallbackCwd = isGuest && personaRoot ? personaRoot : os15.homedir();
53459
53504
  const resolvedCwd = path50.resolve(args.cwd ?? fallbackCwd);
53460
53505
  const target = args.path ? path50.resolve(resolvedCwd, args.path) : resolvedCwd;
53461
53506
  assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
@@ -53511,14 +53556,14 @@ init_protocol();
53511
53556
 
53512
53557
  // src/workspace/git.ts
53513
53558
  var import_node_child_process10 = require("child_process");
53514
- var import_node_fs37 = __toESM(require("fs"), 1);
53559
+ var import_node_fs38 = __toESM(require("fs"), 1);
53515
53560
  var import_node_path39 = __toESM(require("path"), 1);
53516
53561
  var import_node_util = require("util");
53517
53562
  var pexec = (0, import_node_util.promisify)(import_node_child_process10.execFile);
53518
53563
  function normalizePath(p2) {
53519
53564
  const resolved = import_node_path39.default.resolve(p2);
53520
53565
  try {
53521
- return import_node_fs37.default.realpathSync(resolved);
53566
+ return import_node_fs38.default.realpathSync(resolved);
53522
53567
  } catch {
53523
53568
  return resolved;
53524
53569
  }
@@ -53714,7 +53759,8 @@ function buildInboxHandlers(deps) {
53714
53759
  senderDeviceId: ctx.principal.id,
53715
53760
  text: args.text,
53716
53761
  id: args.id,
53717
- createdAt: args.createdAt
53762
+ createdAt: args.createdAt,
53763
+ origin: args.origin
53718
53764
  });
53719
53765
  return {
53720
53766
  response: { type: "inbox:postMessage:ok", message }
@@ -53753,8 +53799,66 @@ function buildInboxHandlers(deps) {
53753
53799
  }
53754
53800
  };
53755
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
+ };
53756
53859
  return {
53757
53860
  "inbox:postMessage": postMessage,
53861
+ "inbox:sendDm": sendDm,
53758
53862
  "inbox:list": list,
53759
53863
  "inbox:markRead": markRead
53760
53864
  };
@@ -53981,7 +54085,7 @@ function buildDeviceHandlers(deps) {
53981
54085
  }
53982
54086
 
53983
54087
  // src/handlers/meta.ts
53984
- var import_node_os17 = __toESM(require("os"), 1);
54088
+ var import_node_os16 = __toESM(require("os"), 1);
53985
54089
  init_protocol();
53986
54090
 
53987
54091
  // src/version.ts
@@ -54013,7 +54117,7 @@ function buildReadyFrame(deps, client) {
54013
54117
  return {
54014
54118
  version,
54015
54119
  protocolVersion: PROTOCOL_VERSION,
54016
- hostname: import_node_os17.default.hostname(),
54120
+ hostname: import_node_os16.default.hostname(),
54017
54121
  os: process.platform,
54018
54122
  tools,
54019
54123
  runningSessions: info.runningSessions,
@@ -54383,15 +54487,15 @@ function computePublishCheck(args) {
54383
54487
  // src/extension/install-flow.ts
54384
54488
  var import_promises6 = __toESM(require("fs/promises"), 1);
54385
54489
  var import_node_path43 = __toESM(require("path"), 1);
54386
- var import_node_os19 = __toESM(require("os"), 1);
54490
+ var import_node_os18 = __toESM(require("os"), 1);
54387
54491
  var import_node_crypto14 = __toESM(require("crypto"), 1);
54388
54492
  var import_jszip3 = __toESM(require_lib3(), 1);
54389
54493
 
54390
54494
  // src/extension/paths.ts
54391
- var import_node_os18 = __toESM(require("os"), 1);
54495
+ var import_node_os17 = __toESM(require("os"), 1);
54392
54496
  var import_node_path42 = __toESM(require("path"), 1);
54393
54497
  function clawdHomeRoot(override) {
54394
- 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");
54395
54499
  }
54396
54500
  function extensionsRoot(override) {
54397
54501
  return import_node_path42.default.join(clawdHomeRoot(override), "extensions");
@@ -54473,7 +54577,7 @@ async function installFromChannel(args, deps) {
54473
54577
  );
54474
54578
  }
54475
54579
  const stage = await import_promises6.default.mkdtemp(
54476
- 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}-`)
54477
54581
  );
54478
54582
  try {
54479
54583
  for (const [name, entry] of Object.entries(zip.files)) {
@@ -54504,7 +54608,7 @@ async function installFromChannel(args, deps) {
54504
54608
  // src/extension/update-flow.ts
54505
54609
  var import_promises7 = __toESM(require("fs/promises"), 1);
54506
54610
  var import_node_path44 = __toESM(require("path"), 1);
54507
- var import_node_os20 = __toESM(require("os"), 1);
54611
+ var import_node_os19 = __toESM(require("os"), 1);
54508
54612
  var import_node_crypto15 = __toESM(require("crypto"), 1);
54509
54613
  var import_jszip4 = __toESM(require_lib3(), 1);
54510
54614
  var UpdateError = class extends Error {
@@ -54592,7 +54696,7 @@ async function updateFromChannel(args, deps) {
54592
54696
  await import_promises7.default.rm(prevDir, { recursive: true, force: true });
54593
54697
  await import_promises7.default.rename(liveDir, prevDir);
54594
54698
  const stage = await import_promises7.default.mkdtemp(
54595
- 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}-`)
54596
54700
  );
54597
54701
  try {
54598
54702
  for (const [name, entry] of Object.entries(zip.files)) {
@@ -54974,7 +55078,7 @@ function buildExtensionHandlers(deps) {
54974
55078
  }
54975
55079
 
54976
55080
  // src/app-builder/project-store.ts
54977
- var import_node_fs38 = require("fs");
55081
+ var import_node_fs39 = require("fs");
54978
55082
  var import_node_child_process11 = require("child_process");
54979
55083
  var import_node_path46 = require("path");
54980
55084
  init_protocol();
@@ -55002,7 +55106,7 @@ var ProjectStore = class {
55002
55106
  async list() {
55003
55107
  let entries;
55004
55108
  try {
55005
- entries = await import_node_fs38.promises.readdir(this.projectsRoot());
55109
+ entries = await import_node_fs39.promises.readdir(this.projectsRoot());
55006
55110
  } catch (err) {
55007
55111
  if (err.code === "ENOENT") return [];
55008
55112
  throw err;
@@ -55010,7 +55114,7 @@ var ProjectStore = class {
55010
55114
  const out = [];
55011
55115
  for (const name of entries) {
55012
55116
  try {
55013
- 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");
55014
55118
  const json = JSON.parse(raw);
55015
55119
  let migrated = false;
55016
55120
  if (typeof json.devCommand !== "string" || json.devCommand.length === 0) {
@@ -55021,7 +55125,7 @@ var ProjectStore = class {
55021
55125
  if (parsed.success) {
55022
55126
  out.push(parsed.data);
55023
55127
  if (migrated) {
55024
- 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(() => {
55025
55129
  });
55026
55130
  }
55027
55131
  }
@@ -55065,8 +55169,8 @@ var ProjectStore = class {
55065
55169
  throw new Error(`invalid name "${name}": ${validated.error.message}`);
55066
55170
  }
55067
55171
  const dir = this.projectDir(name);
55068
- await import_node_fs38.promises.mkdir(dir, { recursive: true });
55069
- 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");
55070
55174
  return meta;
55071
55175
  }
55072
55176
  /**
@@ -55109,7 +55213,7 @@ var ProjectStore = class {
55109
55213
  }
55110
55214
  async delete(name) {
55111
55215
  const dir = this.projectDir(name);
55112
- await import_node_fs38.promises.rm(dir, { recursive: true, force: true });
55216
+ await import_node_fs39.promises.rm(dir, { recursive: true, force: true });
55113
55217
  }
55114
55218
  async updatePort(name, newPort) {
55115
55219
  if (newPort < PROJECT_PORT_MIN || newPort > PROJECT_PORT_MAX) {
@@ -55125,7 +55229,7 @@ var ProjectStore = class {
55125
55229
  throw new Error(`port ${newPort} already used / \u5DF2\u88AB project "${conflict.name}" \u5360\u7528`);
55126
55230
  }
55127
55231
  const updated = { ...target, port: newPort };
55128
- 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");
55129
55233
  return updated;
55130
55234
  }
55131
55235
  /**
@@ -55142,7 +55246,7 @@ var ProjectStore = class {
55142
55246
  if (!validated.success) {
55143
55247
  throw new Error(`invalid prodUrl "${url}": ${validated.error.message}`);
55144
55248
  }
55145
- 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");
55146
55250
  return validated.data;
55147
55251
  }
55148
55252
  /**
@@ -55163,7 +55267,7 @@ var ProjectStore = class {
55163
55267
  if (!validated.success) {
55164
55268
  throw new Error(`invalid publishJob: ${validated.error.message}`);
55165
55269
  }
55166
- 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");
55167
55271
  return validated.data;
55168
55272
  }
55169
55273
  /** 清掉 .clawd-project.json.publishJob 字段。其他字段保持原样。 */
@@ -55178,7 +55282,7 @@ var ProjectStore = class {
55178
55282
  if (!validated.success) {
55179
55283
  throw new Error(`failed to clear publishJob: ${validated.error.message}`);
55180
55284
  }
55181
- 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");
55182
55286
  return validated.data;
55183
55287
  }
55184
55288
  };
@@ -55299,7 +55403,7 @@ var PublishJobRegistry = class {
55299
55403
 
55300
55404
  // src/app-builder/publish-job-runner.ts
55301
55405
  var import_node_child_process13 = require("child_process");
55302
- var import_node_fs39 = require("fs");
55406
+ var import_node_fs40 = require("fs");
55303
55407
  var import_node_path47 = require("path");
55304
55408
 
55305
55409
  // src/app-builder/publish-stage-parser.ts
@@ -55335,7 +55439,7 @@ async function startPublishJob(deps, args) {
55335
55439
  const logPath = (0, import_node_path47.join)(projDir, ".publish.log");
55336
55440
  let logStream = null;
55337
55441
  try {
55338
- logStream = (0, import_node_fs39.createWriteStream)(logPath, { flags: "w" });
55442
+ logStream = (0, import_node_fs40.createWriteStream)(logPath, { flags: "w" });
55339
55443
  } catch {
55340
55444
  logStream = null;
55341
55445
  }
@@ -55593,7 +55697,7 @@ async function recoverInterruptedJobs(deps) {
55593
55697
  // src/handlers/app-builder.ts
55594
55698
  init_protocol();
55595
55699
  var import_node_path48 = require("path");
55596
- var import_node_fs40 = require("fs");
55700
+ var import_node_fs41 = require("fs");
55597
55701
  var APP_BUILDER_PERSONAS = ["persona-app-builder", "persona-dataclaw-builder"];
55598
55702
  var DEV_SERVER_READY_TIMEOUT_MS = 3e4;
55599
55703
  async function recoverInterruptedPublishJobs(store, logger) {
@@ -55674,7 +55778,7 @@ function buildAppBuilderHandlers(deps) {
55674
55778
  async function listAllUsersProjects() {
55675
55779
  if (!deps.usersRoot || !deps.getStore) return [];
55676
55780
  const getStore = deps.getStore;
55677
- const userIds = await import_node_fs40.promises.readdir(deps.usersRoot).catch(() => []);
55781
+ const userIds = await import_node_fs41.promises.readdir(deps.usersRoot).catch(() => []);
55678
55782
  const perUser = await Promise.all(
55679
55783
  userIds.map((uid) => getStore(uid).list().catch(() => []))
55680
55784
  );
@@ -56225,6 +56329,7 @@ async function uninstall(deps) {
56225
56329
  }
56226
56330
 
56227
56331
  // src/handlers/index.ts
56332
+ var import_node_crypto17 = require("crypto");
56228
56333
  function buildMethodHandlers(deps) {
56229
56334
  return {
56230
56335
  ...buildSessionHandlers({
@@ -56249,7 +56354,18 @@ function buildMethodHandlers(deps) {
56249
56354
  manager: deps.capabilityManager
56250
56355
  }),
56251
56356
  ...buildInboxHandlers({
56252
- 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
+ }
56253
56369
  }),
56254
56370
  ...buildContactHandlers({
56255
56371
  store: deps.contactStore,
@@ -57137,7 +57253,7 @@ async function startDaemon(config) {
57137
57253
  },
57138
57254
  source: "daemon",
57139
57255
  sampling: logShippingCfg.sampling,
57140
- homeDir: import_node_os21.default.homedir()
57256
+ homeDir: import_node_os20.default.homedir()
57141
57257
  });
57142
57258
  const logger = createLogger({
57143
57259
  level: config.logLevel,
@@ -57309,7 +57425,7 @@ async function startDaemon(config) {
57309
57425
  import_node_path54.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
57310
57426
  // dev tsx src/index → ../dist/dispatch/mcp-server.cjs
57311
57427
  ];
57312
- const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs41.default.existsSync(p2));
57428
+ const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs42.default.existsSync(p2));
57313
57429
  let dispatchMcpConfigPath2;
57314
57430
  if (dispatchServerScriptPath) {
57315
57431
  const dispatchLogPath = import_node_path54.default.join(config.dataDir, "dispatch-mcp-server.log");
@@ -57332,7 +57448,7 @@ async function startDaemon(config) {
57332
57448
  import_node_path54.default.join(here, "ticket", "mcp-server.cjs"),
57333
57449
  import_node_path54.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
57334
57450
  ];
57335
- const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs41.default.existsSync(p2));
57451
+ const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs42.default.existsSync(p2));
57336
57452
  const ticketOwnerUnionId = feishuIdentity?.identity.unionId ?? "";
57337
57453
  const ticketOwnerName = feishuIdentity?.identity.displayName ?? "";
57338
57454
  let ticketMcpConfigPath2;
@@ -57361,7 +57477,7 @@ async function startDaemon(config) {
57361
57477
  import_node_path54.default.join(here, "shift", "mcp-server.cjs"),
57362
57478
  import_node_path54.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
57363
57479
  ];
57364
- const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs41.default.existsSync(p2));
57480
+ const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs42.default.existsSync(p2));
57365
57481
  let shiftMcpConfigPath2;
57366
57482
  if (shiftServerScriptPath) {
57367
57483
  const shiftLogPath = import_node_path54.default.join(config.dataDir, "shift-mcp-server.log");
@@ -57381,6 +57497,27 @@ async function startDaemon(config) {
57381
57497
  { tried: shiftServerCandidates }
57382
57498
  );
57383
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
+ }
57384
57521
  const shiftStore = createShiftStore({
57385
57522
  filePath: import_node_path54.default.join(config.dataDir, "shift.json"),
57386
57523
  ownerIdProvider: () => ownerPrincipalId,
@@ -57422,6 +57559,8 @@ async function startDaemon(config) {
57422
57559
  // shift v1:所有 persona session 都挂 shift.mcp.json(不做 persona gating)。
57423
57560
  // 缺省 = shift-mcp-server.cjs 没 build 出来,cc 看不到 shift tool 但 scheduler 仍跑。
57424
57561
  shiftMcpConfigPath: shiftMcpConfigPath2,
57562
+ // sendDm MCP tool:所有 persona session 都挂 inbox.mcp.json(无 gating)。
57563
+ inboxMcpConfigPath: inboxMcpConfigPath2,
57425
57564
  broadcastFrame: (frame, target) => {
57426
57565
  if (target === "all") {
57427
57566
  transport?.broadcastAll(frame);
@@ -57444,7 +57583,7 @@ async function startDaemon(config) {
57444
57583
  const absPath = import_node_path54.default.isAbsolute(input.relPath) ? input.relPath : import_node_path54.default.join(input.cwd, input.relPath);
57445
57584
  let size = 0;
57446
57585
  try {
57447
- size = import_node_fs41.default.statSync(absPath).size;
57586
+ size = import_node_fs42.default.statSync(absPath).size;
57448
57587
  } catch (err) {
57449
57588
  logger.warn("attachment.onFileEdit stat failed", {
57450
57589
  sessionId: input.sessionId,
@@ -57666,6 +57805,8 @@ async function startDaemon(config) {
57666
57805
  inboxStore,
57667
57806
  // 联系人列表 store(device:connect / 自动反向落同一 store)
57668
57807
  contactStore,
57808
+ // inbox:sendDm 用:sessionId → session 出身(复用 attachment 同款 findOwnedSessionScope)
57809
+ getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
57669
57810
  // contact:removed broadcast;复用 capability:tokenIssued 同款通路
57670
57811
  broadcastToOwners: (frame) => wsServer?.broadcastToOwners(frame),
57671
57812
  // extension runtime (v1: local-mode only). Instance owned by daemon top
@@ -57801,7 +57942,7 @@ async function startDaemon(config) {
57801
57942
  let sourceJsonlPath = "(no transcript yet \u2014 operate from the task description alone)";
57802
57943
  if (sourceFile && sourceFile.toolSessionId) {
57803
57944
  sourceJsonlPath = import_node_path54.default.join(
57804
- import_node_os21.default.homedir(),
57945
+ import_node_os20.default.homedir(),
57805
57946
  ".claude",
57806
57947
  "projects",
57807
57948
  cwdToHashDir(sourceFile.cwd),
@@ -58115,7 +58256,7 @@ ${bar}
58115
58256
  `);
58116
58257
  try {
58117
58258
  const connectPath = import_node_path54.default.join(config.dataDir, "connect.txt");
58118
- 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 });
58119
58260
  } catch {
58120
58261
  }
58121
58262
  } catch (err) {
@@ -58189,7 +58330,7 @@ ${bar}
58189
58330
  function migrateDropPersonsDir(dataDir) {
58190
58331
  const dir = import_node_path54.default.join(dataDir, "persons");
58191
58332
  try {
58192
- import_node_fs41.default.rmSync(dir, { recursive: true, force: true });
58333
+ import_node_fs42.default.rmSync(dir, { recursive: true, force: true });
58193
58334
  } catch {
58194
58335
  }
58195
58336
  }