@clawos-dev/clawd 0.2.33 → 0.2.34-beta.50.1515dc2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.cjs +257 -183
  2. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -296,8 +296,8 @@ var require_req = __commonJS({
296
296
  if (req.originalUrl) {
297
297
  _req.url = req.originalUrl;
298
298
  } else {
299
- const path22 = req.path;
300
- _req.url = typeof path22 === "string" ? path22 : req.url ? req.url.path || req.url : void 0;
299
+ const path23 = req.path;
300
+ _req.url = typeof path23 === "string" ? path23 : req.url ? req.url.path || req.url : void 0;
301
301
  }
302
302
  if (req.query) {
303
303
  _req.query = req.query;
@@ -462,14 +462,14 @@ var require_redact = __commonJS({
462
462
  }
463
463
  return obj;
464
464
  }
465
- function parsePath(path22) {
465
+ function parsePath(path23) {
466
466
  const parts = [];
467
467
  let current = "";
468
468
  let inBrackets = false;
469
469
  let inQuotes = false;
470
470
  let quoteChar = "";
471
- for (let i = 0; i < path22.length; i++) {
472
- const char = path22[i];
471
+ for (let i = 0; i < path23.length; i++) {
472
+ const char = path23[i];
473
473
  if (!inBrackets && char === ".") {
474
474
  if (current) {
475
475
  parts.push(current);
@@ -600,10 +600,10 @@ var require_redact = __commonJS({
600
600
  return current;
601
601
  }
602
602
  function redactPaths(obj, paths, censor, remove = false) {
603
- for (const path22 of paths) {
604
- const parts = parsePath(path22);
603
+ for (const path23 of paths) {
604
+ const parts = parsePath(path23);
605
605
  if (parts.includes("*")) {
606
- redactWildcardPath(obj, parts, censor, path22, remove);
606
+ redactWildcardPath(obj, parts, censor, path23, remove);
607
607
  } else {
608
608
  if (remove) {
609
609
  removeKey(obj, parts);
@@ -688,8 +688,8 @@ var require_redact = __commonJS({
688
688
  }
689
689
  } else {
690
690
  if (afterWildcard.includes("*")) {
691
- const wrappedCensor = typeof censor === "function" ? (value, path22) => {
692
- const fullPath = [...pathArray.slice(0, pathLength), ...path22];
691
+ const wrappedCensor = typeof censor === "function" ? (value, path23) => {
692
+ const fullPath = [...pathArray.slice(0, pathLength), ...path23];
693
693
  return censor(value, fullPath);
694
694
  } : censor;
695
695
  redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
@@ -724,8 +724,8 @@ var require_redact = __commonJS({
724
724
  return null;
725
725
  }
726
726
  const pathStructure = /* @__PURE__ */ new Map();
727
- for (const path22 of pathsToClone) {
728
- const parts = parsePath(path22);
727
+ for (const path23 of pathsToClone) {
728
+ const parts = parsePath(path23);
729
729
  let current = pathStructure;
730
730
  for (let i = 0; i < parts.length; i++) {
731
731
  const part = parts[i];
@@ -777,24 +777,24 @@ var require_redact = __commonJS({
777
777
  }
778
778
  return cloneSelectively(obj, pathStructure);
779
779
  }
780
- function validatePath(path22) {
781
- if (typeof path22 !== "string") {
780
+ function validatePath(path23) {
781
+ if (typeof path23 !== "string") {
782
782
  throw new Error("Paths must be (non-empty) strings");
783
783
  }
784
- if (path22 === "") {
784
+ if (path23 === "") {
785
785
  throw new Error("Invalid redaction path ()");
786
786
  }
787
- if (path22.includes("..")) {
788
- throw new Error(`Invalid redaction path (${path22})`);
787
+ if (path23.includes("..")) {
788
+ throw new Error(`Invalid redaction path (${path23})`);
789
789
  }
790
- if (path22.includes(",")) {
791
- throw new Error(`Invalid redaction path (${path22})`);
790
+ if (path23.includes(",")) {
791
+ throw new Error(`Invalid redaction path (${path23})`);
792
792
  }
793
793
  let bracketCount = 0;
794
794
  let inQuotes = false;
795
795
  let quoteChar = "";
796
- for (let i = 0; i < path22.length; i++) {
797
- const char = path22[i];
796
+ for (let i = 0; i < path23.length; i++) {
797
+ const char = path23[i];
798
798
  if ((char === '"' || char === "'") && bracketCount > 0) {
799
799
  if (!inQuotes) {
800
800
  inQuotes = true;
@@ -808,20 +808,20 @@ var require_redact = __commonJS({
808
808
  } else if (char === "]" && !inQuotes) {
809
809
  bracketCount--;
810
810
  if (bracketCount < 0) {
811
- throw new Error(`Invalid redaction path (${path22})`);
811
+ throw new Error(`Invalid redaction path (${path23})`);
812
812
  }
813
813
  }
814
814
  }
815
815
  if (bracketCount !== 0) {
816
- throw new Error(`Invalid redaction path (${path22})`);
816
+ throw new Error(`Invalid redaction path (${path23})`);
817
817
  }
818
818
  }
819
819
  function validatePaths(paths) {
820
820
  if (!Array.isArray(paths)) {
821
821
  throw new TypeError("paths must be an array");
822
822
  }
823
- for (const path22 of paths) {
824
- validatePath(path22);
823
+ for (const path23 of paths) {
824
+ validatePath(path23);
825
825
  }
826
826
  }
827
827
  function slowRedact(options = {}) {
@@ -989,8 +989,8 @@ var require_redaction = __commonJS({
989
989
  if (shape[k] === null) {
990
990
  o[k] = (value) => topCensor(value, [k]);
991
991
  } else {
992
- const wrappedCensor = typeof censor === "function" ? (value, path22) => {
993
- return censor(value, [k, ...path22]);
992
+ const wrappedCensor = typeof censor === "function" ? (value, path23) => {
993
+ return censor(value, [k, ...path23]);
994
994
  } : censor;
995
995
  o[k] = Redact({
996
996
  paths: shape[k],
@@ -1211,7 +1211,7 @@ var require_sonic_boom = __commonJS({
1211
1211
  var fs22 = require("fs");
1212
1212
  var EventEmitter = require("events");
1213
1213
  var inherits = require("util").inherits;
1214
- var path22 = require("path");
1214
+ var path23 = require("path");
1215
1215
  var sleep = require_atomic_sleep();
1216
1216
  var assert = require("assert");
1217
1217
  var BUSY_WRITE_TIMEOUT = 100;
@@ -1265,7 +1265,7 @@ var require_sonic_boom = __commonJS({
1265
1265
  const mode = sonic.mode;
1266
1266
  if (sonic.sync) {
1267
1267
  try {
1268
- if (sonic.mkdir) fs22.mkdirSync(path22.dirname(file), { recursive: true });
1268
+ if (sonic.mkdir) fs22.mkdirSync(path23.dirname(file), { recursive: true });
1269
1269
  const fd = fs22.openSync(file, flags, mode);
1270
1270
  fileOpened(null, fd);
1271
1271
  } catch (err) {
@@ -1273,7 +1273,7 @@ var require_sonic_boom = __commonJS({
1273
1273
  throw err;
1274
1274
  }
1275
1275
  } else if (sonic.mkdir) {
1276
- fs22.mkdir(path22.dirname(file), { recursive: true }, (err) => {
1276
+ fs22.mkdir(path23.dirname(file), { recursive: true }, (err) => {
1277
1277
  if (err) return fileOpened(err);
1278
1278
  fs22.open(file, flags, mode, fileOpened);
1279
1279
  });
@@ -4892,8 +4892,8 @@ var init_parseUtil = __esm({
4892
4892
  init_errors2();
4893
4893
  init_en();
4894
4894
  makeIssue = (params) => {
4895
- const { data, path: path22, errorMaps, issueData } = params;
4896
- const fullPath = [...path22, ...issueData.path || []];
4895
+ const { data, path: path23, errorMaps, issueData } = params;
4896
+ const fullPath = [...path23, ...issueData.path || []];
4897
4897
  const fullIssue = {
4898
4898
  ...issueData,
4899
4899
  path: fullPath
@@ -5204,11 +5204,11 @@ var init_types = __esm({
5204
5204
  init_parseUtil();
5205
5205
  init_util();
5206
5206
  ParseInputLazyPath = class {
5207
- constructor(parent, value, path22, key) {
5207
+ constructor(parent, value, path23, key) {
5208
5208
  this._cachedPath = [];
5209
5209
  this.parent = parent;
5210
5210
  this.data = value;
5211
- this._path = path22;
5211
+ this._path = path23;
5212
5212
  this._key = key;
5213
5213
  }
5214
5214
  get path() {
@@ -8741,6 +8741,9 @@ var init_schemas = __esm({
8741
8741
  // 由 session:fork 派生的 session 在 create 时记录源 transcript 的 toolSessionId;
8742
8742
  // sidebar 据此挂 fork 图标。非 fork session 该字段缺省
8743
8743
  forkedFromToolSessionId: external_exports.string().min(1).optional(),
8744
+ // owner-mode persona session 身份标识;UI 用它在 SessionList 过滤 + jump,
8745
+ // daemon 用它做 idempotent dedupe + spawn 时派生 ctx.personaMode='owner'
8746
+ ownerPersonaId: external_exports.string().min(1).optional(),
8744
8747
  createdAt: external_exports.string().min(1),
8745
8748
  updatedAt: external_exports.string().min(1)
8746
8749
  });
@@ -8940,7 +8943,8 @@ var init_schemas = __esm({
8940
8943
  })
8941
8944
  ]);
8942
8945
  SessionCreateArgs = external_exports.object({
8943
- cwd: external_exports.string().min(1),
8946
+ // 当 ownerPersonaId 存在时 cwd 由 daemon 派生,UI 可不传
8947
+ cwd: external_exports.string().min(1).optional(),
8944
8948
  tool: external_exports.string().optional(),
8945
8949
  label: external_exports.string().optional(),
8946
8950
  model: external_exports.string().optional(),
@@ -8952,7 +8956,12 @@ var init_schemas = __esm({
8952
8956
  worktreeRoot: external_exports.string().min(1).optional(),
8953
8957
  worktreeBranch: external_exports.string().min(1).optional(),
8954
8958
  // session:fork 派生 session 时由 UI 传入,daemon 写到 SessionFile.forkedFromToolSessionId
8955
- forkedFromToolSessionId: external_exports.string().min(1).optional()
8959
+ forkedFromToolSessionId: external_exports.string().min(1).optional(),
8960
+ // owner-mode persona session:传此字段时 daemon 自行派生 cwd 和启动参数,
8961
+ // 且按 ownerPersonaId 做 idempotent dedupe(每 persona 永远只有一个 owner session)
8962
+ ownerPersonaId: external_exports.string().min(1).optional()
8963
+ }).refine((args) => args.cwd != null || args.ownerPersonaId != null, {
8964
+ message: "cwd \u4E0E ownerPersonaId \u81F3\u5C11\u4F20\u4E00\u4E2A"
8956
8965
  });
8957
8966
  SessionIdArgs = external_exports.object({ sessionId: external_exports.string().min(1) });
8958
8967
  SessionUpdateArgs = external_exports.object({
@@ -9202,6 +9211,13 @@ var init_frames = __esm({
9202
9211
  }
9203
9212
  });
9204
9213
 
9214
+ // ../protocol/src/persona-mode.ts
9215
+ var init_persona_mode = __esm({
9216
+ "../protocol/src/persona-mode.ts"() {
9217
+ "use strict";
9218
+ }
9219
+ });
9220
+
9205
9221
  // ../protocol/src/runtime.ts
9206
9222
  var init_runtime = __esm({
9207
9223
  "../protocol/src/runtime.ts"() {
@@ -9212,6 +9228,7 @@ var init_runtime = __esm({
9212
9228
  init_schemas();
9213
9229
  init_frames();
9214
9230
  init_persona_schemas();
9231
+ init_persona_mode();
9215
9232
  }
9216
9233
  });
9217
9234
 
@@ -9788,11 +9805,11 @@ var init_lib = __esm({
9788
9805
  }
9789
9806
  }
9790
9807
  },
9791
- addToPath: function addToPath(path22, added, removed, oldPosInc, options) {
9792
- var last = path22.lastComponent;
9808
+ addToPath: function addToPath(path23, added, removed, oldPosInc, options) {
9809
+ var last = path23.lastComponent;
9793
9810
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
9794
9811
  return {
9795
- oldPos: path22.oldPos + oldPosInc,
9812
+ oldPos: path23.oldPos + oldPosInc,
9796
9813
  lastComponent: {
9797
9814
  count: last.count + 1,
9798
9815
  added,
@@ -9802,7 +9819,7 @@ var init_lib = __esm({
9802
9819
  };
9803
9820
  } else {
9804
9821
  return {
9805
- oldPos: path22.oldPos + oldPosInc,
9822
+ oldPos: path23.oldPos + oldPosInc,
9806
9823
  lastComponent: {
9807
9824
  count: 1,
9808
9825
  added,
@@ -10233,10 +10250,10 @@ function attachmentToHistoryMessage(o, ts) {
10233
10250
  const memories = raw.map((m) => {
10234
10251
  if (!m || typeof m !== "object") return null;
10235
10252
  const rec = m;
10236
- const path22 = typeof rec.path === "string" ? rec.path : null;
10253
+ const path23 = typeof rec.path === "string" ? rec.path : null;
10237
10254
  const content = typeof rec.content === "string" ? rec.content : null;
10238
- if (!path22 || content == null) return null;
10239
- const entry = { path: path22, content };
10255
+ if (!path23 || content == null) return null;
10256
+ const entry = { path: path23, content };
10240
10257
  if (typeof rec.mtimeMs === "number") entry.mtimeMs = rec.mtimeMs;
10241
10258
  return entry;
10242
10259
  }).filter((m) => m !== null);
@@ -10273,7 +10290,7 @@ function readBackupContent(fileHistoryRoot, toolSessionId, backupFileName) {
10273
10290
  if (backupFileName === null) return null;
10274
10291
  try {
10275
10292
  return import_node_fs6.default.readFileSync(
10276
- import_node_path5.default.join(fileHistoryRoot, toolSessionId, backupFileName),
10293
+ import_node_path6.default.join(fileHistoryRoot, toolSessionId, backupFileName),
10277
10294
  "utf8"
10278
10295
  );
10279
10296
  } catch {
@@ -10288,13 +10305,13 @@ function readCurrentContent(filePath) {
10288
10305
  return null;
10289
10306
  }
10290
10307
  }
10291
- var import_node_fs6, import_node_os2, import_node_path5, 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;
10308
+ var import_node_fs6, import_node_os2, import_node_path6, 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;
10292
10309
  var init_claude_history = __esm({
10293
10310
  "src/tools/claude-history.ts"() {
10294
10311
  "use strict";
10295
10312
  import_node_fs6 = __toESM(require("fs"), 1);
10296
10313
  import_node_os2 = __toESM(require("os"), 1);
10297
- import_node_path5 = __toESM(require("path"), 1);
10314
+ import_node_path6 = __toESM(require("path"), 1);
10298
10315
  init_lib();
10299
10316
  init_tool_result_extra();
10300
10317
  TASK_NOTIFICATION_RE = /<task-notification\b[\s\S]*?<\/task-notification>/i;
@@ -10318,9 +10335,9 @@ var init_claude_history = __esm({
10318
10335
  // 每次 user 提交前 trackEdit 拷一份,作为 rewind 回退目标
10319
10336
  fileHistoryRoot;
10320
10337
  constructor(opts = {}) {
10321
- const base = opts.baseDir ?? import_node_path5.default.join(import_node_os2.default.homedir(), ".claude");
10322
- this.projectsRoot = import_node_path5.default.join(base, "projects");
10323
- this.fileHistoryRoot = import_node_path5.default.join(base, "file-history");
10338
+ const base = opts.baseDir ?? import_node_path6.default.join(import_node_os2.default.homedir(), ".claude");
10339
+ this.projectsRoot = import_node_path6.default.join(base, "projects");
10340
+ this.fileHistoryRoot = import_node_path6.default.join(base, "file-history");
10324
10341
  }
10325
10342
  async listProjects() {
10326
10343
  let entries;
@@ -10333,9 +10350,9 @@ var init_claude_history = __esm({
10333
10350
  const out = [];
10334
10351
  for (const ent of entries) {
10335
10352
  if (!ent.isDirectory()) continue;
10336
- const dir = import_node_path5.default.join(this.projectsRoot, ent.name);
10353
+ const dir = import_node_path6.default.join(this.projectsRoot, ent.name);
10337
10354
  const files = import_node_fs6.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
10338
- const updatedAtMs = files.reduce((m, f) => Math.max(m, safeStatMtime(import_node_path5.default.join(dir, f))), 0);
10355
+ const updatedAtMs = files.reduce((m, f) => Math.max(m, safeStatMtime(import_node_path6.default.join(dir, f))), 0);
10339
10356
  out.push({
10340
10357
  projectPath: hashDirToCwd(ent.name),
10341
10358
  hashDir: ent.name,
@@ -10347,7 +10364,7 @@ var init_claude_history = __esm({
10347
10364
  return out;
10348
10365
  }
10349
10366
  async listSessions(args) {
10350
- const dir = import_node_path5.default.join(this.projectsRoot, cwdToHashDir(args.projectPath));
10367
+ const dir = import_node_path6.default.join(this.projectsRoot, cwdToHashDir(args.projectPath));
10351
10368
  let files;
10352
10369
  try {
10353
10370
  files = import_node_fs6.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
@@ -10357,7 +10374,7 @@ var init_claude_history = __esm({
10357
10374
  }
10358
10375
  const out = [];
10359
10376
  for (const f of files) {
10360
- const full = import_node_path5.default.join(dir, f);
10377
+ const full = import_node_path6.default.join(dir, f);
10361
10378
  const toolSessionId = f.slice(0, -".jsonl".length);
10362
10379
  const lines = readJsonlLines(full);
10363
10380
  let summary = "";
@@ -10412,7 +10429,7 @@ var init_claude_history = __esm({
10412
10429
  return out;
10413
10430
  }
10414
10431
  async read(args) {
10415
- const file = import_node_path5.default.join(
10432
+ const file = import_node_path6.default.join(
10416
10433
  this.projectsRoot,
10417
10434
  cwdToHashDir(args.cwd),
10418
10435
  `${args.toolSessionId}.jsonl`
@@ -10445,7 +10462,7 @@ var init_claude_history = __esm({
10445
10462
  // 独立目录路径:<projectsRoot>/<cwdHash>/<toolSessionId>/subagents/*.jsonl
10446
10463
  // 返回 null 表示目录不存在(调用方回退旧实现);返回空数组表示目录存在但无 jsonl
10447
10464
  listSubagentsFromDirectory(cwd, toolSessionId) {
10448
- const dir = import_node_path5.default.join(
10465
+ const dir = import_node_path6.default.join(
10449
10466
  this.projectsRoot,
10450
10467
  cwdToHashDir(cwd),
10451
10468
  toolSessionId,
@@ -10463,7 +10480,7 @@ var init_claude_history = __esm({
10463
10480
  if (!e.isFile()) continue;
10464
10481
  if (!e.name.startsWith("agent-") || !e.name.endsWith(".jsonl")) continue;
10465
10482
  const subagentId = e.name.slice("agent-".length, -".jsonl".length);
10466
- const filePath = import_node_path5.default.join(dir, e.name);
10483
+ const filePath = import_node_path6.default.join(dir, e.name);
10467
10484
  const lines = readJsonlLines(filePath);
10468
10485
  let firstText = "";
10469
10486
  let messageCount = 0;
@@ -10480,7 +10497,7 @@ var init_claude_history = __esm({
10480
10497
  return out;
10481
10498
  }
10482
10499
  listSubagentsFromMainJsonl(cwd, toolSessionId) {
10483
- const file = import_node_path5.default.join(
10500
+ const file = import_node_path6.default.join(
10484
10501
  this.projectsRoot,
10485
10502
  cwdToHashDir(cwd),
10486
10503
  `${toolSessionId}.jsonl`
@@ -10515,7 +10532,7 @@ var init_claude_history = __esm({
10515
10532
  }
10516
10533
  // 独立文件路径:agent-<subagentId>.jsonl;文件不存在返回 null 让调用方回退旧实现
10517
10534
  readSubagentFromFile(cwd, toolSessionId, subagentId) {
10518
- const file = import_node_path5.default.join(
10535
+ const file = import_node_path6.default.join(
10519
10536
  this.projectsRoot,
10520
10537
  cwdToHashDir(cwd),
10521
10538
  toolSessionId,
@@ -10543,7 +10560,7 @@ var init_claude_history = __esm({
10543
10560
  * "那一刻每个 tracked 文件对应的 backup 文件名"
10544
10561
  */
10545
10562
  readFileHistorySnapshots(args) {
10546
- const file = import_node_path5.default.join(
10563
+ const file = import_node_path6.default.join(
10547
10564
  this.projectsRoot,
10548
10565
  cwdToHashDir(args.cwd),
10549
10566
  `${args.toolSessionId}.jsonl`
@@ -10588,7 +10605,7 @@ var init_claude_history = __esm({
10588
10605
  for (const [anchorId, target] of snapshots) {
10589
10606
  let hasAny = false;
10590
10607
  for (const [rawPath, backup] of Object.entries(target)) {
10591
- const absPath = import_node_path5.default.isAbsolute(rawPath) ? rawPath : import_node_path5.default.join(args.cwd, rawPath);
10608
+ const absPath = import_node_path6.default.isAbsolute(rawPath) ? rawPath : import_node_path6.default.join(args.cwd, rawPath);
10592
10609
  const backupContent = readBackupContent(
10593
10610
  this.fileHistoryRoot,
10594
10611
  args.toolSessionId,
@@ -10628,7 +10645,7 @@ var init_claude_history = __esm({
10628
10645
  let totalInsertions = 0;
10629
10646
  let totalDeletions = 0;
10630
10647
  for (const [rawPath, backup] of Object.entries(target)) {
10631
- const absPath = import_node_path5.default.isAbsolute(rawPath) ? rawPath : import_node_path5.default.join(args.cwd, rawPath);
10648
+ const absPath = import_node_path6.default.isAbsolute(rawPath) ? rawPath : import_node_path6.default.join(args.cwd, rawPath);
10632
10649
  const backupContent = readBackupContent(
10633
10650
  this.fileHistoryRoot,
10634
10651
  args.toolSessionId,
@@ -10675,7 +10692,7 @@ var init_claude_history = __esm({
10675
10692
  };
10676
10693
  }
10677
10694
  readSubagentFromMainJsonl(cwd, toolSessionId, subagentId) {
10678
- const file = import_node_path5.default.join(
10695
+ const file = import_node_path6.default.join(
10679
10696
  this.projectsRoot,
10680
10697
  cwdToHashDir(cwd),
10681
10698
  `${toolSessionId}.jsonl`
@@ -10699,7 +10716,7 @@ var init_claude_history = __esm({
10699
10716
  // src/tools/claude.ts
10700
10717
  function macOSDesktopCandidates(home) {
10701
10718
  return [
10702
- import_node_path6.default.join(home, "Applications", "Claude.app", "Contents", "Resources", "app.asar.unpacked", "node_modules", "@anthropic-ai", "claude-code", "cli.js"),
10719
+ import_node_path7.default.join(home, "Applications", "Claude.app", "Contents", "Resources", "app.asar.unpacked", "node_modules", "@anthropic-ai", "claude-code", "cli.js"),
10703
10720
  "/Applications/Claude.app/Contents/Resources/app.asar.unpacked/node_modules/@anthropic-ai/claude-code/cli.js"
10704
10721
  ];
10705
10722
  }
@@ -10744,10 +10761,21 @@ function buildSpawnArgs(ctx) {
10744
10761
  "--verbose"
10745
10762
  ];
10746
10763
  if (ctx.model) args.push("--model", ctx.model);
10747
- if (ctx.personaMode) {
10748
- args.push("--setting-sources", "project,local");
10749
- } else if (ctx.permissionMode) {
10750
- args.push("--permission-mode", ctx.permissionMode);
10764
+ switch (ctx.personaMode) {
10765
+ case "listener":
10766
+ args.push("--setting-sources", "project,local");
10767
+ break;
10768
+ case "owner":
10769
+ args.push("--setting-sources", "user");
10770
+ args.push("--permission-mode", "bypassPermissions");
10771
+ break;
10772
+ case void 0:
10773
+ if (ctx.permissionMode) args.push("--permission-mode", ctx.permissionMode);
10774
+ break;
10775
+ default: {
10776
+ const _exhaustive = ctx.personaMode;
10777
+ throw new Error(`unexpected personaMode: ${String(_exhaustive)}`);
10778
+ }
10751
10779
  }
10752
10780
  if (ctx.effort) args.push("--effort", ctx.effort);
10753
10781
  if (ctx.toolSessionId) args.push("--resume", ctx.toolSessionId);
@@ -11027,10 +11055,10 @@ function parseAttachment(obj) {
11027
11055
  const memories = raw.map((m) => {
11028
11056
  if (!m || typeof m !== "object") return null;
11029
11057
  const rec = m;
11030
- const path22 = typeof rec.path === "string" ? rec.path : null;
11058
+ const path23 = typeof rec.path === "string" ? rec.path : null;
11031
11059
  const content = typeof rec.content === "string" ? rec.content : null;
11032
- if (!path22 || content == null) return null;
11033
- const out = { path: path22, content };
11060
+ if (!path23 || content == null) return null;
11061
+ const out = { path: path23, content };
11034
11062
  if (typeof rec.mtimeMs === "number") out.mtimeMs = rec.mtimeMs;
11035
11063
  return out;
11036
11064
  }).filter((m) => m !== null);
@@ -11134,7 +11162,7 @@ function encodeClaudeStdin(text) {
11134
11162
  };
11135
11163
  return JSON.stringify(frame) + "\n";
11136
11164
  }
11137
- var import_node_child_process, import_node_child_process2, import_node_fs7, import_node_os3, import_node_path6, ATTACHMENT_SILENT_SUBTYPES2, unknownTypeHandler, ATTACHMENT_RE, IMAGE_EXT_MIME, CLAUDE_MODELS, CLAUDE_PERMISSION_MODES, CLAUDE_CAPABILITIES, ClaudeAdapter;
11165
+ var import_node_child_process, import_node_child_process2, import_node_fs7, import_node_os3, import_node_path7, ATTACHMENT_SILENT_SUBTYPES2, unknownTypeHandler, ATTACHMENT_RE, IMAGE_EXT_MIME, CLAUDE_MODELS, CLAUDE_PERMISSION_MODES, CLAUDE_CAPABILITIES, ClaudeAdapter;
11138
11166
  var init_claude = __esm({
11139
11167
  "src/tools/claude.ts"() {
11140
11168
  "use strict";
@@ -11142,7 +11170,7 @@ var init_claude = __esm({
11142
11170
  import_node_child_process2 = require("child_process");
11143
11171
  import_node_fs7 = __toESM(require("fs"), 1);
11144
11172
  import_node_os3 = __toESM(require("os"), 1);
11145
- import_node_path6 = __toESM(require("path"), 1);
11173
+ import_node_path7 = __toESM(require("path"), 1);
11146
11174
  init_protocol();
11147
11175
  init_claude_history();
11148
11176
  init_tool_result_extra();
@@ -14897,7 +14925,7 @@ var require_websocket_server = __commonJS({
14897
14925
  // src/run-case/recorder.ts
14898
14926
  function startRunCaseRecorder(opts) {
14899
14927
  const now = opts.now ?? Date.now;
14900
- const dir = import_node_path19.default.dirname(opts.recordPath);
14928
+ const dir = import_node_path20.default.dirname(opts.recordPath);
14901
14929
  let stream = null;
14902
14930
  let closing = false;
14903
14931
  let closedSettled = false;
@@ -14937,12 +14965,12 @@ function startRunCaseRecorder(opts) {
14937
14965
  };
14938
14966
  return { tap, close, closed };
14939
14967
  }
14940
- var import_node_fs20, import_node_path19;
14968
+ var import_node_fs20, import_node_path20;
14941
14969
  var init_recorder = __esm({
14942
14970
  "src/run-case/recorder.ts"() {
14943
14971
  "use strict";
14944
14972
  import_node_fs20 = __toESM(require("fs"), 1);
14945
- import_node_path19 = __toESM(require("path"), 1);
14973
+ import_node_path20 = __toESM(require("path"), 1);
14946
14974
  }
14947
14975
  });
14948
14976
 
@@ -14985,7 +15013,7 @@ var init_wire = __esm({
14985
15013
  // src/run-case/controller.ts
14986
15014
  async function runController(opts) {
14987
15015
  const now = opts.now ?? Date.now;
14988
- const cwd = opts.cwd ?? (0, import_node_fs21.mkdtempSync)(import_node_path20.default.join(import_node_os13.default.tmpdir(), "clawd-runcase-"));
15016
+ const cwd = opts.cwd ?? (0, import_node_fs21.mkdtempSync)(import_node_path21.default.join(import_node_os13.default.tmpdir(), "clawd-runcase-"));
14989
15017
  const ownsCwd = opts.cwd === void 0;
14990
15018
  const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
14991
15019
  const spawnCtx = { cwd };
@@ -15152,13 +15180,13 @@ async function runController(opts) {
15152
15180
  }
15153
15181
  return exitCode ?? 0;
15154
15182
  }
15155
- var import_node_fs21, import_node_os13, import_node_path20;
15183
+ var import_node_fs21, import_node_os13, import_node_path21;
15156
15184
  var init_controller = __esm({
15157
15185
  "src/run-case/controller.ts"() {
15158
15186
  "use strict";
15159
15187
  import_node_fs21 = require("fs");
15160
15188
  import_node_os13 = __toESM(require("os"), 1);
15161
- import_node_path20 = __toESM(require("path"), 1);
15189
+ import_node_path21 = __toESM(require("path"), 1);
15162
15190
  init_claude();
15163
15191
  init_stdout_splitter();
15164
15192
  init_permission_stdio();
@@ -15383,7 +15411,7 @@ Env (advanced):
15383
15411
  `;
15384
15412
 
15385
15413
  // src/index.ts
15386
- var import_node_path18 = __toESM(require("path"), 1);
15414
+ var import_node_path19 = __toESM(require("path"), 1);
15387
15415
  var import_node_fs19 = __toESM(require("fs"), 1);
15388
15416
 
15389
15417
  // src/logger.ts
@@ -15514,6 +15542,7 @@ var SessionStore = class {
15514
15542
 
15515
15543
  // src/session/manager.ts
15516
15544
  var import_node_fs5 = __toESM(require("fs"), 1);
15545
+ var import_node_path5 = __toESM(require("path"), 1);
15517
15546
 
15518
15547
  // ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/stringify.js
15519
15548
  var byteToHex = [];
@@ -15660,7 +15689,7 @@ function buildSpawnContext(state) {
15660
15689
  };
15661
15690
  const meta = state.subSessionMeta;
15662
15691
  if (meta?.personaMode) {
15663
- ctx.personaMode = true;
15692
+ ctx.personaMode = meta.personaMode;
15664
15693
  }
15665
15694
  return ctx;
15666
15695
  }
@@ -16657,10 +16686,22 @@ var SessionManager = class {
16657
16686
  this.capabilitiesCache.set(tool, caps);
16658
16687
  return caps;
16659
16688
  }
16689
+ // 按优先级解析 SubSessionMeta:subSessionMetaBySid 缓存(内存,首次 create/registerSubSession 写入)
16690
+ // → SessionFile.ownerPersonaId 派生(持久化兜底,daemon 重启后 subSessionMetaBySid 丢失时生效)
16691
+ // → undefined(普通 session)
16692
+ resolveSubSessionMeta(file) {
16693
+ const cached = this.subSessionMetaBySid.get(file.sessionId);
16694
+ if (cached) return cached;
16695
+ if (file.ownerPersonaId) {
16696
+ return { idleKillEnabled: false, personaMode: "owner" };
16697
+ }
16698
+ return void 0;
16699
+ }
16660
16700
  // 创建 runner 时包一层 broadcast hook:所有外出 frame 统一走 routeFromRunner,
16661
16701
  // 经过 compressFrameForWire 后决定是 push collector 还是走 deps.broadcastFrame
16662
16702
  // store:默认 deps.store;persona sub-session 路径下传该 personaId 对应的 SessionStore
16663
- // subSessionMeta:persona 路径传 { idleKillEnabled: true },其它路径不传
16703
+ // subSessionMeta:listener { idleKillEnabled: true, personaMode: 'listener' }
16704
+ // owner 传 { idleKillEnabled: false, personaMode: 'owner' };普通 session 不传
16664
16705
  newRunner(file, opts = {}) {
16665
16706
  const adapter = this.deps.getAdapter(file.tool ?? "claude");
16666
16707
  const store = opts.store ?? this.deps.store;
@@ -16718,18 +16759,34 @@ var SessionManager = class {
16718
16759
  }
16719
16760
  // ---- 命令方法:均返回 { response, broadcast[] },由 dispatcher 聚合 ----
16720
16761
  create(args) {
16762
+ if (args.ownerPersonaId) {
16763
+ const existing = this.deps.store.list().find((s) => s.ownerPersonaId === args.ownerPersonaId);
16764
+ if (existing) {
16765
+ return { response: existing, broadcast: [] };
16766
+ }
16767
+ }
16768
+ let cwd = args.cwd;
16769
+ if (args.ownerPersonaId && !cwd) {
16770
+ if (!this.deps.personaRoot) {
16771
+ throw new Error("personaRoot required to derive cwd from ownerPersonaId");
16772
+ }
16773
+ cwd = import_node_path5.default.join(this.deps.personaRoot, safeFileName(args.ownerPersonaId));
16774
+ }
16775
+ if (!cwd) {
16776
+ throw new ClawdError(ERROR_CODES.INVALID_CWD, "cwd required when ownerPersonaId is absent");
16777
+ }
16721
16778
  try {
16722
- const stat = import_node_fs5.default.statSync(args.cwd);
16779
+ const stat = import_node_fs5.default.statSync(cwd);
16723
16780
  if (!stat.isDirectory()) throw new Error("not dir");
16724
16781
  } catch {
16725
- throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${args.cwd}`);
16782
+ throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${cwd}`);
16726
16783
  }
16727
16784
  const tool = args.tool ?? "claude";
16728
16785
  this.deps.getAdapter(tool);
16729
16786
  const iso = nowIso2(this.deps);
16730
16787
  const file = {
16731
16788
  sessionId: newSessionId(),
16732
- cwd: args.cwd,
16789
+ cwd,
16733
16790
  tool,
16734
16791
  label: args.label,
16735
16792
  model: args.model,
@@ -16739,10 +16796,17 @@ var SessionManager = class {
16739
16796
  worktreeRoot: args.worktreeRoot,
16740
16797
  worktreeBranch: args.worktreeBranch,
16741
16798
  forkedFromToolSessionId: args.forkedFromToolSessionId,
16799
+ ownerPersonaId: args.ownerPersonaId,
16742
16800
  createdAt: iso,
16743
16801
  updatedAt: iso
16744
16802
  };
16745
16803
  const written = this.deps.store.write(file);
16804
+ if (args.ownerPersonaId) {
16805
+ this.subSessionMetaBySid.set(written.sessionId, {
16806
+ idleKillEnabled: false,
16807
+ personaMode: "owner"
16808
+ });
16809
+ }
16746
16810
  return { response: written, broadcast: [] };
16747
16811
  }
16748
16812
  pin(args) {
@@ -16898,7 +16962,8 @@ var SessionManager = class {
16898
16962
  const existing = this.getFile(args.sessionId);
16899
16963
  let runner = this.runners.get(args.sessionId);
16900
16964
  if (!runner) {
16901
- runner = this.newRunner(existing);
16965
+ const subSessionMeta = this.resolveSubSessionMeta(existing);
16966
+ runner = this.newRunner(existing, { subSessionMeta });
16902
16967
  this.runners.set(args.sessionId, runner);
16903
16968
  }
16904
16969
  const { broadcast } = this.withCollector(() => {
@@ -16992,7 +17057,8 @@ var SessionManager = class {
16992
17057
  const file = this.getFile(args.sessionId);
16993
17058
  let runner = this.runners.get(args.sessionId);
16994
17059
  if (!runner) {
16995
- runner = this.newRunner(file);
17060
+ const subSessionMeta = this.resolveSubSessionMeta(file);
17061
+ runner = this.newRunner(file, { subSessionMeta });
16996
17062
  this.runners.set(args.sessionId, runner);
16997
17063
  }
16998
17064
  if (!runner.getState().procAlive) {
@@ -17150,7 +17216,7 @@ var SessionManager = class {
17150
17216
  ensureSession(file) {
17151
17217
  let r = this.runners.get(file.sessionId);
17152
17218
  if (r) return r;
17153
- const subSessionMeta = this.subSessionMetaBySid.get(file.sessionId);
17219
+ const subSessionMeta = this.resolveSubSessionMeta(file);
17154
17220
  r = this.newRunner(file, { subSessionMeta });
17155
17221
  this.runners.set(file.sessionId, r);
17156
17222
  return r;
@@ -17326,7 +17392,7 @@ var SessionManager = class {
17326
17392
  const existing = this.runners.get(file.sessionId);
17327
17393
  if (existing) return existing;
17328
17394
  const store = this.storeFor(agentId);
17329
- const subSessionMeta = this.subSessionMetaBySid.get(file.sessionId);
17395
+ const subSessionMeta = this.resolveSubSessionMeta(file);
17330
17396
  const runner = this.newRunner(file, { store, subSessionMeta });
17331
17397
  this.runners.set(file.sessionId, runner);
17332
17398
  return runner;
@@ -17348,7 +17414,7 @@ var SessionManager = class {
17348
17414
  }
17349
17415
  let runner = this.runners.get(args.sessionId);
17350
17416
  if (!runner) {
17351
- const subSessionMeta = this.subSessionMetaBySid.get(args.sessionId);
17417
+ const subSessionMeta = this.resolveSubSessionMeta(file);
17352
17418
  runner = this.newRunner(file, { store, subSessionMeta });
17353
17419
  this.runners.set(args.sessionId, runner);
17354
17420
  }
@@ -17420,7 +17486,7 @@ var SessionManager = class {
17420
17486
 
17421
17487
  // src/persona/store.ts
17422
17488
  var fs6 = __toESM(require("fs"), 1);
17423
- var path5 = __toESM(require("path"), 1);
17489
+ var path6 = __toESM(require("path"), 1);
17424
17490
  init_protocol();
17425
17491
  var DEFAULT_SETTINGS = {
17426
17492
  permissions: {
@@ -17449,21 +17515,21 @@ var PersonaStore = class {
17449
17515
  }
17450
17516
  root;
17451
17517
  personaDir(personaId) {
17452
- return path5.join(this.root, safeFileName(personaId));
17518
+ return path6.join(this.root, safeFileName(personaId));
17453
17519
  }
17454
17520
  metaPath(personaId) {
17455
- return path5.join(this.personaDir(personaId), ".clawd", "persona.json");
17521
+ return path6.join(this.personaDir(personaId), ".clawd", "persona.json");
17456
17522
  }
17457
17523
  claudeMdPath(personaId) {
17458
- return path5.join(this.personaDir(personaId), "CLAUDE.md");
17524
+ return path6.join(this.personaDir(personaId), "CLAUDE.md");
17459
17525
  }
17460
17526
  settingsPath(personaId) {
17461
- return path5.join(this.personaDir(personaId), ".claude", "settings.json");
17527
+ return path6.join(this.personaDir(personaId), ".claude", "settings.json");
17462
17528
  }
17463
17529
  write(persona, personality) {
17464
17530
  const dir = this.personaDir(persona.personaId);
17465
- fs6.mkdirSync(path5.join(dir, ".claude"), { recursive: true });
17466
- fs6.mkdirSync(path5.join(dir, ".clawd"), { recursive: true });
17531
+ fs6.mkdirSync(path6.join(dir, ".claude"), { recursive: true });
17532
+ fs6.mkdirSync(path6.join(dir, ".clawd"), { recursive: true });
17467
17533
  this.atomicWrite(this.claudeMdPath(persona.personaId), personality);
17468
17534
  this.atomicWrite(this.settingsPath(persona.personaId), JSON.stringify(DEFAULT_SETTINGS, null, 2));
17469
17535
  this.atomicWrite(this.metaPath(persona.personaId), JSON.stringify(persona, null, 2));
@@ -17488,7 +17554,7 @@ var PersonaStore = class {
17488
17554
  list() {
17489
17555
  if (!fs6.existsSync(this.root)) return [];
17490
17556
  return fs6.readdirSync(this.root).filter((name) => {
17491
- return fs6.existsSync(path5.join(this.root, name, ".clawd", "persona.json"));
17557
+ return fs6.existsSync(path6.join(this.root, name, ".clawd", "persona.json"));
17492
17558
  });
17493
17559
  }
17494
17560
  remove(personaId) {
@@ -17653,7 +17719,7 @@ var PersonaManager = class {
17653
17719
  tool: "claude",
17654
17720
  label: subLabel,
17655
17721
  model: persona.model,
17656
- subSessionMeta: { idleKillEnabled: true, personaMode: true }
17722
+ subSessionMeta: { idleKillEnabled: true, personaMode: "listener" }
17657
17723
  });
17658
17724
  return { sessionFile, isNew: true };
17659
17725
  }
@@ -17689,14 +17755,14 @@ init_claude_history();
17689
17755
  // src/workspace/browser.ts
17690
17756
  var import_node_fs8 = __toESM(require("fs"), 1);
17691
17757
  var import_node_os4 = __toESM(require("os"), 1);
17692
- var import_node_path7 = __toESM(require("path"), 1);
17758
+ var import_node_path8 = __toESM(require("path"), 1);
17693
17759
  init_protocol();
17694
17760
  var MAX_FILE_BYTES = 2 * 1024 * 1024;
17695
17761
  function resolveInsideCwd(cwd, subpath) {
17696
- const absCwd = import_node_path7.default.resolve(cwd);
17697
- const joined = import_node_path7.default.resolve(absCwd, subpath ?? ".");
17698
- const rel = import_node_path7.default.relative(absCwd, joined);
17699
- if (rel.startsWith("..") || import_node_path7.default.isAbsolute(rel)) {
17762
+ const absCwd = import_node_path8.default.resolve(cwd);
17763
+ const joined = import_node_path8.default.resolve(absCwd, subpath ?? ".");
17764
+ const rel = import_node_path8.default.relative(absCwd, joined);
17765
+ if (rel.startsWith("..") || import_node_path8.default.isAbsolute(rel)) {
17700
17766
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
17701
17767
  }
17702
17768
  return joined;
@@ -17727,7 +17793,7 @@ var WorkspaceBrowser = class {
17727
17793
  mtime: ""
17728
17794
  };
17729
17795
  try {
17730
- const st = import_node_fs8.default.statSync(import_node_path7.default.join(full, d.name));
17796
+ const st = import_node_fs8.default.statSync(import_node_path8.default.join(full, d.name));
17731
17797
  entry.mtime = new Date(st.mtimeMs).toISOString();
17732
17798
  if (d.isFile()) entry.size = st.size;
17733
17799
  } catch {
@@ -17774,7 +17840,7 @@ var WorkspaceBrowser = class {
17774
17840
  // src/skills/scanner.ts
17775
17841
  var import_node_fs9 = __toESM(require("fs"), 1);
17776
17842
  var import_node_os5 = __toESM(require("os"), 1);
17777
- var import_node_path8 = __toESM(require("path"), 1);
17843
+ var import_node_path9 = __toESM(require("path"), 1);
17778
17844
 
17779
17845
  // src/skills/frontmatter.ts
17780
17846
  var STRIP_QUOTES = /^["']|["']$/g;
@@ -17896,14 +17962,14 @@ function scanSkillDir(dir, source, seen, out, pluginName) {
17896
17962
  return;
17897
17963
  }
17898
17964
  for (const ent of entries) {
17899
- const entryPath = import_node_path8.default.join(dir, ent.name);
17965
+ const entryPath = import_node_path9.default.join(dir, ent.name);
17900
17966
  if (!ent.isDirectory() && !(ent.isSymbolicLink() && isDirLikeSync(entryPath))) continue;
17901
17967
  let content;
17902
17968
  try {
17903
- content = import_node_fs9.default.readFileSync(import_node_path8.default.join(entryPath, "SKILL.md"), "utf8");
17969
+ content = import_node_fs9.default.readFileSync(import_node_path9.default.join(entryPath, "SKILL.md"), "utf8");
17904
17970
  } catch {
17905
17971
  try {
17906
- content = import_node_fs9.default.readFileSync(import_node_path8.default.join(entryPath, "skill.md"), "utf8");
17972
+ content = import_node_fs9.default.readFileSync(import_node_path9.default.join(entryPath, "skill.md"), "utf8");
17907
17973
  } catch {
17908
17974
  continue;
17909
17975
  }
@@ -17926,7 +17992,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
17926
17992
  return;
17927
17993
  }
17928
17994
  for (const ent of entries) {
17929
- const entryPath = import_node_path8.default.join(dir, ent.name);
17995
+ const entryPath = import_node_path9.default.join(dir, ent.name);
17930
17996
  if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync(entryPath)) {
17931
17997
  const ns = ent.name;
17932
17998
  let subEntries;
@@ -17937,7 +18003,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
17937
18003
  }
17938
18004
  for (const se of subEntries) {
17939
18005
  if (!se.name.endsWith(".md")) continue;
17940
- const sePath = import_node_path8.default.join(entryPath, se.name);
18006
+ const sePath = import_node_path9.default.join(entryPath, se.name);
17941
18007
  let content;
17942
18008
  try {
17943
18009
  content = import_node_fs9.default.readFileSync(sePath, "utf8");
@@ -17973,7 +18039,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
17973
18039
  }
17974
18040
  }
17975
18041
  function readInstalledPlugins(home) {
17976
- const file = import_node_path8.default.join(home, ".claude", "plugins", "installed_plugins.json");
18042
+ const file = import_node_path9.default.join(home, ".claude", "plugins", "installed_plugins.json");
17977
18043
  let raw;
17978
18044
  try {
17979
18045
  raw = import_node_fs9.default.readFileSync(file, "utf8");
@@ -18024,14 +18090,14 @@ var SkillsScanner = class {
18024
18090
  });
18025
18091
  }
18026
18092
  const fsBlock = [];
18027
- scanSkillDir(import_node_path8.default.join(this.home, ".claude", "skills"), "global", seen, fsBlock);
18028
- scanCommandDir(import_node_path8.default.join(this.home, ".claude", "commands"), "global", seen, fsBlock);
18029
- scanSkillDir(import_node_path8.default.join(args.cwd, ".claude", "skills"), "project", seen, fsBlock);
18030
- scanCommandDir(import_node_path8.default.join(args.cwd, ".claude", "commands"), "project", seen, fsBlock);
18093
+ scanSkillDir(import_node_path9.default.join(this.home, ".claude", "skills"), "global", seen, fsBlock);
18094
+ scanCommandDir(import_node_path9.default.join(this.home, ".claude", "commands"), "global", seen, fsBlock);
18095
+ scanSkillDir(import_node_path9.default.join(args.cwd, ".claude", "skills"), "project", seen, fsBlock);
18096
+ scanCommandDir(import_node_path9.default.join(args.cwd, ".claude", "commands"), "project", seen, fsBlock);
18031
18097
  const plugins = [...readInstalledPlugins(this.home), ...this.extraPluginRoots];
18032
18098
  for (const { name, root } of plugins) {
18033
- scanSkillDir(import_node_path8.default.join(root, "skills"), "plugin", seen, fsBlock, name);
18034
- scanCommandDir(import_node_path8.default.join(root, "commands"), "plugin", seen, fsBlock, name);
18099
+ scanSkillDir(import_node_path9.default.join(root, "skills"), "plugin", seen, fsBlock, name);
18100
+ scanCommandDir(import_node_path9.default.join(root, "commands"), "plugin", seen, fsBlock, name);
18035
18101
  }
18036
18102
  fsBlock.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
18037
18103
  return [...builtinBlock, ...fsBlock];
@@ -18041,7 +18107,7 @@ var SkillsScanner = class {
18041
18107
  // src/skills/agents-scanner.ts
18042
18108
  var import_node_fs10 = __toESM(require("fs"), 1);
18043
18109
  var import_node_os6 = __toESM(require("os"), 1);
18044
- var import_node_path9 = __toESM(require("path"), 1);
18110
+ var import_node_path10 = __toESM(require("path"), 1);
18045
18111
  var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
18046
18112
  function isDirLikeSync2(p) {
18047
18113
  try {
@@ -18079,10 +18145,10 @@ function scanAgentsDir(dir, source, seen, out) {
18079
18145
  }
18080
18146
  for (const ent of entries) {
18081
18147
  if (!ent.name.endsWith(".md")) continue;
18082
- if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path9.default.join(dir, ent.name)))) {
18148
+ if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path10.default.join(dir, ent.name)))) {
18083
18149
  continue;
18084
18150
  }
18085
- const filePath = import_node_path9.default.join(dir, ent.name);
18151
+ const filePath = import_node_path10.default.join(dir, ent.name);
18086
18152
  const baseName = ent.name.replace(/\.md$/, "");
18087
18153
  if (seen.has(baseName)) continue;
18088
18154
  seen.add(baseName);
@@ -18105,7 +18171,7 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
18105
18171
  return;
18106
18172
  }
18107
18173
  for (const ent of entries) {
18108
- const childPath = import_node_path9.default.join(dir, ent.name);
18174
+ const childPath = import_node_path10.default.join(dir, ent.name);
18109
18175
  if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
18110
18176
  walk(childPath, [...namespaces, ent.name]);
18111
18177
  continue;
@@ -18130,9 +18196,9 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
18130
18196
  walk(root, []);
18131
18197
  }
18132
18198
  function readInstalledPlugins2(home) {
18133
- const pluginsDir = import_node_path9.default.join(home, ".claude", "plugins");
18134
- const v2 = import_node_path9.default.join(pluginsDir, "installed_plugins_v2.json");
18135
- const v1 = import_node_path9.default.join(pluginsDir, "installed_plugins.json");
18199
+ const pluginsDir = import_node_path10.default.join(home, ".claude", "plugins");
18200
+ const v2 = import_node_path10.default.join(pluginsDir, "installed_plugins_v2.json");
18201
+ const v1 = import_node_path10.default.join(pluginsDir, "installed_plugins.json");
18136
18202
  let raw = null;
18137
18203
  for (const candidate of [v2, v1]) {
18138
18204
  try {
@@ -18161,19 +18227,19 @@ function readInstalledPlugins2(home) {
18161
18227
  return out;
18162
18228
  }
18163
18229
  function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
18164
- let cur = import_node_path9.default.resolve(startCwd);
18165
- const fsRoot = import_node_path9.default.parse(cur).root;
18230
+ let cur = import_node_path10.default.resolve(startCwd);
18231
+ const fsRoot = import_node_path10.default.parse(cur).root;
18166
18232
  while (true) {
18167
- scanAgentsDir(import_node_path9.default.join(cur, ".claude", "agents"), "project", seen, out);
18233
+ scanAgentsDir(import_node_path10.default.join(cur, ".claude", "agents"), "project", seen, out);
18168
18234
  let hasGit = false;
18169
18235
  try {
18170
- hasGit = import_node_fs10.default.existsSync(import_node_path9.default.join(cur, ".git"));
18236
+ hasGit = import_node_fs10.default.existsSync(import_node_path10.default.join(cur, ".git"));
18171
18237
  } catch {
18172
18238
  }
18173
18239
  if (hasGit) return;
18174
18240
  if (cur === home) return;
18175
18241
  if (cur === fsRoot) return;
18176
- const parent = import_node_path9.default.dirname(cur);
18242
+ const parent = import_node_path10.default.dirname(cur);
18177
18243
  if (parent === cur) return;
18178
18244
  cur = parent;
18179
18245
  }
@@ -18208,7 +18274,7 @@ var AgentsScanner = class {
18208
18274
  }
18209
18275
  const fsBlock = [];
18210
18276
  scanAgentsDir(
18211
- import_node_path9.default.join(this.home, ".claude", "agents"),
18277
+ import_node_path10.default.join(this.home, ".claude", "agents"),
18212
18278
  "global",
18213
18279
  seen,
18214
18280
  fsBlock
@@ -18222,7 +18288,7 @@ var AgentsScanner = class {
18222
18288
  ...this.extraPluginRoots
18223
18289
  ];
18224
18290
  for (const { name, root } of plugins) {
18225
- const agentsRoot = import_node_path9.default.join(root, "agents");
18291
+ const agentsRoot = import_node_path10.default.join(root, "agents");
18226
18292
  scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
18227
18293
  }
18228
18294
  return [...builtinBlock, ...fsBlock];
@@ -18232,7 +18298,7 @@ var AgentsScanner = class {
18232
18298
  // src/observer/session-observer.ts
18233
18299
  var import_node_fs11 = __toESM(require("fs"), 1);
18234
18300
  var import_node_os7 = __toESM(require("os"), 1);
18235
- var import_node_path10 = __toESM(require("path"), 1);
18301
+ var import_node_path11 = __toESM(require("path"), 1);
18236
18302
  init_claude_history();
18237
18303
  var SessionObserver = class {
18238
18304
  constructor(opts) {
@@ -18244,7 +18310,7 @@ var SessionObserver = class {
18244
18310
  watches = /* @__PURE__ */ new Map();
18245
18311
  resolveJsonlPath(cwd, toolSessionId, override) {
18246
18312
  if (override) return override;
18247
- return import_node_path10.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
18313
+ return import_node_path11.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
18248
18314
  }
18249
18315
  start(args) {
18250
18316
  this.stop(args.sessionId);
@@ -18264,10 +18330,10 @@ var SessionObserver = class {
18264
18330
  adapter: args.adapter
18265
18331
  };
18266
18332
  try {
18267
- import_node_fs11.default.mkdirSync(import_node_path10.default.dirname(filePath), { recursive: true });
18333
+ import_node_fs11.default.mkdirSync(import_node_path11.default.dirname(filePath), { recursive: true });
18268
18334
  } catch {
18269
18335
  }
18270
- w.watcher = import_node_fs11.default.watch(import_node_path10.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
18336
+ w.watcher = import_node_fs11.default.watch(import_node_path11.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
18271
18337
  if (!changedName || !filePath.endsWith(changedName)) return;
18272
18338
  this.poll(w);
18273
18339
  });
@@ -18983,9 +19049,9 @@ function isLocalhost(addr) {
18983
19049
 
18984
19050
  // src/discovery/state-file.ts
18985
19051
  var import_node_fs12 = __toESM(require("fs"), 1);
18986
- var import_node_path11 = __toESM(require("path"), 1);
19052
+ var import_node_path12 = __toESM(require("path"), 1);
18987
19053
  function defaultStateFilePath(dataDir) {
18988
- return import_node_path11.default.join(dataDir, "state.json");
19054
+ return import_node_path12.default.join(dataDir, "state.json");
18989
19055
  }
18990
19056
  function isPidAlive(pid) {
18991
19057
  if (!Number.isFinite(pid) || pid <= 0) return false;
@@ -19021,7 +19087,7 @@ var StateFileManager = class {
19021
19087
  return { status: "stale", existing };
19022
19088
  }
19023
19089
  write(state) {
19024
- import_node_fs12.default.mkdirSync(import_node_path11.default.dirname(this.file), { recursive: true });
19090
+ import_node_fs12.default.mkdirSync(import_node_path12.default.dirname(this.file), { recursive: true });
19025
19091
  const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
19026
19092
  import_node_fs12.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
19027
19093
  import_node_fs12.default.renameSync(tmp, this.file);
@@ -19042,13 +19108,13 @@ var StateFileManager = class {
19042
19108
 
19043
19109
  // src/tunnel/tunnel-manager.ts
19044
19110
  var import_node_fs15 = __toESM(require("fs"), 1);
19045
- var import_node_path14 = __toESM(require("path"), 1);
19111
+ var import_node_path15 = __toESM(require("path"), 1);
19046
19112
  var import_node_crypto4 = __toESM(require("crypto"), 1);
19047
19113
  var import_node_child_process4 = require("child_process");
19048
19114
 
19049
19115
  // src/tunnel/tunnel-store.ts
19050
19116
  var import_node_fs13 = __toESM(require("fs"), 1);
19051
- var import_node_path12 = __toESM(require("path"), 1);
19117
+ var import_node_path13 = __toESM(require("path"), 1);
19052
19118
  var TunnelStore = class {
19053
19119
  constructor(filePath) {
19054
19120
  this.filePath = filePath;
@@ -19067,7 +19133,7 @@ var TunnelStore = class {
19067
19133
  }
19068
19134
  }
19069
19135
  async set(v) {
19070
- const dir = import_node_path12.default.dirname(this.filePath);
19136
+ const dir = import_node_path13.default.dirname(this.filePath);
19071
19137
  await import_node_fs13.default.promises.mkdir(dir, { recursive: true });
19072
19138
  const data = JSON.stringify(v, null, 2);
19073
19139
  const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
@@ -19179,7 +19245,7 @@ function escape(v) {
19179
19245
  // src/tunnel/frpc-binary.ts
19180
19246
  var import_node_fs14 = __toESM(require("fs"), 1);
19181
19247
  var import_node_os8 = __toESM(require("os"), 1);
19182
- var import_node_path13 = __toESM(require("path"), 1);
19248
+ var import_node_path14 = __toESM(require("path"), 1);
19183
19249
  var import_node_child_process3 = require("child_process");
19184
19250
  var import_node_stream = require("stream");
19185
19251
  var import_promises = require("stream/promises");
@@ -19218,13 +19284,13 @@ async function ensureFrpcBinary(opts) {
19218
19284
  }
19219
19285
  const version2 = opts.version ?? FRPC_VERSION;
19220
19286
  const platform = opts.platform ?? detectPlatform();
19221
- const binDir = import_node_path13.default.join(opts.dataDir, "bin");
19287
+ const binDir = import_node_path14.default.join(opts.dataDir, "bin");
19222
19288
  import_node_fs14.default.mkdirSync(binDir, { recursive: true });
19223
19289
  cleanupStaleArtifacts(binDir);
19224
- const stableBin = import_node_path13.default.join(binDir, "frpc");
19290
+ const stableBin = import_node_path14.default.join(binDir, "frpc");
19225
19291
  if (import_node_fs14.default.existsSync(stableBin)) return stableBin;
19226
19292
  const partialBin = `${stableBin}.partial`;
19227
- const tarballPath = import_node_path13.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
19293
+ const tarballPath = import_node_path14.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
19228
19294
  try {
19229
19295
  const url = frpcDownloadUrl(version2, platform);
19230
19296
  await downloadToFile(url, tarballPath, opts.fetchImpl);
@@ -19250,7 +19316,7 @@ function cleanupStaleArtifacts(binDir) {
19250
19316
  }
19251
19317
  for (const name of entries) {
19252
19318
  if (name.endsWith(".partial") || name.startsWith("extract-")) {
19253
- const full = import_node_path13.default.join(binDir, name);
19319
+ const full = import_node_path14.default.join(binDir, name);
19254
19320
  try {
19255
19321
  import_node_fs14.default.rmSync(full, { recursive: true, force: true });
19256
19322
  } catch {
@@ -19276,7 +19342,7 @@ async function downloadToFile(url, dest, fetchImpl) {
19276
19342
  await (0, import_promises.pipeline)(nodeStream, out);
19277
19343
  }
19278
19344
  async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
19279
- const work = import_node_path13.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
19345
+ const work = import_node_path14.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
19280
19346
  import_node_fs14.default.mkdirSync(work, { recursive: true });
19281
19347
  try {
19282
19348
  await new Promise((resolve, reject) => {
@@ -19285,7 +19351,7 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
19285
19351
  proc.on("exit", (code) => code === 0 ? resolve() : reject(new Error(`tar exited ${code}`)));
19286
19352
  });
19287
19353
  const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
19288
- const src = import_node_path13.default.join(work, dirName, "frpc");
19354
+ const src = import_node_path14.default.join(work, dirName, "frpc");
19289
19355
  if (!import_node_fs14.default.existsSync(src)) {
19290
19356
  throw new Error(`frpc not found inside tarball at ${src}`);
19291
19357
  }
@@ -19300,7 +19366,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
19300
19366
  var TunnelManager = class {
19301
19367
  constructor(deps) {
19302
19368
  this.deps = deps;
19303
- this.store = deps.store ?? new TunnelStore(import_node_path14.default.join(deps.dataDir, "tunnel.json"));
19369
+ this.store = deps.store ?? new TunnelStore(import_node_path15.default.join(deps.dataDir, "tunnel.json"));
19304
19370
  this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
19305
19371
  this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
19306
19372
  }
@@ -19417,7 +19483,7 @@ var TunnelManager = class {
19417
19483
  dataDir: this.deps.dataDir,
19418
19484
  override: this.deps.frpcBinaryOverride ?? void 0
19419
19485
  });
19420
- const tomlPath = import_node_path14.default.join(this.deps.dataDir, "frpc.toml");
19486
+ const tomlPath = import_node_path15.default.join(this.deps.dataDir, "frpc.toml");
19421
19487
  const proxyName = `clawd-${t.subdomain}-${localPort}-${import_node_crypto4.default.randomBytes(3).toString("hex")}`;
19422
19488
  const toml = buildFrpcToml({
19423
19489
  serverAddr: t.frpsHost,
@@ -19432,7 +19498,7 @@ var TunnelManager = class {
19432
19498
  const proc = (this.deps.spawnImpl ?? import_node_child_process4.spawn)(frpcBin, ["-c", tomlPath], {
19433
19499
  stdio: ["ignore", "pipe", "pipe"]
19434
19500
  });
19435
- const logFilePath = import_node_path14.default.join(this.deps.dataDir, "frpc.log");
19501
+ const logFilePath = import_node_path15.default.join(this.deps.dataDir, "frpc.log");
19436
19502
  const logStream = import_node_fs15.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
19437
19503
  logStream.on("error", () => {
19438
19504
  });
@@ -19526,11 +19592,11 @@ function deriveStableDeviceKey(opts = {}) {
19526
19592
 
19527
19593
  // src/auth-store.ts
19528
19594
  var import_node_fs16 = __toESM(require("fs"), 1);
19529
- var import_node_path15 = __toESM(require("path"), 1);
19595
+ var import_node_path16 = __toESM(require("path"), 1);
19530
19596
  var import_node_crypto6 = __toESM(require("crypto"), 1);
19531
19597
  var AUTH_FILE_NAME = "auth.json";
19532
19598
  function authFilePath(dataDir) {
19533
- return import_node_path15.default.join(dataDir, AUTH_FILE_NAME);
19599
+ return import_node_path16.default.join(dataDir, AUTH_FILE_NAME);
19534
19600
  }
19535
19601
  function loadOrCreateAuthToken(opts) {
19536
19602
  const file = authFilePath(opts.dataDir);
@@ -19562,7 +19628,7 @@ function readAuthFile(file) {
19562
19628
  }
19563
19629
  }
19564
19630
  function writeAuthFile(file, content) {
19565
- import_node_fs16.default.mkdirSync(import_node_path15.default.dirname(file), { recursive: true });
19631
+ import_node_fs16.default.mkdirSync(import_node_path16.default.dirname(file), { recursive: true });
19566
19632
  import_node_fs16.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
19567
19633
  try {
19568
19634
  import_node_fs16.default.chmodSync(file, 384);
@@ -19579,7 +19645,7 @@ init_protocol();
19579
19645
  // src/session/fork.ts
19580
19646
  var import_node_fs17 = __toESM(require("fs"), 1);
19581
19647
  var import_node_os10 = __toESM(require("os"), 1);
19582
- var import_node_path16 = __toESM(require("path"), 1);
19648
+ var import_node_path17 = __toESM(require("path"), 1);
19583
19649
  init_claude_history();
19584
19650
  function readJsonlEntries(file) {
19585
19651
  const raw = import_node_fs17.default.readFileSync(file, "utf8");
@@ -19595,9 +19661,9 @@ function readJsonlEntries(file) {
19595
19661
  return out;
19596
19662
  }
19597
19663
  function forkSession(input) {
19598
- const baseDir = input.baseDir ?? import_node_path16.default.join(import_node_os10.default.homedir(), ".claude");
19599
- const projectDir = import_node_path16.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
19600
- const sourceFile = import_node_path16.default.join(projectDir, `${input.toolSessionId}.jsonl`);
19664
+ const baseDir = input.baseDir ?? import_node_path17.default.join(import_node_os10.default.homedir(), ".claude");
19665
+ const projectDir = import_node_path17.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
19666
+ const sourceFile = import_node_path17.default.join(projectDir, `${input.toolSessionId}.jsonl`);
19601
19667
  if (!import_node_fs17.default.existsSync(sourceFile)) {
19602
19668
  throw new Error(`fork: source transcript not found: ${sourceFile}`);
19603
19669
  }
@@ -19628,7 +19694,7 @@ function forkSession(input) {
19628
19694
  }
19629
19695
  forkedLines.push(JSON.stringify(forked));
19630
19696
  }
19631
- const forkedFilePath = import_node_path16.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
19697
+ const forkedFilePath = import_node_path17.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
19632
19698
  import_node_fs17.default.mkdirSync(projectDir, { recursive: true });
19633
19699
  import_node_fs17.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
19634
19700
  return { forkedToolSessionId, forkedFilePath };
@@ -19639,6 +19705,12 @@ function buildSessionHandlers(deps) {
19639
19705
  const { manager, observer, getAdapter: getAdapter2 } = deps;
19640
19706
  const create = async (frame) => {
19641
19707
  const args = SessionCreateArgs.parse(frame);
19708
+ if (args.ownerPersonaId) {
19709
+ const persona = deps.personaRegistry.get(args.ownerPersonaId);
19710
+ if (!persona) {
19711
+ throw new Error(`persona not found: ${args.ownerPersonaId}`);
19712
+ }
19713
+ }
19642
19714
  const { response, broadcast } = manager.create(args);
19643
19715
  return { response: { type: "session:info", ...response }, broadcast };
19644
19716
  };
@@ -19908,7 +19980,7 @@ init_protocol();
19908
19980
  var import_node_child_process5 = require("child_process");
19909
19981
  var import_node_fs18 = __toESM(require("fs"), 1);
19910
19982
  var import_node_os11 = __toESM(require("os"), 1);
19911
- var import_node_path17 = __toESM(require("path"), 1);
19983
+ var import_node_path18 = __toESM(require("path"), 1);
19912
19984
  var import_node_util = require("util");
19913
19985
  var pexec = (0, import_node_util.promisify)(import_node_child_process5.execFile);
19914
19986
  function formatChildProcessError(err) {
@@ -19923,7 +19995,7 @@ function formatChildProcessError(err) {
19923
19995
  return e.message ?? "unknown error";
19924
19996
  }
19925
19997
  function normalizePath(p) {
19926
- const resolved = import_node_path17.default.resolve(p);
19998
+ const resolved = import_node_path18.default.resolve(p);
19927
19999
  try {
19928
20000
  return import_node_fs18.default.realpathSync(resolved);
19929
20001
  } catch {
@@ -20026,13 +20098,13 @@ function flattenToDirName(branch) {
20026
20098
  }
20027
20099
  function encodeClaudeProjectDir(absPath) {
20028
20100
  if (!absPath || typeof absPath !== "string") return "";
20029
- let canonical = import_node_path17.default.resolve(absPath);
20101
+ let canonical = import_node_path18.default.resolve(absPath);
20030
20102
  try {
20031
20103
  canonical = import_node_fs18.default.realpathSync(canonical);
20032
20104
  } catch {
20033
20105
  try {
20034
- const parent = import_node_fs18.default.realpathSync(import_node_path17.default.dirname(canonical));
20035
- canonical = import_node_path17.default.join(parent, import_node_path17.default.basename(canonical));
20106
+ const parent = import_node_fs18.default.realpathSync(import_node_path18.default.dirname(canonical));
20107
+ canonical = import_node_path18.default.join(parent, import_node_path18.default.basename(canonical));
20036
20108
  } catch {
20037
20109
  }
20038
20110
  }
@@ -20056,17 +20128,19 @@ async function createWorktree(input) {
20056
20128
  if (!isGitRoot) {
20057
20129
  throw new Error(`\u76EE\u5F55 ${cwd} \u4E0D\u662F git repo \u6839`);
20058
20130
  }
20059
- const parent = import_node_path17.default.dirname(import_node_path17.default.resolve(cwd));
20060
- if (parent === "/" || parent === import_node_path17.default.resolve(cwd)) {
20131
+ const parent = import_node_path18.default.dirname(import_node_path18.default.resolve(cwd));
20132
+ if (parent === "/" || parent === import_node_path18.default.resolve(cwd)) {
20061
20133
  throw new Error("repo \u5728\u78C1\u76D8\u6839\u76EE\u5F55\uFF0C\u65E0\u6CD5\u5728\u540C\u7EA7\u521B\u5EFA worktree");
20062
20134
  }
20063
- const worktreeRoot = import_node_path17.default.join(parent, dirName);
20135
+ const worktreeRoot = import_node_path18.default.join(parent, dirName);
20064
20136
  try {
20065
- await pexec("git", ["-C", cwd, "rev-parse", "--verify", `refs/heads/${baseBranch}`], {
20066
- timeout: 3e3
20137
+ await pexec("git", ["-C", cwd, "fetch", "origin", baseBranch, "--no-tags"], {
20138
+ timeout: 3e4
20067
20139
  });
20068
- } catch {
20069
- throw new Error(`\u57FA\u51C6\u5206\u652F ${baseBranch} \u4E0D\u5B58\u5728`);
20140
+ } catch (err) {
20141
+ throw new Error(
20142
+ `\u57FA\u51C6\u5206\u652F ${baseBranch} \u4E0D\u5B58\u5728\u6216 fetch \u8FDC\u7AEF\u5931\u8D25\uFF1A${formatChildProcessError(err)}`
20143
+ );
20070
20144
  }
20071
20145
  try {
20072
20146
  await pexec("git", ["-C", cwd, "rev-parse", "--verify", `refs/heads/${branch}`], {
@@ -20083,7 +20157,7 @@ async function createWorktree(input) {
20083
20157
  try {
20084
20158
  await pexec(
20085
20159
  "git",
20086
- ["-C", cwd, "worktree", "add", worktreeRoot, "-b", branch, baseBranch],
20160
+ ["-C", cwd, "worktree", "add", worktreeRoot, "-b", branch, `origin/${baseBranch}`],
20087
20161
  { timeout: 15e3 }
20088
20162
  );
20089
20163
  } catch (err) {
@@ -20105,8 +20179,8 @@ async function removeWorktree(input) {
20105
20179
  );
20106
20180
  const gitCommonDir = stdout.trim();
20107
20181
  if (!gitCommonDir) throw new Error("empty git-common-dir");
20108
- const absGitCommon = import_node_path17.default.isAbsolute(gitCommonDir) ? gitCommonDir : import_node_path17.default.resolve(worktreeRoot, gitCommonDir);
20109
- repoRoot = import_node_path17.default.dirname(absGitCommon);
20182
+ const absGitCommon = import_node_path18.default.isAbsolute(gitCommonDir) ? gitCommonDir : import_node_path18.default.resolve(worktreeRoot, gitCommonDir);
20183
+ repoRoot = import_node_path18.default.dirname(absGitCommon);
20110
20184
  } catch {
20111
20185
  repoRoot = null;
20112
20186
  }
@@ -20137,9 +20211,9 @@ async function removeWorktree(input) {
20137
20211
  try {
20138
20212
  const encoded = encodeClaudeProjectDir(worktreeRoot);
20139
20213
  if (encoded) {
20140
- const projectsRoot = import_node_path17.default.join(import_node_os11.default.homedir(), ".claude", "projects");
20141
- const target = import_node_path17.default.resolve(projectsRoot, encoded);
20142
- if (target.startsWith(projectsRoot + import_node_path17.default.sep) && target !== projectsRoot) {
20214
+ const projectsRoot = import_node_path18.default.join(import_node_os11.default.homedir(), ".claude", "projects");
20215
+ const target = import_node_path18.default.resolve(projectsRoot, encoded);
20216
+ if (target.startsWith(projectsRoot + import_node_path18.default.sep) && target !== projectsRoot) {
20143
20217
  import_node_fs18.default.rmSync(target, { recursive: true, force: true });
20144
20218
  }
20145
20219
  }
@@ -20352,7 +20426,7 @@ function buildMethodHandlers(deps) {
20352
20426
  async function startDaemon(config) {
20353
20427
  const logger = createLogger({
20354
20428
  level: config.logLevel,
20355
- file: import_node_path18.default.join(config.dataDir, "clawd.log")
20429
+ file: import_node_path19.default.join(config.dataDir, "clawd.log")
20356
20430
  });
20357
20431
  logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
20358
20432
  const stateMgr = new StateFileManager({ dataDir: config.dataDir });
@@ -20394,7 +20468,7 @@ async function startDaemon(config) {
20394
20468
  getAdapter,
20395
20469
  historyReader: history,
20396
20470
  dataDir: config.dataDir,
20397
- personaRoot: import_node_path18.default.join(config.dataDir, "personas"),
20471
+ personaRoot: import_node_path19.default.join(config.dataDir, "personas"),
20398
20472
  broadcastFrame: (frame, target) => {
20399
20473
  if (target === "all") {
20400
20474
  transport?.broadcastAll(frame);
@@ -20434,7 +20508,7 @@ async function startDaemon(config) {
20434
20508
  manager.recordRealUserUuid({ sessionId, realUuid, text });
20435
20509
  }
20436
20510
  });
20437
- const personaStore = new PersonaStore(import_node_path18.default.join(config.dataDir, "personas"));
20511
+ const personaStore = new PersonaStore(import_node_path19.default.join(config.dataDir, "personas"));
20438
20512
  const personaRegistry = new PersonaRegistry(personaStore);
20439
20513
  const personaManager = new PersonaManager({
20440
20514
  store: personaStore,
@@ -20567,8 +20641,8 @@ async function startDaemon(config) {
20567
20641
  const lines = [
20568
20642
  `Tunnel: ${r.url}`,
20569
20643
  ...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
20570
- `Frpc config: ${import_node_path18.default.join(config.dataDir, "frpc.toml")}`,
20571
- `Frpc log: ${import_node_path18.default.join(config.dataDir, "frpc.log")}`
20644
+ `Frpc config: ${import_node_path19.default.join(config.dataDir, "frpc.toml")}`,
20645
+ `Frpc log: ${import_node_path19.default.join(config.dataDir, "frpc.log")}`
20572
20646
  ];
20573
20647
  const width = Math.max(...lines.map((l) => l.length));
20574
20648
  const bar = "\u2550".repeat(width + 4);
@@ -20581,7 +20655,7 @@ ${bar}
20581
20655
 
20582
20656
  `);
20583
20657
  try {
20584
- const connectPath = import_node_path18.default.join(config.dataDir, "connect.txt");
20658
+ const connectPath = import_node_path19.default.join(config.dataDir, "connect.txt");
20585
20659
  import_node_fs19.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
20586
20660
  } catch {
20587
20661
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawos-dev/clawd",
3
- "version": "0.2.33",
3
+ "version": "0.2.34-beta.50.1515dc2",
4
4
  "description": "Standalone clawd daemon — Claude Code (and future Codex) session server over WebSocket",
5
5
  "type": "module",
6
6
  "license": "MIT",