@clawos-dev/clawd 0.2.33 → 0.2.34-beta.49.e300ede

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 +282 -529
  2. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -1208,7 +1208,7 @@ var require_atomic_sleep = __commonJS({
1208
1208
  var require_sonic_boom = __commonJS({
1209
1209
  "../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
1210
1210
  "use strict";
1211
- var fs22 = require("fs");
1211
+ var fs21 = require("fs");
1212
1212
  var EventEmitter = require("events");
1213
1213
  var inherits = require("util").inherits;
1214
1214
  var path22 = require("path");
@@ -1265,20 +1265,20 @@ 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 });
1269
- const fd = fs22.openSync(file, flags, mode);
1268
+ if (sonic.mkdir) fs21.mkdirSync(path22.dirname(file), { recursive: true });
1269
+ const fd = fs21.openSync(file, flags, mode);
1270
1270
  fileOpened(null, fd);
1271
1271
  } catch (err) {
1272
1272
  fileOpened(err);
1273
1273
  throw err;
1274
1274
  }
1275
1275
  } else if (sonic.mkdir) {
1276
- fs22.mkdir(path22.dirname(file), { recursive: true }, (err) => {
1276
+ fs21.mkdir(path22.dirname(file), { recursive: true }, (err) => {
1277
1277
  if (err) return fileOpened(err);
1278
- fs22.open(file, flags, mode, fileOpened);
1278
+ fs21.open(file, flags, mode, fileOpened);
1279
1279
  });
1280
1280
  } else {
1281
- fs22.open(file, flags, mode, fileOpened);
1281
+ fs21.open(file, flags, mode, fileOpened);
1282
1282
  }
1283
1283
  }
1284
1284
  function SonicBoom(opts) {
@@ -1319,8 +1319,8 @@ var require_sonic_boom = __commonJS({
1319
1319
  this.flush = flushBuffer;
1320
1320
  this.flushSync = flushBufferSync;
1321
1321
  this._actualWrite = actualWriteBuffer;
1322
- fsWriteSync = () => fs22.writeSync(this.fd, this._writingBuf);
1323
- fsWrite = () => fs22.write(this.fd, this._writingBuf, this.release);
1322
+ fsWriteSync = () => fs21.writeSync(this.fd, this._writingBuf);
1323
+ fsWrite = () => fs21.write(this.fd, this._writingBuf, this.release);
1324
1324
  } else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
1325
1325
  this._writingBuf = "";
1326
1326
  this.write = write;
@@ -1329,15 +1329,15 @@ var require_sonic_boom = __commonJS({
1329
1329
  this._actualWrite = actualWrite;
1330
1330
  fsWriteSync = () => {
1331
1331
  if (Buffer.isBuffer(this._writingBuf)) {
1332
- return fs22.writeSync(this.fd, this._writingBuf);
1332
+ return fs21.writeSync(this.fd, this._writingBuf);
1333
1333
  }
1334
- return fs22.writeSync(this.fd, this._writingBuf, "utf8");
1334
+ return fs21.writeSync(this.fd, this._writingBuf, "utf8");
1335
1335
  };
1336
1336
  fsWrite = () => {
1337
1337
  if (Buffer.isBuffer(this._writingBuf)) {
1338
- return fs22.write(this.fd, this._writingBuf, this.release);
1338
+ return fs21.write(this.fd, this._writingBuf, this.release);
1339
1339
  }
1340
- return fs22.write(this.fd, this._writingBuf, "utf8", this.release);
1340
+ return fs21.write(this.fd, this._writingBuf, "utf8", this.release);
1341
1341
  };
1342
1342
  } else {
1343
1343
  throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
@@ -1394,7 +1394,7 @@ var require_sonic_boom = __commonJS({
1394
1394
  }
1395
1395
  }
1396
1396
  if (this._fsync) {
1397
- fs22.fsyncSync(this.fd);
1397
+ fs21.fsyncSync(this.fd);
1398
1398
  }
1399
1399
  const len = this._len;
1400
1400
  if (this._reopening) {
@@ -1508,7 +1508,7 @@ var require_sonic_boom = __commonJS({
1508
1508
  const onDrain = () => {
1509
1509
  if (!this._fsync) {
1510
1510
  try {
1511
- fs22.fsync(this.fd, (err) => {
1511
+ fs21.fsync(this.fd, (err) => {
1512
1512
  this._flushPending = false;
1513
1513
  cb(err);
1514
1514
  });
@@ -1610,7 +1610,7 @@ var require_sonic_boom = __commonJS({
1610
1610
  const fd = this.fd;
1611
1611
  this.once("ready", () => {
1612
1612
  if (fd !== this.fd) {
1613
- fs22.close(fd, (err) => {
1613
+ fs21.close(fd, (err) => {
1614
1614
  if (err) {
1615
1615
  return this.emit("error", err);
1616
1616
  }
@@ -1659,7 +1659,7 @@ var require_sonic_boom = __commonJS({
1659
1659
  buf = this._bufs[0];
1660
1660
  }
1661
1661
  try {
1662
- const n = Buffer.isBuffer(buf) ? fs22.writeSync(this.fd, buf) : fs22.writeSync(this.fd, buf, "utf8");
1662
+ const n = Buffer.isBuffer(buf) ? fs21.writeSync(this.fd, buf) : fs21.writeSync(this.fd, buf, "utf8");
1663
1663
  const releasedBufObj = releaseWritingBuf(buf, this._len, n);
1664
1664
  buf = releasedBufObj.writingBuf;
1665
1665
  this._len = releasedBufObj.len;
@@ -1675,7 +1675,7 @@ var require_sonic_boom = __commonJS({
1675
1675
  }
1676
1676
  }
1677
1677
  try {
1678
- fs22.fsyncSync(this.fd);
1678
+ fs21.fsyncSync(this.fd);
1679
1679
  } catch {
1680
1680
  }
1681
1681
  }
@@ -1696,7 +1696,7 @@ var require_sonic_boom = __commonJS({
1696
1696
  buf = mergeBuf(this._bufs[0], this._lens[0]);
1697
1697
  }
1698
1698
  try {
1699
- const n = fs22.writeSync(this.fd, buf);
1699
+ const n = fs21.writeSync(this.fd, buf);
1700
1700
  buf = buf.subarray(n);
1701
1701
  this._len = Math.max(this._len - n, 0);
1702
1702
  if (buf.length <= 0) {
@@ -1724,13 +1724,13 @@ var require_sonic_boom = __commonJS({
1724
1724
  this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
1725
1725
  if (this.sync) {
1726
1726
  try {
1727
- const written = Buffer.isBuffer(this._writingBuf) ? fs22.writeSync(this.fd, this._writingBuf) : fs22.writeSync(this.fd, this._writingBuf, "utf8");
1727
+ const written = Buffer.isBuffer(this._writingBuf) ? fs21.writeSync(this.fd, this._writingBuf) : fs21.writeSync(this.fd, this._writingBuf, "utf8");
1728
1728
  release(null, written);
1729
1729
  } catch (err) {
1730
1730
  release(err);
1731
1731
  }
1732
1732
  } else {
1733
- fs22.write(this.fd, this._writingBuf, release);
1733
+ fs21.write(this.fd, this._writingBuf, release);
1734
1734
  }
1735
1735
  }
1736
1736
  function actualWriteBuffer() {
@@ -1739,7 +1739,7 @@ var require_sonic_boom = __commonJS({
1739
1739
  this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
1740
1740
  if (this.sync) {
1741
1741
  try {
1742
- const written = fs22.writeSync(this.fd, this._writingBuf);
1742
+ const written = fs21.writeSync(this.fd, this._writingBuf);
1743
1743
  release(null, written);
1744
1744
  } catch (err) {
1745
1745
  release(err);
@@ -1748,7 +1748,7 @@ var require_sonic_boom = __commonJS({
1748
1748
  if (kCopyBuffer) {
1749
1749
  this._writingBuf = Buffer.from(this._writingBuf);
1750
1750
  }
1751
- fs22.write(this.fd, this._writingBuf, release);
1751
+ fs21.write(this.fd, this._writingBuf, release);
1752
1752
  }
1753
1753
  }
1754
1754
  function actualClose(sonic) {
@@ -1764,12 +1764,12 @@ var require_sonic_boom = __commonJS({
1764
1764
  sonic._lens = [];
1765
1765
  assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
1766
1766
  try {
1767
- fs22.fsync(sonic.fd, closeWrapped);
1767
+ fs21.fsync(sonic.fd, closeWrapped);
1768
1768
  } catch {
1769
1769
  }
1770
1770
  function closeWrapped() {
1771
1771
  if (sonic.fd !== 1 && sonic.fd !== 2) {
1772
- fs22.close(sonic.fd, done);
1772
+ fs21.close(sonic.fd, done);
1773
1773
  } else {
1774
1774
  done();
1775
1775
  }
@@ -4133,7 +4133,7 @@ var require_multistream = __commonJS({
4133
4133
  var require_pino = __commonJS({
4134
4134
  "../node_modules/.pnpm/pino@9.14.0/node_modules/pino/pino.js"(exports2, module2) {
4135
4135
  "use strict";
4136
- var os14 = require("os");
4136
+ var os13 = require("os");
4137
4137
  var stdSerializers = require_pino_std_serializers();
4138
4138
  var caller = require_caller();
4139
4139
  var redaction = require_redaction();
@@ -4180,7 +4180,7 @@ var require_pino = __commonJS({
4180
4180
  } = symbols;
4181
4181
  var { epochTime, nullTime } = time;
4182
4182
  var { pid } = process;
4183
- var hostname = os14.hostname();
4183
+ var hostname = os13.hostname();
4184
4184
  var defaultErrorSerializer = stdSerializers.err;
4185
4185
  var defaultOptions = {
4186
4186
  level: "info",
@@ -4384,7 +4384,6 @@ var init_methods = __esm({
4384
4384
  "workspace:list",
4385
4385
  "workspace:read",
4386
4386
  "skills:list",
4387
- "agents:list",
4388
4387
  "git:root",
4389
4388
  "git:branch",
4390
4389
  "git:branches",
@@ -4409,7 +4408,7 @@ var init_methods = __esm({
4409
4408
  });
4410
4409
 
4411
4410
  // ../protocol/src/events.ts
4412
- var SESSION_STATUS_VALUES, HISTORY_USER_META_VALUES, SKILL_SOURCE_VALUES, AGENT_SOURCE_VALUES, ASK_USER_QUESTION_TOOL_NAME;
4411
+ var SESSION_STATUS_VALUES, HISTORY_USER_META_VALUES, ASK_USER_QUESTION_TOOL_NAME;
4413
4412
  var init_events = __esm({
4414
4413
  "../protocol/src/events.ts"() {
4415
4414
  "use strict";
@@ -4430,14 +4429,6 @@ var init_events = __esm({
4430
4429
  "attachment-skills",
4431
4430
  "attachment-deferred-tools"
4432
4431
  ];
4433
- SKILL_SOURCE_VALUES = ["builtin", "global", "project", "plugin"];
4434
- AGENT_SOURCE_VALUES = [
4435
- "builtin",
4436
- "global",
4437
- "project",
4438
- "policy",
4439
- "plugin"
4440
- ];
4441
4432
  ASK_USER_QUESTION_TOOL_NAME = "AskUserQuestion";
4442
4433
  }
4443
4434
  });
@@ -8646,7 +8637,7 @@ var init_persona_schemas = __esm({
8646
8637
  });
8647
8638
 
8648
8639
  // ../protocol/src/schemas.ts
8649
- var SessionStatusSchema, UsageSchema, ContextUsageSchema, sessionMetaShape, SessionMetaSchema, ModelInfoSchema, ModeInfoSchema, ConfigFieldSchemaSchema, CapabilitiesGetArgs, CapabilitiesResponseSchema, AllowRuleSchema, SessionFileSchema, ParsedEventBase, HistoryUserMetaSchema, SubagentToolStatsSchema, StructuredPatchHunkSchema, ToolResultExtraSchema, MemoryEntrySchema, AskQuestionOptionSchema, AskQuestionItemSchema, ParsedEventSchema, SessionCreateArgs, SessionIdArgs, SessionUpdateArgs, SessionSendArgs, SessionRewindArgs, SessionRewindResponseSchema, SessionRewindDiffArgs, RewindDiffHunkSchema, RewindDiffFileSchema, SessionRewindDiffResponseSchema, SessionRewindableMessageIdsArgs, SessionRewindableMessageIdsResponseSchema, SessionResumeArgs, SessionForkArgs, SessionForkResponseSchema, SessionObserveArgs, SessionEventsArgs, PermissionRespondArgs, HistoryListArgs, HistoryReadArgs, HistorySubagentsArgs, HistorySubagentReadArgs, WorkspaceListArgs, WorkspaceReadArgs, SkillsListArgs, SkillEntrySchema, AgentEntrySchema, AgentsListArgs, AgentsListResponseSchema, SessionSubscribeArgs, SessionPinArgs, SessionReorderPinsArgs, GitRootArgs, GitRootResponseSchema, GitBranchArgs, GitBranchResponseSchema, GitBranchesArgs, GitBranchesResponseSchema, GitWorktreePrefixArgs, GitWorktreePrefixResponseSchema, GitWorktreeCreateArgs, GitWorktreeCreateResponseSchema, GitWorktreeRemoveArgs, GitWorktreeRemoveResponseSchema, HistoryRecentDirsArgs, RecentDirEntrySchema, HistoryRecentDirsResponseSchema, SessionQuestionFrameSchema, SessionQuestionClearedFrameSchema, AnswerQuestionArgs, AnswerQuestionResponseSchema, AuthRequestFrameSchema, AuthOkFrameSchema, TunnelExitedEventSchema, InfoRunningSessionSchema, InfoResponseSchema;
8640
+ var SessionStatusSchema, UsageSchema, ContextUsageSchema, sessionMetaShape, SessionMetaSchema, ModelInfoSchema, ModeInfoSchema, ConfigFieldSchemaSchema, CapabilitiesGetArgs, CapabilitiesResponseSchema, AllowRuleSchema, SessionFileSchema, ParsedEventBase, HistoryUserMetaSchema, SubagentToolStatsSchema, StructuredPatchHunkSchema, ToolResultExtraSchema, MemoryEntrySchema, AskQuestionOptionSchema, AskQuestionItemSchema, ParsedEventSchema, SessionCreateArgs, SessionIdArgs, SessionUpdateArgs, SessionSendArgs, SessionRewindArgs, SessionRewindResponseSchema, SessionRewindDiffArgs, RewindDiffHunkSchema, RewindDiffFileSchema, SessionRewindDiffResponseSchema, SessionRewindableMessageIdsArgs, SessionRewindableMessageIdsResponseSchema, SessionResumeArgs, SessionForkArgs, SessionForkResponseSchema, SessionObserveArgs, SessionEventsArgs, PermissionRespondArgs, HistoryListArgs, HistoryReadArgs, HistorySubagentsArgs, HistorySubagentReadArgs, WorkspaceListArgs, WorkspaceReadArgs, SkillsListArgs, SessionSubscribeArgs, SessionPinArgs, SessionReorderPinsArgs, GitRootArgs, GitRootResponseSchema, GitBranchArgs, GitBranchResponseSchema, GitBranchesArgs, GitBranchesResponseSchema, GitWorktreePrefixArgs, GitWorktreePrefixResponseSchema, GitWorktreeCreateArgs, GitWorktreeCreateResponseSchema, GitWorktreeRemoveArgs, GitWorktreeRemoveResponseSchema, HistoryRecentDirsArgs, RecentDirEntrySchema, HistoryRecentDirsResponseSchema, SessionQuestionFrameSchema, SessionQuestionClearedFrameSchema, AnswerQuestionArgs, AnswerQuestionResponseSchema, AuthRequestFrameSchema, AuthOkFrameSchema, TunnelExitedEventSchema, InfoRunningSessionSchema, InfoResponseSchema;
8650
8641
  var init_schemas = __esm({
8651
8642
  "../protocol/src/schemas.ts"() {
8652
8643
  "use strict";
@@ -8741,6 +8732,9 @@ var init_schemas = __esm({
8741
8732
  // 由 session:fork 派生的 session 在 create 时记录源 transcript 的 toolSessionId;
8742
8733
  // sidebar 据此挂 fork 图标。非 fork session 该字段缺省
8743
8734
  forkedFromToolSessionId: external_exports.string().min(1).optional(),
8735
+ // owner-mode persona session 身份标识;UI 用它在 SessionList 过滤 + jump,
8736
+ // daemon 用它做 idempotent dedupe + spawn 时派生 ctx.personaMode='owner'
8737
+ ownerPersonaId: external_exports.string().min(1).optional(),
8744
8738
  createdAt: external_exports.string().min(1),
8745
8739
  updatedAt: external_exports.string().min(1)
8746
8740
  });
@@ -8940,7 +8934,8 @@ var init_schemas = __esm({
8940
8934
  })
8941
8935
  ]);
8942
8936
  SessionCreateArgs = external_exports.object({
8943
- cwd: external_exports.string().min(1),
8937
+ // 当 ownerPersonaId 存在时 cwd 由 daemon 派生,UI 可不传
8938
+ cwd: external_exports.string().min(1).optional(),
8944
8939
  tool: external_exports.string().optional(),
8945
8940
  label: external_exports.string().optional(),
8946
8941
  model: external_exports.string().optional(),
@@ -8952,7 +8947,12 @@ var init_schemas = __esm({
8952
8947
  worktreeRoot: external_exports.string().min(1).optional(),
8953
8948
  worktreeBranch: external_exports.string().min(1).optional(),
8954
8949
  // session:fork 派生 session 时由 UI 传入,daemon 写到 SessionFile.forkedFromToolSessionId
8955
- forkedFromToolSessionId: external_exports.string().min(1).optional()
8950
+ forkedFromToolSessionId: external_exports.string().min(1).optional(),
8951
+ // owner-mode persona session:传此字段时 daemon 自行派生 cwd 和启动参数,
8952
+ // 且按 ownerPersonaId 做 idempotent dedupe(每 persona 永远只有一个 owner session)
8953
+ ownerPersonaId: external_exports.string().min(1).optional()
8954
+ }).refine((args) => args.cwd != null || args.ownerPersonaId != null, {
8955
+ message: "cwd \u4E0E ownerPersonaId \u81F3\u5C11\u4F20\u4E00\u4E2A"
8956
8956
  });
8957
8957
  SessionIdArgs = external_exports.object({ sessionId: external_exports.string().min(1) });
8958
8958
  SessionUpdateArgs = external_exports.object({
@@ -9069,25 +9069,6 @@ var init_schemas = __esm({
9069
9069
  path: external_exports.string().min(1)
9070
9070
  });
9071
9071
  SkillsListArgs = external_exports.object({ cwd: external_exports.string().min(1) });
9072
- SkillEntrySchema = external_exports.object({
9073
- name: external_exports.string().min(1),
9074
- source: external_exports.enum(SKILL_SOURCE_VALUES),
9075
- path: external_exports.string().optional(),
9076
- description: external_exports.string().optional(),
9077
- plugin: external_exports.string().optional()
9078
- });
9079
- AgentEntrySchema = external_exports.object({
9080
- name: external_exports.string().min(1),
9081
- source: external_exports.enum(AGENT_SOURCE_VALUES),
9082
- path: external_exports.string().optional(),
9083
- description: external_exports.string().optional(),
9084
- whenToUse: external_exports.string().optional(),
9085
- plugin: external_exports.string().optional()
9086
- });
9087
- AgentsListArgs = external_exports.object({ cwd: external_exports.string().min(1) });
9088
- AgentsListResponseSchema = external_exports.object({
9089
- agents: external_exports.array(AgentEntrySchema)
9090
- });
9091
9072
  SessionSubscribeArgs = external_exports.object({ sessionId: external_exports.string().min(1) });
9092
9073
  SessionPinArgs = external_exports.object({
9093
9074
  sessionId: external_exports.string().min(1),
@@ -9202,6 +9183,13 @@ var init_frames = __esm({
9202
9183
  }
9203
9184
  });
9204
9185
 
9186
+ // ../protocol/src/persona-mode.ts
9187
+ var init_persona_mode = __esm({
9188
+ "../protocol/src/persona-mode.ts"() {
9189
+ "use strict";
9190
+ }
9191
+ });
9192
+
9205
9193
  // ../protocol/src/runtime.ts
9206
9194
  var init_runtime = __esm({
9207
9195
  "../protocol/src/runtime.ts"() {
@@ -9212,6 +9200,7 @@ var init_runtime = __esm({
9212
9200
  init_schemas();
9213
9201
  init_frames();
9214
9202
  init_persona_schemas();
9203
+ init_persona_mode();
9215
9204
  }
9216
9205
  });
9217
9206
 
@@ -10273,7 +10262,7 @@ function readBackupContent(fileHistoryRoot, toolSessionId, backupFileName) {
10273
10262
  if (backupFileName === null) return null;
10274
10263
  try {
10275
10264
  return import_node_fs6.default.readFileSync(
10276
- import_node_path5.default.join(fileHistoryRoot, toolSessionId, backupFileName),
10265
+ import_node_path6.default.join(fileHistoryRoot, toolSessionId, backupFileName),
10277
10266
  "utf8"
10278
10267
  );
10279
10268
  } catch {
@@ -10288,13 +10277,13 @@ function readCurrentContent(filePath) {
10288
10277
  return null;
10289
10278
  }
10290
10279
  }
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;
10280
+ 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
10281
  var init_claude_history = __esm({
10293
10282
  "src/tools/claude-history.ts"() {
10294
10283
  "use strict";
10295
10284
  import_node_fs6 = __toESM(require("fs"), 1);
10296
10285
  import_node_os2 = __toESM(require("os"), 1);
10297
- import_node_path5 = __toESM(require("path"), 1);
10286
+ import_node_path6 = __toESM(require("path"), 1);
10298
10287
  init_lib();
10299
10288
  init_tool_result_extra();
10300
10289
  TASK_NOTIFICATION_RE = /<task-notification\b[\s\S]*?<\/task-notification>/i;
@@ -10318,9 +10307,9 @@ var init_claude_history = __esm({
10318
10307
  // 每次 user 提交前 trackEdit 拷一份,作为 rewind 回退目标
10319
10308
  fileHistoryRoot;
10320
10309
  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");
10310
+ const base = opts.baseDir ?? import_node_path6.default.join(import_node_os2.default.homedir(), ".claude");
10311
+ this.projectsRoot = import_node_path6.default.join(base, "projects");
10312
+ this.fileHistoryRoot = import_node_path6.default.join(base, "file-history");
10324
10313
  }
10325
10314
  async listProjects() {
10326
10315
  let entries;
@@ -10333,9 +10322,9 @@ var init_claude_history = __esm({
10333
10322
  const out = [];
10334
10323
  for (const ent of entries) {
10335
10324
  if (!ent.isDirectory()) continue;
10336
- const dir = import_node_path5.default.join(this.projectsRoot, ent.name);
10325
+ const dir = import_node_path6.default.join(this.projectsRoot, ent.name);
10337
10326
  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);
10327
+ const updatedAtMs = files.reduce((m, f) => Math.max(m, safeStatMtime(import_node_path6.default.join(dir, f))), 0);
10339
10328
  out.push({
10340
10329
  projectPath: hashDirToCwd(ent.name),
10341
10330
  hashDir: ent.name,
@@ -10347,7 +10336,7 @@ var init_claude_history = __esm({
10347
10336
  return out;
10348
10337
  }
10349
10338
  async listSessions(args) {
10350
- const dir = import_node_path5.default.join(this.projectsRoot, cwdToHashDir(args.projectPath));
10339
+ const dir = import_node_path6.default.join(this.projectsRoot, cwdToHashDir(args.projectPath));
10351
10340
  let files;
10352
10341
  try {
10353
10342
  files = import_node_fs6.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
@@ -10357,7 +10346,7 @@ var init_claude_history = __esm({
10357
10346
  }
10358
10347
  const out = [];
10359
10348
  for (const f of files) {
10360
- const full = import_node_path5.default.join(dir, f);
10349
+ const full = import_node_path6.default.join(dir, f);
10361
10350
  const toolSessionId = f.slice(0, -".jsonl".length);
10362
10351
  const lines = readJsonlLines(full);
10363
10352
  let summary = "";
@@ -10412,7 +10401,7 @@ var init_claude_history = __esm({
10412
10401
  return out;
10413
10402
  }
10414
10403
  async read(args) {
10415
- const file = import_node_path5.default.join(
10404
+ const file = import_node_path6.default.join(
10416
10405
  this.projectsRoot,
10417
10406
  cwdToHashDir(args.cwd),
10418
10407
  `${args.toolSessionId}.jsonl`
@@ -10445,7 +10434,7 @@ var init_claude_history = __esm({
10445
10434
  // 独立目录路径:<projectsRoot>/<cwdHash>/<toolSessionId>/subagents/*.jsonl
10446
10435
  // 返回 null 表示目录不存在(调用方回退旧实现);返回空数组表示目录存在但无 jsonl
10447
10436
  listSubagentsFromDirectory(cwd, toolSessionId) {
10448
- const dir = import_node_path5.default.join(
10437
+ const dir = import_node_path6.default.join(
10449
10438
  this.projectsRoot,
10450
10439
  cwdToHashDir(cwd),
10451
10440
  toolSessionId,
@@ -10463,7 +10452,7 @@ var init_claude_history = __esm({
10463
10452
  if (!e.isFile()) continue;
10464
10453
  if (!e.name.startsWith("agent-") || !e.name.endsWith(".jsonl")) continue;
10465
10454
  const subagentId = e.name.slice("agent-".length, -".jsonl".length);
10466
- const filePath = import_node_path5.default.join(dir, e.name);
10455
+ const filePath = import_node_path6.default.join(dir, e.name);
10467
10456
  const lines = readJsonlLines(filePath);
10468
10457
  let firstText = "";
10469
10458
  let messageCount = 0;
@@ -10480,7 +10469,7 @@ var init_claude_history = __esm({
10480
10469
  return out;
10481
10470
  }
10482
10471
  listSubagentsFromMainJsonl(cwd, toolSessionId) {
10483
- const file = import_node_path5.default.join(
10472
+ const file = import_node_path6.default.join(
10484
10473
  this.projectsRoot,
10485
10474
  cwdToHashDir(cwd),
10486
10475
  `${toolSessionId}.jsonl`
@@ -10515,7 +10504,7 @@ var init_claude_history = __esm({
10515
10504
  }
10516
10505
  // 独立文件路径:agent-<subagentId>.jsonl;文件不存在返回 null 让调用方回退旧实现
10517
10506
  readSubagentFromFile(cwd, toolSessionId, subagentId) {
10518
- const file = import_node_path5.default.join(
10507
+ const file = import_node_path6.default.join(
10519
10508
  this.projectsRoot,
10520
10509
  cwdToHashDir(cwd),
10521
10510
  toolSessionId,
@@ -10543,7 +10532,7 @@ var init_claude_history = __esm({
10543
10532
  * "那一刻每个 tracked 文件对应的 backup 文件名"
10544
10533
  */
10545
10534
  readFileHistorySnapshots(args) {
10546
- const file = import_node_path5.default.join(
10535
+ const file = import_node_path6.default.join(
10547
10536
  this.projectsRoot,
10548
10537
  cwdToHashDir(args.cwd),
10549
10538
  `${args.toolSessionId}.jsonl`
@@ -10588,7 +10577,7 @@ var init_claude_history = __esm({
10588
10577
  for (const [anchorId, target] of snapshots) {
10589
10578
  let hasAny = false;
10590
10579
  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);
10580
+ const absPath = import_node_path6.default.isAbsolute(rawPath) ? rawPath : import_node_path6.default.join(args.cwd, rawPath);
10592
10581
  const backupContent = readBackupContent(
10593
10582
  this.fileHistoryRoot,
10594
10583
  args.toolSessionId,
@@ -10628,7 +10617,7 @@ var init_claude_history = __esm({
10628
10617
  let totalInsertions = 0;
10629
10618
  let totalDeletions = 0;
10630
10619
  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);
10620
+ const absPath = import_node_path6.default.isAbsolute(rawPath) ? rawPath : import_node_path6.default.join(args.cwd, rawPath);
10632
10621
  const backupContent = readBackupContent(
10633
10622
  this.fileHistoryRoot,
10634
10623
  args.toolSessionId,
@@ -10675,7 +10664,7 @@ var init_claude_history = __esm({
10675
10664
  };
10676
10665
  }
10677
10666
  readSubagentFromMainJsonl(cwd, toolSessionId, subagentId) {
10678
- const file = import_node_path5.default.join(
10667
+ const file = import_node_path6.default.join(
10679
10668
  this.projectsRoot,
10680
10669
  cwdToHashDir(cwd),
10681
10670
  `${toolSessionId}.jsonl`
@@ -10699,7 +10688,7 @@ var init_claude_history = __esm({
10699
10688
  // src/tools/claude.ts
10700
10689
  function macOSDesktopCandidates(home) {
10701
10690
  return [
10702
- import_node_path6.default.join(home, "Applications", "Claude.app", "Contents", "Resources", "app.asar.unpacked", "node_modules", "@anthropic-ai", "claude-code", "cli.js"),
10691
+ import_node_path7.default.join(home, "Applications", "Claude.app", "Contents", "Resources", "app.asar.unpacked", "node_modules", "@anthropic-ai", "claude-code", "cli.js"),
10703
10692
  "/Applications/Claude.app/Contents/Resources/app.asar.unpacked/node_modules/@anthropic-ai/claude-code/cli.js"
10704
10693
  ];
10705
10694
  }
@@ -10744,10 +10733,21 @@ function buildSpawnArgs(ctx) {
10744
10733
  "--verbose"
10745
10734
  ];
10746
10735
  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);
10736
+ switch (ctx.personaMode) {
10737
+ case "listener":
10738
+ args.push("--setting-sources", "project,local");
10739
+ break;
10740
+ case "owner":
10741
+ args.push("--setting-sources", "user");
10742
+ args.push("--permission-mode", "bypassPermissions");
10743
+ break;
10744
+ case void 0:
10745
+ if (ctx.permissionMode) args.push("--permission-mode", ctx.permissionMode);
10746
+ break;
10747
+ default: {
10748
+ const _exhaustive = ctx.personaMode;
10749
+ throw new Error(`unexpected personaMode: ${String(_exhaustive)}`);
10750
+ }
10751
10751
  }
10752
10752
  if (ctx.effort) args.push("--effort", ctx.effort);
10753
10753
  if (ctx.toolSessionId) args.push("--resume", ctx.toolSessionId);
@@ -11134,7 +11134,7 @@ function encodeClaudeStdin(text) {
11134
11134
  };
11135
11135
  return JSON.stringify(frame) + "\n";
11136
11136
  }
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;
11137
+ 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
11138
  var init_claude = __esm({
11139
11139
  "src/tools/claude.ts"() {
11140
11140
  "use strict";
@@ -11142,7 +11142,7 @@ var init_claude = __esm({
11142
11142
  import_node_child_process2 = require("child_process");
11143
11143
  import_node_fs7 = __toESM(require("fs"), 1);
11144
11144
  import_node_os3 = __toESM(require("os"), 1);
11145
- import_node_path6 = __toESM(require("path"), 1);
11145
+ import_node_path7 = __toESM(require("path"), 1);
11146
11146
  init_protocol();
11147
11147
  init_claude_history();
11148
11148
  init_tool_result_extra();
@@ -14911,8 +14911,8 @@ function startRunCaseRecorder(opts) {
14911
14911
  });
14912
14912
  const ensureStream = () => {
14913
14913
  if (stream) return stream;
14914
- import_node_fs20.default.mkdirSync(dir, { recursive: true });
14915
- stream = import_node_fs20.default.createWriteStream(opts.recordPath, { flags: "a" });
14914
+ import_node_fs19.default.mkdirSync(dir, { recursive: true });
14915
+ stream = import_node_fs19.default.createWriteStream(opts.recordPath, { flags: "a" });
14916
14916
  stream.on("close", () => closedResolve());
14917
14917
  return stream;
14918
14918
  };
@@ -14937,11 +14937,11 @@ function startRunCaseRecorder(opts) {
14937
14937
  };
14938
14938
  return { tap, close, closed };
14939
14939
  }
14940
- var import_node_fs20, import_node_path19;
14940
+ var import_node_fs19, import_node_path19;
14941
14941
  var init_recorder = __esm({
14942
14942
  "src/run-case/recorder.ts"() {
14943
14943
  "use strict";
14944
- import_node_fs20 = __toESM(require("fs"), 1);
14944
+ import_node_fs19 = __toESM(require("fs"), 1);
14945
14945
  import_node_path19 = __toESM(require("path"), 1);
14946
14946
  }
14947
14947
  });
@@ -14985,7 +14985,7 @@ var init_wire = __esm({
14985
14985
  // src/run-case/controller.ts
14986
14986
  async function runController(opts) {
14987
14987
  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-"));
14988
+ const cwd = opts.cwd ?? (0, import_node_fs20.mkdtempSync)(import_node_path20.default.join(import_node_os12.default.tmpdir(), "clawd-runcase-"));
14989
14989
  const ownsCwd = opts.cwd === void 0;
14990
14990
  const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
14991
14991
  const spawnCtx = { cwd };
@@ -15146,18 +15146,18 @@ async function runController(opts) {
15146
15146
  if (sigintHandler) process.off("SIGINT", sigintHandler);
15147
15147
  if (ownsCwd) {
15148
15148
  try {
15149
- (0, import_node_fs21.rmSync)(cwd, { recursive: true, force: true });
15149
+ (0, import_node_fs20.rmSync)(cwd, { recursive: true, force: true });
15150
15150
  } catch {
15151
15151
  }
15152
15152
  }
15153
15153
  return exitCode ?? 0;
15154
15154
  }
15155
- var import_node_fs21, import_node_os13, import_node_path20;
15155
+ var import_node_fs20, import_node_os12, import_node_path20;
15156
15156
  var init_controller = __esm({
15157
15157
  "src/run-case/controller.ts"() {
15158
15158
  "use strict";
15159
- import_node_fs21 = require("fs");
15160
- import_node_os13 = __toESM(require("os"), 1);
15159
+ import_node_fs20 = require("fs");
15160
+ import_node_os12 = __toESM(require("os"), 1);
15161
15161
  import_node_path20 = __toESM(require("path"), 1);
15162
15162
  init_claude();
15163
15163
  init_stdout_splitter();
@@ -15384,7 +15384,7 @@ Env (advanced):
15384
15384
 
15385
15385
  // src/index.ts
15386
15386
  var import_node_path18 = __toESM(require("path"), 1);
15387
- var import_node_fs19 = __toESM(require("fs"), 1);
15387
+ var import_node_fs18 = __toESM(require("fs"), 1);
15388
15388
 
15389
15389
  // src/logger.ts
15390
15390
  var import_node_fs2 = __toESM(require("fs"), 1);
@@ -15514,6 +15514,7 @@ var SessionStore = class {
15514
15514
 
15515
15515
  // src/session/manager.ts
15516
15516
  var import_node_fs5 = __toESM(require("fs"), 1);
15517
+ var import_node_path5 = __toESM(require("path"), 1);
15517
15518
 
15518
15519
  // ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/stringify.js
15519
15520
  var byteToHex = [];
@@ -15660,7 +15661,7 @@ function buildSpawnContext(state) {
15660
15661
  };
15661
15662
  const meta = state.subSessionMeta;
15662
15663
  if (meta?.personaMode) {
15663
- ctx.personaMode = true;
15664
+ ctx.personaMode = meta.personaMode;
15664
15665
  }
15665
15666
  return ctx;
15666
15667
  }
@@ -15686,7 +15687,7 @@ function applyMetaUpdate(state, patch, deps) {
15686
15687
  if (shallowEqMeta(next.file, merged)) {
15687
15688
  return { state: next, effects: [] };
15688
15689
  }
15689
- next.file = merged;
15690
+ next.file = { ...merged, updatedAt: nowIso(deps) };
15690
15691
  return {
15691
15692
  state: next,
15692
15693
  effects: [
@@ -15788,7 +15789,6 @@ function pushEventToBuffer(state, event, deps) {
15788
15789
  next.nextSeq = seq + 1;
15789
15790
  if (newBuffer.length === 1) next.bufferStartSeq = seq;
15790
15791
  const isTurnEnd = withSeq.kind === "turn_end";
15791
- const isUserText = withSeq.kind === "user_text";
15792
15792
  if (isTurnEnd) next.turnOpen = false;
15793
15793
  else if (!next.turnOpen) next.turnOpen = true;
15794
15794
  if (!next.turnOpen && next.buffer.length > deps.bufferCap) {
@@ -15799,11 +15799,6 @@ function pushEventToBuffer(state, event, deps) {
15799
15799
  }
15800
15800
  if (next.freshSpawn) next.freshSpawn = false;
15801
15801
  const effects = [emitSessionEvent(next.file.sessionId, withSeq)];
15802
- if (isUserText || isTurnEnd) {
15803
- next.file = { ...next.file, updatedAt: nowIso(deps) };
15804
- effects.push({ kind: "persist-file", file: next.file });
15805
- effects.push(sessionInfoFrame(next.file));
15806
- }
15807
15802
  if (isTurnEnd && next.subSessionMeta?.idleKillEnabled && next.procAlive && (next.status === "running" || next.status === "spawning")) {
15808
15803
  next.status = "running-idle";
15809
15804
  effects.push({
@@ -15820,14 +15815,6 @@ var RUNTIME_PATCH_KEYS = [
15820
15815
  "effort",
15821
15816
  "cwd"
15822
15817
  ];
15823
- var MARKER_PATCH_KEYS = ["pinnedAt", "pinSortOrder"];
15824
- function isMarkerOnlyPatch(patch) {
15825
- const keys = Object.keys(patch).filter(
15826
- (k) => patch[k] !== void 0
15827
- );
15828
- if (keys.length === 0) return false;
15829
- return keys.every((k) => MARKER_PATCH_KEYS.includes(k));
15830
- }
15831
15818
  function applyCommand(state, command, deps) {
15832
15819
  const next = cloneState(state);
15833
15820
  const effects = [];
@@ -15934,8 +15921,7 @@ function applyCommand(state, command, deps) {
15934
15921
  const runtimePatch = RUNTIME_PATCH_KEYS.some(
15935
15922
  (k) => patch[k] !== void 0
15936
15923
  );
15937
- const markerOnly = isMarkerOnlyPatch(patch);
15938
- next.file = markerOnly ? { ...next.file, ...patch } : { ...next.file, ...patch, updatedAt: nowIso(deps) };
15924
+ next.file = { ...next.file, ...patch, updatedAt: nowIso(deps) };
15939
15925
  effects.push({ kind: "persist-file", file: next.file });
15940
15926
  effects.push(sessionInfoFrame(next.file));
15941
15927
  if (runtimePatch && next.procAlive) {
@@ -16657,10 +16643,22 @@ var SessionManager = class {
16657
16643
  this.capabilitiesCache.set(tool, caps);
16658
16644
  return caps;
16659
16645
  }
16646
+ // 按优先级解析 SubSessionMeta:subSessionMetaBySid 缓存(内存,首次 create/registerSubSession 写入)
16647
+ // → SessionFile.ownerPersonaId 派生(持久化兜底,daemon 重启后 subSessionMetaBySid 丢失时生效)
16648
+ // → undefined(普通 session)
16649
+ resolveSubSessionMeta(file) {
16650
+ const cached = this.subSessionMetaBySid.get(file.sessionId);
16651
+ if (cached) return cached;
16652
+ if (file.ownerPersonaId) {
16653
+ return { idleKillEnabled: false, personaMode: "owner" };
16654
+ }
16655
+ return void 0;
16656
+ }
16660
16657
  // 创建 runner 时包一层 broadcast hook:所有外出 frame 统一走 routeFromRunner,
16661
16658
  // 经过 compressFrameForWire 后决定是 push collector 还是走 deps.broadcastFrame
16662
16659
  // store:默认 deps.store;persona sub-session 路径下传该 personaId 对应的 SessionStore
16663
- // subSessionMeta:persona 路径传 { idleKillEnabled: true },其它路径不传
16660
+ // subSessionMeta:listener { idleKillEnabled: true, personaMode: 'listener' }
16661
+ // owner 传 { idleKillEnabled: false, personaMode: 'owner' };普通 session 不传
16664
16662
  newRunner(file, opts = {}) {
16665
16663
  const adapter = this.deps.getAdapter(file.tool ?? "claude");
16666
16664
  const store = opts.store ?? this.deps.store;
@@ -16718,18 +16716,34 @@ var SessionManager = class {
16718
16716
  }
16719
16717
  // ---- 命令方法:均返回 { response, broadcast[] },由 dispatcher 聚合 ----
16720
16718
  create(args) {
16719
+ if (args.ownerPersonaId) {
16720
+ const existing = this.deps.store.list().find((s) => s.ownerPersonaId === args.ownerPersonaId);
16721
+ if (existing) {
16722
+ return { response: existing, broadcast: [] };
16723
+ }
16724
+ }
16725
+ let cwd = args.cwd;
16726
+ if (args.ownerPersonaId && !cwd) {
16727
+ if (!this.deps.personaRoot) {
16728
+ throw new Error("personaRoot required to derive cwd from ownerPersonaId");
16729
+ }
16730
+ cwd = import_node_path5.default.join(this.deps.personaRoot, safeFileName(args.ownerPersonaId));
16731
+ }
16732
+ if (!cwd) {
16733
+ throw new ClawdError(ERROR_CODES.INVALID_CWD, "cwd required when ownerPersonaId is absent");
16734
+ }
16721
16735
  try {
16722
- const stat = import_node_fs5.default.statSync(args.cwd);
16736
+ const stat = import_node_fs5.default.statSync(cwd);
16723
16737
  if (!stat.isDirectory()) throw new Error("not dir");
16724
16738
  } catch {
16725
- throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${args.cwd}`);
16739
+ throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${cwd}`);
16726
16740
  }
16727
16741
  const tool = args.tool ?? "claude";
16728
16742
  this.deps.getAdapter(tool);
16729
16743
  const iso = nowIso2(this.deps);
16730
16744
  const file = {
16731
16745
  sessionId: newSessionId(),
16732
- cwd: args.cwd,
16746
+ cwd,
16733
16747
  tool,
16734
16748
  label: args.label,
16735
16749
  model: args.model,
@@ -16739,10 +16753,17 @@ var SessionManager = class {
16739
16753
  worktreeRoot: args.worktreeRoot,
16740
16754
  worktreeBranch: args.worktreeBranch,
16741
16755
  forkedFromToolSessionId: args.forkedFromToolSessionId,
16756
+ ownerPersonaId: args.ownerPersonaId,
16742
16757
  createdAt: iso,
16743
16758
  updatedAt: iso
16744
16759
  };
16745
16760
  const written = this.deps.store.write(file);
16761
+ if (args.ownerPersonaId) {
16762
+ this.subSessionMetaBySid.set(written.sessionId, {
16763
+ idleKillEnabled: false,
16764
+ personaMode: "owner"
16765
+ });
16766
+ }
16746
16767
  return { response: written, broadcast: [] };
16747
16768
  }
16748
16769
  pin(args) {
@@ -16756,7 +16777,7 @@ var SessionManager = class {
16756
16777
  });
16757
16778
  return { response: value, broadcast };
16758
16779
  }
16759
- const updated = { ...existing, pinnedAt };
16780
+ const updated = { ...existing, pinnedAt, updatedAt: nowIso2(this.deps) };
16760
16781
  this.deps.store.write(updated);
16761
16782
  return { response: updated, broadcast: [] };
16762
16783
  }
@@ -16792,7 +16813,11 @@ var SessionManager = class {
16792
16813
  broadcast.push(...b);
16793
16814
  } else {
16794
16815
  const existing = this.getFile(sessionId);
16795
- const updated = { ...existing, pinSortOrder: index };
16816
+ const updated = {
16817
+ ...existing,
16818
+ pinSortOrder: index,
16819
+ updatedAt: nowIso2(this.deps)
16820
+ };
16796
16821
  this.deps.store.write(updated);
16797
16822
  updatedFiles.push(updated);
16798
16823
  }
@@ -16898,7 +16923,8 @@ var SessionManager = class {
16898
16923
  const existing = this.getFile(args.sessionId);
16899
16924
  let runner = this.runners.get(args.sessionId);
16900
16925
  if (!runner) {
16901
- runner = this.newRunner(existing);
16926
+ const subSessionMeta = this.resolveSubSessionMeta(existing);
16927
+ runner = this.newRunner(existing, { subSessionMeta });
16902
16928
  this.runners.set(args.sessionId, runner);
16903
16929
  }
16904
16930
  const { broadcast } = this.withCollector(() => {
@@ -16992,7 +17018,8 @@ var SessionManager = class {
16992
17018
  const file = this.getFile(args.sessionId);
16993
17019
  let runner = this.runners.get(args.sessionId);
16994
17020
  if (!runner) {
16995
- runner = this.newRunner(file);
17021
+ const subSessionMeta = this.resolveSubSessionMeta(file);
17022
+ runner = this.newRunner(file, { subSessionMeta });
16996
17023
  this.runners.set(args.sessionId, runner);
16997
17024
  }
16998
17025
  if (!runner.getState().procAlive) {
@@ -17150,7 +17177,7 @@ var SessionManager = class {
17150
17177
  ensureSession(file) {
17151
17178
  let r = this.runners.get(file.sessionId);
17152
17179
  if (r) return r;
17153
- const subSessionMeta = this.subSessionMetaBySid.get(file.sessionId);
17180
+ const subSessionMeta = this.resolveSubSessionMeta(file);
17154
17181
  r = this.newRunner(file, { subSessionMeta });
17155
17182
  this.runners.set(file.sessionId, r);
17156
17183
  return r;
@@ -17326,7 +17353,7 @@ var SessionManager = class {
17326
17353
  const existing = this.runners.get(file.sessionId);
17327
17354
  if (existing) return existing;
17328
17355
  const store = this.storeFor(agentId);
17329
- const subSessionMeta = this.subSessionMetaBySid.get(file.sessionId);
17356
+ const subSessionMeta = this.resolveSubSessionMeta(file);
17330
17357
  const runner = this.newRunner(file, { store, subSessionMeta });
17331
17358
  this.runners.set(file.sessionId, runner);
17332
17359
  return runner;
@@ -17348,7 +17375,7 @@ var SessionManager = class {
17348
17375
  }
17349
17376
  let runner = this.runners.get(args.sessionId);
17350
17377
  if (!runner) {
17351
- const subSessionMeta = this.subSessionMetaBySid.get(args.sessionId);
17378
+ const subSessionMeta = this.resolveSubSessionMeta(file);
17352
17379
  runner = this.newRunner(file, { store, subSessionMeta });
17353
17380
  this.runners.set(args.sessionId, runner);
17354
17381
  }
@@ -17420,7 +17447,7 @@ var SessionManager = class {
17420
17447
 
17421
17448
  // src/persona/store.ts
17422
17449
  var fs6 = __toESM(require("fs"), 1);
17423
- var path5 = __toESM(require("path"), 1);
17450
+ var path6 = __toESM(require("path"), 1);
17424
17451
  init_protocol();
17425
17452
  var DEFAULT_SETTINGS = {
17426
17453
  permissions: {
@@ -17449,21 +17476,21 @@ var PersonaStore = class {
17449
17476
  }
17450
17477
  root;
17451
17478
  personaDir(personaId) {
17452
- return path5.join(this.root, safeFileName(personaId));
17479
+ return path6.join(this.root, safeFileName(personaId));
17453
17480
  }
17454
17481
  metaPath(personaId) {
17455
- return path5.join(this.personaDir(personaId), ".clawd", "persona.json");
17482
+ return path6.join(this.personaDir(personaId), ".clawd", "persona.json");
17456
17483
  }
17457
17484
  claudeMdPath(personaId) {
17458
- return path5.join(this.personaDir(personaId), "CLAUDE.md");
17485
+ return path6.join(this.personaDir(personaId), "CLAUDE.md");
17459
17486
  }
17460
17487
  settingsPath(personaId) {
17461
- return path5.join(this.personaDir(personaId), ".claude", "settings.json");
17488
+ return path6.join(this.personaDir(personaId), ".claude", "settings.json");
17462
17489
  }
17463
17490
  write(persona, personality) {
17464
17491
  const dir = this.personaDir(persona.personaId);
17465
- fs6.mkdirSync(path5.join(dir, ".claude"), { recursive: true });
17466
- fs6.mkdirSync(path5.join(dir, ".clawd"), { recursive: true });
17492
+ fs6.mkdirSync(path6.join(dir, ".claude"), { recursive: true });
17493
+ fs6.mkdirSync(path6.join(dir, ".clawd"), { recursive: true });
17467
17494
  this.atomicWrite(this.claudeMdPath(persona.personaId), personality);
17468
17495
  this.atomicWrite(this.settingsPath(persona.personaId), JSON.stringify(DEFAULT_SETTINGS, null, 2));
17469
17496
  this.atomicWrite(this.metaPath(persona.personaId), JSON.stringify(persona, null, 2));
@@ -17488,7 +17515,7 @@ var PersonaStore = class {
17488
17515
  list() {
17489
17516
  if (!fs6.existsSync(this.root)) return [];
17490
17517
  return fs6.readdirSync(this.root).filter((name) => {
17491
- return fs6.existsSync(path5.join(this.root, name, ".clawd", "persona.json"));
17518
+ return fs6.existsSync(path6.join(this.root, name, ".clawd", "persona.json"));
17492
17519
  });
17493
17520
  }
17494
17521
  remove(personaId) {
@@ -17653,7 +17680,7 @@ var PersonaManager = class {
17653
17680
  tool: "claude",
17654
17681
  label: subLabel,
17655
17682
  model: persona.model,
17656
- subSessionMeta: { idleKillEnabled: true, personaMode: true }
17683
+ subSessionMeta: { idleKillEnabled: true, personaMode: "listener" }
17657
17684
  });
17658
17685
  return { sessionFile, isNew: true };
17659
17686
  }
@@ -17689,14 +17716,14 @@ init_claude_history();
17689
17716
  // src/workspace/browser.ts
17690
17717
  var import_node_fs8 = __toESM(require("fs"), 1);
17691
17718
  var import_node_os4 = __toESM(require("os"), 1);
17692
- var import_node_path7 = __toESM(require("path"), 1);
17719
+ var import_node_path8 = __toESM(require("path"), 1);
17693
17720
  init_protocol();
17694
17721
  var MAX_FILE_BYTES = 2 * 1024 * 1024;
17695
17722
  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)) {
17723
+ const absCwd = import_node_path8.default.resolve(cwd);
17724
+ const joined = import_node_path8.default.resolve(absCwd, subpath ?? ".");
17725
+ const rel = import_node_path8.default.relative(absCwd, joined);
17726
+ if (rel.startsWith("..") || import_node_path8.default.isAbsolute(rel)) {
17700
17727
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
17701
17728
  }
17702
17729
  return joined;
@@ -17727,7 +17754,7 @@ var WorkspaceBrowser = class {
17727
17754
  mtime: ""
17728
17755
  };
17729
17756
  try {
17730
- const st = import_node_fs8.default.statSync(import_node_path7.default.join(full, d.name));
17757
+ const st = import_node_fs8.default.statSync(import_node_path8.default.join(full, d.name));
17731
17758
  entry.mtime = new Date(st.mtimeMs).toISOString();
17732
17759
  if (d.isFile()) entry.size = st.size;
17733
17760
  } catch {
@@ -17774,25 +17801,21 @@ var WorkspaceBrowser = class {
17774
17801
  // src/skills/scanner.ts
17775
17802
  var import_node_fs9 = __toESM(require("fs"), 1);
17776
17803
  var import_node_os5 = __toESM(require("os"), 1);
17777
- var import_node_path8 = __toESM(require("path"), 1);
17778
-
17779
- // src/skills/frontmatter.ts
17780
- var STRIP_QUOTES = /^["']|["']$/g;
17781
- function strip(s) {
17782
- return s.trim().replace(STRIP_QUOTES, "");
17783
- }
17784
- function parseFrontmatter(content, keys) {
17785
- const out = {};
17786
- if (!content.startsWith("---")) return out;
17804
+ var import_node_path9 = __toESM(require("path"), 1);
17805
+ function parseFrontmatter(content) {
17806
+ if (!content.startsWith("---")) return { name: "", description: "" };
17787
17807
  const end = content.indexOf("---", 3);
17788
- if (end === -1) return out;
17808
+ if (end === -1) return { name: "", description: "" };
17789
17809
  const lines = content.slice(3, end).split("\n");
17810
+ const strip = (s) => s.trim().replace(/^["']|["']$/g, "");
17811
+ let name = "";
17812
+ let description = "";
17790
17813
  for (let i = 0; i < lines.length; i++) {
17791
17814
  const trimmed = lines[i].trim();
17792
- for (const key of keys) {
17793
- const prefix = `${key}:`;
17794
- if (!trimmed.startsWith(prefix)) continue;
17795
- const rest = trimmed.slice(prefix.length).trim();
17815
+ if (trimmed.startsWith("name:")) {
17816
+ name = strip(trimmed.slice(5));
17817
+ } else if (trimmed.startsWith("description:")) {
17818
+ const rest = trimmed.slice(12).trim();
17796
17819
  if (rest === "|" || rest === ">" || rest === "|-" || rest === ">-") {
17797
17820
  const parts = [];
17798
17821
  for (let j = i + 1; j < lines.length; j++) {
@@ -17804,82 +17827,13 @@ function parseFrontmatter(content, keys) {
17804
17827
  if (!/^\s/.test(next)) break;
17805
17828
  parts.push(next.replace(/^\s+/, ""));
17806
17829
  }
17807
- const value = parts.filter(Boolean).join(" ").trim();
17808
- if (value) out[key] = value;
17830
+ description = parts.filter(Boolean).join(" ").trim();
17809
17831
  } else {
17810
- const value = strip(rest);
17811
- if (value) out[key] = value;
17832
+ description = strip(rest);
17812
17833
  }
17813
- break;
17814
17834
  }
17815
17835
  }
17816
- return out;
17817
- }
17818
-
17819
- // src/skills/builtin-cc-resources.ts
17820
- var BUILTIN_SKILLS = [
17821
- { name: "update-config", source: "builtin", description: "Update Claude Code configuration." },
17822
- { name: "keybindings-help", source: "builtin", description: "Show available keybindings." },
17823
- { name: "verify", source: "builtin", description: "Verify the implementation." },
17824
- { name: "debug", source: "builtin", description: "Debug current issue." },
17825
- { name: "lorem-ipsum", source: "builtin", description: "Generate lorem ipsum placeholder text." },
17826
- { name: "skillify", source: "builtin", description: "Convert a process into a reusable skill." },
17827
- { name: "remember", source: "builtin", description: "Remember context for later use." },
17828
- { name: "simplify", source: "builtin", description: "Simplify the code or message." },
17829
- { name: "batch", source: "builtin", description: "Run a batch of similar operations." },
17830
- { name: "stuck", source: "builtin", description: "Help unstick a stalled task." },
17831
- { name: "loop", source: "builtin", description: "Loop a task until a condition is met." },
17832
- { name: "cron-list", source: "builtin", description: "List scheduled cron tasks." },
17833
- { name: "cron-delete", source: "builtin", description: "Delete a scheduled cron task." },
17834
- { name: "dream", source: "builtin", description: "Brainstorm freely without constraints." },
17835
- { name: "hunter", source: "builtin", description: "Hunt down a bug or root cause." },
17836
- { name: "schedule", source: "builtin", description: "Schedule a task to run later." },
17837
- { name: "claude-api", source: "builtin", description: "Use the Claude API directly." },
17838
- { name: "claude-in-chrome", source: "builtin", description: "Drive Claude inside Chrome via the Chrome extension." }
17839
- ];
17840
- var BUILTIN_AGENTS = [
17841
- {
17842
- name: "general-purpose",
17843
- source: "builtin",
17844
- description: "General-purpose agent for researching complex questions and executing multi-step tasks.",
17845
- whenToUse: "When you are searching for a keyword or file and are not confident you will find the right match in the first few tries."
17846
- },
17847
- {
17848
- name: "statusline-setup",
17849
- source: "builtin",
17850
- description: "Configure the user's Claude Code status line setting.",
17851
- whenToUse: "When the user is setting up or changing their status line configuration."
17852
- },
17853
- {
17854
- name: "Explore",
17855
- source: "builtin",
17856
- description: "Explore the codebase to gather context.",
17857
- whenToUse: "Before making changes that require understanding the surrounding code."
17858
- },
17859
- {
17860
- name: "Plan",
17861
- source: "builtin",
17862
- description: "Produce an implementation plan before writing code.",
17863
- whenToUse: "When the task is non-trivial and would benefit from an explicit plan."
17864
- },
17865
- {
17866
- name: "claude-code-guide",
17867
- source: "builtin",
17868
- description: "Guide the user through Claude Code features.",
17869
- whenToUse: "When the user needs help understanding what Claude Code can do."
17870
- },
17871
- {
17872
- name: "verification",
17873
- source: "builtin",
17874
- description: "Verify that a change works as intended.",
17875
- whenToUse: "After implementing a change, before declaring it done."
17876
- }
17877
- ];
17878
-
17879
- // src/skills/scanner.ts
17880
- function parseDescription(content) {
17881
- const fields = parseFrontmatter(content, ["description"]);
17882
- return { description: fields.description ?? "" };
17836
+ return { name, description };
17883
17837
  }
17884
17838
  function isDirLikeSync(p) {
17885
17839
  try {
@@ -17896,19 +17850,19 @@ function scanSkillDir(dir, source, seen, out, pluginName) {
17896
17850
  return;
17897
17851
  }
17898
17852
  for (const ent of entries) {
17899
- const entryPath = import_node_path8.default.join(dir, ent.name);
17853
+ const entryPath = import_node_path9.default.join(dir, ent.name);
17900
17854
  if (!ent.isDirectory() && !(ent.isSymbolicLink() && isDirLikeSync(entryPath))) continue;
17901
17855
  let content;
17902
17856
  try {
17903
- content = import_node_fs9.default.readFileSync(import_node_path8.default.join(entryPath, "SKILL.md"), "utf8");
17857
+ content = import_node_fs9.default.readFileSync(import_node_path9.default.join(entryPath, "SKILL.md"), "utf8");
17904
17858
  } catch {
17905
17859
  try {
17906
- content = import_node_fs9.default.readFileSync(import_node_path8.default.join(entryPath, "skill.md"), "utf8");
17860
+ content = import_node_fs9.default.readFileSync(import_node_path9.default.join(entryPath, "skill.md"), "utf8");
17907
17861
  } catch {
17908
17862
  continue;
17909
17863
  }
17910
17864
  }
17911
- const { description } = parseDescription(content);
17865
+ const { description } = parseFrontmatter(content);
17912
17866
  const baseName = ent.name;
17913
17867
  const name = pluginName ? `${pluginName}:${baseName}` : baseName;
17914
17868
  if (seen.has(name)) continue;
@@ -17926,7 +17880,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
17926
17880
  return;
17927
17881
  }
17928
17882
  for (const ent of entries) {
17929
- const entryPath = import_node_path8.default.join(dir, ent.name);
17883
+ const entryPath = import_node_path9.default.join(dir, ent.name);
17930
17884
  if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync(entryPath)) {
17931
17885
  const ns = ent.name;
17932
17886
  let subEntries;
@@ -17937,7 +17891,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
17937
17891
  }
17938
17892
  for (const se of subEntries) {
17939
17893
  if (!se.name.endsWith(".md")) continue;
17940
- const sePath = import_node_path8.default.join(entryPath, se.name);
17894
+ const sePath = import_node_path9.default.join(entryPath, se.name);
17941
17895
  let content;
17942
17896
  try {
17943
17897
  content = import_node_fs9.default.readFileSync(sePath, "utf8");
@@ -17945,7 +17899,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
17945
17899
  continue;
17946
17900
  }
17947
17901
  const cmd = se.name.replace(/\.md$/, "");
17948
- const { description } = parseDescription(content);
17902
+ const { description } = parseFrontmatter(content);
17949
17903
  const qualified = `${ns}:${cmd}`;
17950
17904
  const name = pluginName ? `${pluginName}:${qualified}` : qualified;
17951
17905
  if (seen.has(name)) continue;
@@ -17962,7 +17916,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
17962
17916
  continue;
17963
17917
  }
17964
17918
  const cmd = ent.name.replace(/\.md$/, "");
17965
- const { description } = parseDescription(content);
17919
+ const { description } = parseFrontmatter(content);
17966
17920
  const name = pluginName ? `${pluginName}:${cmd}` : cmd;
17967
17921
  if (seen.has(name)) continue;
17968
17922
  seen.add(name);
@@ -17973,7 +17927,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
17973
17927
  }
17974
17928
  }
17975
17929
  function readInstalledPlugins(home) {
17976
- const file = import_node_path8.default.join(home, ".claude", "plugins", "installed_plugins.json");
17930
+ const file = import_node_path9.default.join(home, ".claude", "plugins", "installed_plugins.json");
17977
17931
  let raw;
17978
17932
  try {
17979
17933
  raw = import_node_fs9.default.readFileSync(file, "utf8");
@@ -18013,231 +17967,30 @@ var SkillsScanner = class {
18013
17967
  */
18014
17968
  list(args) {
18015
17969
  const seen = /* @__PURE__ */ new Set();
18016
- const builtinBlock = [];
18017
- for (const b of BUILTIN_SKILLS) {
18018
- if (seen.has(b.name)) continue;
18019
- seen.add(b.name);
18020
- builtinBlock.push({
18021
- name: b.name,
18022
- source: "builtin",
18023
- description: b.description
18024
- });
18025
- }
18026
- 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);
17970
+ const out = [];
17971
+ scanSkillDir(import_node_path9.default.join(this.home, ".claude", "skills"), "global", seen, out);
17972
+ scanCommandDir(import_node_path9.default.join(this.home, ".claude", "commands"), "global", seen, out);
17973
+ scanSkillDir(import_node_path9.default.join(args.cwd, ".claude", "skills"), "project", seen, out);
17974
+ scanCommandDir(import_node_path9.default.join(args.cwd, ".claude", "commands"), "project", seen, out);
18031
17975
  const plugins = [...readInstalledPlugins(this.home), ...this.extraPluginRoots];
18032
17976
  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);
17977
+ scanSkillDir(import_node_path9.default.join(root, "skills"), "plugin", seen, out, name);
17978
+ scanCommandDir(import_node_path9.default.join(root, "commands"), "plugin", seen, out, name);
18035
17979
  }
18036
- fsBlock.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
18037
- return [...builtinBlock, ...fsBlock];
17980
+ out.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
17981
+ return out;
18038
17982
  }
18039
17983
  };
18040
17984
 
18041
- // src/skills/agents-scanner.ts
17985
+ // src/observer/session-observer.ts
18042
17986
  var import_node_fs10 = __toESM(require("fs"), 1);
18043
17987
  var import_node_os6 = __toESM(require("os"), 1);
18044
- var import_node_path9 = __toESM(require("path"), 1);
18045
- var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
18046
- function isDirLikeSync2(p) {
18047
- try {
18048
- return import_node_fs10.default.statSync(p).isDirectory();
18049
- } catch {
18050
- return false;
18051
- }
18052
- }
18053
- function fileExistsSync(p) {
18054
- try {
18055
- return import_node_fs10.default.statSync(p).isFile();
18056
- } catch {
18057
- return false;
18058
- }
18059
- }
18060
- function parseAgentFile(filePath) {
18061
- let content;
18062
- try {
18063
- content = import_node_fs10.default.readFileSync(filePath, "utf8");
18064
- } catch {
18065
- return {};
18066
- }
18067
- const fm = parseFrontmatter(content, ["description", "whenToUse"]);
18068
- return {
18069
- description: fm.description,
18070
- whenToUse: fm.whenToUse
18071
- };
18072
- }
18073
- function scanAgentsDir(dir, source, seen, out) {
18074
- let entries;
18075
- try {
18076
- entries = import_node_fs10.default.readdirSync(dir, { withFileTypes: true });
18077
- } catch {
18078
- return;
18079
- }
18080
- for (const ent of entries) {
18081
- if (!ent.name.endsWith(".md")) continue;
18082
- if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path9.default.join(dir, ent.name)))) {
18083
- continue;
18084
- }
18085
- const filePath = import_node_path9.default.join(dir, ent.name);
18086
- const baseName = ent.name.replace(/\.md$/, "");
18087
- if (seen.has(baseName)) continue;
18088
- seen.add(baseName);
18089
- const { description, whenToUse } = parseAgentFile(filePath);
18090
- out.push({
18091
- name: baseName,
18092
- source,
18093
- path: filePath,
18094
- ...description ? { description } : {},
18095
- ...whenToUse ? { whenToUse } : {}
18096
- });
18097
- }
18098
- }
18099
- function scanPluginAgentsTree(root, pluginName, seen, out) {
18100
- function walk(dir, namespaces) {
18101
- let entries;
18102
- try {
18103
- entries = import_node_fs10.default.readdirSync(dir, { withFileTypes: true });
18104
- } catch {
18105
- return;
18106
- }
18107
- for (const ent of entries) {
18108
- const childPath = import_node_path9.default.join(dir, ent.name);
18109
- if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
18110
- walk(childPath, [...namespaces, ent.name]);
18111
- continue;
18112
- }
18113
- if (!ent.name.endsWith(".md")) continue;
18114
- const baseName = ent.name.replace(/\.md$/, "");
18115
- const nameParts = [pluginName, ...namespaces, baseName];
18116
- const name = nameParts.join(":");
18117
- if (seen.has(name)) continue;
18118
- seen.add(name);
18119
- const { description, whenToUse } = parseAgentFile(childPath);
18120
- out.push({
18121
- name,
18122
- source: "plugin",
18123
- path: childPath,
18124
- plugin: pluginName,
18125
- ...description ? { description } : {},
18126
- ...whenToUse ? { whenToUse } : {}
18127
- });
18128
- }
18129
- }
18130
- walk(root, []);
18131
- }
18132
- 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");
18136
- let raw = null;
18137
- for (const candidate of [v2, v1]) {
18138
- try {
18139
- raw = import_node_fs10.default.readFileSync(candidate, "utf8");
18140
- break;
18141
- } catch {
18142
- }
18143
- }
18144
- if (!raw) return [];
18145
- let parsed;
18146
- try {
18147
- parsed = JSON.parse(raw);
18148
- } catch {
18149
- return [];
18150
- }
18151
- const out = [];
18152
- for (const [key, entries] of Object.entries(parsed.plugins ?? {})) {
18153
- if (!Array.isArray(entries) || entries.length === 0) continue;
18154
- const entry = entries[0];
18155
- if (!entry?.installPath) continue;
18156
- if (entry.enabled === false) continue;
18157
- const pluginName = key.includes("@") ? key.slice(0, key.indexOf("@")) : key;
18158
- if (!pluginName) continue;
18159
- out.push({ name: pluginName, root: entry.installPath });
18160
- }
18161
- return out;
18162
- }
18163
- 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;
18166
- while (true) {
18167
- scanAgentsDir(import_node_path9.default.join(cur, ".claude", "agents"), "project", seen, out);
18168
- let hasGit = false;
18169
- try {
18170
- hasGit = import_node_fs10.default.existsSync(import_node_path9.default.join(cur, ".git"));
18171
- } catch {
18172
- }
18173
- if (hasGit) return;
18174
- if (cur === home) return;
18175
- if (cur === fsRoot) return;
18176
- const parent = import_node_path9.default.dirname(cur);
18177
- if (parent === cur) return;
18178
- cur = parent;
18179
- }
18180
- }
18181
- var AgentsScanner = class {
18182
- home;
18183
- extraPluginRoots;
18184
- policyDir;
18185
- constructor(opts = {}) {
18186
- this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os6.default.homedir();
18187
- this.extraPluginRoots = opts.extraPluginRoots ?? [];
18188
- if (opts.policyDir !== void 0) {
18189
- this.policyDir = opts.policyDir;
18190
- } else if (process.platform === "darwin") {
18191
- this.policyDir = DEFAULT_POLICY_DIR_DARWIN;
18192
- } else {
18193
- this.policyDir = null;
18194
- }
18195
- }
18196
- list(args) {
18197
- const seen = /* @__PURE__ */ new Set();
18198
- const builtinBlock = [];
18199
- for (const b of BUILTIN_AGENTS) {
18200
- if (seen.has(b.name)) continue;
18201
- seen.add(b.name);
18202
- builtinBlock.push({
18203
- name: b.name,
18204
- source: "builtin",
18205
- ...b.description ? { description: b.description } : {},
18206
- ...b.whenToUse ? { whenToUse: b.whenToUse } : {}
18207
- });
18208
- }
18209
- const fsBlock = [];
18210
- scanAgentsDir(
18211
- import_node_path9.default.join(this.home, ".claude", "agents"),
18212
- "global",
18213
- seen,
18214
- fsBlock
18215
- );
18216
- walkUpProjectAgentsDirs(args.cwd, this.home, seen, fsBlock);
18217
- if (this.policyDir) {
18218
- scanAgentsDir(this.policyDir, "policy", seen, fsBlock);
18219
- }
18220
- const plugins = [
18221
- ...readInstalledPlugins2(this.home),
18222
- ...this.extraPluginRoots
18223
- ];
18224
- for (const { name, root } of plugins) {
18225
- const agentsRoot = import_node_path9.default.join(root, "agents");
18226
- scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
18227
- }
18228
- return [...builtinBlock, ...fsBlock];
18229
- }
18230
- };
18231
-
18232
- // src/observer/session-observer.ts
18233
- var import_node_fs11 = __toESM(require("fs"), 1);
18234
- var import_node_os7 = __toESM(require("os"), 1);
18235
17988
  var import_node_path10 = __toESM(require("path"), 1);
18236
17989
  init_claude_history();
18237
17990
  var SessionObserver = class {
18238
17991
  constructor(opts) {
18239
17992
  this.opts = opts;
18240
- this.home = opts.home ?? import_node_os7.default.homedir();
17993
+ this.home = opts.home ?? import_node_os6.default.homedir();
18241
17994
  }
18242
17995
  opts;
18243
17996
  home;
@@ -18251,7 +18004,7 @@ var SessionObserver = class {
18251
18004
  const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
18252
18005
  let size = 0;
18253
18006
  try {
18254
- size = import_node_fs11.default.statSync(filePath).size;
18007
+ size = import_node_fs10.default.statSync(filePath).size;
18255
18008
  } catch {
18256
18009
  }
18257
18010
  const w = {
@@ -18264,10 +18017,10 @@ var SessionObserver = class {
18264
18017
  adapter: args.adapter
18265
18018
  };
18266
18019
  try {
18267
- import_node_fs11.default.mkdirSync(import_node_path10.default.dirname(filePath), { recursive: true });
18020
+ import_node_fs10.default.mkdirSync(import_node_path10.default.dirname(filePath), { recursive: true });
18268
18021
  } catch {
18269
18022
  }
18270
- w.watcher = import_node_fs11.default.watch(import_node_path10.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
18023
+ w.watcher = import_node_fs10.default.watch(import_node_path10.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
18271
18024
  if (!changedName || !filePath.endsWith(changedName)) return;
18272
18025
  this.poll(w);
18273
18026
  });
@@ -18282,7 +18035,7 @@ var SessionObserver = class {
18282
18035
  // reducer.shallowEqMeta diff 让重复 patch 静默吞掉;异常静默吞,不阻塞 watcher 启动
18283
18036
  hydrateMetaTail(w, maxLines = 200) {
18284
18037
  try {
18285
- const raw = import_node_fs11.default.readFileSync(w.filePath, "utf8");
18038
+ const raw = import_node_fs10.default.readFileSync(w.filePath, "utf8");
18286
18039
  if (!raw) return;
18287
18040
  const allLines = raw.split("\n").filter((l) => l.trim().length > 0);
18288
18041
  if (allLines.length === 0) return;
@@ -18303,7 +18056,7 @@ var SessionObserver = class {
18303
18056
  poll(w) {
18304
18057
  let size = 0;
18305
18058
  try {
18306
- size = import_node_fs11.default.statSync(w.filePath).size;
18059
+ size = import_node_fs10.default.statSync(w.filePath).size;
18307
18060
  } catch {
18308
18061
  return;
18309
18062
  }
@@ -18312,11 +18065,11 @@ var SessionObserver = class {
18312
18065
  w.buf = "";
18313
18066
  }
18314
18067
  if (size === w.lastSize) return;
18315
- const fd = import_node_fs11.default.openSync(w.filePath, "r");
18068
+ const fd = import_node_fs10.default.openSync(w.filePath, "r");
18316
18069
  try {
18317
18070
  const len = size - w.lastSize;
18318
18071
  const buf = Buffer.alloc(len);
18319
- import_node_fs11.default.readSync(fd, buf, 0, len, w.lastSize);
18072
+ import_node_fs10.default.readSync(fd, buf, 0, len, w.lastSize);
18320
18073
  w.lastSize = size;
18321
18074
  w.buf += buf.toString("utf8");
18322
18075
  let newlineIndex;
@@ -18330,7 +18083,7 @@ var SessionObserver = class {
18330
18083
  this.maybeReportUserMessage(w.sessionId, line);
18331
18084
  }
18332
18085
  } finally {
18333
- import_node_fs11.default.closeSync(fd);
18086
+ import_node_fs10.default.closeSync(fd);
18334
18087
  }
18335
18088
  }
18336
18089
  // 解析 JSONL 单行:仅当是主链 user 文本行(非 sidechain / 非 sub-agent / message.role='user'
@@ -18982,7 +18735,7 @@ function isLocalhost(addr) {
18982
18735
  }
18983
18736
 
18984
18737
  // src/discovery/state-file.ts
18985
- var import_node_fs12 = __toESM(require("fs"), 1);
18738
+ var import_node_fs11 = __toESM(require("fs"), 1);
18986
18739
  var import_node_path11 = __toESM(require("path"), 1);
18987
18740
  function defaultStateFilePath(dataDir) {
18988
18741
  return import_node_path11.default.join(dataDir, "state.json");
@@ -19007,7 +18760,7 @@ var StateFileManager = class {
19007
18760
  }
19008
18761
  read() {
19009
18762
  try {
19010
- const raw = import_node_fs12.default.readFileSync(this.file, "utf8");
18763
+ const raw = import_node_fs11.default.readFileSync(this.file, "utf8");
19011
18764
  const parsed = JSON.parse(raw);
19012
18765
  return parsed;
19013
18766
  } catch {
@@ -19021,33 +18774,33 @@ var StateFileManager = class {
19021
18774
  return { status: "stale", existing };
19022
18775
  }
19023
18776
  write(state) {
19024
- import_node_fs12.default.mkdirSync(import_node_path11.default.dirname(this.file), { recursive: true });
18777
+ import_node_fs11.default.mkdirSync(import_node_path11.default.dirname(this.file), { recursive: true });
19025
18778
  const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
19026
- import_node_fs12.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
19027
- import_node_fs12.default.renameSync(tmp, this.file);
18779
+ import_node_fs11.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
18780
+ import_node_fs11.default.renameSync(tmp, this.file);
19028
18781
  if (process.platform !== "win32") {
19029
18782
  try {
19030
- import_node_fs12.default.chmodSync(this.file, 384);
18783
+ import_node_fs11.default.chmodSync(this.file, 384);
19031
18784
  } catch {
19032
18785
  }
19033
18786
  }
19034
18787
  }
19035
18788
  delete() {
19036
18789
  try {
19037
- import_node_fs12.default.unlinkSync(this.file);
18790
+ import_node_fs11.default.unlinkSync(this.file);
19038
18791
  } catch {
19039
18792
  }
19040
18793
  }
19041
18794
  };
19042
18795
 
19043
18796
  // src/tunnel/tunnel-manager.ts
19044
- var import_node_fs15 = __toESM(require("fs"), 1);
18797
+ var import_node_fs14 = __toESM(require("fs"), 1);
19045
18798
  var import_node_path14 = __toESM(require("path"), 1);
19046
18799
  var import_node_crypto4 = __toESM(require("crypto"), 1);
19047
18800
  var import_node_child_process4 = require("child_process");
19048
18801
 
19049
18802
  // src/tunnel/tunnel-store.ts
19050
- var import_node_fs13 = __toESM(require("fs"), 1);
18803
+ var import_node_fs12 = __toESM(require("fs"), 1);
19051
18804
  var import_node_path12 = __toESM(require("path"), 1);
19052
18805
  var TunnelStore = class {
19053
18806
  constructor(filePath) {
@@ -19056,7 +18809,7 @@ var TunnelStore = class {
19056
18809
  filePath;
19057
18810
  async get() {
19058
18811
  try {
19059
- const raw = await import_node_fs13.default.promises.readFile(this.filePath, "utf8");
18812
+ const raw = await import_node_fs12.default.promises.readFile(this.filePath, "utf8");
19060
18813
  const obj = JSON.parse(raw);
19061
18814
  if (!isPersistedTunnel(obj)) return null;
19062
18815
  return obj;
@@ -19068,21 +18821,21 @@ var TunnelStore = class {
19068
18821
  }
19069
18822
  async set(v) {
19070
18823
  const dir = import_node_path12.default.dirname(this.filePath);
19071
- await import_node_fs13.default.promises.mkdir(dir, { recursive: true });
18824
+ await import_node_fs12.default.promises.mkdir(dir, { recursive: true });
19072
18825
  const data = JSON.stringify(v, null, 2);
19073
18826
  const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
19074
- await import_node_fs13.default.promises.writeFile(tmp, data, { mode: 384 });
18827
+ await import_node_fs12.default.promises.writeFile(tmp, data, { mode: 384 });
19075
18828
  if (process.platform !== "win32") {
19076
18829
  try {
19077
- await import_node_fs13.default.promises.chmod(tmp, 384);
18830
+ await import_node_fs12.default.promises.chmod(tmp, 384);
19078
18831
  } catch {
19079
18832
  }
19080
18833
  }
19081
- await import_node_fs13.default.promises.rename(tmp, this.filePath);
18834
+ await import_node_fs12.default.promises.rename(tmp, this.filePath);
19082
18835
  }
19083
18836
  async clear() {
19084
18837
  try {
19085
- await import_node_fs13.default.promises.unlink(this.filePath);
18838
+ await import_node_fs12.default.promises.unlink(this.filePath);
19086
18839
  } catch (err) {
19087
18840
  const code = err?.code;
19088
18841
  if (code !== "ENOENT") throw err;
@@ -19177,8 +18930,8 @@ function escape(v) {
19177
18930
  }
19178
18931
 
19179
18932
  // src/tunnel/frpc-binary.ts
19180
- var import_node_fs14 = __toESM(require("fs"), 1);
19181
- var import_node_os8 = __toESM(require("os"), 1);
18933
+ var import_node_fs13 = __toESM(require("fs"), 1);
18934
+ var import_node_os7 = __toESM(require("os"), 1);
19182
18935
  var import_node_path13 = __toESM(require("path"), 1);
19183
18936
  var import_node_child_process3 = require("child_process");
19184
18937
  var import_node_stream = require("stream");
@@ -19211,7 +18964,7 @@ function frpcDownloadUrl(version2, p) {
19211
18964
  }
19212
18965
  async function ensureFrpcBinary(opts) {
19213
18966
  if (opts.override) {
19214
- if (!import_node_fs14.default.existsSync(opts.override)) {
18967
+ if (!import_node_fs13.default.existsSync(opts.override)) {
19215
18968
  throw new Error(`frpc binary not found at override path: ${opts.override}`);
19216
18969
  }
19217
18970
  return opts.override;
@@ -19219,10 +18972,10 @@ async function ensureFrpcBinary(opts) {
19219
18972
  const version2 = opts.version ?? FRPC_VERSION;
19220
18973
  const platform = opts.platform ?? detectPlatform();
19221
18974
  const binDir = import_node_path13.default.join(opts.dataDir, "bin");
19222
- import_node_fs14.default.mkdirSync(binDir, { recursive: true });
18975
+ import_node_fs13.default.mkdirSync(binDir, { recursive: true });
19223
18976
  cleanupStaleArtifacts(binDir);
19224
18977
  const stableBin = import_node_path13.default.join(binDir, "frpc");
19225
- if (import_node_fs14.default.existsSync(stableBin)) return stableBin;
18978
+ if (import_node_fs13.default.existsSync(stableBin)) return stableBin;
19226
18979
  const partialBin = `${stableBin}.partial`;
19227
18980
  const tarballPath = import_node_path13.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
19228
18981
  try {
@@ -19233,8 +18986,8 @@ async function ensureFrpcBinary(opts) {
19233
18986
  } else {
19234
18987
  await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
19235
18988
  }
19236
- import_node_fs14.default.chmodSync(partialBin, 493);
19237
- import_node_fs14.default.renameSync(partialBin, stableBin);
18989
+ import_node_fs13.default.chmodSync(partialBin, 493);
18990
+ import_node_fs13.default.renameSync(partialBin, stableBin);
19238
18991
  } finally {
19239
18992
  safeUnlink(tarballPath);
19240
18993
  safeUnlink(partialBin);
@@ -19244,7 +18997,7 @@ async function ensureFrpcBinary(opts) {
19244
18997
  function cleanupStaleArtifacts(binDir) {
19245
18998
  let entries;
19246
18999
  try {
19247
- entries = import_node_fs14.default.readdirSync(binDir);
19000
+ entries = import_node_fs13.default.readdirSync(binDir);
19248
19001
  } catch {
19249
19002
  return;
19250
19003
  }
@@ -19252,7 +19005,7 @@ function cleanupStaleArtifacts(binDir) {
19252
19005
  if (name.endsWith(".partial") || name.startsWith("extract-")) {
19253
19006
  const full = import_node_path13.default.join(binDir, name);
19254
19007
  try {
19255
- import_node_fs14.default.rmSync(full, { recursive: true, force: true });
19008
+ import_node_fs13.default.rmSync(full, { recursive: true, force: true });
19256
19009
  } catch {
19257
19010
  }
19258
19011
  }
@@ -19260,7 +19013,7 @@ function cleanupStaleArtifacts(binDir) {
19260
19013
  }
19261
19014
  function safeUnlink(p) {
19262
19015
  try {
19263
- import_node_fs14.default.unlinkSync(p);
19016
+ import_node_fs13.default.unlinkSync(p);
19264
19017
  } catch {
19265
19018
  }
19266
19019
  }
@@ -19271,13 +19024,13 @@ async function downloadToFile(url, dest, fetchImpl) {
19271
19024
  if (!res.ok || !res.body) {
19272
19025
  throw new Error(`download failed: ${res.status} ${res.statusText}`);
19273
19026
  }
19274
- const out = import_node_fs14.default.createWriteStream(dest);
19027
+ const out = import_node_fs13.default.createWriteStream(dest);
19275
19028
  const nodeStream = import_node_stream.Readable.fromWeb(res.body);
19276
19029
  await (0, import_promises.pipeline)(nodeStream, out);
19277
19030
  }
19278
19031
  async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
19279
19032
  const work = import_node_path13.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
19280
- import_node_fs14.default.mkdirSync(work, { recursive: true });
19033
+ import_node_fs13.default.mkdirSync(work, { recursive: true });
19281
19034
  try {
19282
19035
  await new Promise((resolve, reject) => {
19283
19036
  const proc = (0, import_node_child_process3.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
@@ -19286,12 +19039,12 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
19286
19039
  });
19287
19040
  const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
19288
19041
  const src = import_node_path13.default.join(work, dirName, "frpc");
19289
- if (!import_node_fs14.default.existsSync(src)) {
19042
+ if (!import_node_fs13.default.existsSync(src)) {
19290
19043
  throw new Error(`frpc not found inside tarball at ${src}`);
19291
19044
  }
19292
- import_node_fs14.default.copyFileSync(src, destBin);
19045
+ import_node_fs13.default.copyFileSync(src, destBin);
19293
19046
  } finally {
19294
- import_node_fs14.default.rmSync(work, { recursive: true, force: true });
19047
+ import_node_fs13.default.rmSync(work, { recursive: true, force: true });
19295
19048
  }
19296
19049
  }
19297
19050
 
@@ -19428,12 +19181,12 @@ var TunnelManager = class {
19428
19181
  localPort,
19429
19182
  logLevel: "info"
19430
19183
  });
19431
- await import_node_fs15.default.promises.writeFile(tomlPath, toml, { mode: 384 });
19184
+ await import_node_fs14.default.promises.writeFile(tomlPath, toml, { mode: 384 });
19432
19185
  const proc = (this.deps.spawnImpl ?? import_node_child_process4.spawn)(frpcBin, ["-c", tomlPath], {
19433
19186
  stdio: ["ignore", "pipe", "pipe"]
19434
19187
  });
19435
19188
  const logFilePath = import_node_path14.default.join(this.deps.dataDir, "frpc.log");
19436
- const logStream = import_node_fs15.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
19189
+ const logStream = import_node_fs14.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
19437
19190
  logStream.on("error", () => {
19438
19191
  });
19439
19192
  const tee = (chunk) => {
@@ -19514,18 +19267,18 @@ async function waitForFrpcReady(proc, timeoutMs) {
19514
19267
  }
19515
19268
 
19516
19269
  // src/tunnel/device-key.ts
19517
- var import_node_os9 = __toESM(require("os"), 1);
19270
+ var import_node_os8 = __toESM(require("os"), 1);
19518
19271
  var import_node_crypto5 = __toESM(require("crypto"), 1);
19519
19272
  var DERIVE_SALT = "clawd-tunnel-device-v1";
19520
19273
  function deriveStableDeviceKey(opts = {}) {
19521
- const hostname = opts.hostname ?? import_node_os9.default.hostname();
19522
- const uid = opts.uid ?? (typeof import_node_os9.default.userInfo === "function" ? import_node_os9.default.userInfo().uid : 0);
19274
+ const hostname = opts.hostname ?? import_node_os8.default.hostname();
19275
+ const uid = opts.uid ?? (typeof import_node_os8.default.userInfo === "function" ? import_node_os8.default.userInfo().uid : 0);
19523
19276
  const input = `${hostname}::${uid}`;
19524
19277
  return import_node_crypto5.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
19525
19278
  }
19526
19279
 
19527
19280
  // src/auth-store.ts
19528
- var import_node_fs16 = __toESM(require("fs"), 1);
19281
+ var import_node_fs15 = __toESM(require("fs"), 1);
19529
19282
  var import_node_path15 = __toESM(require("path"), 1);
19530
19283
  var import_node_crypto6 = __toESM(require("crypto"), 1);
19531
19284
  var AUTH_FILE_NAME = "auth.json";
@@ -19546,7 +19299,7 @@ function defaultGenerate() {
19546
19299
  }
19547
19300
  function readAuthFile(file) {
19548
19301
  try {
19549
- const raw = import_node_fs16.default.readFileSync(file, "utf8");
19302
+ const raw = import_node_fs15.default.readFileSync(file, "utf8");
19550
19303
  const parsed = JSON.parse(raw);
19551
19304
  if (typeof parsed?.token === "string" && parsed.token.length > 0) {
19552
19305
  return {
@@ -19562,10 +19315,10 @@ function readAuthFile(file) {
19562
19315
  }
19563
19316
  }
19564
19317
  function writeAuthFile(file, content) {
19565
- import_node_fs16.default.mkdirSync(import_node_path15.default.dirname(file), { recursive: true });
19566
- import_node_fs16.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
19318
+ import_node_fs15.default.mkdirSync(import_node_path15.default.dirname(file), { recursive: true });
19319
+ import_node_fs15.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
19567
19320
  try {
19568
- import_node_fs16.default.chmodSync(file, 384);
19321
+ import_node_fs15.default.chmodSync(file, 384);
19569
19322
  } catch {
19570
19323
  }
19571
19324
  }
@@ -19577,12 +19330,12 @@ init_protocol();
19577
19330
  init_protocol();
19578
19331
 
19579
19332
  // src/session/fork.ts
19580
- var import_node_fs17 = __toESM(require("fs"), 1);
19581
- var import_node_os10 = __toESM(require("os"), 1);
19333
+ var import_node_fs16 = __toESM(require("fs"), 1);
19334
+ var import_node_os9 = __toESM(require("os"), 1);
19582
19335
  var import_node_path16 = __toESM(require("path"), 1);
19583
19336
  init_claude_history();
19584
19337
  function readJsonlEntries(file) {
19585
- const raw = import_node_fs17.default.readFileSync(file, "utf8");
19338
+ const raw = import_node_fs16.default.readFileSync(file, "utf8");
19586
19339
  const out = [];
19587
19340
  for (const line of raw.split("\n")) {
19588
19341
  const t = line.trim();
@@ -19595,10 +19348,10 @@ function readJsonlEntries(file) {
19595
19348
  return out;
19596
19349
  }
19597
19350
  function forkSession(input) {
19598
- const baseDir = input.baseDir ?? import_node_path16.default.join(import_node_os10.default.homedir(), ".claude");
19351
+ const baseDir = input.baseDir ?? import_node_path16.default.join(import_node_os9.default.homedir(), ".claude");
19599
19352
  const projectDir = import_node_path16.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
19600
19353
  const sourceFile = import_node_path16.default.join(projectDir, `${input.toolSessionId}.jsonl`);
19601
- if (!import_node_fs17.default.existsSync(sourceFile)) {
19354
+ if (!import_node_fs16.default.existsSync(sourceFile)) {
19602
19355
  throw new Error(`fork: source transcript not found: ${sourceFile}`);
19603
19356
  }
19604
19357
  const entries = readJsonlEntries(sourceFile);
@@ -19629,8 +19382,8 @@ function forkSession(input) {
19629
19382
  forkedLines.push(JSON.stringify(forked));
19630
19383
  }
19631
19384
  const forkedFilePath = import_node_path16.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
19632
- import_node_fs17.default.mkdirSync(projectDir, { recursive: true });
19633
- import_node_fs17.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
19385
+ import_node_fs16.default.mkdirSync(projectDir, { recursive: true });
19386
+ import_node_fs16.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
19634
19387
  return { forkedToolSessionId, forkedFilePath };
19635
19388
  }
19636
19389
 
@@ -19639,6 +19392,12 @@ function buildSessionHandlers(deps) {
19639
19392
  const { manager, observer, getAdapter: getAdapter2 } = deps;
19640
19393
  const create = async (frame) => {
19641
19394
  const args = SessionCreateArgs.parse(frame);
19395
+ if (args.ownerPersonaId) {
19396
+ const persona = deps.personaRegistry.get(args.ownerPersonaId);
19397
+ if (!persona) {
19398
+ throw new Error(`persona not found: ${args.ownerPersonaId}`);
19399
+ }
19400
+ }
19642
19401
  const { response, broadcast } = manager.create(args);
19643
19402
  return { response: { type: "session:info", ...response }, broadcast };
19644
19403
  };
@@ -19872,7 +19631,7 @@ function buildHistoryHandlers(deps) {
19872
19631
  // src/handlers/workspace.ts
19873
19632
  init_protocol();
19874
19633
  function buildWorkspaceHandlers(deps) {
19875
- const { workspace, skills, agents } = deps;
19634
+ const { workspace, skills } = deps;
19876
19635
  const list = async (frame) => {
19877
19636
  const args = WorkspaceListArgs.parse(frame);
19878
19637
  const res = workspace.list(args);
@@ -19888,16 +19647,10 @@ function buildWorkspaceHandlers(deps) {
19888
19647
  const list2 = skills.list(args);
19889
19648
  return { response: { type: "skills:list", skills: list2 } };
19890
19649
  };
19891
- const agentsList = async (frame) => {
19892
- const args = AgentsListArgs.parse(frame);
19893
- const list2 = agents.list(args);
19894
- return { response: { type: "agents:list", agents: list2 } };
19895
- };
19896
19650
  return {
19897
19651
  "workspace:list": list,
19898
19652
  "workspace:read": read,
19899
- "skills:list": skillsList,
19900
- "agents:list": agentsList
19653
+ "skills:list": skillsList
19901
19654
  };
19902
19655
  }
19903
19656
 
@@ -19906,8 +19659,8 @@ init_protocol();
19906
19659
 
19907
19660
  // src/workspace/git.ts
19908
19661
  var import_node_child_process5 = require("child_process");
19909
- var import_node_fs18 = __toESM(require("fs"), 1);
19910
- var import_node_os11 = __toESM(require("os"), 1);
19662
+ var import_node_fs17 = __toESM(require("fs"), 1);
19663
+ var import_node_os10 = __toESM(require("os"), 1);
19911
19664
  var import_node_path17 = __toESM(require("path"), 1);
19912
19665
  var import_node_util = require("util");
19913
19666
  var pexec = (0, import_node_util.promisify)(import_node_child_process5.execFile);
@@ -19925,7 +19678,7 @@ function formatChildProcessError(err) {
19925
19678
  function normalizePath(p) {
19926
19679
  const resolved = import_node_path17.default.resolve(p);
19927
19680
  try {
19928
- return import_node_fs18.default.realpathSync(resolved);
19681
+ return import_node_fs17.default.realpathSync(resolved);
19929
19682
  } catch {
19930
19683
  return resolved;
19931
19684
  }
@@ -20012,7 +19765,7 @@ function sanitizeLabel(raw) {
20012
19765
  function computePrefix() {
20013
19766
  let username;
20014
19767
  try {
20015
- username = import_node_os11.default.userInfo().username;
19768
+ username = import_node_os10.default.userInfo().username;
20016
19769
  } catch {
20017
19770
  username = void 0;
20018
19771
  }
@@ -20028,10 +19781,10 @@ function encodeClaudeProjectDir(absPath) {
20028
19781
  if (!absPath || typeof absPath !== "string") return "";
20029
19782
  let canonical = import_node_path17.default.resolve(absPath);
20030
19783
  try {
20031
- canonical = import_node_fs18.default.realpathSync(canonical);
19784
+ canonical = import_node_fs17.default.realpathSync(canonical);
20032
19785
  } catch {
20033
19786
  try {
20034
- const parent = import_node_fs18.default.realpathSync(import_node_path17.default.dirname(canonical));
19787
+ const parent = import_node_fs17.default.realpathSync(import_node_path17.default.dirname(canonical));
20035
19788
  canonical = import_node_path17.default.join(parent, import_node_path17.default.basename(canonical));
20036
19789
  } catch {
20037
19790
  }
@@ -20062,11 +19815,13 @@ async function createWorktree(input) {
20062
19815
  }
20063
19816
  const worktreeRoot = import_node_path17.default.join(parent, dirName);
20064
19817
  try {
20065
- await pexec("git", ["-C", cwd, "rev-parse", "--verify", `refs/heads/${baseBranch}`], {
20066
- timeout: 3e3
19818
+ await pexec("git", ["-C", cwd, "fetch", "origin", baseBranch, "--no-tags"], {
19819
+ timeout: 3e4
20067
19820
  });
20068
- } catch {
20069
- throw new Error(`\u57FA\u51C6\u5206\u652F ${baseBranch} \u4E0D\u5B58\u5728`);
19821
+ } catch (err) {
19822
+ throw new Error(
19823
+ `\u57FA\u51C6\u5206\u652F ${baseBranch} \u4E0D\u5B58\u5728\u6216 fetch \u8FDC\u7AEF\u5931\u8D25\uFF1A${formatChildProcessError(err)}`
19824
+ );
20070
19825
  }
20071
19826
  try {
20072
19827
  await pexec("git", ["-C", cwd, "rev-parse", "--verify", `refs/heads/${branch}`], {
@@ -20077,13 +19832,13 @@ async function createWorktree(input) {
20077
19832
  const msg = err.message;
20078
19833
  if (msg.startsWith("\u5206\u652F ")) throw err;
20079
19834
  }
20080
- if (import_node_fs18.default.existsSync(worktreeRoot)) {
19835
+ if (import_node_fs17.default.existsSync(worktreeRoot)) {
20081
19836
  throw new Error(`\u76EE\u5F55 ${worktreeRoot} \u5DF2\u5B58\u5728\uFF0C\u8BF7\u6362\u4E00\u4E2A label \u6216\u6E05\u7406\u540E\u91CD\u8BD5`);
20082
19837
  }
20083
19838
  try {
20084
19839
  await pexec(
20085
19840
  "git",
20086
- ["-C", cwd, "worktree", "add", worktreeRoot, "-b", branch, baseBranch],
19841
+ ["-C", cwd, "worktree", "add", worktreeRoot, "-b", branch, `origin/${baseBranch}`],
20087
19842
  { timeout: 15e3 }
20088
19843
  );
20089
19844
  } catch (err) {
@@ -20118,7 +19873,7 @@ async function removeWorktree(input) {
20118
19873
  } catch (err) {
20119
19874
  const stderr = err.stderr ?? "";
20120
19875
  const lower = stderr.toLowerCase();
20121
- const vanished = lower.includes("not a working tree") || lower.includes("is not a working tree") || !import_node_fs18.default.existsSync(worktreeRoot);
19876
+ const vanished = lower.includes("not a working tree") || lower.includes("is not a working tree") || !import_node_fs17.default.existsSync(worktreeRoot);
20122
19877
  if (!vanished) {
20123
19878
  throw new Error(`\u6E05\u7406 worktree \u5931\u8D25\uFF1A${formatChildProcessError(err)}`);
20124
19879
  }
@@ -20137,10 +19892,10 @@ async function removeWorktree(input) {
20137
19892
  try {
20138
19893
  const encoded = encodeClaudeProjectDir(worktreeRoot);
20139
19894
  if (encoded) {
20140
- const projectsRoot = import_node_path17.default.join(import_node_os11.default.homedir(), ".claude", "projects");
19895
+ const projectsRoot = import_node_path17.default.join(import_node_os10.default.homedir(), ".claude", "projects");
20141
19896
  const target = import_node_path17.default.resolve(projectsRoot, encoded);
20142
19897
  if (target.startsWith(projectsRoot + import_node_path17.default.sep) && target !== projectsRoot) {
20143
- import_node_fs18.default.rmSync(target, { recursive: true, force: true });
19898
+ import_node_fs17.default.rmSync(target, { recursive: true, force: true });
20144
19899
  }
20145
19900
  }
20146
19901
  } catch {
@@ -20212,7 +19967,7 @@ function buildCapabilitiesHandlers(deps) {
20212
19967
  }
20213
19968
 
20214
19969
  // src/handlers/meta.ts
20215
- var import_node_os12 = __toESM(require("os"), 1);
19970
+ var import_node_os11 = __toESM(require("os"), 1);
20216
19971
  init_protocol();
20217
19972
 
20218
19973
  // src/version.ts
@@ -20234,7 +19989,7 @@ function buildReadyFrame(deps) {
20234
19989
  return {
20235
19990
  version,
20236
19991
  protocolVersion: PROTOCOL_VERSION,
20237
- hostname: import_node_os12.default.hostname(),
19992
+ hostname: import_node_os11.default.hostname(),
20238
19993
  os: process.platform,
20239
19994
  tools,
20240
19995
  runningSessions: info.runningSessions,
@@ -20385,7 +20140,6 @@ async function startDaemon(config) {
20385
20140
  const store = new SessionStore({ dataDir: config.dataDir });
20386
20141
  const workspace = new WorkspaceBrowser();
20387
20142
  const skills = new SkillsScanner();
20388
- const agents = new AgentsScanner();
20389
20143
  const history = new ClaudeHistoryReader();
20390
20144
  let transport = null;
20391
20145
  const manager = new SessionManager({
@@ -20446,7 +20200,6 @@ async function startDaemon(config) {
20446
20200
  manager,
20447
20201
  workspace,
20448
20202
  skills,
20449
- agents,
20450
20203
  history,
20451
20204
  observer,
20452
20205
  getAdapter,
@@ -20582,7 +20335,7 @@ ${bar}
20582
20335
  `);
20583
20336
  try {
20584
20337
  const connectPath = import_node_path18.default.join(config.dataDir, "connect.txt");
20585
- import_node_fs19.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
20338
+ import_node_fs18.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
20586
20339
  } catch {
20587
20340
  }
20588
20341
  } catch (err) {