@clawos-dev/clawd 0.2.32 → 0.2.33-beta.48.5d86147

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 +538 -239
  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 path21 = req.path;
300
- _req.url = typeof path21 === "string" ? path21 : req.url ? req.url.path || req.url : void 0;
299
+ const path22 = req.path;
300
+ _req.url = typeof path22 === "string" ? path22 : 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(path21) {
465
+ function parsePath(path22) {
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 < path21.length; i++) {
472
- const char = path21[i];
471
+ for (let i = 0; i < path22.length; i++) {
472
+ const char = path22[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 path21 of paths) {
604
- const parts = parsePath(path21);
603
+ for (const path22 of paths) {
604
+ const parts = parsePath(path22);
605
605
  if (parts.includes("*")) {
606
- redactWildcardPath(obj, parts, censor, path21, remove);
606
+ redactWildcardPath(obj, parts, censor, path22, 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, path21) => {
692
- const fullPath = [...pathArray.slice(0, pathLength), ...path21];
691
+ const wrappedCensor = typeof censor === "function" ? (value, path22) => {
692
+ const fullPath = [...pathArray.slice(0, pathLength), ...path22];
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 path21 of pathsToClone) {
728
- const parts = parsePath(path21);
727
+ for (const path22 of pathsToClone) {
728
+ const parts = parsePath(path22);
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(path21) {
781
- if (typeof path21 !== "string") {
780
+ function validatePath(path22) {
781
+ if (typeof path22 !== "string") {
782
782
  throw new Error("Paths must be (non-empty) strings");
783
783
  }
784
- if (path21 === "") {
784
+ if (path22 === "") {
785
785
  throw new Error("Invalid redaction path ()");
786
786
  }
787
- if (path21.includes("..")) {
788
- throw new Error(`Invalid redaction path (${path21})`);
787
+ if (path22.includes("..")) {
788
+ throw new Error(`Invalid redaction path (${path22})`);
789
789
  }
790
- if (path21.includes(",")) {
791
- throw new Error(`Invalid redaction path (${path21})`);
790
+ if (path22.includes(",")) {
791
+ throw new Error(`Invalid redaction path (${path22})`);
792
792
  }
793
793
  let bracketCount = 0;
794
794
  let inQuotes = false;
795
795
  let quoteChar = "";
796
- for (let i = 0; i < path21.length; i++) {
797
- const char = path21[i];
796
+ for (let i = 0; i < path22.length; i++) {
797
+ const char = path22[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 (${path21})`);
811
+ throw new Error(`Invalid redaction path (${path22})`);
812
812
  }
813
813
  }
814
814
  }
815
815
  if (bracketCount !== 0) {
816
- throw new Error(`Invalid redaction path (${path21})`);
816
+ throw new Error(`Invalid redaction path (${path22})`);
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 path21 of paths) {
824
- validatePath(path21);
823
+ for (const path22 of paths) {
824
+ validatePath(path22);
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, path21) => {
993
- return censor(value, [k, ...path21]);
992
+ const wrappedCensor = typeof censor === "function" ? (value, path22) => {
993
+ return censor(value, [k, ...path22]);
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 path21 = require("path");
1214
+ var path22 = 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(path21.dirname(file), { recursive: true });
1269
- const fd = fs21.openSync(file, flags, mode);
1268
+ if (sonic.mkdir) fs22.mkdirSync(path22.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(path21.dirname(file), { recursive: true }, (err) => {
1276
+ fs22.mkdir(path22.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: path21, errorMaps, issueData } = params;
4887
- const fullPath = [...path21, ...issueData.path || []];
4895
+ const { data, path: path22, errorMaps, issueData } = params;
4896
+ const fullPath = [...path22, ...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, path21, key) {
5207
+ constructor(parent, value, path22, key) {
5199
5208
  this._cachedPath = [];
5200
5209
  this.parent = parent;
5201
5210
  this.data = value;
5202
- this._path = path21;
5211
+ this._path = path22;
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";
@@ -9060,6 +9069,25 @@ var init_schemas = __esm({
9060
9069
  path: external_exports.string().min(1)
9061
9070
  });
9062
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
+ });
9063
9091
  SessionSubscribeArgs = external_exports.object({ sessionId: external_exports.string().min(1) });
9064
9092
  SessionPinArgs = external_exports.object({
9065
9093
  sessionId: external_exports.string().min(1),
@@ -9760,11 +9788,11 @@ var init_lib = __esm({
9760
9788
  }
9761
9789
  }
9762
9790
  },
9763
- addToPath: function addToPath(path21, added, removed, oldPosInc, options) {
9764
- var last = path21.lastComponent;
9791
+ addToPath: function addToPath(path22, added, removed, oldPosInc, options) {
9792
+ var last = path22.lastComponent;
9765
9793
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
9766
9794
  return {
9767
- oldPos: path21.oldPos + oldPosInc,
9795
+ oldPos: path22.oldPos + oldPosInc,
9768
9796
  lastComponent: {
9769
9797
  count: last.count + 1,
9770
9798
  added,
@@ -9774,7 +9802,7 @@ var init_lib = __esm({
9774
9802
  };
9775
9803
  } else {
9776
9804
  return {
9777
- oldPos: path21.oldPos + oldPosInc,
9805
+ oldPos: path22.oldPos + oldPosInc,
9778
9806
  lastComponent: {
9779
9807
  count: 1,
9780
9808
  added,
@@ -10205,10 +10233,10 @@ function attachmentToHistoryMessage(o, ts) {
10205
10233
  const memories = raw.map((m) => {
10206
10234
  if (!m || typeof m !== "object") return null;
10207
10235
  const rec = m;
10208
- const path21 = typeof rec.path === "string" ? rec.path : null;
10236
+ const path22 = typeof rec.path === "string" ? rec.path : null;
10209
10237
  const content = typeof rec.content === "string" ? rec.content : null;
10210
- if (!path21 || content == null) return null;
10211
- const entry = { path: path21, content };
10238
+ if (!path22 || content == null) return null;
10239
+ const entry = { path: path22, content };
10212
10240
  if (typeof rec.mtimeMs === "number") entry.mtimeMs = rec.mtimeMs;
10213
10241
  return entry;
10214
10242
  }).filter((m) => m !== null);
@@ -10999,10 +11027,10 @@ function parseAttachment(obj) {
10999
11027
  const memories = raw.map((m) => {
11000
11028
  if (!m || typeof m !== "object") return null;
11001
11029
  const rec = m;
11002
- const path21 = typeof rec.path === "string" ? rec.path : null;
11030
+ const path22 = typeof rec.path === "string" ? rec.path : null;
11003
11031
  const content = typeof rec.content === "string" ? rec.content : null;
11004
- if (!path21 || content == null) return null;
11005
- const out = { path: path21, content };
11032
+ if (!path22 || content == null) return null;
11033
+ const out = { path: path22, content };
11006
11034
  if (typeof rec.mtimeMs === "number") out.mtimeMs = rec.mtimeMs;
11007
11035
  return out;
11008
11036
  }).filter((m) => m !== null);
@@ -14869,7 +14897,7 @@ var require_websocket_server = __commonJS({
14869
14897
  // src/run-case/recorder.ts
14870
14898
  function startRunCaseRecorder(opts) {
14871
14899
  const now = opts.now ?? Date.now;
14872
- const dir = import_node_path18.default.dirname(opts.recordPath);
14900
+ const dir = import_node_path19.default.dirname(opts.recordPath);
14873
14901
  let stream = null;
14874
14902
  let closing = false;
14875
14903
  let closedSettled = false;
@@ -14883,8 +14911,8 @@ function startRunCaseRecorder(opts) {
14883
14911
  });
14884
14912
  const ensureStream = () => {
14885
14913
  if (stream) return stream;
14886
- import_node_fs19.default.mkdirSync(dir, { recursive: true });
14887
- stream = import_node_fs19.default.createWriteStream(opts.recordPath, { flags: "a" });
14914
+ import_node_fs20.default.mkdirSync(dir, { recursive: true });
14915
+ stream = import_node_fs20.default.createWriteStream(opts.recordPath, { flags: "a" });
14888
14916
  stream.on("close", () => closedResolve());
14889
14917
  return stream;
14890
14918
  };
@@ -14909,12 +14937,12 @@ function startRunCaseRecorder(opts) {
14909
14937
  };
14910
14938
  return { tap, close, closed };
14911
14939
  }
14912
- var import_node_fs19, import_node_path18;
14940
+ var import_node_fs20, import_node_path19;
14913
14941
  var init_recorder = __esm({
14914
14942
  "src/run-case/recorder.ts"() {
14915
14943
  "use strict";
14916
- import_node_fs19 = __toESM(require("fs"), 1);
14917
- import_node_path18 = __toESM(require("path"), 1);
14944
+ import_node_fs20 = __toESM(require("fs"), 1);
14945
+ import_node_path19 = __toESM(require("path"), 1);
14918
14946
  }
14919
14947
  });
14920
14948
 
@@ -14957,7 +14985,7 @@ var init_wire = __esm({
14957
14985
  // src/run-case/controller.ts
14958
14986
  async function runController(opts) {
14959
14987
  const now = opts.now ?? Date.now;
14960
- const cwd = opts.cwd ?? (0, import_node_fs20.mkdtempSync)(import_node_path19.default.join(import_node_os12.default.tmpdir(), "clawd-runcase-"));
14988
+ const cwd = opts.cwd ?? (0, import_node_fs21.mkdtempSync)(import_node_path20.default.join(import_node_os13.default.tmpdir(), "clawd-runcase-"));
14961
14989
  const ownsCwd = opts.cwd === void 0;
14962
14990
  const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
14963
14991
  const spawnCtx = { cwd };
@@ -15118,19 +15146,19 @@ async function runController(opts) {
15118
15146
  if (sigintHandler) process.off("SIGINT", sigintHandler);
15119
15147
  if (ownsCwd) {
15120
15148
  try {
15121
- (0, import_node_fs20.rmSync)(cwd, { recursive: true, force: true });
15149
+ (0, import_node_fs21.rmSync)(cwd, { recursive: true, force: true });
15122
15150
  } catch {
15123
15151
  }
15124
15152
  }
15125
15153
  return exitCode ?? 0;
15126
15154
  }
15127
- var import_node_fs20, import_node_os12, import_node_path19;
15155
+ var import_node_fs21, import_node_os13, import_node_path20;
15128
15156
  var init_controller = __esm({
15129
15157
  "src/run-case/controller.ts"() {
15130
15158
  "use strict";
15131
- import_node_fs20 = require("fs");
15132
- import_node_os12 = __toESM(require("os"), 1);
15133
- import_node_path19 = __toESM(require("path"), 1);
15159
+ import_node_fs21 = require("fs");
15160
+ import_node_os13 = __toESM(require("os"), 1);
15161
+ import_node_path20 = __toESM(require("path"), 1);
15134
15162
  init_claude();
15135
15163
  init_stdout_splitter();
15136
15164
  init_permission_stdio();
@@ -15355,8 +15383,8 @@ Env (advanced):
15355
15383
  `;
15356
15384
 
15357
15385
  // src/index.ts
15358
- var import_node_path17 = __toESM(require("path"), 1);
15359
- var import_node_fs18 = __toESM(require("fs"), 1);
15386
+ var import_node_path18 = __toESM(require("path"), 1);
15387
+ var import_node_fs19 = __toESM(require("fs"), 1);
15360
15388
 
15361
15389
  // src/logger.ts
15362
15390
  var import_node_fs2 = __toESM(require("fs"), 1);
@@ -15658,7 +15686,7 @@ function applyMetaUpdate(state, patch, deps) {
15658
15686
  if (shallowEqMeta(next.file, merged)) {
15659
15687
  return { state: next, effects: [] };
15660
15688
  }
15661
- next.file = merged;
15689
+ next.file = { ...merged, updatedAt: nowIso(deps) };
15662
15690
  return {
15663
15691
  state: next,
15664
15692
  effects: [
@@ -15760,7 +15788,6 @@ function pushEventToBuffer(state, event, deps) {
15760
15788
  next.nextSeq = seq + 1;
15761
15789
  if (newBuffer.length === 1) next.bufferStartSeq = seq;
15762
15790
  const isTurnEnd = withSeq.kind === "turn_end";
15763
- const isUserText = withSeq.kind === "user_text";
15764
15791
  if (isTurnEnd) next.turnOpen = false;
15765
15792
  else if (!next.turnOpen) next.turnOpen = true;
15766
15793
  if (!next.turnOpen && next.buffer.length > deps.bufferCap) {
@@ -15771,11 +15798,6 @@ function pushEventToBuffer(state, event, deps) {
15771
15798
  }
15772
15799
  if (next.freshSpawn) next.freshSpawn = false;
15773
15800
  const effects = [emitSessionEvent(next.file.sessionId, withSeq)];
15774
- if (isUserText || isTurnEnd) {
15775
- next.file = { ...next.file, updatedAt: nowIso(deps) };
15776
- effects.push({ kind: "persist-file", file: next.file });
15777
- effects.push(sessionInfoFrame(next.file));
15778
- }
15779
15801
  if (isTurnEnd && next.subSessionMeta?.idleKillEnabled && next.procAlive && (next.status === "running" || next.status === "spawning")) {
15780
15802
  next.status = "running-idle";
15781
15803
  effects.push({
@@ -15792,14 +15814,6 @@ var RUNTIME_PATCH_KEYS = [
15792
15814
  "effort",
15793
15815
  "cwd"
15794
15816
  ];
15795
- var MARKER_PATCH_KEYS = ["pinnedAt", "pinSortOrder"];
15796
- function isMarkerOnlyPatch(patch) {
15797
- const keys = Object.keys(patch).filter(
15798
- (k) => patch[k] !== void 0
15799
- );
15800
- if (keys.length === 0) return false;
15801
- return keys.every((k) => MARKER_PATCH_KEYS.includes(k));
15802
- }
15803
15817
  function applyCommand(state, command, deps) {
15804
15818
  const next = cloneState(state);
15805
15819
  const effects = [];
@@ -15906,8 +15920,7 @@ function applyCommand(state, command, deps) {
15906
15920
  const runtimePatch = RUNTIME_PATCH_KEYS.some(
15907
15921
  (k) => patch[k] !== void 0
15908
15922
  );
15909
- const markerOnly = isMarkerOnlyPatch(patch);
15910
- next.file = markerOnly ? { ...next.file, ...patch } : { ...next.file, ...patch, updatedAt: nowIso(deps) };
15923
+ next.file = { ...next.file, ...patch, updatedAt: nowIso(deps) };
15911
15924
  effects.push({ kind: "persist-file", file: next.file });
15912
15925
  effects.push(sessionInfoFrame(next.file));
15913
15926
  if (runtimePatch && next.procAlive) {
@@ -16728,7 +16741,7 @@ var SessionManager = class {
16728
16741
  });
16729
16742
  return { response: value, broadcast };
16730
16743
  }
16731
- const updated = { ...existing, pinnedAt };
16744
+ const updated = { ...existing, pinnedAt, updatedAt: nowIso2(this.deps) };
16732
16745
  this.deps.store.write(updated);
16733
16746
  return { response: updated, broadcast: [] };
16734
16747
  }
@@ -16764,7 +16777,11 @@ var SessionManager = class {
16764
16777
  broadcast.push(...b);
16765
16778
  } else {
16766
16779
  const existing = this.getFile(sessionId);
16767
- const updated = { ...existing, pinSortOrder: index };
16780
+ const updated = {
16781
+ ...existing,
16782
+ pinSortOrder: index,
16783
+ updatedAt: nowIso2(this.deps)
16784
+ };
16768
16785
  this.deps.store.write(updated);
16769
16786
  updatedFiles.push(updated);
16770
16787
  }
@@ -17747,20 +17764,24 @@ var WorkspaceBrowser = class {
17747
17764
  var import_node_fs9 = __toESM(require("fs"), 1);
17748
17765
  var import_node_os5 = __toESM(require("os"), 1);
17749
17766
  var import_node_path8 = __toESM(require("path"), 1);
17750
- function parseFrontmatter(content) {
17751
- if (!content.startsWith("---")) return { name: "", description: "" };
17767
+
17768
+ // src/skills/frontmatter.ts
17769
+ var STRIP_QUOTES = /^["']|["']$/g;
17770
+ function strip(s) {
17771
+ return s.trim().replace(STRIP_QUOTES, "");
17772
+ }
17773
+ function parseFrontmatter(content, keys) {
17774
+ const out = {};
17775
+ if (!content.startsWith("---")) return out;
17752
17776
  const end = content.indexOf("---", 3);
17753
- if (end === -1) return { name: "", description: "" };
17777
+ if (end === -1) return out;
17754
17778
  const lines = content.slice(3, end).split("\n");
17755
- const strip = (s) => s.trim().replace(/^["']|["']$/g, "");
17756
- let name = "";
17757
- let description = "";
17758
17779
  for (let i = 0; i < lines.length; i++) {
17759
17780
  const trimmed = lines[i].trim();
17760
- if (trimmed.startsWith("name:")) {
17761
- name = strip(trimmed.slice(5));
17762
- } else if (trimmed.startsWith("description:")) {
17763
- const rest = trimmed.slice(12).trim();
17781
+ for (const key of keys) {
17782
+ const prefix = `${key}:`;
17783
+ if (!trimmed.startsWith(prefix)) continue;
17784
+ const rest = trimmed.slice(prefix.length).trim();
17764
17785
  if (rest === "|" || rest === ">" || rest === "|-" || rest === ">-") {
17765
17786
  const parts = [];
17766
17787
  for (let j = i + 1; j < lines.length; j++) {
@@ -17772,13 +17793,82 @@ function parseFrontmatter(content) {
17772
17793
  if (!/^\s/.test(next)) break;
17773
17794
  parts.push(next.replace(/^\s+/, ""));
17774
17795
  }
17775
- description = parts.filter(Boolean).join(" ").trim();
17796
+ const value = parts.filter(Boolean).join(" ").trim();
17797
+ if (value) out[key] = value;
17776
17798
  } else {
17777
- description = strip(rest);
17799
+ const value = strip(rest);
17800
+ if (value) out[key] = value;
17778
17801
  }
17802
+ break;
17779
17803
  }
17780
17804
  }
17781
- return { name, description };
17805
+ return out;
17806
+ }
17807
+
17808
+ // src/skills/builtin-cc-resources.ts
17809
+ var BUILTIN_SKILLS = [
17810
+ { name: "update-config", source: "builtin", description: "Update Claude Code configuration." },
17811
+ { name: "keybindings-help", source: "builtin", description: "Show available keybindings." },
17812
+ { name: "verify", source: "builtin", description: "Verify the implementation." },
17813
+ { name: "debug", source: "builtin", description: "Debug current issue." },
17814
+ { name: "lorem-ipsum", source: "builtin", description: "Generate lorem ipsum placeholder text." },
17815
+ { name: "skillify", source: "builtin", description: "Convert a process into a reusable skill." },
17816
+ { name: "remember", source: "builtin", description: "Remember context for later use." },
17817
+ { name: "simplify", source: "builtin", description: "Simplify the code or message." },
17818
+ { name: "batch", source: "builtin", description: "Run a batch of similar operations." },
17819
+ { name: "stuck", source: "builtin", description: "Help unstick a stalled task." },
17820
+ { name: "loop", source: "builtin", description: "Loop a task until a condition is met." },
17821
+ { name: "cron-list", source: "builtin", description: "List scheduled cron tasks." },
17822
+ { name: "cron-delete", source: "builtin", description: "Delete a scheduled cron task." },
17823
+ { name: "dream", source: "builtin", description: "Brainstorm freely without constraints." },
17824
+ { name: "hunter", source: "builtin", description: "Hunt down a bug or root cause." },
17825
+ { name: "schedule", source: "builtin", description: "Schedule a task to run later." },
17826
+ { name: "claude-api", source: "builtin", description: "Use the Claude API directly." },
17827
+ { name: "claude-in-chrome", source: "builtin", description: "Drive Claude inside Chrome via the Chrome extension." }
17828
+ ];
17829
+ var BUILTIN_AGENTS = [
17830
+ {
17831
+ name: "general-purpose",
17832
+ source: "builtin",
17833
+ description: "General-purpose agent for researching complex questions and executing multi-step tasks.",
17834
+ 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."
17835
+ },
17836
+ {
17837
+ name: "statusline-setup",
17838
+ source: "builtin",
17839
+ description: "Configure the user's Claude Code status line setting.",
17840
+ whenToUse: "When the user is setting up or changing their status line configuration."
17841
+ },
17842
+ {
17843
+ name: "Explore",
17844
+ source: "builtin",
17845
+ description: "Explore the codebase to gather context.",
17846
+ whenToUse: "Before making changes that require understanding the surrounding code."
17847
+ },
17848
+ {
17849
+ name: "Plan",
17850
+ source: "builtin",
17851
+ description: "Produce an implementation plan before writing code.",
17852
+ whenToUse: "When the task is non-trivial and would benefit from an explicit plan."
17853
+ },
17854
+ {
17855
+ name: "claude-code-guide",
17856
+ source: "builtin",
17857
+ description: "Guide the user through Claude Code features.",
17858
+ whenToUse: "When the user needs help understanding what Claude Code can do."
17859
+ },
17860
+ {
17861
+ name: "verification",
17862
+ source: "builtin",
17863
+ description: "Verify that a change works as intended.",
17864
+ whenToUse: "After implementing a change, before declaring it done."
17865
+ }
17866
+ ];
17867
+
17868
+ // src/skills/scanner.ts
17869
+ function parseDescription(content) {
17870
+ const fields = parseFrontmatter(content, ["description"]);
17871
+ return { description: fields.description ?? "" };
17782
17872
  }
17783
17873
  function isDirLikeSync(p) {
17784
17874
  try {
@@ -17807,7 +17897,7 @@ function scanSkillDir(dir, source, seen, out, pluginName) {
17807
17897
  continue;
17808
17898
  }
17809
17899
  }
17810
- const { description } = parseFrontmatter(content);
17900
+ const { description } = parseDescription(content);
17811
17901
  const baseName = ent.name;
17812
17902
  const name = pluginName ? `${pluginName}:${baseName}` : baseName;
17813
17903
  if (seen.has(name)) continue;
@@ -17844,7 +17934,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
17844
17934
  continue;
17845
17935
  }
17846
17936
  const cmd = se.name.replace(/\.md$/, "");
17847
- const { description } = parseFrontmatter(content);
17937
+ const { description } = parseDescription(content);
17848
17938
  const qualified = `${ns}:${cmd}`;
17849
17939
  const name = pluginName ? `${pluginName}:${qualified}` : qualified;
17850
17940
  if (seen.has(name)) continue;
@@ -17861,7 +17951,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
17861
17951
  continue;
17862
17952
  }
17863
17953
  const cmd = ent.name.replace(/\.md$/, "");
17864
- const { description } = parseFrontmatter(content);
17954
+ const { description } = parseDescription(content);
17865
17955
  const name = pluginName ? `${pluginName}:${cmd}` : cmd;
17866
17956
  if (seen.has(name)) continue;
17867
17957
  seen.add(name);
@@ -17912,44 +18002,245 @@ var SkillsScanner = class {
17912
18002
  */
17913
18003
  list(args) {
17914
18004
  const seen = /* @__PURE__ */ new Set();
17915
- const out = [];
17916
- scanSkillDir(import_node_path8.default.join(this.home, ".claude", "skills"), "global", seen, out);
17917
- scanCommandDir(import_node_path8.default.join(this.home, ".claude", "commands"), "global", seen, out);
17918
- scanSkillDir(import_node_path8.default.join(args.cwd, ".claude", "skills"), "project", seen, out);
17919
- scanCommandDir(import_node_path8.default.join(args.cwd, ".claude", "commands"), "project", seen, out);
18005
+ const builtinBlock = [];
18006
+ for (const b of BUILTIN_SKILLS) {
18007
+ if (seen.has(b.name)) continue;
18008
+ seen.add(b.name);
18009
+ builtinBlock.push({
18010
+ name: b.name,
18011
+ source: "builtin",
18012
+ description: b.description
18013
+ });
18014
+ }
18015
+ const fsBlock = [];
18016
+ scanSkillDir(import_node_path8.default.join(this.home, ".claude", "skills"), "global", seen, fsBlock);
18017
+ scanCommandDir(import_node_path8.default.join(this.home, ".claude", "commands"), "global", seen, fsBlock);
18018
+ scanSkillDir(import_node_path8.default.join(args.cwd, ".claude", "skills"), "project", seen, fsBlock);
18019
+ scanCommandDir(import_node_path8.default.join(args.cwd, ".claude", "commands"), "project", seen, fsBlock);
17920
18020
  const plugins = [...readInstalledPlugins(this.home), ...this.extraPluginRoots];
17921
18021
  for (const { name, root } of plugins) {
17922
- scanSkillDir(import_node_path8.default.join(root, "skills"), "plugin", seen, out, name);
17923
- scanCommandDir(import_node_path8.default.join(root, "commands"), "plugin", seen, out, name);
18022
+ scanSkillDir(import_node_path8.default.join(root, "skills"), "plugin", seen, fsBlock, name);
18023
+ scanCommandDir(import_node_path8.default.join(root, "commands"), "plugin", seen, fsBlock, name);
17924
18024
  }
17925
- out.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
17926
- return out;
18025
+ fsBlock.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
18026
+ return [...builtinBlock, ...fsBlock];
17927
18027
  }
17928
18028
  };
17929
18029
 
17930
- // src/observer/session-observer.ts
18030
+ // src/skills/agents-scanner.ts
17931
18031
  var import_node_fs10 = __toESM(require("fs"), 1);
17932
18032
  var import_node_os6 = __toESM(require("os"), 1);
17933
18033
  var import_node_path9 = __toESM(require("path"), 1);
18034
+ var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
18035
+ function isDirLikeSync2(p) {
18036
+ try {
18037
+ return import_node_fs10.default.statSync(p).isDirectory();
18038
+ } catch {
18039
+ return false;
18040
+ }
18041
+ }
18042
+ function fileExistsSync(p) {
18043
+ try {
18044
+ return import_node_fs10.default.statSync(p).isFile();
18045
+ } catch {
18046
+ return false;
18047
+ }
18048
+ }
18049
+ function parseAgentFile(filePath) {
18050
+ let content;
18051
+ try {
18052
+ content = import_node_fs10.default.readFileSync(filePath, "utf8");
18053
+ } catch {
18054
+ return {};
18055
+ }
18056
+ const fm = parseFrontmatter(content, ["description", "whenToUse"]);
18057
+ return {
18058
+ description: fm.description,
18059
+ whenToUse: fm.whenToUse
18060
+ };
18061
+ }
18062
+ function scanAgentsDir(dir, source, seen, out) {
18063
+ let entries;
18064
+ try {
18065
+ entries = import_node_fs10.default.readdirSync(dir, { withFileTypes: true });
18066
+ } catch {
18067
+ return;
18068
+ }
18069
+ for (const ent of entries) {
18070
+ if (!ent.name.endsWith(".md")) continue;
18071
+ if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path9.default.join(dir, ent.name)))) {
18072
+ continue;
18073
+ }
18074
+ const filePath = import_node_path9.default.join(dir, ent.name);
18075
+ const baseName = ent.name.replace(/\.md$/, "");
18076
+ if (seen.has(baseName)) continue;
18077
+ seen.add(baseName);
18078
+ const { description, whenToUse } = parseAgentFile(filePath);
18079
+ out.push({
18080
+ name: baseName,
18081
+ source,
18082
+ path: filePath,
18083
+ ...description ? { description } : {},
18084
+ ...whenToUse ? { whenToUse } : {}
18085
+ });
18086
+ }
18087
+ }
18088
+ function scanPluginAgentsTree(root, pluginName, seen, out) {
18089
+ function walk(dir, namespaces) {
18090
+ let entries;
18091
+ try {
18092
+ entries = import_node_fs10.default.readdirSync(dir, { withFileTypes: true });
18093
+ } catch {
18094
+ return;
18095
+ }
18096
+ for (const ent of entries) {
18097
+ const childPath = import_node_path9.default.join(dir, ent.name);
18098
+ if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
18099
+ walk(childPath, [...namespaces, ent.name]);
18100
+ continue;
18101
+ }
18102
+ if (!ent.name.endsWith(".md")) continue;
18103
+ const baseName = ent.name.replace(/\.md$/, "");
18104
+ const nameParts = [pluginName, ...namespaces, baseName];
18105
+ const name = nameParts.join(":");
18106
+ if (seen.has(name)) continue;
18107
+ seen.add(name);
18108
+ const { description, whenToUse } = parseAgentFile(childPath);
18109
+ out.push({
18110
+ name,
18111
+ source: "plugin",
18112
+ path: childPath,
18113
+ plugin: pluginName,
18114
+ ...description ? { description } : {},
18115
+ ...whenToUse ? { whenToUse } : {}
18116
+ });
18117
+ }
18118
+ }
18119
+ walk(root, []);
18120
+ }
18121
+ function readInstalledPlugins2(home) {
18122
+ const pluginsDir = import_node_path9.default.join(home, ".claude", "plugins");
18123
+ const v2 = import_node_path9.default.join(pluginsDir, "installed_plugins_v2.json");
18124
+ const v1 = import_node_path9.default.join(pluginsDir, "installed_plugins.json");
18125
+ let raw = null;
18126
+ for (const candidate of [v2, v1]) {
18127
+ try {
18128
+ raw = import_node_fs10.default.readFileSync(candidate, "utf8");
18129
+ break;
18130
+ } catch {
18131
+ }
18132
+ }
18133
+ if (!raw) return [];
18134
+ let parsed;
18135
+ try {
18136
+ parsed = JSON.parse(raw);
18137
+ } catch {
18138
+ return [];
18139
+ }
18140
+ const out = [];
18141
+ for (const [key, entries] of Object.entries(parsed.plugins ?? {})) {
18142
+ if (!Array.isArray(entries) || entries.length === 0) continue;
18143
+ const entry = entries[0];
18144
+ if (!entry?.installPath) continue;
18145
+ if (entry.enabled === false) continue;
18146
+ const pluginName = key.includes("@") ? key.slice(0, key.indexOf("@")) : key;
18147
+ if (!pluginName) continue;
18148
+ out.push({ name: pluginName, root: entry.installPath });
18149
+ }
18150
+ return out;
18151
+ }
18152
+ function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
18153
+ let cur = import_node_path9.default.resolve(startCwd);
18154
+ const fsRoot = import_node_path9.default.parse(cur).root;
18155
+ while (true) {
18156
+ scanAgentsDir(import_node_path9.default.join(cur, ".claude", "agents"), "project", seen, out);
18157
+ let hasGit = false;
18158
+ try {
18159
+ hasGit = import_node_fs10.default.existsSync(import_node_path9.default.join(cur, ".git"));
18160
+ } catch {
18161
+ }
18162
+ if (hasGit) return;
18163
+ if (cur === home) return;
18164
+ if (cur === fsRoot) return;
18165
+ const parent = import_node_path9.default.dirname(cur);
18166
+ if (parent === cur) return;
18167
+ cur = parent;
18168
+ }
18169
+ }
18170
+ var AgentsScanner = class {
18171
+ home;
18172
+ extraPluginRoots;
18173
+ policyDir;
18174
+ constructor(opts = {}) {
18175
+ this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os6.default.homedir();
18176
+ this.extraPluginRoots = opts.extraPluginRoots ?? [];
18177
+ if (opts.policyDir !== void 0) {
18178
+ this.policyDir = opts.policyDir;
18179
+ } else if (process.platform === "darwin") {
18180
+ this.policyDir = DEFAULT_POLICY_DIR_DARWIN;
18181
+ } else {
18182
+ this.policyDir = null;
18183
+ }
18184
+ }
18185
+ list(args) {
18186
+ const seen = /* @__PURE__ */ new Set();
18187
+ const builtinBlock = [];
18188
+ for (const b of BUILTIN_AGENTS) {
18189
+ if (seen.has(b.name)) continue;
18190
+ seen.add(b.name);
18191
+ builtinBlock.push({
18192
+ name: b.name,
18193
+ source: "builtin",
18194
+ ...b.description ? { description: b.description } : {},
18195
+ ...b.whenToUse ? { whenToUse: b.whenToUse } : {}
18196
+ });
18197
+ }
18198
+ const fsBlock = [];
18199
+ scanAgentsDir(
18200
+ import_node_path9.default.join(this.home, ".claude", "agents"),
18201
+ "global",
18202
+ seen,
18203
+ fsBlock
18204
+ );
18205
+ walkUpProjectAgentsDirs(args.cwd, this.home, seen, fsBlock);
18206
+ if (this.policyDir) {
18207
+ scanAgentsDir(this.policyDir, "policy", seen, fsBlock);
18208
+ }
18209
+ const plugins = [
18210
+ ...readInstalledPlugins2(this.home),
18211
+ ...this.extraPluginRoots
18212
+ ];
18213
+ for (const { name, root } of plugins) {
18214
+ const agentsRoot = import_node_path9.default.join(root, "agents");
18215
+ scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
18216
+ }
18217
+ return [...builtinBlock, ...fsBlock];
18218
+ }
18219
+ };
18220
+
18221
+ // src/observer/session-observer.ts
18222
+ var import_node_fs11 = __toESM(require("fs"), 1);
18223
+ var import_node_os7 = __toESM(require("os"), 1);
18224
+ var import_node_path10 = __toESM(require("path"), 1);
17934
18225
  init_claude_history();
17935
18226
  var SessionObserver = class {
17936
18227
  constructor(opts) {
17937
18228
  this.opts = opts;
17938
- this.home = opts.home ?? import_node_os6.default.homedir();
18229
+ this.home = opts.home ?? import_node_os7.default.homedir();
17939
18230
  }
17940
18231
  opts;
17941
18232
  home;
17942
18233
  watches = /* @__PURE__ */ new Map();
17943
18234
  resolveJsonlPath(cwd, toolSessionId, override) {
17944
18235
  if (override) return override;
17945
- return import_node_path9.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
18236
+ return import_node_path10.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
17946
18237
  }
17947
18238
  start(args) {
17948
18239
  this.stop(args.sessionId);
17949
18240
  const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
17950
18241
  let size = 0;
17951
18242
  try {
17952
- size = import_node_fs10.default.statSync(filePath).size;
18243
+ size = import_node_fs11.default.statSync(filePath).size;
17953
18244
  } catch {
17954
18245
  }
17955
18246
  const w = {
@@ -17962,10 +18253,10 @@ var SessionObserver = class {
17962
18253
  adapter: args.adapter
17963
18254
  };
17964
18255
  try {
17965
- import_node_fs10.default.mkdirSync(import_node_path9.default.dirname(filePath), { recursive: true });
18256
+ import_node_fs11.default.mkdirSync(import_node_path10.default.dirname(filePath), { recursive: true });
17966
18257
  } catch {
17967
18258
  }
17968
- w.watcher = import_node_fs10.default.watch(import_node_path9.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
18259
+ w.watcher = import_node_fs11.default.watch(import_node_path10.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
17969
18260
  if (!changedName || !filePath.endsWith(changedName)) return;
17970
18261
  this.poll(w);
17971
18262
  });
@@ -17980,7 +18271,7 @@ var SessionObserver = class {
17980
18271
  // reducer.shallowEqMeta diff 让重复 patch 静默吞掉;异常静默吞,不阻塞 watcher 启动
17981
18272
  hydrateMetaTail(w, maxLines = 200) {
17982
18273
  try {
17983
- const raw = import_node_fs10.default.readFileSync(w.filePath, "utf8");
18274
+ const raw = import_node_fs11.default.readFileSync(w.filePath, "utf8");
17984
18275
  if (!raw) return;
17985
18276
  const allLines = raw.split("\n").filter((l) => l.trim().length > 0);
17986
18277
  if (allLines.length === 0) return;
@@ -18001,7 +18292,7 @@ var SessionObserver = class {
18001
18292
  poll(w) {
18002
18293
  let size = 0;
18003
18294
  try {
18004
- size = import_node_fs10.default.statSync(w.filePath).size;
18295
+ size = import_node_fs11.default.statSync(w.filePath).size;
18005
18296
  } catch {
18006
18297
  return;
18007
18298
  }
@@ -18010,11 +18301,11 @@ var SessionObserver = class {
18010
18301
  w.buf = "";
18011
18302
  }
18012
18303
  if (size === w.lastSize) return;
18013
- const fd = import_node_fs10.default.openSync(w.filePath, "r");
18304
+ const fd = import_node_fs11.default.openSync(w.filePath, "r");
18014
18305
  try {
18015
18306
  const len = size - w.lastSize;
18016
18307
  const buf = Buffer.alloc(len);
18017
- import_node_fs10.default.readSync(fd, buf, 0, len, w.lastSize);
18308
+ import_node_fs11.default.readSync(fd, buf, 0, len, w.lastSize);
18018
18309
  w.lastSize = size;
18019
18310
  w.buf += buf.toString("utf8");
18020
18311
  let newlineIndex;
@@ -18028,7 +18319,7 @@ var SessionObserver = class {
18028
18319
  this.maybeReportUserMessage(w.sessionId, line);
18029
18320
  }
18030
18321
  } finally {
18031
- import_node_fs10.default.closeSync(fd);
18322
+ import_node_fs11.default.closeSync(fd);
18032
18323
  }
18033
18324
  }
18034
18325
  // 解析 JSONL 单行:仅当是主链 user 文本行(非 sidechain / 非 sub-agent / message.role='user'
@@ -18680,10 +18971,10 @@ function isLocalhost(addr) {
18680
18971
  }
18681
18972
 
18682
18973
  // src/discovery/state-file.ts
18683
- var import_node_fs11 = __toESM(require("fs"), 1);
18684
- var import_node_path10 = __toESM(require("path"), 1);
18974
+ var import_node_fs12 = __toESM(require("fs"), 1);
18975
+ var import_node_path11 = __toESM(require("path"), 1);
18685
18976
  function defaultStateFilePath(dataDir) {
18686
- return import_node_path10.default.join(dataDir, "state.json");
18977
+ return import_node_path11.default.join(dataDir, "state.json");
18687
18978
  }
18688
18979
  function isPidAlive(pid) {
18689
18980
  if (!Number.isFinite(pid) || pid <= 0) return false;
@@ -18705,7 +18996,7 @@ var StateFileManager = class {
18705
18996
  }
18706
18997
  read() {
18707
18998
  try {
18708
- const raw = import_node_fs11.default.readFileSync(this.file, "utf8");
18999
+ const raw = import_node_fs12.default.readFileSync(this.file, "utf8");
18709
19000
  const parsed = JSON.parse(raw);
18710
19001
  return parsed;
18711
19002
  } catch {
@@ -18719,34 +19010,34 @@ var StateFileManager = class {
18719
19010
  return { status: "stale", existing };
18720
19011
  }
18721
19012
  write(state) {
18722
- import_node_fs11.default.mkdirSync(import_node_path10.default.dirname(this.file), { recursive: true });
19013
+ import_node_fs12.default.mkdirSync(import_node_path11.default.dirname(this.file), { recursive: true });
18723
19014
  const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
18724
- import_node_fs11.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
18725
- import_node_fs11.default.renameSync(tmp, this.file);
19015
+ import_node_fs12.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
19016
+ import_node_fs12.default.renameSync(tmp, this.file);
18726
19017
  if (process.platform !== "win32") {
18727
19018
  try {
18728
- import_node_fs11.default.chmodSync(this.file, 384);
19019
+ import_node_fs12.default.chmodSync(this.file, 384);
18729
19020
  } catch {
18730
19021
  }
18731
19022
  }
18732
19023
  }
18733
19024
  delete() {
18734
19025
  try {
18735
- import_node_fs11.default.unlinkSync(this.file);
19026
+ import_node_fs12.default.unlinkSync(this.file);
18736
19027
  } catch {
18737
19028
  }
18738
19029
  }
18739
19030
  };
18740
19031
 
18741
19032
  // src/tunnel/tunnel-manager.ts
18742
- var import_node_fs14 = __toESM(require("fs"), 1);
18743
- var import_node_path13 = __toESM(require("path"), 1);
19033
+ var import_node_fs15 = __toESM(require("fs"), 1);
19034
+ var import_node_path14 = __toESM(require("path"), 1);
18744
19035
  var import_node_crypto4 = __toESM(require("crypto"), 1);
18745
19036
  var import_node_child_process4 = require("child_process");
18746
19037
 
18747
19038
  // src/tunnel/tunnel-store.ts
18748
- var import_node_fs12 = __toESM(require("fs"), 1);
18749
- var import_node_path11 = __toESM(require("path"), 1);
19039
+ var import_node_fs13 = __toESM(require("fs"), 1);
19040
+ var import_node_path12 = __toESM(require("path"), 1);
18750
19041
  var TunnelStore = class {
18751
19042
  constructor(filePath) {
18752
19043
  this.filePath = filePath;
@@ -18754,7 +19045,7 @@ var TunnelStore = class {
18754
19045
  filePath;
18755
19046
  async get() {
18756
19047
  try {
18757
- const raw = await import_node_fs12.default.promises.readFile(this.filePath, "utf8");
19048
+ const raw = await import_node_fs13.default.promises.readFile(this.filePath, "utf8");
18758
19049
  const obj = JSON.parse(raw);
18759
19050
  if (!isPersistedTunnel(obj)) return null;
18760
19051
  return obj;
@@ -18765,22 +19056,22 @@ var TunnelStore = class {
18765
19056
  }
18766
19057
  }
18767
19058
  async set(v) {
18768
- const dir = import_node_path11.default.dirname(this.filePath);
18769
- await import_node_fs12.default.promises.mkdir(dir, { recursive: true });
19059
+ const dir = import_node_path12.default.dirname(this.filePath);
19060
+ await import_node_fs13.default.promises.mkdir(dir, { recursive: true });
18770
19061
  const data = JSON.stringify(v, null, 2);
18771
19062
  const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
18772
- await import_node_fs12.default.promises.writeFile(tmp, data, { mode: 384 });
19063
+ await import_node_fs13.default.promises.writeFile(tmp, data, { mode: 384 });
18773
19064
  if (process.platform !== "win32") {
18774
19065
  try {
18775
- await import_node_fs12.default.promises.chmod(tmp, 384);
19066
+ await import_node_fs13.default.promises.chmod(tmp, 384);
18776
19067
  } catch {
18777
19068
  }
18778
19069
  }
18779
- await import_node_fs12.default.promises.rename(tmp, this.filePath);
19070
+ await import_node_fs13.default.promises.rename(tmp, this.filePath);
18780
19071
  }
18781
19072
  async clear() {
18782
19073
  try {
18783
- await import_node_fs12.default.promises.unlink(this.filePath);
19074
+ await import_node_fs13.default.promises.unlink(this.filePath);
18784
19075
  } catch (err) {
18785
19076
  const code = err?.code;
18786
19077
  if (code !== "ENOENT") throw err;
@@ -18875,9 +19166,9 @@ function escape(v) {
18875
19166
  }
18876
19167
 
18877
19168
  // src/tunnel/frpc-binary.ts
18878
- var import_node_fs13 = __toESM(require("fs"), 1);
18879
- var import_node_os7 = __toESM(require("os"), 1);
18880
- var import_node_path12 = __toESM(require("path"), 1);
19169
+ var import_node_fs14 = __toESM(require("fs"), 1);
19170
+ var import_node_os8 = __toESM(require("os"), 1);
19171
+ var import_node_path13 = __toESM(require("path"), 1);
18881
19172
  var import_node_child_process3 = require("child_process");
18882
19173
  var import_node_stream = require("stream");
18883
19174
  var import_promises = require("stream/promises");
@@ -18909,20 +19200,20 @@ function frpcDownloadUrl(version2, p) {
18909
19200
  }
18910
19201
  async function ensureFrpcBinary(opts) {
18911
19202
  if (opts.override) {
18912
- if (!import_node_fs13.default.existsSync(opts.override)) {
19203
+ if (!import_node_fs14.default.existsSync(opts.override)) {
18913
19204
  throw new Error(`frpc binary not found at override path: ${opts.override}`);
18914
19205
  }
18915
19206
  return opts.override;
18916
19207
  }
18917
19208
  const version2 = opts.version ?? FRPC_VERSION;
18918
19209
  const platform = opts.platform ?? detectPlatform();
18919
- const binDir = import_node_path12.default.join(opts.dataDir, "bin");
18920
- import_node_fs13.default.mkdirSync(binDir, { recursive: true });
19210
+ const binDir = import_node_path13.default.join(opts.dataDir, "bin");
19211
+ import_node_fs14.default.mkdirSync(binDir, { recursive: true });
18921
19212
  cleanupStaleArtifacts(binDir);
18922
- const stableBin = import_node_path12.default.join(binDir, "frpc");
18923
- if (import_node_fs13.default.existsSync(stableBin)) return stableBin;
19213
+ const stableBin = import_node_path13.default.join(binDir, "frpc");
19214
+ if (import_node_fs14.default.existsSync(stableBin)) return stableBin;
18924
19215
  const partialBin = `${stableBin}.partial`;
18925
- const tarballPath = import_node_path12.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
19216
+ const tarballPath = import_node_path13.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
18926
19217
  try {
18927
19218
  const url = frpcDownloadUrl(version2, platform);
18928
19219
  await downloadToFile(url, tarballPath, opts.fetchImpl);
@@ -18931,8 +19222,8 @@ async function ensureFrpcBinary(opts) {
18931
19222
  } else {
18932
19223
  await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
18933
19224
  }
18934
- import_node_fs13.default.chmodSync(partialBin, 493);
18935
- import_node_fs13.default.renameSync(partialBin, stableBin);
19225
+ import_node_fs14.default.chmodSync(partialBin, 493);
19226
+ import_node_fs14.default.renameSync(partialBin, stableBin);
18936
19227
  } finally {
18937
19228
  safeUnlink(tarballPath);
18938
19229
  safeUnlink(partialBin);
@@ -18942,15 +19233,15 @@ async function ensureFrpcBinary(opts) {
18942
19233
  function cleanupStaleArtifacts(binDir) {
18943
19234
  let entries;
18944
19235
  try {
18945
- entries = import_node_fs13.default.readdirSync(binDir);
19236
+ entries = import_node_fs14.default.readdirSync(binDir);
18946
19237
  } catch {
18947
19238
  return;
18948
19239
  }
18949
19240
  for (const name of entries) {
18950
19241
  if (name.endsWith(".partial") || name.startsWith("extract-")) {
18951
- const full = import_node_path12.default.join(binDir, name);
19242
+ const full = import_node_path13.default.join(binDir, name);
18952
19243
  try {
18953
- import_node_fs13.default.rmSync(full, { recursive: true, force: true });
19244
+ import_node_fs14.default.rmSync(full, { recursive: true, force: true });
18954
19245
  } catch {
18955
19246
  }
18956
19247
  }
@@ -18958,7 +19249,7 @@ function cleanupStaleArtifacts(binDir) {
18958
19249
  }
18959
19250
  function safeUnlink(p) {
18960
19251
  try {
18961
- import_node_fs13.default.unlinkSync(p);
19252
+ import_node_fs14.default.unlinkSync(p);
18962
19253
  } catch {
18963
19254
  }
18964
19255
  }
@@ -18969,13 +19260,13 @@ async function downloadToFile(url, dest, fetchImpl) {
18969
19260
  if (!res.ok || !res.body) {
18970
19261
  throw new Error(`download failed: ${res.status} ${res.statusText}`);
18971
19262
  }
18972
- const out = import_node_fs13.default.createWriteStream(dest);
19263
+ const out = import_node_fs14.default.createWriteStream(dest);
18973
19264
  const nodeStream = import_node_stream.Readable.fromWeb(res.body);
18974
19265
  await (0, import_promises.pipeline)(nodeStream, out);
18975
19266
  }
18976
19267
  async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
18977
- const work = import_node_path12.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
18978
- import_node_fs13.default.mkdirSync(work, { recursive: true });
19268
+ const work = import_node_path13.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
19269
+ import_node_fs14.default.mkdirSync(work, { recursive: true });
18979
19270
  try {
18980
19271
  await new Promise((resolve, reject) => {
18981
19272
  const proc = (0, import_node_child_process3.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
@@ -18983,13 +19274,13 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
18983
19274
  proc.on("exit", (code) => code === 0 ? resolve() : reject(new Error(`tar exited ${code}`)));
18984
19275
  });
18985
19276
  const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
18986
- const src = import_node_path12.default.join(work, dirName, "frpc");
18987
- if (!import_node_fs13.default.existsSync(src)) {
19277
+ const src = import_node_path13.default.join(work, dirName, "frpc");
19278
+ if (!import_node_fs14.default.existsSync(src)) {
18988
19279
  throw new Error(`frpc not found inside tarball at ${src}`);
18989
19280
  }
18990
- import_node_fs13.default.copyFileSync(src, destBin);
19281
+ import_node_fs14.default.copyFileSync(src, destBin);
18991
19282
  } finally {
18992
- import_node_fs13.default.rmSync(work, { recursive: true, force: true });
19283
+ import_node_fs14.default.rmSync(work, { recursive: true, force: true });
18993
19284
  }
18994
19285
  }
18995
19286
 
@@ -18998,7 +19289,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
18998
19289
  var TunnelManager = class {
18999
19290
  constructor(deps) {
19000
19291
  this.deps = deps;
19001
- this.store = deps.store ?? new TunnelStore(import_node_path13.default.join(deps.dataDir, "tunnel.json"));
19292
+ this.store = deps.store ?? new TunnelStore(import_node_path14.default.join(deps.dataDir, "tunnel.json"));
19002
19293
  this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
19003
19294
  this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
19004
19295
  }
@@ -19115,7 +19406,7 @@ var TunnelManager = class {
19115
19406
  dataDir: this.deps.dataDir,
19116
19407
  override: this.deps.frpcBinaryOverride ?? void 0
19117
19408
  });
19118
- const tomlPath = import_node_path13.default.join(this.deps.dataDir, "frpc.toml");
19409
+ const tomlPath = import_node_path14.default.join(this.deps.dataDir, "frpc.toml");
19119
19410
  const proxyName = `clawd-${t.subdomain}-${localPort}-${import_node_crypto4.default.randomBytes(3).toString("hex")}`;
19120
19411
  const toml = buildFrpcToml({
19121
19412
  serverAddr: t.frpsHost,
@@ -19126,12 +19417,12 @@ var TunnelManager = class {
19126
19417
  localPort,
19127
19418
  logLevel: "info"
19128
19419
  });
19129
- await import_node_fs14.default.promises.writeFile(tomlPath, toml, { mode: 384 });
19420
+ await import_node_fs15.default.promises.writeFile(tomlPath, toml, { mode: 384 });
19130
19421
  const proc = (this.deps.spawnImpl ?? import_node_child_process4.spawn)(frpcBin, ["-c", tomlPath], {
19131
19422
  stdio: ["ignore", "pipe", "pipe"]
19132
19423
  });
19133
- const logFilePath = import_node_path13.default.join(this.deps.dataDir, "frpc.log");
19134
- const logStream = import_node_fs14.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
19424
+ const logFilePath = import_node_path14.default.join(this.deps.dataDir, "frpc.log");
19425
+ const logStream = import_node_fs15.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
19135
19426
  logStream.on("error", () => {
19136
19427
  });
19137
19428
  const tee = (chunk) => {
@@ -19212,23 +19503,23 @@ async function waitForFrpcReady(proc, timeoutMs) {
19212
19503
  }
19213
19504
 
19214
19505
  // src/tunnel/device-key.ts
19215
- var import_node_os8 = __toESM(require("os"), 1);
19506
+ var import_node_os9 = __toESM(require("os"), 1);
19216
19507
  var import_node_crypto5 = __toESM(require("crypto"), 1);
19217
19508
  var DERIVE_SALT = "clawd-tunnel-device-v1";
19218
19509
  function deriveStableDeviceKey(opts = {}) {
19219
- const hostname = opts.hostname ?? import_node_os8.default.hostname();
19220
- const uid = opts.uid ?? (typeof import_node_os8.default.userInfo === "function" ? import_node_os8.default.userInfo().uid : 0);
19510
+ const hostname = opts.hostname ?? import_node_os9.default.hostname();
19511
+ const uid = opts.uid ?? (typeof import_node_os9.default.userInfo === "function" ? import_node_os9.default.userInfo().uid : 0);
19221
19512
  const input = `${hostname}::${uid}`;
19222
19513
  return import_node_crypto5.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
19223
19514
  }
19224
19515
 
19225
19516
  // src/auth-store.ts
19226
- var import_node_fs15 = __toESM(require("fs"), 1);
19227
- var import_node_path14 = __toESM(require("path"), 1);
19517
+ var import_node_fs16 = __toESM(require("fs"), 1);
19518
+ var import_node_path15 = __toESM(require("path"), 1);
19228
19519
  var import_node_crypto6 = __toESM(require("crypto"), 1);
19229
19520
  var AUTH_FILE_NAME = "auth.json";
19230
19521
  function authFilePath(dataDir) {
19231
- return import_node_path14.default.join(dataDir, AUTH_FILE_NAME);
19522
+ return import_node_path15.default.join(dataDir, AUTH_FILE_NAME);
19232
19523
  }
19233
19524
  function loadOrCreateAuthToken(opts) {
19234
19525
  const file = authFilePath(opts.dataDir);
@@ -19244,7 +19535,7 @@ function defaultGenerate() {
19244
19535
  }
19245
19536
  function readAuthFile(file) {
19246
19537
  try {
19247
- const raw = import_node_fs15.default.readFileSync(file, "utf8");
19538
+ const raw = import_node_fs16.default.readFileSync(file, "utf8");
19248
19539
  const parsed = JSON.parse(raw);
19249
19540
  if (typeof parsed?.token === "string" && parsed.token.length > 0) {
19250
19541
  return {
@@ -19260,10 +19551,10 @@ function readAuthFile(file) {
19260
19551
  }
19261
19552
  }
19262
19553
  function writeAuthFile(file, content) {
19263
- import_node_fs15.default.mkdirSync(import_node_path14.default.dirname(file), { recursive: true });
19264
- import_node_fs15.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
19554
+ import_node_fs16.default.mkdirSync(import_node_path15.default.dirname(file), { recursive: true });
19555
+ import_node_fs16.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
19265
19556
  try {
19266
- import_node_fs15.default.chmodSync(file, 384);
19557
+ import_node_fs16.default.chmodSync(file, 384);
19267
19558
  } catch {
19268
19559
  }
19269
19560
  }
@@ -19275,12 +19566,12 @@ init_protocol();
19275
19566
  init_protocol();
19276
19567
 
19277
19568
  // src/session/fork.ts
19278
- var import_node_fs16 = __toESM(require("fs"), 1);
19279
- var import_node_os9 = __toESM(require("os"), 1);
19280
- var import_node_path15 = __toESM(require("path"), 1);
19569
+ var import_node_fs17 = __toESM(require("fs"), 1);
19570
+ var import_node_os10 = __toESM(require("os"), 1);
19571
+ var import_node_path16 = __toESM(require("path"), 1);
19281
19572
  init_claude_history();
19282
19573
  function readJsonlEntries(file) {
19283
- const raw = import_node_fs16.default.readFileSync(file, "utf8");
19574
+ const raw = import_node_fs17.default.readFileSync(file, "utf8");
19284
19575
  const out = [];
19285
19576
  for (const line of raw.split("\n")) {
19286
19577
  const t = line.trim();
@@ -19293,10 +19584,10 @@ function readJsonlEntries(file) {
19293
19584
  return out;
19294
19585
  }
19295
19586
  function forkSession(input) {
19296
- const baseDir = input.baseDir ?? import_node_path15.default.join(import_node_os9.default.homedir(), ".claude");
19297
- const projectDir = import_node_path15.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
19298
- const sourceFile = import_node_path15.default.join(projectDir, `${input.toolSessionId}.jsonl`);
19299
- if (!import_node_fs16.default.existsSync(sourceFile)) {
19587
+ const baseDir = input.baseDir ?? import_node_path16.default.join(import_node_os10.default.homedir(), ".claude");
19588
+ const projectDir = import_node_path16.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
19589
+ const sourceFile = import_node_path16.default.join(projectDir, `${input.toolSessionId}.jsonl`);
19590
+ if (!import_node_fs17.default.existsSync(sourceFile)) {
19300
19591
  throw new Error(`fork: source transcript not found: ${sourceFile}`);
19301
19592
  }
19302
19593
  const entries = readJsonlEntries(sourceFile);
@@ -19326,9 +19617,9 @@ function forkSession(input) {
19326
19617
  }
19327
19618
  forkedLines.push(JSON.stringify(forked));
19328
19619
  }
19329
- const forkedFilePath = import_node_path15.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
19330
- import_node_fs16.default.mkdirSync(projectDir, { recursive: true });
19331
- import_node_fs16.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
19620
+ const forkedFilePath = import_node_path16.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
19621
+ import_node_fs17.default.mkdirSync(projectDir, { recursive: true });
19622
+ import_node_fs17.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
19332
19623
  return { forkedToolSessionId, forkedFilePath };
19333
19624
  }
19334
19625
 
@@ -19570,7 +19861,7 @@ function buildHistoryHandlers(deps) {
19570
19861
  // src/handlers/workspace.ts
19571
19862
  init_protocol();
19572
19863
  function buildWorkspaceHandlers(deps) {
19573
- const { workspace, skills } = deps;
19864
+ const { workspace, skills, agents } = deps;
19574
19865
  const list = async (frame) => {
19575
19866
  const args = WorkspaceListArgs.parse(frame);
19576
19867
  const res = workspace.list(args);
@@ -19586,10 +19877,16 @@ function buildWorkspaceHandlers(deps) {
19586
19877
  const list2 = skills.list(args);
19587
19878
  return { response: { type: "skills:list", skills: list2 } };
19588
19879
  };
19880
+ const agentsList = async (frame) => {
19881
+ const args = AgentsListArgs.parse(frame);
19882
+ const list2 = agents.list(args);
19883
+ return { response: { type: "agents:list", agents: list2 } };
19884
+ };
19589
19885
  return {
19590
19886
  "workspace:list": list,
19591
19887
  "workspace:read": read,
19592
- "skills:list": skillsList
19888
+ "skills:list": skillsList,
19889
+ "agents:list": agentsList
19593
19890
  };
19594
19891
  }
19595
19892
 
@@ -19598,9 +19895,9 @@ init_protocol();
19598
19895
 
19599
19896
  // src/workspace/git.ts
19600
19897
  var import_node_child_process5 = require("child_process");
19601
- var import_node_fs17 = __toESM(require("fs"), 1);
19602
- var import_node_os10 = __toESM(require("os"), 1);
19603
- var import_node_path16 = __toESM(require("path"), 1);
19898
+ var import_node_fs18 = __toESM(require("fs"), 1);
19899
+ var import_node_os11 = __toESM(require("os"), 1);
19900
+ var import_node_path17 = __toESM(require("path"), 1);
19604
19901
  var import_node_util = require("util");
19605
19902
  var pexec = (0, import_node_util.promisify)(import_node_child_process5.execFile);
19606
19903
  function formatChildProcessError(err) {
@@ -19615,9 +19912,9 @@ function formatChildProcessError(err) {
19615
19912
  return e.message ?? "unknown error";
19616
19913
  }
19617
19914
  function normalizePath(p) {
19618
- const resolved = import_node_path16.default.resolve(p);
19915
+ const resolved = import_node_path17.default.resolve(p);
19619
19916
  try {
19620
- return import_node_fs17.default.realpathSync(resolved);
19917
+ return import_node_fs18.default.realpathSync(resolved);
19621
19918
  } catch {
19622
19919
  return resolved;
19623
19920
  }
@@ -19704,7 +20001,7 @@ function sanitizeLabel(raw) {
19704
20001
  function computePrefix() {
19705
20002
  let username;
19706
20003
  try {
19707
- username = import_node_os10.default.userInfo().username;
20004
+ username = import_node_os11.default.userInfo().username;
19708
20005
  } catch {
19709
20006
  username = void 0;
19710
20007
  }
@@ -19718,13 +20015,13 @@ function flattenToDirName(branch) {
19718
20015
  }
19719
20016
  function encodeClaudeProjectDir(absPath) {
19720
20017
  if (!absPath || typeof absPath !== "string") return "";
19721
- let canonical = import_node_path16.default.resolve(absPath);
20018
+ let canonical = import_node_path17.default.resolve(absPath);
19722
20019
  try {
19723
- canonical = import_node_fs17.default.realpathSync(canonical);
20020
+ canonical = import_node_fs18.default.realpathSync(canonical);
19724
20021
  } catch {
19725
20022
  try {
19726
- const parent = import_node_fs17.default.realpathSync(import_node_path16.default.dirname(canonical));
19727
- canonical = import_node_path16.default.join(parent, import_node_path16.default.basename(canonical));
20023
+ const parent = import_node_fs18.default.realpathSync(import_node_path17.default.dirname(canonical));
20024
+ canonical = import_node_path17.default.join(parent, import_node_path17.default.basename(canonical));
19728
20025
  } catch {
19729
20026
  }
19730
20027
  }
@@ -19748,11 +20045,11 @@ async function createWorktree(input) {
19748
20045
  if (!isGitRoot) {
19749
20046
  throw new Error(`\u76EE\u5F55 ${cwd} \u4E0D\u662F git repo \u6839`);
19750
20047
  }
19751
- const parent = import_node_path16.default.dirname(import_node_path16.default.resolve(cwd));
19752
- if (parent === "/" || parent === import_node_path16.default.resolve(cwd)) {
20048
+ const parent = import_node_path17.default.dirname(import_node_path17.default.resolve(cwd));
20049
+ if (parent === "/" || parent === import_node_path17.default.resolve(cwd)) {
19753
20050
  throw new Error("repo \u5728\u78C1\u76D8\u6839\u76EE\u5F55\uFF0C\u65E0\u6CD5\u5728\u540C\u7EA7\u521B\u5EFA worktree");
19754
20051
  }
19755
- const worktreeRoot = import_node_path16.default.join(parent, dirName);
20052
+ const worktreeRoot = import_node_path17.default.join(parent, dirName);
19756
20053
  try {
19757
20054
  await pexec("git", ["-C", cwd, "rev-parse", "--verify", `refs/heads/${baseBranch}`], {
19758
20055
  timeout: 3e3
@@ -19769,7 +20066,7 @@ async function createWorktree(input) {
19769
20066
  const msg = err.message;
19770
20067
  if (msg.startsWith("\u5206\u652F ")) throw err;
19771
20068
  }
19772
- if (import_node_fs17.default.existsSync(worktreeRoot)) {
20069
+ if (import_node_fs18.default.existsSync(worktreeRoot)) {
19773
20070
  throw new Error(`\u76EE\u5F55 ${worktreeRoot} \u5DF2\u5B58\u5728\uFF0C\u8BF7\u6362\u4E00\u4E2A label \u6216\u6E05\u7406\u540E\u91CD\u8BD5`);
19774
20071
  }
19775
20072
  try {
@@ -19797,8 +20094,8 @@ async function removeWorktree(input) {
19797
20094
  );
19798
20095
  const gitCommonDir = stdout.trim();
19799
20096
  if (!gitCommonDir) throw new Error("empty git-common-dir");
19800
- const absGitCommon = import_node_path16.default.isAbsolute(gitCommonDir) ? gitCommonDir : import_node_path16.default.resolve(worktreeRoot, gitCommonDir);
19801
- repoRoot = import_node_path16.default.dirname(absGitCommon);
20097
+ const absGitCommon = import_node_path17.default.isAbsolute(gitCommonDir) ? gitCommonDir : import_node_path17.default.resolve(worktreeRoot, gitCommonDir);
20098
+ repoRoot = import_node_path17.default.dirname(absGitCommon);
19802
20099
  } catch {
19803
20100
  repoRoot = null;
19804
20101
  }
@@ -19810,7 +20107,7 @@ async function removeWorktree(input) {
19810
20107
  } catch (err) {
19811
20108
  const stderr = err.stderr ?? "";
19812
20109
  const lower = stderr.toLowerCase();
19813
- const vanished = lower.includes("not a working tree") || lower.includes("is not a working tree") || !import_node_fs17.default.existsSync(worktreeRoot);
20110
+ const vanished = lower.includes("not a working tree") || lower.includes("is not a working tree") || !import_node_fs18.default.existsSync(worktreeRoot);
19814
20111
  if (!vanished) {
19815
20112
  throw new Error(`\u6E05\u7406 worktree \u5931\u8D25\uFF1A${formatChildProcessError(err)}`);
19816
20113
  }
@@ -19829,10 +20126,10 @@ async function removeWorktree(input) {
19829
20126
  try {
19830
20127
  const encoded = encodeClaudeProjectDir(worktreeRoot);
19831
20128
  if (encoded) {
19832
- const projectsRoot = import_node_path16.default.join(import_node_os10.default.homedir(), ".claude", "projects");
19833
- const target = import_node_path16.default.resolve(projectsRoot, encoded);
19834
- if (target.startsWith(projectsRoot + import_node_path16.default.sep) && target !== projectsRoot) {
19835
- import_node_fs17.default.rmSync(target, { recursive: true, force: true });
20129
+ const projectsRoot = import_node_path17.default.join(import_node_os11.default.homedir(), ".claude", "projects");
20130
+ const target = import_node_path17.default.resolve(projectsRoot, encoded);
20131
+ if (target.startsWith(projectsRoot + import_node_path17.default.sep) && target !== projectsRoot) {
20132
+ import_node_fs18.default.rmSync(target, { recursive: true, force: true });
19836
20133
  }
19837
20134
  }
19838
20135
  } catch {
@@ -19904,7 +20201,7 @@ function buildCapabilitiesHandlers(deps) {
19904
20201
  }
19905
20202
 
19906
20203
  // src/handlers/meta.ts
19907
- var import_node_os11 = __toESM(require("os"), 1);
20204
+ var import_node_os12 = __toESM(require("os"), 1);
19908
20205
  init_protocol();
19909
20206
 
19910
20207
  // src/version.ts
@@ -19926,7 +20223,7 @@ function buildReadyFrame(deps) {
19926
20223
  return {
19927
20224
  version,
19928
20225
  protocolVersion: PROTOCOL_VERSION,
19929
- hostname: import_node_os11.default.hostname(),
20226
+ hostname: import_node_os12.default.hostname(),
19930
20227
  os: process.platform,
19931
20228
  tools,
19932
20229
  runningSessions: info.runningSessions,
@@ -20044,7 +20341,7 @@ function buildMethodHandlers(deps) {
20044
20341
  async function startDaemon(config) {
20045
20342
  const logger = createLogger({
20046
20343
  level: config.logLevel,
20047
- file: import_node_path17.default.join(config.dataDir, "clawd.log")
20344
+ file: import_node_path18.default.join(config.dataDir, "clawd.log")
20048
20345
  });
20049
20346
  logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
20050
20347
  const stateMgr = new StateFileManager({ dataDir: config.dataDir });
@@ -20077,6 +20374,7 @@ async function startDaemon(config) {
20077
20374
  const store = new SessionStore({ dataDir: config.dataDir });
20078
20375
  const workspace = new WorkspaceBrowser();
20079
20376
  const skills = new SkillsScanner();
20377
+ const agents = new AgentsScanner();
20080
20378
  const history = new ClaudeHistoryReader();
20081
20379
  let transport = null;
20082
20380
  const manager = new SessionManager({
@@ -20085,7 +20383,7 @@ async function startDaemon(config) {
20085
20383
  getAdapter,
20086
20384
  historyReader: history,
20087
20385
  dataDir: config.dataDir,
20088
- personaRoot: import_node_path17.default.join(config.dataDir, "personas"),
20386
+ personaRoot: import_node_path18.default.join(config.dataDir, "personas"),
20089
20387
  broadcastFrame: (frame, target) => {
20090
20388
  if (target === "all") {
20091
20389
  transport?.broadcastAll(frame);
@@ -20125,7 +20423,7 @@ async function startDaemon(config) {
20125
20423
  manager.recordRealUserUuid({ sessionId, realUuid, text });
20126
20424
  }
20127
20425
  });
20128
- const personaStore = new PersonaStore(import_node_path17.default.join(config.dataDir, "personas"));
20426
+ const personaStore = new PersonaStore(import_node_path18.default.join(config.dataDir, "personas"));
20129
20427
  const personaRegistry = new PersonaRegistry(personaStore);
20130
20428
  const personaManager = new PersonaManager({
20131
20429
  store: personaStore,
@@ -20137,6 +20435,7 @@ async function startDaemon(config) {
20137
20435
  manager,
20138
20436
  workspace,
20139
20437
  skills,
20438
+ agents,
20140
20439
  history,
20141
20440
  observer,
20142
20441
  getAdapter,
@@ -20257,8 +20556,8 @@ async function startDaemon(config) {
20257
20556
  const lines = [
20258
20557
  `Tunnel: ${r.url}`,
20259
20558
  ...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
20260
- `Frpc config: ${import_node_path17.default.join(config.dataDir, "frpc.toml")}`,
20261
- `Frpc log: ${import_node_path17.default.join(config.dataDir, "frpc.log")}`
20559
+ `Frpc config: ${import_node_path18.default.join(config.dataDir, "frpc.toml")}`,
20560
+ `Frpc log: ${import_node_path18.default.join(config.dataDir, "frpc.log")}`
20262
20561
  ];
20263
20562
  const width = Math.max(...lines.map((l) => l.length));
20264
20563
  const bar = "\u2550".repeat(width + 4);
@@ -20271,8 +20570,8 @@ ${bar}
20271
20570
 
20272
20571
  `);
20273
20572
  try {
20274
- const connectPath = import_node_path17.default.join(config.dataDir, "connect.txt");
20275
- import_node_fs18.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
20573
+ const connectPath = import_node_path18.default.join(config.dataDir, "connect.txt");
20574
+ import_node_fs19.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
20276
20575
  } catch {
20277
20576
  }
20278
20577
  } catch (err) {