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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.cjs +549 -228
  2. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -296,8 +296,8 @@ var require_req = __commonJS({
296
296
  if (req.originalUrl) {
297
297
  _req.url = req.originalUrl;
298
298
  } else {
299
- const path22 = req.path;
300
- _req.url = typeof path22 === "string" ? path22 : req.url ? req.url.path || req.url : void 0;
299
+ const path23 = req.path;
300
+ _req.url = typeof path23 === "string" ? path23 : req.url ? req.url.path || req.url : void 0;
301
301
  }
302
302
  if (req.query) {
303
303
  _req.query = req.query;
@@ -462,14 +462,14 @@ var require_redact = __commonJS({
462
462
  }
463
463
  return obj;
464
464
  }
465
- function parsePath(path22) {
465
+ function parsePath(path23) {
466
466
  const parts = [];
467
467
  let current = "";
468
468
  let inBrackets = false;
469
469
  let inQuotes = false;
470
470
  let quoteChar = "";
471
- for (let i = 0; i < path22.length; i++) {
472
- const char = path22[i];
471
+ for (let i = 0; i < path23.length; i++) {
472
+ const char = path23[i];
473
473
  if (!inBrackets && char === ".") {
474
474
  if (current) {
475
475
  parts.push(current);
@@ -600,10 +600,10 @@ var require_redact = __commonJS({
600
600
  return current;
601
601
  }
602
602
  function redactPaths(obj, paths, censor, remove = false) {
603
- for (const path22 of paths) {
604
- const parts = parsePath(path22);
603
+ for (const path23 of paths) {
604
+ const parts = parsePath(path23);
605
605
  if (parts.includes("*")) {
606
- redactWildcardPath(obj, parts, censor, path22, remove);
606
+ redactWildcardPath(obj, parts, censor, path23, remove);
607
607
  } else {
608
608
  if (remove) {
609
609
  removeKey(obj, parts);
@@ -688,8 +688,8 @@ var require_redact = __commonJS({
688
688
  }
689
689
  } else {
690
690
  if (afterWildcard.includes("*")) {
691
- const wrappedCensor = typeof censor === "function" ? (value, path22) => {
692
- const fullPath = [...pathArray.slice(0, pathLength), ...path22];
691
+ const wrappedCensor = typeof censor === "function" ? (value, path23) => {
692
+ const fullPath = [...pathArray.slice(0, pathLength), ...path23];
693
693
  return censor(value, fullPath);
694
694
  } : censor;
695
695
  redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
@@ -724,8 +724,8 @@ var require_redact = __commonJS({
724
724
  return null;
725
725
  }
726
726
  const pathStructure = /* @__PURE__ */ new Map();
727
- for (const path22 of pathsToClone) {
728
- const parts = parsePath(path22);
727
+ for (const path23 of pathsToClone) {
728
+ const parts = parsePath(path23);
729
729
  let current = pathStructure;
730
730
  for (let i = 0; i < parts.length; i++) {
731
731
  const part = parts[i];
@@ -777,24 +777,24 @@ var require_redact = __commonJS({
777
777
  }
778
778
  return cloneSelectively(obj, pathStructure);
779
779
  }
780
- function validatePath(path22) {
781
- if (typeof path22 !== "string") {
780
+ function validatePath(path23) {
781
+ if (typeof path23 !== "string") {
782
782
  throw new Error("Paths must be (non-empty) strings");
783
783
  }
784
- if (path22 === "") {
784
+ if (path23 === "") {
785
785
  throw new Error("Invalid redaction path ()");
786
786
  }
787
- if (path22.includes("..")) {
788
- throw new Error(`Invalid redaction path (${path22})`);
787
+ if (path23.includes("..")) {
788
+ throw new Error(`Invalid redaction path (${path23})`);
789
789
  }
790
- if (path22.includes(",")) {
791
- throw new Error(`Invalid redaction path (${path22})`);
790
+ if (path23.includes(",")) {
791
+ throw new Error(`Invalid redaction path (${path23})`);
792
792
  }
793
793
  let bracketCount = 0;
794
794
  let inQuotes = false;
795
795
  let quoteChar = "";
796
- for (let i = 0; i < path22.length; i++) {
797
- const char = path22[i];
796
+ for (let i = 0; i < path23.length; i++) {
797
+ const char = path23[i];
798
798
  if ((char === '"' || char === "'") && bracketCount > 0) {
799
799
  if (!inQuotes) {
800
800
  inQuotes = true;
@@ -808,20 +808,20 @@ var require_redact = __commonJS({
808
808
  } else if (char === "]" && !inQuotes) {
809
809
  bracketCount--;
810
810
  if (bracketCount < 0) {
811
- throw new Error(`Invalid redaction path (${path22})`);
811
+ throw new Error(`Invalid redaction path (${path23})`);
812
812
  }
813
813
  }
814
814
  }
815
815
  if (bracketCount !== 0) {
816
- throw new Error(`Invalid redaction path (${path22})`);
816
+ throw new Error(`Invalid redaction path (${path23})`);
817
817
  }
818
818
  }
819
819
  function validatePaths(paths) {
820
820
  if (!Array.isArray(paths)) {
821
821
  throw new TypeError("paths must be an array");
822
822
  }
823
- for (const path22 of paths) {
824
- validatePath(path22);
823
+ for (const path23 of paths) {
824
+ validatePath(path23);
825
825
  }
826
826
  }
827
827
  function slowRedact(options = {}) {
@@ -989,8 +989,8 @@ var require_redaction = __commonJS({
989
989
  if (shape[k] === null) {
990
990
  o[k] = (value) => topCensor(value, [k]);
991
991
  } else {
992
- const wrappedCensor = typeof censor === "function" ? (value, path22) => {
993
- return censor(value, [k, ...path22]);
992
+ const wrappedCensor = typeof censor === "function" ? (value, path23) => {
993
+ return censor(value, [k, ...path23]);
994
994
  } : censor;
995
995
  o[k] = Redact({
996
996
  paths: shape[k],
@@ -1208,10 +1208,10 @@ 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 fs21 = require("fs");
1211
+ var fs22 = require("fs");
1212
1212
  var EventEmitter = require("events");
1213
1213
  var inherits = require("util").inherits;
1214
- var path22 = require("path");
1214
+ var path23 = require("path");
1215
1215
  var sleep = require_atomic_sleep();
1216
1216
  var assert = require("assert");
1217
1217
  var BUSY_WRITE_TIMEOUT = 100;
@@ -1265,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) fs21.mkdirSync(path22.dirname(file), { recursive: true });
1269
- const fd = fs21.openSync(file, flags, mode);
1268
+ if (sonic.mkdir) fs22.mkdirSync(path23.dirname(file), { recursive: true });
1269
+ const fd = fs22.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
- fs21.mkdir(path22.dirname(file), { recursive: true }, (err) => {
1276
+ fs22.mkdir(path23.dirname(file), { recursive: true }, (err) => {
1277
1277
  if (err) return fileOpened(err);
1278
- fs21.open(file, flags, mode, fileOpened);
1278
+ fs22.open(file, flags, mode, fileOpened);
1279
1279
  });
1280
1280
  } else {
1281
- fs21.open(file, flags, mode, fileOpened);
1281
+ fs22.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 = () => fs21.writeSync(this.fd, this._writingBuf);
1323
- fsWrite = () => fs21.write(this.fd, this._writingBuf, this.release);
1322
+ fsWriteSync = () => fs22.writeSync(this.fd, this._writingBuf);
1323
+ fsWrite = () => fs22.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 fs21.writeSync(this.fd, this._writingBuf);
1332
+ return fs22.writeSync(this.fd, this._writingBuf);
1333
1333
  }
1334
- return fs21.writeSync(this.fd, this._writingBuf, "utf8");
1334
+ return fs22.writeSync(this.fd, this._writingBuf, "utf8");
1335
1335
  };
1336
1336
  fsWrite = () => {
1337
1337
  if (Buffer.isBuffer(this._writingBuf)) {
1338
- return fs21.write(this.fd, this._writingBuf, this.release);
1338
+ return fs22.write(this.fd, this._writingBuf, this.release);
1339
1339
  }
1340
- return fs21.write(this.fd, this._writingBuf, "utf8", this.release);
1340
+ return fs22.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
- fs21.fsyncSync(this.fd);
1397
+ fs22.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
- fs21.fsync(this.fd, (err) => {
1511
+ fs22.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
- fs21.close(fd, (err) => {
1613
+ fs22.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) ? fs21.writeSync(this.fd, buf) : fs21.writeSync(this.fd, buf, "utf8");
1662
+ const n = Buffer.isBuffer(buf) ? fs22.writeSync(this.fd, buf) : fs22.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
- fs21.fsyncSync(this.fd);
1678
+ fs22.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 = fs21.writeSync(this.fd, buf);
1699
+ const n = fs22.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) ? fs21.writeSync(this.fd, this._writingBuf) : fs21.writeSync(this.fd, this._writingBuf, "utf8");
1727
+ const written = Buffer.isBuffer(this._writingBuf) ? fs22.writeSync(this.fd, this._writingBuf) : fs22.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
- fs21.write(this.fd, this._writingBuf, release);
1733
+ fs22.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 = fs21.writeSync(this.fd, this._writingBuf);
1742
+ const written = fs22.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
- fs21.write(this.fd, this._writingBuf, release);
1751
+ fs22.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
- fs21.fsync(sonic.fd, closeWrapped);
1767
+ fs22.fsync(sonic.fd, closeWrapped);
1768
1768
  } catch {
1769
1769
  }
1770
1770
  function closeWrapped() {
1771
1771
  if (sonic.fd !== 1 && sonic.fd !== 2) {
1772
- fs21.close(sonic.fd, done);
1772
+ fs22.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 os13 = require("os");
4136
+ var os14 = 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 = os13.hostname();
4183
+ var hostname = os14.hostname();
4184
4184
  var defaultErrorSerializer = stdSerializers.err;
4185
4185
  var defaultOptions = {
4186
4186
  level: "info",
@@ -4384,6 +4384,7 @@ var init_methods = __esm({
4384
4384
  "workspace:list",
4385
4385
  "workspace:read",
4386
4386
  "skills:list",
4387
+ "agents:list",
4387
4388
  "git:root",
4388
4389
  "git:branch",
4389
4390
  "git:branches",
@@ -4408,7 +4409,7 @@ var init_methods = __esm({
4408
4409
  });
4409
4410
 
4410
4411
  // ../protocol/src/events.ts
4411
- var SESSION_STATUS_VALUES, HISTORY_USER_META_VALUES, ASK_USER_QUESTION_TOOL_NAME;
4412
+ var SESSION_STATUS_VALUES, HISTORY_USER_META_VALUES, SKILL_SOURCE_VALUES, AGENT_SOURCE_VALUES, ASK_USER_QUESTION_TOOL_NAME;
4412
4413
  var init_events = __esm({
4413
4414
  "../protocol/src/events.ts"() {
4414
4415
  "use strict";
@@ -4429,6 +4430,14 @@ var init_events = __esm({
4429
4430
  "attachment-skills",
4430
4431
  "attachment-deferred-tools"
4431
4432
  ];
4433
+ SKILL_SOURCE_VALUES = ["builtin", "global", "project", "plugin"];
4434
+ AGENT_SOURCE_VALUES = [
4435
+ "builtin",
4436
+ "global",
4437
+ "project",
4438
+ "policy",
4439
+ "plugin"
4440
+ ];
4432
4441
  ASK_USER_QUESTION_TOOL_NAME = "AskUserQuestion";
4433
4442
  }
4434
4443
  });
@@ -4883,8 +4892,8 @@ var init_parseUtil = __esm({
4883
4892
  init_errors2();
4884
4893
  init_en();
4885
4894
  makeIssue = (params) => {
4886
- const { data, path: path22, errorMaps, issueData } = params;
4887
- const fullPath = [...path22, ...issueData.path || []];
4895
+ const { data, path: path23, errorMaps, issueData } = params;
4896
+ const fullPath = [...path23, ...issueData.path || []];
4888
4897
  const fullIssue = {
4889
4898
  ...issueData,
4890
4899
  path: fullPath
@@ -5195,11 +5204,11 @@ var init_types = __esm({
5195
5204
  init_parseUtil();
5196
5205
  init_util();
5197
5206
  ParseInputLazyPath = class {
5198
- constructor(parent, value, path22, key) {
5207
+ constructor(parent, value, path23, key) {
5199
5208
  this._cachedPath = [];
5200
5209
  this.parent = parent;
5201
5210
  this.data = value;
5202
- this._path = path22;
5211
+ this._path = path23;
5203
5212
  this._key = key;
5204
5213
  }
5205
5214
  get path() {
@@ -8637,7 +8646,7 @@ var init_persona_schemas = __esm({
8637
8646
  });
8638
8647
 
8639
8648
  // ../protocol/src/schemas.ts
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;
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;
8641
8650
  var init_schemas = __esm({
8642
8651
  "../protocol/src/schemas.ts"() {
8643
8652
  "use strict";
@@ -9069,6 +9078,25 @@ var init_schemas = __esm({
9069
9078
  path: external_exports.string().min(1)
9070
9079
  });
9071
9080
  SkillsListArgs = external_exports.object({ cwd: external_exports.string().min(1) });
9081
+ SkillEntrySchema = external_exports.object({
9082
+ name: external_exports.string().min(1),
9083
+ source: external_exports.enum(SKILL_SOURCE_VALUES),
9084
+ path: external_exports.string().optional(),
9085
+ description: external_exports.string().optional(),
9086
+ plugin: external_exports.string().optional()
9087
+ });
9088
+ AgentEntrySchema = external_exports.object({
9089
+ name: external_exports.string().min(1),
9090
+ source: external_exports.enum(AGENT_SOURCE_VALUES),
9091
+ path: external_exports.string().optional(),
9092
+ description: external_exports.string().optional(),
9093
+ whenToUse: external_exports.string().optional(),
9094
+ plugin: external_exports.string().optional()
9095
+ });
9096
+ AgentsListArgs = external_exports.object({ cwd: external_exports.string().min(1) });
9097
+ AgentsListResponseSchema = external_exports.object({
9098
+ agents: external_exports.array(AgentEntrySchema)
9099
+ });
9072
9100
  SessionSubscribeArgs = external_exports.object({ sessionId: external_exports.string().min(1) });
9073
9101
  SessionPinArgs = external_exports.object({
9074
9102
  sessionId: external_exports.string().min(1),
@@ -9777,11 +9805,11 @@ var init_lib = __esm({
9777
9805
  }
9778
9806
  }
9779
9807
  },
9780
- addToPath: function addToPath(path22, added, removed, oldPosInc, options) {
9781
- var last = path22.lastComponent;
9808
+ addToPath: function addToPath(path23, added, removed, oldPosInc, options) {
9809
+ var last = path23.lastComponent;
9782
9810
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
9783
9811
  return {
9784
- oldPos: path22.oldPos + oldPosInc,
9812
+ oldPos: path23.oldPos + oldPosInc,
9785
9813
  lastComponent: {
9786
9814
  count: last.count + 1,
9787
9815
  added,
@@ -9791,7 +9819,7 @@ var init_lib = __esm({
9791
9819
  };
9792
9820
  } else {
9793
9821
  return {
9794
- oldPos: path22.oldPos + oldPosInc,
9822
+ oldPos: path23.oldPos + oldPosInc,
9795
9823
  lastComponent: {
9796
9824
  count: 1,
9797
9825
  added,
@@ -10222,10 +10250,10 @@ function attachmentToHistoryMessage(o, ts) {
10222
10250
  const memories = raw.map((m) => {
10223
10251
  if (!m || typeof m !== "object") return null;
10224
10252
  const rec = m;
10225
- const path22 = typeof rec.path === "string" ? rec.path : null;
10253
+ const path23 = typeof rec.path === "string" ? rec.path : null;
10226
10254
  const content = typeof rec.content === "string" ? rec.content : null;
10227
- if (!path22 || content == null) return null;
10228
- const entry = { path: path22, content };
10255
+ if (!path23 || content == null) return null;
10256
+ const entry = { path: path23, content };
10229
10257
  if (typeof rec.mtimeMs === "number") entry.mtimeMs = rec.mtimeMs;
10230
10258
  return entry;
10231
10259
  }).filter((m) => m !== null);
@@ -11027,10 +11055,10 @@ function parseAttachment(obj) {
11027
11055
  const memories = raw.map((m) => {
11028
11056
  if (!m || typeof m !== "object") return null;
11029
11057
  const rec = m;
11030
- const path22 = typeof rec.path === "string" ? rec.path : null;
11058
+ const path23 = typeof rec.path === "string" ? rec.path : null;
11031
11059
  const content = typeof rec.content === "string" ? rec.content : null;
11032
- if (!path22 || content == null) return null;
11033
- const out = { path: path22, content };
11060
+ if (!path23 || content == null) return null;
11061
+ const out = { path: path23, content };
11034
11062
  if (typeof rec.mtimeMs === "number") out.mtimeMs = rec.mtimeMs;
11035
11063
  return out;
11036
11064
  }).filter((m) => m !== null);
@@ -14897,7 +14925,7 @@ var require_websocket_server = __commonJS({
14897
14925
  // src/run-case/recorder.ts
14898
14926
  function startRunCaseRecorder(opts) {
14899
14927
  const now = opts.now ?? Date.now;
14900
- const dir = import_node_path19.default.dirname(opts.recordPath);
14928
+ const dir = import_node_path20.default.dirname(opts.recordPath);
14901
14929
  let stream = null;
14902
14930
  let closing = false;
14903
14931
  let closedSettled = false;
@@ -14911,8 +14939,8 @@ function startRunCaseRecorder(opts) {
14911
14939
  });
14912
14940
  const ensureStream = () => {
14913
14941
  if (stream) return stream;
14914
- import_node_fs19.default.mkdirSync(dir, { recursive: true });
14915
- stream = import_node_fs19.default.createWriteStream(opts.recordPath, { flags: "a" });
14942
+ import_node_fs20.default.mkdirSync(dir, { recursive: true });
14943
+ stream = import_node_fs20.default.createWriteStream(opts.recordPath, { flags: "a" });
14916
14944
  stream.on("close", () => closedResolve());
14917
14945
  return stream;
14918
14946
  };
@@ -14937,12 +14965,12 @@ function startRunCaseRecorder(opts) {
14937
14965
  };
14938
14966
  return { tap, close, closed };
14939
14967
  }
14940
- var import_node_fs19, import_node_path19;
14968
+ var import_node_fs20, import_node_path20;
14941
14969
  var init_recorder = __esm({
14942
14970
  "src/run-case/recorder.ts"() {
14943
14971
  "use strict";
14944
- import_node_fs19 = __toESM(require("fs"), 1);
14945
- import_node_path19 = __toESM(require("path"), 1);
14972
+ import_node_fs20 = __toESM(require("fs"), 1);
14973
+ import_node_path20 = __toESM(require("path"), 1);
14946
14974
  }
14947
14975
  });
14948
14976
 
@@ -14985,7 +15013,7 @@ var init_wire = __esm({
14985
15013
  // src/run-case/controller.ts
14986
15014
  async function runController(opts) {
14987
15015
  const now = opts.now ?? Date.now;
14988
- const cwd = opts.cwd ?? (0, import_node_fs20.mkdtempSync)(import_node_path20.default.join(import_node_os12.default.tmpdir(), "clawd-runcase-"));
15016
+ const cwd = opts.cwd ?? (0, import_node_fs21.mkdtempSync)(import_node_path21.default.join(import_node_os13.default.tmpdir(), "clawd-runcase-"));
14989
15017
  const ownsCwd = opts.cwd === void 0;
14990
15018
  const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
14991
15019
  const spawnCtx = { cwd };
@@ -15146,19 +15174,19 @@ async function runController(opts) {
15146
15174
  if (sigintHandler) process.off("SIGINT", sigintHandler);
15147
15175
  if (ownsCwd) {
15148
15176
  try {
15149
- (0, import_node_fs20.rmSync)(cwd, { recursive: true, force: true });
15177
+ (0, import_node_fs21.rmSync)(cwd, { recursive: true, force: true });
15150
15178
  } catch {
15151
15179
  }
15152
15180
  }
15153
15181
  return exitCode ?? 0;
15154
15182
  }
15155
- var import_node_fs20, import_node_os12, import_node_path20;
15183
+ var import_node_fs21, import_node_os13, import_node_path21;
15156
15184
  var init_controller = __esm({
15157
15185
  "src/run-case/controller.ts"() {
15158
15186
  "use strict";
15159
- import_node_fs20 = require("fs");
15160
- import_node_os12 = __toESM(require("os"), 1);
15161
- import_node_path20 = __toESM(require("path"), 1);
15187
+ import_node_fs21 = require("fs");
15188
+ import_node_os13 = __toESM(require("os"), 1);
15189
+ import_node_path21 = __toESM(require("path"), 1);
15162
15190
  init_claude();
15163
15191
  init_stdout_splitter();
15164
15192
  init_permission_stdio();
@@ -15383,8 +15411,8 @@ Env (advanced):
15383
15411
  `;
15384
15412
 
15385
15413
  // src/index.ts
15386
- var import_node_path18 = __toESM(require("path"), 1);
15387
- var import_node_fs18 = __toESM(require("fs"), 1);
15414
+ var import_node_path19 = __toESM(require("path"), 1);
15415
+ var import_node_fs19 = __toESM(require("fs"), 1);
15388
15416
 
15389
15417
  // src/logger.ts
15390
15418
  var import_node_fs2 = __toESM(require("fs"), 1);
@@ -15687,7 +15715,7 @@ function applyMetaUpdate(state, patch, deps) {
15687
15715
  if (shallowEqMeta(next.file, merged)) {
15688
15716
  return { state: next, effects: [] };
15689
15717
  }
15690
- next.file = { ...merged, updatedAt: nowIso(deps) };
15718
+ next.file = merged;
15691
15719
  return {
15692
15720
  state: next,
15693
15721
  effects: [
@@ -15789,6 +15817,7 @@ function pushEventToBuffer(state, event, deps) {
15789
15817
  next.nextSeq = seq + 1;
15790
15818
  if (newBuffer.length === 1) next.bufferStartSeq = seq;
15791
15819
  const isTurnEnd = withSeq.kind === "turn_end";
15820
+ const isUserText = withSeq.kind === "user_text";
15792
15821
  if (isTurnEnd) next.turnOpen = false;
15793
15822
  else if (!next.turnOpen) next.turnOpen = true;
15794
15823
  if (!next.turnOpen && next.buffer.length > deps.bufferCap) {
@@ -15799,6 +15828,11 @@ function pushEventToBuffer(state, event, deps) {
15799
15828
  }
15800
15829
  if (next.freshSpawn) next.freshSpawn = false;
15801
15830
  const effects = [emitSessionEvent(next.file.sessionId, withSeq)];
15831
+ if (isUserText || isTurnEnd) {
15832
+ next.file = { ...next.file, updatedAt: nowIso(deps) };
15833
+ effects.push({ kind: "persist-file", file: next.file });
15834
+ effects.push(sessionInfoFrame(next.file));
15835
+ }
15802
15836
  if (isTurnEnd && next.subSessionMeta?.idleKillEnabled && next.procAlive && (next.status === "running" || next.status === "spawning")) {
15803
15837
  next.status = "running-idle";
15804
15838
  effects.push({
@@ -15815,6 +15849,14 @@ var RUNTIME_PATCH_KEYS = [
15815
15849
  "effort",
15816
15850
  "cwd"
15817
15851
  ];
15852
+ var MARKER_PATCH_KEYS = ["pinnedAt", "pinSortOrder"];
15853
+ function isMarkerOnlyPatch(patch) {
15854
+ const keys = Object.keys(patch).filter(
15855
+ (k) => patch[k] !== void 0
15856
+ );
15857
+ if (keys.length === 0) return false;
15858
+ return keys.every((k) => MARKER_PATCH_KEYS.includes(k));
15859
+ }
15818
15860
  function applyCommand(state, command, deps) {
15819
15861
  const next = cloneState(state);
15820
15862
  const effects = [];
@@ -15921,7 +15963,8 @@ function applyCommand(state, command, deps) {
15921
15963
  const runtimePatch = RUNTIME_PATCH_KEYS.some(
15922
15964
  (k) => patch[k] !== void 0
15923
15965
  );
15924
- next.file = { ...next.file, ...patch, updatedAt: nowIso(deps) };
15966
+ const markerOnly = isMarkerOnlyPatch(patch);
15967
+ next.file = markerOnly ? { ...next.file, ...patch } : { ...next.file, ...patch, updatedAt: nowIso(deps) };
15925
15968
  effects.push({ kind: "persist-file", file: next.file });
15926
15969
  effects.push(sessionInfoFrame(next.file));
15927
15970
  if (runtimePatch && next.procAlive) {
@@ -16777,7 +16820,7 @@ var SessionManager = class {
16777
16820
  });
16778
16821
  return { response: value, broadcast };
16779
16822
  }
16780
- const updated = { ...existing, pinnedAt, updatedAt: nowIso2(this.deps) };
16823
+ const updated = { ...existing, pinnedAt };
16781
16824
  this.deps.store.write(updated);
16782
16825
  return { response: updated, broadcast: [] };
16783
16826
  }
@@ -16813,11 +16856,7 @@ var SessionManager = class {
16813
16856
  broadcast.push(...b);
16814
16857
  } else {
16815
16858
  const existing = this.getFile(sessionId);
16816
- const updated = {
16817
- ...existing,
16818
- pinSortOrder: index,
16819
- updatedAt: nowIso2(this.deps)
16820
- };
16859
+ const updated = { ...existing, pinSortOrder: index };
16821
16860
  this.deps.store.write(updated);
16822
16861
  updatedFiles.push(updated);
16823
16862
  }
@@ -17802,20 +17841,24 @@ var WorkspaceBrowser = class {
17802
17841
  var import_node_fs9 = __toESM(require("fs"), 1);
17803
17842
  var import_node_os5 = __toESM(require("os"), 1);
17804
17843
  var import_node_path9 = __toESM(require("path"), 1);
17805
- function parseFrontmatter(content) {
17806
- if (!content.startsWith("---")) return { name: "", description: "" };
17844
+
17845
+ // src/skills/frontmatter.ts
17846
+ var STRIP_QUOTES = /^["']|["']$/g;
17847
+ function strip(s) {
17848
+ return s.trim().replace(STRIP_QUOTES, "");
17849
+ }
17850
+ function parseFrontmatter(content, keys) {
17851
+ const out = {};
17852
+ if (!content.startsWith("---")) return out;
17807
17853
  const end = content.indexOf("---", 3);
17808
- if (end === -1) return { name: "", description: "" };
17854
+ if (end === -1) return out;
17809
17855
  const lines = content.slice(3, end).split("\n");
17810
- const strip = (s) => s.trim().replace(/^["']|["']$/g, "");
17811
- let name = "";
17812
- let description = "";
17813
17856
  for (let i = 0; i < lines.length; i++) {
17814
17857
  const trimmed = lines[i].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();
17858
+ for (const key of keys) {
17859
+ const prefix = `${key}:`;
17860
+ if (!trimmed.startsWith(prefix)) continue;
17861
+ const rest = trimmed.slice(prefix.length).trim();
17819
17862
  if (rest === "|" || rest === ">" || rest === "|-" || rest === ">-") {
17820
17863
  const parts = [];
17821
17864
  for (let j = i + 1; j < lines.length; j++) {
@@ -17827,13 +17870,82 @@ function parseFrontmatter(content) {
17827
17870
  if (!/^\s/.test(next)) break;
17828
17871
  parts.push(next.replace(/^\s+/, ""));
17829
17872
  }
17830
- description = parts.filter(Boolean).join(" ").trim();
17873
+ const value = parts.filter(Boolean).join(" ").trim();
17874
+ if (value) out[key] = value;
17831
17875
  } else {
17832
- description = strip(rest);
17876
+ const value = strip(rest);
17877
+ if (value) out[key] = value;
17833
17878
  }
17879
+ break;
17834
17880
  }
17835
17881
  }
17836
- return { name, description };
17882
+ return out;
17883
+ }
17884
+
17885
+ // src/skills/builtin-cc-resources.ts
17886
+ var BUILTIN_SKILLS = [
17887
+ { name: "update-config", source: "builtin", description: "Update Claude Code configuration." },
17888
+ { name: "keybindings-help", source: "builtin", description: "Show available keybindings." },
17889
+ { name: "verify", source: "builtin", description: "Verify the implementation." },
17890
+ { name: "debug", source: "builtin", description: "Debug current issue." },
17891
+ { name: "lorem-ipsum", source: "builtin", description: "Generate lorem ipsum placeholder text." },
17892
+ { name: "skillify", source: "builtin", description: "Convert a process into a reusable skill." },
17893
+ { name: "remember", source: "builtin", description: "Remember context for later use." },
17894
+ { name: "simplify", source: "builtin", description: "Simplify the code or message." },
17895
+ { name: "batch", source: "builtin", description: "Run a batch of similar operations." },
17896
+ { name: "stuck", source: "builtin", description: "Help unstick a stalled task." },
17897
+ { name: "loop", source: "builtin", description: "Loop a task until a condition is met." },
17898
+ { name: "cron-list", source: "builtin", description: "List scheduled cron tasks." },
17899
+ { name: "cron-delete", source: "builtin", description: "Delete a scheduled cron task." },
17900
+ { name: "dream", source: "builtin", description: "Brainstorm freely without constraints." },
17901
+ { name: "hunter", source: "builtin", description: "Hunt down a bug or root cause." },
17902
+ { name: "schedule", source: "builtin", description: "Schedule a task to run later." },
17903
+ { name: "claude-api", source: "builtin", description: "Use the Claude API directly." },
17904
+ { name: "claude-in-chrome", source: "builtin", description: "Drive Claude inside Chrome via the Chrome extension." }
17905
+ ];
17906
+ var BUILTIN_AGENTS = [
17907
+ {
17908
+ name: "general-purpose",
17909
+ source: "builtin",
17910
+ description: "General-purpose agent for researching complex questions and executing multi-step tasks.",
17911
+ 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."
17912
+ },
17913
+ {
17914
+ name: "statusline-setup",
17915
+ source: "builtin",
17916
+ description: "Configure the user's Claude Code status line setting.",
17917
+ whenToUse: "When the user is setting up or changing their status line configuration."
17918
+ },
17919
+ {
17920
+ name: "Explore",
17921
+ source: "builtin",
17922
+ description: "Explore the codebase to gather context.",
17923
+ whenToUse: "Before making changes that require understanding the surrounding code."
17924
+ },
17925
+ {
17926
+ name: "Plan",
17927
+ source: "builtin",
17928
+ description: "Produce an implementation plan before writing code.",
17929
+ whenToUse: "When the task is non-trivial and would benefit from an explicit plan."
17930
+ },
17931
+ {
17932
+ name: "claude-code-guide",
17933
+ source: "builtin",
17934
+ description: "Guide the user through Claude Code features.",
17935
+ whenToUse: "When the user needs help understanding what Claude Code can do."
17936
+ },
17937
+ {
17938
+ name: "verification",
17939
+ source: "builtin",
17940
+ description: "Verify that a change works as intended.",
17941
+ whenToUse: "After implementing a change, before declaring it done."
17942
+ }
17943
+ ];
17944
+
17945
+ // src/skills/scanner.ts
17946
+ function parseDescription(content) {
17947
+ const fields = parseFrontmatter(content, ["description"]);
17948
+ return { description: fields.description ?? "" };
17837
17949
  }
17838
17950
  function isDirLikeSync(p) {
17839
17951
  try {
@@ -17862,7 +17974,7 @@ function scanSkillDir(dir, source, seen, out, pluginName) {
17862
17974
  continue;
17863
17975
  }
17864
17976
  }
17865
- const { description } = parseFrontmatter(content);
17977
+ const { description } = parseDescription(content);
17866
17978
  const baseName = ent.name;
17867
17979
  const name = pluginName ? `${pluginName}:${baseName}` : baseName;
17868
17980
  if (seen.has(name)) continue;
@@ -17899,7 +18011,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
17899
18011
  continue;
17900
18012
  }
17901
18013
  const cmd = se.name.replace(/\.md$/, "");
17902
- const { description } = parseFrontmatter(content);
18014
+ const { description } = parseDescription(content);
17903
18015
  const qualified = `${ns}:${cmd}`;
17904
18016
  const name = pluginName ? `${pluginName}:${qualified}` : qualified;
17905
18017
  if (seen.has(name)) continue;
@@ -17916,7 +18028,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
17916
18028
  continue;
17917
18029
  }
17918
18030
  const cmd = ent.name.replace(/\.md$/, "");
17919
- const { description } = parseFrontmatter(content);
18031
+ const { description } = parseDescription(content);
17920
18032
  const name = pluginName ? `${pluginName}:${cmd}` : cmd;
17921
18033
  if (seen.has(name)) continue;
17922
18034
  seen.add(name);
@@ -17967,44 +18079,245 @@ var SkillsScanner = class {
17967
18079
  */
17968
18080
  list(args) {
17969
18081
  const seen = /* @__PURE__ */ new Set();
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);
18082
+ const builtinBlock = [];
18083
+ for (const b of BUILTIN_SKILLS) {
18084
+ if (seen.has(b.name)) continue;
18085
+ seen.add(b.name);
18086
+ builtinBlock.push({
18087
+ name: b.name,
18088
+ source: "builtin",
18089
+ description: b.description
18090
+ });
18091
+ }
18092
+ const fsBlock = [];
18093
+ scanSkillDir(import_node_path9.default.join(this.home, ".claude", "skills"), "global", seen, fsBlock);
18094
+ scanCommandDir(import_node_path9.default.join(this.home, ".claude", "commands"), "global", seen, fsBlock);
18095
+ scanSkillDir(import_node_path9.default.join(args.cwd, ".claude", "skills"), "project", seen, fsBlock);
18096
+ scanCommandDir(import_node_path9.default.join(args.cwd, ".claude", "commands"), "project", seen, fsBlock);
17975
18097
  const plugins = [...readInstalledPlugins(this.home), ...this.extraPluginRoots];
17976
18098
  for (const { name, root } of plugins) {
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);
18099
+ scanSkillDir(import_node_path9.default.join(root, "skills"), "plugin", seen, fsBlock, name);
18100
+ scanCommandDir(import_node_path9.default.join(root, "commands"), "plugin", seen, fsBlock, name);
17979
18101
  }
17980
- out.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
17981
- return out;
18102
+ fsBlock.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
18103
+ return [...builtinBlock, ...fsBlock];
17982
18104
  }
17983
18105
  };
17984
18106
 
17985
- // src/observer/session-observer.ts
18107
+ // src/skills/agents-scanner.ts
17986
18108
  var import_node_fs10 = __toESM(require("fs"), 1);
17987
18109
  var import_node_os6 = __toESM(require("os"), 1);
17988
18110
  var import_node_path10 = __toESM(require("path"), 1);
18111
+ var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
18112
+ function isDirLikeSync2(p) {
18113
+ try {
18114
+ return import_node_fs10.default.statSync(p).isDirectory();
18115
+ } catch {
18116
+ return false;
18117
+ }
18118
+ }
18119
+ function fileExistsSync(p) {
18120
+ try {
18121
+ return import_node_fs10.default.statSync(p).isFile();
18122
+ } catch {
18123
+ return false;
18124
+ }
18125
+ }
18126
+ function parseAgentFile(filePath) {
18127
+ let content;
18128
+ try {
18129
+ content = import_node_fs10.default.readFileSync(filePath, "utf8");
18130
+ } catch {
18131
+ return {};
18132
+ }
18133
+ const fm = parseFrontmatter(content, ["description", "whenToUse"]);
18134
+ return {
18135
+ description: fm.description,
18136
+ whenToUse: fm.whenToUse
18137
+ };
18138
+ }
18139
+ function scanAgentsDir(dir, source, seen, out) {
18140
+ let entries;
18141
+ try {
18142
+ entries = import_node_fs10.default.readdirSync(dir, { withFileTypes: true });
18143
+ } catch {
18144
+ return;
18145
+ }
18146
+ for (const ent of entries) {
18147
+ if (!ent.name.endsWith(".md")) continue;
18148
+ if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path10.default.join(dir, ent.name)))) {
18149
+ continue;
18150
+ }
18151
+ const filePath = import_node_path10.default.join(dir, ent.name);
18152
+ const baseName = ent.name.replace(/\.md$/, "");
18153
+ if (seen.has(baseName)) continue;
18154
+ seen.add(baseName);
18155
+ const { description, whenToUse } = parseAgentFile(filePath);
18156
+ out.push({
18157
+ name: baseName,
18158
+ source,
18159
+ path: filePath,
18160
+ ...description ? { description } : {},
18161
+ ...whenToUse ? { whenToUse } : {}
18162
+ });
18163
+ }
18164
+ }
18165
+ function scanPluginAgentsTree(root, pluginName, seen, out) {
18166
+ function walk(dir, namespaces) {
18167
+ let entries;
18168
+ try {
18169
+ entries = import_node_fs10.default.readdirSync(dir, { withFileTypes: true });
18170
+ } catch {
18171
+ return;
18172
+ }
18173
+ for (const ent of entries) {
18174
+ const childPath = import_node_path10.default.join(dir, ent.name);
18175
+ if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
18176
+ walk(childPath, [...namespaces, ent.name]);
18177
+ continue;
18178
+ }
18179
+ if (!ent.name.endsWith(".md")) continue;
18180
+ const baseName = ent.name.replace(/\.md$/, "");
18181
+ const nameParts = [pluginName, ...namespaces, baseName];
18182
+ const name = nameParts.join(":");
18183
+ if (seen.has(name)) continue;
18184
+ seen.add(name);
18185
+ const { description, whenToUse } = parseAgentFile(childPath);
18186
+ out.push({
18187
+ name,
18188
+ source: "plugin",
18189
+ path: childPath,
18190
+ plugin: pluginName,
18191
+ ...description ? { description } : {},
18192
+ ...whenToUse ? { whenToUse } : {}
18193
+ });
18194
+ }
18195
+ }
18196
+ walk(root, []);
18197
+ }
18198
+ function readInstalledPlugins2(home) {
18199
+ const pluginsDir = import_node_path10.default.join(home, ".claude", "plugins");
18200
+ const v2 = import_node_path10.default.join(pluginsDir, "installed_plugins_v2.json");
18201
+ const v1 = import_node_path10.default.join(pluginsDir, "installed_plugins.json");
18202
+ let raw = null;
18203
+ for (const candidate of [v2, v1]) {
18204
+ try {
18205
+ raw = import_node_fs10.default.readFileSync(candidate, "utf8");
18206
+ break;
18207
+ } catch {
18208
+ }
18209
+ }
18210
+ if (!raw) return [];
18211
+ let parsed;
18212
+ try {
18213
+ parsed = JSON.parse(raw);
18214
+ } catch {
18215
+ return [];
18216
+ }
18217
+ const out = [];
18218
+ for (const [key, entries] of Object.entries(parsed.plugins ?? {})) {
18219
+ if (!Array.isArray(entries) || entries.length === 0) continue;
18220
+ const entry = entries[0];
18221
+ if (!entry?.installPath) continue;
18222
+ if (entry.enabled === false) continue;
18223
+ const pluginName = key.includes("@") ? key.slice(0, key.indexOf("@")) : key;
18224
+ if (!pluginName) continue;
18225
+ out.push({ name: pluginName, root: entry.installPath });
18226
+ }
18227
+ return out;
18228
+ }
18229
+ function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
18230
+ let cur = import_node_path10.default.resolve(startCwd);
18231
+ const fsRoot = import_node_path10.default.parse(cur).root;
18232
+ while (true) {
18233
+ scanAgentsDir(import_node_path10.default.join(cur, ".claude", "agents"), "project", seen, out);
18234
+ let hasGit = false;
18235
+ try {
18236
+ hasGit = import_node_fs10.default.existsSync(import_node_path10.default.join(cur, ".git"));
18237
+ } catch {
18238
+ }
18239
+ if (hasGit) return;
18240
+ if (cur === home) return;
18241
+ if (cur === fsRoot) return;
18242
+ const parent = import_node_path10.default.dirname(cur);
18243
+ if (parent === cur) return;
18244
+ cur = parent;
18245
+ }
18246
+ }
18247
+ var AgentsScanner = class {
18248
+ home;
18249
+ extraPluginRoots;
18250
+ policyDir;
18251
+ constructor(opts = {}) {
18252
+ this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os6.default.homedir();
18253
+ this.extraPluginRoots = opts.extraPluginRoots ?? [];
18254
+ if (opts.policyDir !== void 0) {
18255
+ this.policyDir = opts.policyDir;
18256
+ } else if (process.platform === "darwin") {
18257
+ this.policyDir = DEFAULT_POLICY_DIR_DARWIN;
18258
+ } else {
18259
+ this.policyDir = null;
18260
+ }
18261
+ }
18262
+ list(args) {
18263
+ const seen = /* @__PURE__ */ new Set();
18264
+ const builtinBlock = [];
18265
+ for (const b of BUILTIN_AGENTS) {
18266
+ if (seen.has(b.name)) continue;
18267
+ seen.add(b.name);
18268
+ builtinBlock.push({
18269
+ name: b.name,
18270
+ source: "builtin",
18271
+ ...b.description ? { description: b.description } : {},
18272
+ ...b.whenToUse ? { whenToUse: b.whenToUse } : {}
18273
+ });
18274
+ }
18275
+ const fsBlock = [];
18276
+ scanAgentsDir(
18277
+ import_node_path10.default.join(this.home, ".claude", "agents"),
18278
+ "global",
18279
+ seen,
18280
+ fsBlock
18281
+ );
18282
+ walkUpProjectAgentsDirs(args.cwd, this.home, seen, fsBlock);
18283
+ if (this.policyDir) {
18284
+ scanAgentsDir(this.policyDir, "policy", seen, fsBlock);
18285
+ }
18286
+ const plugins = [
18287
+ ...readInstalledPlugins2(this.home),
18288
+ ...this.extraPluginRoots
18289
+ ];
18290
+ for (const { name, root } of plugins) {
18291
+ const agentsRoot = import_node_path10.default.join(root, "agents");
18292
+ scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
18293
+ }
18294
+ return [...builtinBlock, ...fsBlock];
18295
+ }
18296
+ };
18297
+
18298
+ // src/observer/session-observer.ts
18299
+ var import_node_fs11 = __toESM(require("fs"), 1);
18300
+ var import_node_os7 = __toESM(require("os"), 1);
18301
+ var import_node_path11 = __toESM(require("path"), 1);
17989
18302
  init_claude_history();
17990
18303
  var SessionObserver = class {
17991
18304
  constructor(opts) {
17992
18305
  this.opts = opts;
17993
- this.home = opts.home ?? import_node_os6.default.homedir();
18306
+ this.home = opts.home ?? import_node_os7.default.homedir();
17994
18307
  }
17995
18308
  opts;
17996
18309
  home;
17997
18310
  watches = /* @__PURE__ */ new Map();
17998
18311
  resolveJsonlPath(cwd, toolSessionId, override) {
17999
18312
  if (override) return override;
18000
- return import_node_path10.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
18313
+ return import_node_path11.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
18001
18314
  }
18002
18315
  start(args) {
18003
18316
  this.stop(args.sessionId);
18004
18317
  const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
18005
18318
  let size = 0;
18006
18319
  try {
18007
- size = import_node_fs10.default.statSync(filePath).size;
18320
+ size = import_node_fs11.default.statSync(filePath).size;
18008
18321
  } catch {
18009
18322
  }
18010
18323
  const w = {
@@ -18017,10 +18330,10 @@ var SessionObserver = class {
18017
18330
  adapter: args.adapter
18018
18331
  };
18019
18332
  try {
18020
- import_node_fs10.default.mkdirSync(import_node_path10.default.dirname(filePath), { recursive: true });
18333
+ import_node_fs11.default.mkdirSync(import_node_path11.default.dirname(filePath), { recursive: true });
18021
18334
  } catch {
18022
18335
  }
18023
- w.watcher = import_node_fs10.default.watch(import_node_path10.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
18336
+ w.watcher = import_node_fs11.default.watch(import_node_path11.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
18024
18337
  if (!changedName || !filePath.endsWith(changedName)) return;
18025
18338
  this.poll(w);
18026
18339
  });
@@ -18035,7 +18348,7 @@ var SessionObserver = class {
18035
18348
  // reducer.shallowEqMeta diff 让重复 patch 静默吞掉;异常静默吞,不阻塞 watcher 启动
18036
18349
  hydrateMetaTail(w, maxLines = 200) {
18037
18350
  try {
18038
- const raw = import_node_fs10.default.readFileSync(w.filePath, "utf8");
18351
+ const raw = import_node_fs11.default.readFileSync(w.filePath, "utf8");
18039
18352
  if (!raw) return;
18040
18353
  const allLines = raw.split("\n").filter((l) => l.trim().length > 0);
18041
18354
  if (allLines.length === 0) return;
@@ -18056,7 +18369,7 @@ var SessionObserver = class {
18056
18369
  poll(w) {
18057
18370
  let size = 0;
18058
18371
  try {
18059
- size = import_node_fs10.default.statSync(w.filePath).size;
18372
+ size = import_node_fs11.default.statSync(w.filePath).size;
18060
18373
  } catch {
18061
18374
  return;
18062
18375
  }
@@ -18065,11 +18378,11 @@ var SessionObserver = class {
18065
18378
  w.buf = "";
18066
18379
  }
18067
18380
  if (size === w.lastSize) return;
18068
- const fd = import_node_fs10.default.openSync(w.filePath, "r");
18381
+ const fd = import_node_fs11.default.openSync(w.filePath, "r");
18069
18382
  try {
18070
18383
  const len = size - w.lastSize;
18071
18384
  const buf = Buffer.alloc(len);
18072
- import_node_fs10.default.readSync(fd, buf, 0, len, w.lastSize);
18385
+ import_node_fs11.default.readSync(fd, buf, 0, len, w.lastSize);
18073
18386
  w.lastSize = size;
18074
18387
  w.buf += buf.toString("utf8");
18075
18388
  let newlineIndex;
@@ -18083,7 +18396,7 @@ var SessionObserver = class {
18083
18396
  this.maybeReportUserMessage(w.sessionId, line);
18084
18397
  }
18085
18398
  } finally {
18086
- import_node_fs10.default.closeSync(fd);
18399
+ import_node_fs11.default.closeSync(fd);
18087
18400
  }
18088
18401
  }
18089
18402
  // 解析 JSONL 单行:仅当是主链 user 文本行(非 sidechain / 非 sub-agent / message.role='user'
@@ -18735,10 +19048,10 @@ function isLocalhost(addr) {
18735
19048
  }
18736
19049
 
18737
19050
  // src/discovery/state-file.ts
18738
- var import_node_fs11 = __toESM(require("fs"), 1);
18739
- var import_node_path11 = __toESM(require("path"), 1);
19051
+ var import_node_fs12 = __toESM(require("fs"), 1);
19052
+ var import_node_path12 = __toESM(require("path"), 1);
18740
19053
  function defaultStateFilePath(dataDir) {
18741
- return import_node_path11.default.join(dataDir, "state.json");
19054
+ return import_node_path12.default.join(dataDir, "state.json");
18742
19055
  }
18743
19056
  function isPidAlive(pid) {
18744
19057
  if (!Number.isFinite(pid) || pid <= 0) return false;
@@ -18760,7 +19073,7 @@ var StateFileManager = class {
18760
19073
  }
18761
19074
  read() {
18762
19075
  try {
18763
- const raw = import_node_fs11.default.readFileSync(this.file, "utf8");
19076
+ const raw = import_node_fs12.default.readFileSync(this.file, "utf8");
18764
19077
  const parsed = JSON.parse(raw);
18765
19078
  return parsed;
18766
19079
  } catch {
@@ -18774,34 +19087,34 @@ var StateFileManager = class {
18774
19087
  return { status: "stale", existing };
18775
19088
  }
18776
19089
  write(state) {
18777
- import_node_fs11.default.mkdirSync(import_node_path11.default.dirname(this.file), { recursive: true });
19090
+ import_node_fs12.default.mkdirSync(import_node_path12.default.dirname(this.file), { recursive: true });
18778
19091
  const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
18779
- import_node_fs11.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
18780
- import_node_fs11.default.renameSync(tmp, this.file);
19092
+ import_node_fs12.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
19093
+ import_node_fs12.default.renameSync(tmp, this.file);
18781
19094
  if (process.platform !== "win32") {
18782
19095
  try {
18783
- import_node_fs11.default.chmodSync(this.file, 384);
19096
+ import_node_fs12.default.chmodSync(this.file, 384);
18784
19097
  } catch {
18785
19098
  }
18786
19099
  }
18787
19100
  }
18788
19101
  delete() {
18789
19102
  try {
18790
- import_node_fs11.default.unlinkSync(this.file);
19103
+ import_node_fs12.default.unlinkSync(this.file);
18791
19104
  } catch {
18792
19105
  }
18793
19106
  }
18794
19107
  };
18795
19108
 
18796
19109
  // src/tunnel/tunnel-manager.ts
18797
- var import_node_fs14 = __toESM(require("fs"), 1);
18798
- var import_node_path14 = __toESM(require("path"), 1);
19110
+ var import_node_fs15 = __toESM(require("fs"), 1);
19111
+ var import_node_path15 = __toESM(require("path"), 1);
18799
19112
  var import_node_crypto4 = __toESM(require("crypto"), 1);
18800
19113
  var import_node_child_process4 = require("child_process");
18801
19114
 
18802
19115
  // src/tunnel/tunnel-store.ts
18803
- var import_node_fs12 = __toESM(require("fs"), 1);
18804
- var import_node_path12 = __toESM(require("path"), 1);
19116
+ var import_node_fs13 = __toESM(require("fs"), 1);
19117
+ var import_node_path13 = __toESM(require("path"), 1);
18805
19118
  var TunnelStore = class {
18806
19119
  constructor(filePath) {
18807
19120
  this.filePath = filePath;
@@ -18809,7 +19122,7 @@ var TunnelStore = class {
18809
19122
  filePath;
18810
19123
  async get() {
18811
19124
  try {
18812
- const raw = await import_node_fs12.default.promises.readFile(this.filePath, "utf8");
19125
+ const raw = await import_node_fs13.default.promises.readFile(this.filePath, "utf8");
18813
19126
  const obj = JSON.parse(raw);
18814
19127
  if (!isPersistedTunnel(obj)) return null;
18815
19128
  return obj;
@@ -18820,22 +19133,22 @@ var TunnelStore = class {
18820
19133
  }
18821
19134
  }
18822
19135
  async set(v) {
18823
- const dir = import_node_path12.default.dirname(this.filePath);
18824
- await import_node_fs12.default.promises.mkdir(dir, { recursive: true });
19136
+ const dir = import_node_path13.default.dirname(this.filePath);
19137
+ await import_node_fs13.default.promises.mkdir(dir, { recursive: true });
18825
19138
  const data = JSON.stringify(v, null, 2);
18826
19139
  const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
18827
- await import_node_fs12.default.promises.writeFile(tmp, data, { mode: 384 });
19140
+ await import_node_fs13.default.promises.writeFile(tmp, data, { mode: 384 });
18828
19141
  if (process.platform !== "win32") {
18829
19142
  try {
18830
- await import_node_fs12.default.promises.chmod(tmp, 384);
19143
+ await import_node_fs13.default.promises.chmod(tmp, 384);
18831
19144
  } catch {
18832
19145
  }
18833
19146
  }
18834
- await import_node_fs12.default.promises.rename(tmp, this.filePath);
19147
+ await import_node_fs13.default.promises.rename(tmp, this.filePath);
18835
19148
  }
18836
19149
  async clear() {
18837
19150
  try {
18838
- await import_node_fs12.default.promises.unlink(this.filePath);
19151
+ await import_node_fs13.default.promises.unlink(this.filePath);
18839
19152
  } catch (err) {
18840
19153
  const code = err?.code;
18841
19154
  if (code !== "ENOENT") throw err;
@@ -18930,9 +19243,9 @@ function escape(v) {
18930
19243
  }
18931
19244
 
18932
19245
  // src/tunnel/frpc-binary.ts
18933
- var import_node_fs13 = __toESM(require("fs"), 1);
18934
- var import_node_os7 = __toESM(require("os"), 1);
18935
- var import_node_path13 = __toESM(require("path"), 1);
19246
+ var import_node_fs14 = __toESM(require("fs"), 1);
19247
+ var import_node_os8 = __toESM(require("os"), 1);
19248
+ var import_node_path14 = __toESM(require("path"), 1);
18936
19249
  var import_node_child_process3 = require("child_process");
18937
19250
  var import_node_stream = require("stream");
18938
19251
  var import_promises = require("stream/promises");
@@ -18964,20 +19277,20 @@ function frpcDownloadUrl(version2, p) {
18964
19277
  }
18965
19278
  async function ensureFrpcBinary(opts) {
18966
19279
  if (opts.override) {
18967
- if (!import_node_fs13.default.existsSync(opts.override)) {
19280
+ if (!import_node_fs14.default.existsSync(opts.override)) {
18968
19281
  throw new Error(`frpc binary not found at override path: ${opts.override}`);
18969
19282
  }
18970
19283
  return opts.override;
18971
19284
  }
18972
19285
  const version2 = opts.version ?? FRPC_VERSION;
18973
19286
  const platform = opts.platform ?? detectPlatform();
18974
- const binDir = import_node_path13.default.join(opts.dataDir, "bin");
18975
- import_node_fs13.default.mkdirSync(binDir, { recursive: true });
19287
+ const binDir = import_node_path14.default.join(opts.dataDir, "bin");
19288
+ import_node_fs14.default.mkdirSync(binDir, { recursive: true });
18976
19289
  cleanupStaleArtifacts(binDir);
18977
- const stableBin = import_node_path13.default.join(binDir, "frpc");
18978
- if (import_node_fs13.default.existsSync(stableBin)) return stableBin;
19290
+ const stableBin = import_node_path14.default.join(binDir, "frpc");
19291
+ if (import_node_fs14.default.existsSync(stableBin)) return stableBin;
18979
19292
  const partialBin = `${stableBin}.partial`;
18980
- const tarballPath = import_node_path13.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
19293
+ const tarballPath = import_node_path14.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
18981
19294
  try {
18982
19295
  const url = frpcDownloadUrl(version2, platform);
18983
19296
  await downloadToFile(url, tarballPath, opts.fetchImpl);
@@ -18986,8 +19299,8 @@ async function ensureFrpcBinary(opts) {
18986
19299
  } else {
18987
19300
  await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
18988
19301
  }
18989
- import_node_fs13.default.chmodSync(partialBin, 493);
18990
- import_node_fs13.default.renameSync(partialBin, stableBin);
19302
+ import_node_fs14.default.chmodSync(partialBin, 493);
19303
+ import_node_fs14.default.renameSync(partialBin, stableBin);
18991
19304
  } finally {
18992
19305
  safeUnlink(tarballPath);
18993
19306
  safeUnlink(partialBin);
@@ -18997,15 +19310,15 @@ async function ensureFrpcBinary(opts) {
18997
19310
  function cleanupStaleArtifacts(binDir) {
18998
19311
  let entries;
18999
19312
  try {
19000
- entries = import_node_fs13.default.readdirSync(binDir);
19313
+ entries = import_node_fs14.default.readdirSync(binDir);
19001
19314
  } catch {
19002
19315
  return;
19003
19316
  }
19004
19317
  for (const name of entries) {
19005
19318
  if (name.endsWith(".partial") || name.startsWith("extract-")) {
19006
- const full = import_node_path13.default.join(binDir, name);
19319
+ const full = import_node_path14.default.join(binDir, name);
19007
19320
  try {
19008
- import_node_fs13.default.rmSync(full, { recursive: true, force: true });
19321
+ import_node_fs14.default.rmSync(full, { recursive: true, force: true });
19009
19322
  } catch {
19010
19323
  }
19011
19324
  }
@@ -19013,7 +19326,7 @@ function cleanupStaleArtifacts(binDir) {
19013
19326
  }
19014
19327
  function safeUnlink(p) {
19015
19328
  try {
19016
- import_node_fs13.default.unlinkSync(p);
19329
+ import_node_fs14.default.unlinkSync(p);
19017
19330
  } catch {
19018
19331
  }
19019
19332
  }
@@ -19024,13 +19337,13 @@ async function downloadToFile(url, dest, fetchImpl) {
19024
19337
  if (!res.ok || !res.body) {
19025
19338
  throw new Error(`download failed: ${res.status} ${res.statusText}`);
19026
19339
  }
19027
- const out = import_node_fs13.default.createWriteStream(dest);
19340
+ const out = import_node_fs14.default.createWriteStream(dest);
19028
19341
  const nodeStream = import_node_stream.Readable.fromWeb(res.body);
19029
19342
  await (0, import_promises.pipeline)(nodeStream, out);
19030
19343
  }
19031
19344
  async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
19032
- const work = import_node_path13.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
19033
- import_node_fs13.default.mkdirSync(work, { recursive: true });
19345
+ const work = import_node_path14.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
19346
+ import_node_fs14.default.mkdirSync(work, { recursive: true });
19034
19347
  try {
19035
19348
  await new Promise((resolve, reject) => {
19036
19349
  const proc = (0, import_node_child_process3.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
@@ -19038,13 +19351,13 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
19038
19351
  proc.on("exit", (code) => code === 0 ? resolve() : reject(new Error(`tar exited ${code}`)));
19039
19352
  });
19040
19353
  const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
19041
- const src = import_node_path13.default.join(work, dirName, "frpc");
19042
- if (!import_node_fs13.default.existsSync(src)) {
19354
+ const src = import_node_path14.default.join(work, dirName, "frpc");
19355
+ if (!import_node_fs14.default.existsSync(src)) {
19043
19356
  throw new Error(`frpc not found inside tarball at ${src}`);
19044
19357
  }
19045
- import_node_fs13.default.copyFileSync(src, destBin);
19358
+ import_node_fs14.default.copyFileSync(src, destBin);
19046
19359
  } finally {
19047
- import_node_fs13.default.rmSync(work, { recursive: true, force: true });
19360
+ import_node_fs14.default.rmSync(work, { recursive: true, force: true });
19048
19361
  }
19049
19362
  }
19050
19363
 
@@ -19053,7 +19366,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
19053
19366
  var TunnelManager = class {
19054
19367
  constructor(deps) {
19055
19368
  this.deps = deps;
19056
- this.store = deps.store ?? new TunnelStore(import_node_path14.default.join(deps.dataDir, "tunnel.json"));
19369
+ this.store = deps.store ?? new TunnelStore(import_node_path15.default.join(deps.dataDir, "tunnel.json"));
19057
19370
  this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
19058
19371
  this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
19059
19372
  }
@@ -19170,7 +19483,7 @@ var TunnelManager = class {
19170
19483
  dataDir: this.deps.dataDir,
19171
19484
  override: this.deps.frpcBinaryOverride ?? void 0
19172
19485
  });
19173
- const tomlPath = import_node_path14.default.join(this.deps.dataDir, "frpc.toml");
19486
+ const tomlPath = import_node_path15.default.join(this.deps.dataDir, "frpc.toml");
19174
19487
  const proxyName = `clawd-${t.subdomain}-${localPort}-${import_node_crypto4.default.randomBytes(3).toString("hex")}`;
19175
19488
  const toml = buildFrpcToml({
19176
19489
  serverAddr: t.frpsHost,
@@ -19181,12 +19494,12 @@ var TunnelManager = class {
19181
19494
  localPort,
19182
19495
  logLevel: "info"
19183
19496
  });
19184
- await import_node_fs14.default.promises.writeFile(tomlPath, toml, { mode: 384 });
19497
+ await import_node_fs15.default.promises.writeFile(tomlPath, toml, { mode: 384 });
19185
19498
  const proc = (this.deps.spawnImpl ?? import_node_child_process4.spawn)(frpcBin, ["-c", tomlPath], {
19186
19499
  stdio: ["ignore", "pipe", "pipe"]
19187
19500
  });
19188
- const logFilePath = import_node_path14.default.join(this.deps.dataDir, "frpc.log");
19189
- const logStream = import_node_fs14.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
19501
+ const logFilePath = import_node_path15.default.join(this.deps.dataDir, "frpc.log");
19502
+ const logStream = import_node_fs15.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
19190
19503
  logStream.on("error", () => {
19191
19504
  });
19192
19505
  const tee = (chunk) => {
@@ -19267,23 +19580,23 @@ async function waitForFrpcReady(proc, timeoutMs) {
19267
19580
  }
19268
19581
 
19269
19582
  // src/tunnel/device-key.ts
19270
- var import_node_os8 = __toESM(require("os"), 1);
19583
+ var import_node_os9 = __toESM(require("os"), 1);
19271
19584
  var import_node_crypto5 = __toESM(require("crypto"), 1);
19272
19585
  var DERIVE_SALT = "clawd-tunnel-device-v1";
19273
19586
  function deriveStableDeviceKey(opts = {}) {
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);
19587
+ const hostname = opts.hostname ?? import_node_os9.default.hostname();
19588
+ const uid = opts.uid ?? (typeof import_node_os9.default.userInfo === "function" ? import_node_os9.default.userInfo().uid : 0);
19276
19589
  const input = `${hostname}::${uid}`;
19277
19590
  return import_node_crypto5.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
19278
19591
  }
19279
19592
 
19280
19593
  // src/auth-store.ts
19281
- var import_node_fs15 = __toESM(require("fs"), 1);
19282
- var import_node_path15 = __toESM(require("path"), 1);
19594
+ var import_node_fs16 = __toESM(require("fs"), 1);
19595
+ var import_node_path16 = __toESM(require("path"), 1);
19283
19596
  var import_node_crypto6 = __toESM(require("crypto"), 1);
19284
19597
  var AUTH_FILE_NAME = "auth.json";
19285
19598
  function authFilePath(dataDir) {
19286
- return import_node_path15.default.join(dataDir, AUTH_FILE_NAME);
19599
+ return import_node_path16.default.join(dataDir, AUTH_FILE_NAME);
19287
19600
  }
19288
19601
  function loadOrCreateAuthToken(opts) {
19289
19602
  const file = authFilePath(opts.dataDir);
@@ -19299,7 +19612,7 @@ function defaultGenerate() {
19299
19612
  }
19300
19613
  function readAuthFile(file) {
19301
19614
  try {
19302
- const raw = import_node_fs15.default.readFileSync(file, "utf8");
19615
+ const raw = import_node_fs16.default.readFileSync(file, "utf8");
19303
19616
  const parsed = JSON.parse(raw);
19304
19617
  if (typeof parsed?.token === "string" && parsed.token.length > 0) {
19305
19618
  return {
@@ -19315,10 +19628,10 @@ function readAuthFile(file) {
19315
19628
  }
19316
19629
  }
19317
19630
  function writeAuthFile(file, content) {
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 });
19631
+ import_node_fs16.default.mkdirSync(import_node_path16.default.dirname(file), { recursive: true });
19632
+ import_node_fs16.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
19320
19633
  try {
19321
- import_node_fs15.default.chmodSync(file, 384);
19634
+ import_node_fs16.default.chmodSync(file, 384);
19322
19635
  } catch {
19323
19636
  }
19324
19637
  }
@@ -19330,12 +19643,12 @@ init_protocol();
19330
19643
  init_protocol();
19331
19644
 
19332
19645
  // src/session/fork.ts
19333
- var import_node_fs16 = __toESM(require("fs"), 1);
19334
- var import_node_os9 = __toESM(require("os"), 1);
19335
- var import_node_path16 = __toESM(require("path"), 1);
19646
+ var import_node_fs17 = __toESM(require("fs"), 1);
19647
+ var import_node_os10 = __toESM(require("os"), 1);
19648
+ var import_node_path17 = __toESM(require("path"), 1);
19336
19649
  init_claude_history();
19337
19650
  function readJsonlEntries(file) {
19338
- const raw = import_node_fs16.default.readFileSync(file, "utf8");
19651
+ const raw = import_node_fs17.default.readFileSync(file, "utf8");
19339
19652
  const out = [];
19340
19653
  for (const line of raw.split("\n")) {
19341
19654
  const t = line.trim();
@@ -19348,10 +19661,10 @@ function readJsonlEntries(file) {
19348
19661
  return out;
19349
19662
  }
19350
19663
  function forkSession(input) {
19351
- const baseDir = input.baseDir ?? import_node_path16.default.join(import_node_os9.default.homedir(), ".claude");
19352
- const projectDir = import_node_path16.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
19353
- const sourceFile = import_node_path16.default.join(projectDir, `${input.toolSessionId}.jsonl`);
19354
- if (!import_node_fs16.default.existsSync(sourceFile)) {
19664
+ const baseDir = input.baseDir ?? import_node_path17.default.join(import_node_os10.default.homedir(), ".claude");
19665
+ const projectDir = import_node_path17.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
19666
+ const sourceFile = import_node_path17.default.join(projectDir, `${input.toolSessionId}.jsonl`);
19667
+ if (!import_node_fs17.default.existsSync(sourceFile)) {
19355
19668
  throw new Error(`fork: source transcript not found: ${sourceFile}`);
19356
19669
  }
19357
19670
  const entries = readJsonlEntries(sourceFile);
@@ -19381,9 +19694,9 @@ function forkSession(input) {
19381
19694
  }
19382
19695
  forkedLines.push(JSON.stringify(forked));
19383
19696
  }
19384
- const forkedFilePath = import_node_path16.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
19385
- import_node_fs16.default.mkdirSync(projectDir, { recursive: true });
19386
- import_node_fs16.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
19697
+ const forkedFilePath = import_node_path17.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
19698
+ import_node_fs17.default.mkdirSync(projectDir, { recursive: true });
19699
+ import_node_fs17.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
19387
19700
  return { forkedToolSessionId, forkedFilePath };
19388
19701
  }
19389
19702
 
@@ -19631,7 +19944,7 @@ function buildHistoryHandlers(deps) {
19631
19944
  // src/handlers/workspace.ts
19632
19945
  init_protocol();
19633
19946
  function buildWorkspaceHandlers(deps) {
19634
- const { workspace, skills } = deps;
19947
+ const { workspace, skills, agents } = deps;
19635
19948
  const list = async (frame) => {
19636
19949
  const args = WorkspaceListArgs.parse(frame);
19637
19950
  const res = workspace.list(args);
@@ -19647,10 +19960,16 @@ function buildWorkspaceHandlers(deps) {
19647
19960
  const list2 = skills.list(args);
19648
19961
  return { response: { type: "skills:list", skills: list2 } };
19649
19962
  };
19963
+ const agentsList = async (frame) => {
19964
+ const args = AgentsListArgs.parse(frame);
19965
+ const list2 = agents.list(args);
19966
+ return { response: { type: "agents:list", agents: list2 } };
19967
+ };
19650
19968
  return {
19651
19969
  "workspace:list": list,
19652
19970
  "workspace:read": read,
19653
- "skills:list": skillsList
19971
+ "skills:list": skillsList,
19972
+ "agents:list": agentsList
19654
19973
  };
19655
19974
  }
19656
19975
 
@@ -19659,9 +19978,9 @@ init_protocol();
19659
19978
 
19660
19979
  // src/workspace/git.ts
19661
19980
  var import_node_child_process5 = require("child_process");
19662
- var import_node_fs17 = __toESM(require("fs"), 1);
19663
- var import_node_os10 = __toESM(require("os"), 1);
19664
- var import_node_path17 = __toESM(require("path"), 1);
19981
+ var import_node_fs18 = __toESM(require("fs"), 1);
19982
+ var import_node_os11 = __toESM(require("os"), 1);
19983
+ var import_node_path18 = __toESM(require("path"), 1);
19665
19984
  var import_node_util = require("util");
19666
19985
  var pexec = (0, import_node_util.promisify)(import_node_child_process5.execFile);
19667
19986
  function formatChildProcessError(err) {
@@ -19676,9 +19995,9 @@ function formatChildProcessError(err) {
19676
19995
  return e.message ?? "unknown error";
19677
19996
  }
19678
19997
  function normalizePath(p) {
19679
- const resolved = import_node_path17.default.resolve(p);
19998
+ const resolved = import_node_path18.default.resolve(p);
19680
19999
  try {
19681
- return import_node_fs17.default.realpathSync(resolved);
20000
+ return import_node_fs18.default.realpathSync(resolved);
19682
20001
  } catch {
19683
20002
  return resolved;
19684
20003
  }
@@ -19765,7 +20084,7 @@ function sanitizeLabel(raw) {
19765
20084
  function computePrefix() {
19766
20085
  let username;
19767
20086
  try {
19768
- username = import_node_os10.default.userInfo().username;
20087
+ username = import_node_os11.default.userInfo().username;
19769
20088
  } catch {
19770
20089
  username = void 0;
19771
20090
  }
@@ -19779,13 +20098,13 @@ function flattenToDirName(branch) {
19779
20098
  }
19780
20099
  function encodeClaudeProjectDir(absPath) {
19781
20100
  if (!absPath || typeof absPath !== "string") return "";
19782
- let canonical = import_node_path17.default.resolve(absPath);
20101
+ let canonical = import_node_path18.default.resolve(absPath);
19783
20102
  try {
19784
- canonical = import_node_fs17.default.realpathSync(canonical);
20103
+ canonical = import_node_fs18.default.realpathSync(canonical);
19785
20104
  } catch {
19786
20105
  try {
19787
- const parent = import_node_fs17.default.realpathSync(import_node_path17.default.dirname(canonical));
19788
- canonical = import_node_path17.default.join(parent, import_node_path17.default.basename(canonical));
20106
+ const parent = import_node_fs18.default.realpathSync(import_node_path18.default.dirname(canonical));
20107
+ canonical = import_node_path18.default.join(parent, import_node_path18.default.basename(canonical));
19789
20108
  } catch {
19790
20109
  }
19791
20110
  }
@@ -19809,11 +20128,11 @@ async function createWorktree(input) {
19809
20128
  if (!isGitRoot) {
19810
20129
  throw new Error(`\u76EE\u5F55 ${cwd} \u4E0D\u662F git repo \u6839`);
19811
20130
  }
19812
- const parent = import_node_path17.default.dirname(import_node_path17.default.resolve(cwd));
19813
- if (parent === "/" || parent === import_node_path17.default.resolve(cwd)) {
20131
+ const parent = import_node_path18.default.dirname(import_node_path18.default.resolve(cwd));
20132
+ if (parent === "/" || parent === import_node_path18.default.resolve(cwd)) {
19814
20133
  throw new Error("repo \u5728\u78C1\u76D8\u6839\u76EE\u5F55\uFF0C\u65E0\u6CD5\u5728\u540C\u7EA7\u521B\u5EFA worktree");
19815
20134
  }
19816
- const worktreeRoot = import_node_path17.default.join(parent, dirName);
20135
+ const worktreeRoot = import_node_path18.default.join(parent, dirName);
19817
20136
  try {
19818
20137
  await pexec("git", ["-C", cwd, "fetch", "origin", baseBranch, "--no-tags"], {
19819
20138
  timeout: 3e4
@@ -19832,7 +20151,7 @@ async function createWorktree(input) {
19832
20151
  const msg = err.message;
19833
20152
  if (msg.startsWith("\u5206\u652F ")) throw err;
19834
20153
  }
19835
- if (import_node_fs17.default.existsSync(worktreeRoot)) {
20154
+ if (import_node_fs18.default.existsSync(worktreeRoot)) {
19836
20155
  throw new Error(`\u76EE\u5F55 ${worktreeRoot} \u5DF2\u5B58\u5728\uFF0C\u8BF7\u6362\u4E00\u4E2A label \u6216\u6E05\u7406\u540E\u91CD\u8BD5`);
19837
20156
  }
19838
20157
  try {
@@ -19860,8 +20179,8 @@ async function removeWorktree(input) {
19860
20179
  );
19861
20180
  const gitCommonDir = stdout.trim();
19862
20181
  if (!gitCommonDir) throw new Error("empty git-common-dir");
19863
- const absGitCommon = import_node_path17.default.isAbsolute(gitCommonDir) ? gitCommonDir : import_node_path17.default.resolve(worktreeRoot, gitCommonDir);
19864
- repoRoot = import_node_path17.default.dirname(absGitCommon);
20182
+ const absGitCommon = import_node_path18.default.isAbsolute(gitCommonDir) ? gitCommonDir : import_node_path18.default.resolve(worktreeRoot, gitCommonDir);
20183
+ repoRoot = import_node_path18.default.dirname(absGitCommon);
19865
20184
  } catch {
19866
20185
  repoRoot = null;
19867
20186
  }
@@ -19873,7 +20192,7 @@ async function removeWorktree(input) {
19873
20192
  } catch (err) {
19874
20193
  const stderr = err.stderr ?? "";
19875
20194
  const lower = stderr.toLowerCase();
19876
- const vanished = lower.includes("not a working tree") || lower.includes("is not a working tree") || !import_node_fs17.default.existsSync(worktreeRoot);
20195
+ const vanished = lower.includes("not a working tree") || lower.includes("is not a working tree") || !import_node_fs18.default.existsSync(worktreeRoot);
19877
20196
  if (!vanished) {
19878
20197
  throw new Error(`\u6E05\u7406 worktree \u5931\u8D25\uFF1A${formatChildProcessError(err)}`);
19879
20198
  }
@@ -19892,10 +20211,10 @@ async function removeWorktree(input) {
19892
20211
  try {
19893
20212
  const encoded = encodeClaudeProjectDir(worktreeRoot);
19894
20213
  if (encoded) {
19895
- const projectsRoot = import_node_path17.default.join(import_node_os10.default.homedir(), ".claude", "projects");
19896
- const target = import_node_path17.default.resolve(projectsRoot, encoded);
19897
- if (target.startsWith(projectsRoot + import_node_path17.default.sep) && target !== projectsRoot) {
19898
- import_node_fs17.default.rmSync(target, { recursive: true, force: true });
20214
+ const projectsRoot = import_node_path18.default.join(import_node_os11.default.homedir(), ".claude", "projects");
20215
+ const target = import_node_path18.default.resolve(projectsRoot, encoded);
20216
+ if (target.startsWith(projectsRoot + import_node_path18.default.sep) && target !== projectsRoot) {
20217
+ import_node_fs18.default.rmSync(target, { recursive: true, force: true });
19899
20218
  }
19900
20219
  }
19901
20220
  } catch {
@@ -19967,7 +20286,7 @@ function buildCapabilitiesHandlers(deps) {
19967
20286
  }
19968
20287
 
19969
20288
  // src/handlers/meta.ts
19970
- var import_node_os11 = __toESM(require("os"), 1);
20289
+ var import_node_os12 = __toESM(require("os"), 1);
19971
20290
  init_protocol();
19972
20291
 
19973
20292
  // src/version.ts
@@ -19989,7 +20308,7 @@ function buildReadyFrame(deps) {
19989
20308
  return {
19990
20309
  version,
19991
20310
  protocolVersion: PROTOCOL_VERSION,
19992
- hostname: import_node_os11.default.hostname(),
20311
+ hostname: import_node_os12.default.hostname(),
19993
20312
  os: process.platform,
19994
20313
  tools,
19995
20314
  runningSessions: info.runningSessions,
@@ -20107,7 +20426,7 @@ function buildMethodHandlers(deps) {
20107
20426
  async function startDaemon(config) {
20108
20427
  const logger = createLogger({
20109
20428
  level: config.logLevel,
20110
- file: import_node_path18.default.join(config.dataDir, "clawd.log")
20429
+ file: import_node_path19.default.join(config.dataDir, "clawd.log")
20111
20430
  });
20112
20431
  logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
20113
20432
  const stateMgr = new StateFileManager({ dataDir: config.dataDir });
@@ -20140,6 +20459,7 @@ async function startDaemon(config) {
20140
20459
  const store = new SessionStore({ dataDir: config.dataDir });
20141
20460
  const workspace = new WorkspaceBrowser();
20142
20461
  const skills = new SkillsScanner();
20462
+ const agents = new AgentsScanner();
20143
20463
  const history = new ClaudeHistoryReader();
20144
20464
  let transport = null;
20145
20465
  const manager = new SessionManager({
@@ -20148,7 +20468,7 @@ async function startDaemon(config) {
20148
20468
  getAdapter,
20149
20469
  historyReader: history,
20150
20470
  dataDir: config.dataDir,
20151
- personaRoot: import_node_path18.default.join(config.dataDir, "personas"),
20471
+ personaRoot: import_node_path19.default.join(config.dataDir, "personas"),
20152
20472
  broadcastFrame: (frame, target) => {
20153
20473
  if (target === "all") {
20154
20474
  transport?.broadcastAll(frame);
@@ -20188,7 +20508,7 @@ async function startDaemon(config) {
20188
20508
  manager.recordRealUserUuid({ sessionId, realUuid, text });
20189
20509
  }
20190
20510
  });
20191
- const personaStore = new PersonaStore(import_node_path18.default.join(config.dataDir, "personas"));
20511
+ const personaStore = new PersonaStore(import_node_path19.default.join(config.dataDir, "personas"));
20192
20512
  const personaRegistry = new PersonaRegistry(personaStore);
20193
20513
  const personaManager = new PersonaManager({
20194
20514
  store: personaStore,
@@ -20200,6 +20520,7 @@ async function startDaemon(config) {
20200
20520
  manager,
20201
20521
  workspace,
20202
20522
  skills,
20523
+ agents,
20203
20524
  history,
20204
20525
  observer,
20205
20526
  getAdapter,
@@ -20320,8 +20641,8 @@ async function startDaemon(config) {
20320
20641
  const lines = [
20321
20642
  `Tunnel: ${r.url}`,
20322
20643
  ...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
20323
- `Frpc config: ${import_node_path18.default.join(config.dataDir, "frpc.toml")}`,
20324
- `Frpc log: ${import_node_path18.default.join(config.dataDir, "frpc.log")}`
20644
+ `Frpc config: ${import_node_path19.default.join(config.dataDir, "frpc.toml")}`,
20645
+ `Frpc log: ${import_node_path19.default.join(config.dataDir, "frpc.log")}`
20325
20646
  ];
20326
20647
  const width = Math.max(...lines.map((l) => l.length));
20327
20648
  const bar = "\u2550".repeat(width + 4);
@@ -20334,8 +20655,8 @@ ${bar}
20334
20655
 
20335
20656
  `);
20336
20657
  try {
20337
- const connectPath = import_node_path18.default.join(config.dataDir, "connect.txt");
20338
- import_node_fs18.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
20658
+ const connectPath = import_node_path19.default.join(config.dataDir, "connect.txt");
20659
+ import_node_fs19.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
20339
20660
  } catch {
20340
20661
  }
20341
20662
  } catch (err) {