@clawos-dev/clawd 0.2.376 → 0.2.378

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs CHANGED
@@ -450,8 +450,8 @@ var init_parseUtil = __esm({
450
450
  init_errors();
451
451
  init_en();
452
452
  makeIssue = (params) => {
453
- const { data, path: path86, errorMaps, issueData } = params;
454
- const fullPath = [...path86, ...issueData.path || []];
453
+ const { data, path: path87, errorMaps, issueData } = params;
454
+ const fullPath = [...path87, ...issueData.path || []];
455
455
  const fullIssue = {
456
456
  ...issueData,
457
457
  path: fullPath
@@ -762,11 +762,11 @@ var init_types = __esm({
762
762
  init_parseUtil();
763
763
  init_util();
764
764
  ParseInputLazyPath = class {
765
- constructor(parent, value, path86, key) {
765
+ constructor(parent, value, path87, key) {
766
766
  this._cachedPath = [];
767
767
  this.parent = parent;
768
768
  this.data = value;
769
- this._path = path86;
769
+ this._path = path87;
770
770
  this._key = key;
771
771
  }
772
772
  get path() {
@@ -6913,7 +6913,7 @@ var init_principal = __esm({
6913
6913
  });
6914
6914
 
6915
6915
  // ../protocol/src/schemas.ts
6916
- var SessionStatusSchema, UsageSchema, ContextUsageSchema, sessionMetaShape, SessionMetaSchema, SelectOptionSchema, ModelInfoSchema, ModeInfoSchema, ConfigFieldSchemaSchema, CapabilitiesGetArgs, ToolFeaturesSchema, CapabilitiesResponseSchema, AllowRuleSchema, SessionFileSchema, ParsedEventBase, HistoryUserMetaSchema, SubagentToolStatsSchema, StructuredPatchHunkSchema, ToolResultExtraSchema, MemoryEntrySchema, AskQuestionOptionSchema, AskQuestionItemSchema, TURN_END_REASONS, ParsedEventSchema, SessionCreateArgs, ProjectEntry, ProjectCreateArgs, SessionImportExternalArgs, SessionListArgs, SessionIdArgs, SessionUpdateArgs, SessionSendArgs, SessionInterruptArgs, 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, SessionCurrentTurnSenderArgs, SessionSubscribeArgs, SessionPinArgs, SessionArchiveArgs, PeerSessionUpsertArgs, PeerSessionUpsertResponseSchema, PeerSessionRemoveArgs, PeerSessionRemoveResponseSchema, SessionReorderPinsArgs, GitRootArgs, GitRootResponseSchema, GitBranchArgs, GitBranchResponseSchema, GitBranchesArgs, GitBranchesResponseSchema, HistoryRecentDirsArgs, RecentDirEntrySchema, HistoryRecentDirsResponseSchema, SessionQuestionFrameSchema, SessionQuestionClearedFrameSchema, AnswerQuestionArgs, AnswerQuestionResponseSchema, CancelQuestionArgs, CancelQuestionResponseSchema, ClientInfoSchema, AuthRequestFrameSchema, AuthOkFrameSchema, DeviceConnectionEntrySchema, DeviceConnectionsResponseSchema, TunnelReadyEventSchema, TunnelExitedEventSchema, TunnelUnavailableEventSchema, InfoRunningSessionSchema, InfoResponseSchema, PROJECT_PORT_MIN, PROJECT_PORT_MAX, projectNameRegex, DEFAULT_DEV_COMMAND, ProjectMetadataSchema, PROJECT_STAGE_VALUES, ProjectStageSchema, ProjectWithStatusSchema, ListProjectsArgsSchema, ListProjectsResultSchema, GetProjectArgsSchema, GetProjectResultSchema, CreateProjectArgsSchema, CreateProjectResultSchema, DeleteProjectArgsSchema, DeleteProjectResultSchema, UpdateProjectPortArgsSchema, UpdateProjectPortResultSchema, SetProdUrlArgsSchema, SetProdUrlResultSchema, StartDevServerArgsSchema, StartDevServerResultSchema, ASSISTANT_REPORTABLE_STAGES, ReportStageArgsSchema, ReportStageResultSchema, StopDevServerArgsSchema, StopDevServerResultSchema, AppBuilderProjectUpdatedEventSchema, PublishArgsSchema, PublishResultSchema, DismissPublishJobArgsSchema, DismissPublishJobResultSchema, AppBuilderPublishProgressEventSchema, AppBuilderPublishFailedEventSchema;
6916
+ var SessionStatusSchema, UsageSchema, ContextUsageSchema, sessionMetaShape, SessionMetaSchema, SelectOptionSchema, ModelInfoSchema, ModeInfoSchema, ConfigFieldSchemaSchema, CapabilitiesGetArgs, ToolFeaturesSchema, CapabilitiesResponseSchema, AllowRuleSchema, SessionFileSchema, ParsedEventBase, HistoryUserMetaSchema, SubagentToolStatsSchema, StructuredPatchHunkSchema, ToolResultExtraSchema, MemoryEntrySchema, AskQuestionOptionSchema, AskQuestionItemSchema, TURN_END_REASONS, ParsedEventSchema, SessionCreateArgs, ProjectEntry, ProjectPatchArgs, ProjectRevealArgs, ProjectCreateArgs, SessionImportExternalArgs, SessionListArgs, SessionIdArgs, SessionUpdateArgs, SessionSendArgs, SessionInterruptArgs, 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, SessionCurrentTurnSenderArgs, SessionSubscribeArgs, SessionPinArgs, SessionArchiveArgs, PeerSessionUpsertArgs, PeerSessionUpsertResponseSchema, PeerSessionRemoveArgs, PeerSessionRemoveResponseSchema, SessionReorderPinsArgs, GitRootArgs, GitRootResponseSchema, GitBranchArgs, GitBranchResponseSchema, GitBranchesArgs, GitBranchesResponseSchema, HistoryRecentDirsArgs, RecentDirEntrySchema, HistoryRecentDirsResponseSchema, SessionQuestionFrameSchema, SessionQuestionClearedFrameSchema, AnswerQuestionArgs, AnswerQuestionResponseSchema, CancelQuestionArgs, CancelQuestionResponseSchema, ClientInfoSchema, AuthRequestFrameSchema, AuthOkFrameSchema, DeviceConnectionEntrySchema, DeviceConnectionsResponseSchema, TunnelReadyEventSchema, TunnelExitedEventSchema, TunnelUnavailableEventSchema, InfoRunningSessionSchema, InfoResponseSchema, PROJECT_PORT_MIN, PROJECT_PORT_MAX, projectNameRegex, DEFAULT_DEV_COMMAND, ProjectMetadataSchema, PROJECT_STAGE_VALUES, ProjectStageSchema, ProjectWithStatusSchema, ListProjectsArgsSchema, ListProjectsResultSchema, GetProjectArgsSchema, GetProjectResultSchema, CreateProjectArgsSchema, CreateProjectResultSchema, DeleteProjectArgsSchema, DeleteProjectResultSchema, UpdateProjectPortArgsSchema, UpdateProjectPortResultSchema, SetProdUrlArgsSchema, SetProdUrlResultSchema, StartDevServerArgsSchema, StartDevServerResultSchema, ASSISTANT_REPORTABLE_STAGES, ReportStageArgsSchema, ReportStageResultSchema, StopDevServerArgsSchema, StopDevServerResultSchema, AppBuilderProjectUpdatedEventSchema, PublishArgsSchema, PublishResultSchema, DismissPublishJobArgsSchema, DismissPublishJobResultSchema, AppBuilderPublishProgressEventSchema, AppBuilderPublishFailedEventSchema;
6917
6917
  var init_schemas = __esm({
6918
6918
  "../protocol/src/schemas.ts"() {
6919
6919
  "use strict";
@@ -7416,7 +7416,17 @@ var init_schemas = __esm({
7416
7416
  path: external_exports.string().min(1),
7417
7417
  /** 展示名,缺省 basename */
7418
7418
  name: external_exports.string().min(1),
7419
- createdAt: external_exports.string().datetime()
7419
+ createdAt: external_exports.string().datetime(),
7420
+ /** 置顶时间(ms epoch,与 SessionFile.pinnedAt 同语义)。clawd-local,不同步 Codex */
7421
+ pinnedAt: external_exports.number().optional()
7422
+ });
7423
+ ProjectPatchArgs = external_exports.object({
7424
+ path: external_exports.string().min(1),
7425
+ /** number = 置顶(ms epoch);null = 取消置顶 */
7426
+ pinnedAt: external_exports.number().nullable()
7427
+ });
7428
+ ProjectRevealArgs = external_exports.object({
7429
+ path: external_exports.string().min(1)
7420
7430
  });
7421
7431
  ProjectCreateArgs = external_exports.object({
7422
7432
  // 在现成目录上登记 project;不传则按 name 在 Codex 的 project 根下新建目录 + git init
@@ -8177,8 +8187,19 @@ var init_methods = __esm({
8177
8187
  args: NO_ARGS
8178
8188
  },
8179
8189
  "project:create": {
8180
- summary: "\u65B0\u5EFA project\uFF1A\u6821\u9A8C\u76EE\u5F55\u5B58\u5728 + \u975E ~/.clawd \u5B50\u6811\uFF0Cupsert \u8FDB ~/.clawd/projects.json\uFF08owner-only\uFF09",
8181
- args: ProjectCreateArgs
8190
+ summary: "\u65B0\u5EFA project\uFF1A\u6821\u9A8C\u76EE\u5F55\u5B58\u5728 + \u975E ~/.clawd \u5B50\u6811\uFF0Cupsert \u8FDB ~/.clawd/projects.json\uFF08owner-only\uFF09\u3002**path \u4E0E name \u81F3\u5C11\u4F20\u4E00\u4E2A**",
8191
+ args: ProjectCreateArgs,
8192
+ argsConstraints: {
8193
+ anyOf: [{ required: ["path"] }, { required: ["name"] }]
8194
+ }
8195
+ },
8196
+ "project:patch": {
8197
+ summary: "\u7F6E\u9876 / \u53D6\u6D88\u7F6E\u9876 project\uFF08owner-only\uFF0CpinnedAt=null \u53D6\u6D88\uFF09\u3002clawd-local\uFF0C\u4E0D\u5199 Codex \u7684 pinned-project-ids",
8198
+ args: ProjectPatchArgs
8199
+ },
8200
+ "project:reveal": {
8201
+ summary: "\u5728 Finder \u4E2D\u663E\u793A\u9879\u76EE\u76EE\u5F55\uFF08owner-only\uFF0Cdarwin\uFF09",
8202
+ args: ProjectRevealArgs
8182
8203
  },
8183
8204
  "workspace:list": {
8184
8205
  summary: "\u5217\u76EE\u5F55\u5185\u5BB9\uFF08\u6587\u4EF6\u6D4F\u89C8\uFF09\uFF1Bguest \u88AB\u9650\u5236\u5728\u88AB\u6388\u6743 persona \u5B50\u6811\u5185",
@@ -9003,8 +9024,8 @@ var require_req = __commonJS({
9003
9024
  if (req.originalUrl) {
9004
9025
  _req.url = req.originalUrl;
9005
9026
  } else {
9006
- const path86 = req.path;
9007
- _req.url = typeof path86 === "string" ? path86 : req.url ? req.url.path || req.url : void 0;
9027
+ const path87 = req.path;
9028
+ _req.url = typeof path87 === "string" ? path87 : req.url ? req.url.path || req.url : void 0;
9008
9029
  }
9009
9030
  if (req.query) {
9010
9031
  _req.query = req.query;
@@ -9169,14 +9190,14 @@ var require_redact = __commonJS({
9169
9190
  }
9170
9191
  return obj;
9171
9192
  }
9172
- function parsePath(path86) {
9193
+ function parsePath(path87) {
9173
9194
  const parts = [];
9174
9195
  let current = "";
9175
9196
  let inBrackets = false;
9176
9197
  let inQuotes = false;
9177
9198
  let quoteChar = "";
9178
- for (let i = 0; i < path86.length; i++) {
9179
- const char = path86[i];
9199
+ for (let i = 0; i < path87.length; i++) {
9200
+ const char = path87[i];
9180
9201
  if (!inBrackets && char === ".") {
9181
9202
  if (current) {
9182
9203
  parts.push(current);
@@ -9307,10 +9328,10 @@ var require_redact = __commonJS({
9307
9328
  return current;
9308
9329
  }
9309
9330
  function redactPaths(obj, paths, censor, remove = false) {
9310
- for (const path86 of paths) {
9311
- const parts = parsePath(path86);
9331
+ for (const path87 of paths) {
9332
+ const parts = parsePath(path87);
9312
9333
  if (parts.includes("*")) {
9313
- redactWildcardPath(obj, parts, censor, path86, remove);
9334
+ redactWildcardPath(obj, parts, censor, path87, remove);
9314
9335
  } else {
9315
9336
  if (remove) {
9316
9337
  removeKey(obj, parts);
@@ -9395,8 +9416,8 @@ var require_redact = __commonJS({
9395
9416
  }
9396
9417
  } else {
9397
9418
  if (afterWildcard.includes("*")) {
9398
- const wrappedCensor = typeof censor === "function" ? (value, path86) => {
9399
- const fullPath = [...pathArray.slice(0, pathLength), ...path86];
9419
+ const wrappedCensor = typeof censor === "function" ? (value, path87) => {
9420
+ const fullPath = [...pathArray.slice(0, pathLength), ...path87];
9400
9421
  return censor(value, fullPath);
9401
9422
  } : censor;
9402
9423
  redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
@@ -9431,8 +9452,8 @@ var require_redact = __commonJS({
9431
9452
  return null;
9432
9453
  }
9433
9454
  const pathStructure = /* @__PURE__ */ new Map();
9434
- for (const path86 of pathsToClone) {
9435
- const parts = parsePath(path86);
9455
+ for (const path87 of pathsToClone) {
9456
+ const parts = parsePath(path87);
9436
9457
  let current = pathStructure;
9437
9458
  for (let i = 0; i < parts.length; i++) {
9438
9459
  const part = parts[i];
@@ -9484,24 +9505,24 @@ var require_redact = __commonJS({
9484
9505
  }
9485
9506
  return cloneSelectively(obj, pathStructure);
9486
9507
  }
9487
- function validatePath(path86) {
9488
- if (typeof path86 !== "string") {
9508
+ function validatePath(path87) {
9509
+ if (typeof path87 !== "string") {
9489
9510
  throw new Error("Paths must be (non-empty) strings");
9490
9511
  }
9491
- if (path86 === "") {
9512
+ if (path87 === "") {
9492
9513
  throw new Error("Invalid redaction path ()");
9493
9514
  }
9494
- if (path86.includes("..")) {
9495
- throw new Error(`Invalid redaction path (${path86})`);
9515
+ if (path87.includes("..")) {
9516
+ throw new Error(`Invalid redaction path (${path87})`);
9496
9517
  }
9497
- if (path86.includes(",")) {
9498
- throw new Error(`Invalid redaction path (${path86})`);
9518
+ if (path87.includes(",")) {
9519
+ throw new Error(`Invalid redaction path (${path87})`);
9499
9520
  }
9500
9521
  let bracketCount = 0;
9501
9522
  let inQuotes = false;
9502
9523
  let quoteChar = "";
9503
- for (let i = 0; i < path86.length; i++) {
9504
- const char = path86[i];
9524
+ for (let i = 0; i < path87.length; i++) {
9525
+ const char = path87[i];
9505
9526
  if ((char === '"' || char === "'") && bracketCount > 0) {
9506
9527
  if (!inQuotes) {
9507
9528
  inQuotes = true;
@@ -9515,20 +9536,20 @@ var require_redact = __commonJS({
9515
9536
  } else if (char === "]" && !inQuotes) {
9516
9537
  bracketCount--;
9517
9538
  if (bracketCount < 0) {
9518
- throw new Error(`Invalid redaction path (${path86})`);
9539
+ throw new Error(`Invalid redaction path (${path87})`);
9519
9540
  }
9520
9541
  }
9521
9542
  }
9522
9543
  if (bracketCount !== 0) {
9523
- throw new Error(`Invalid redaction path (${path86})`);
9544
+ throw new Error(`Invalid redaction path (${path87})`);
9524
9545
  }
9525
9546
  }
9526
9547
  function validatePaths(paths) {
9527
9548
  if (!Array.isArray(paths)) {
9528
9549
  throw new TypeError("paths must be an array");
9529
9550
  }
9530
- for (const path86 of paths) {
9531
- validatePath(path86);
9551
+ for (const path87 of paths) {
9552
+ validatePath(path87);
9532
9553
  }
9533
9554
  }
9534
9555
  function slowRedact(options = {}) {
@@ -9696,8 +9717,8 @@ var require_redaction = __commonJS({
9696
9717
  if (shape[k2] === null) {
9697
9718
  o[k2] = (value) => topCensor(value, [k2]);
9698
9719
  } else {
9699
- const wrappedCensor = typeof censor === "function" ? (value, path86) => {
9700
- return censor(value, [k2, ...path86]);
9720
+ const wrappedCensor = typeof censor === "function" ? (value, path87) => {
9721
+ return censor(value, [k2, ...path87]);
9701
9722
  } : censor;
9702
9723
  o[k2] = Redact({
9703
9724
  paths: shape[k2],
@@ -9918,7 +9939,7 @@ var require_sonic_boom = __commonJS({
9918
9939
  var fs77 = require("fs");
9919
9940
  var EventEmitter3 = require("events");
9920
9941
  var inherits = require("util").inherits;
9921
- var path86 = require("path");
9942
+ var path87 = require("path");
9922
9943
  var sleep2 = require_atomic_sleep();
9923
9944
  var assert = require("assert");
9924
9945
  var BUSY_WRITE_TIMEOUT = 100;
@@ -9972,7 +9993,7 @@ var require_sonic_boom = __commonJS({
9972
9993
  const mode = sonic.mode;
9973
9994
  if (sonic.sync) {
9974
9995
  try {
9975
- if (sonic.mkdir) fs77.mkdirSync(path86.dirname(file), { recursive: true });
9996
+ if (sonic.mkdir) fs77.mkdirSync(path87.dirname(file), { recursive: true });
9976
9997
  const fd = fs77.openSync(file, flags, mode);
9977
9998
  fileOpened(null, fd);
9978
9999
  } catch (err) {
@@ -9980,7 +10001,7 @@ var require_sonic_boom = __commonJS({
9980
10001
  throw err;
9981
10002
  }
9982
10003
  } else if (sonic.mkdir) {
9983
- fs77.mkdir(path86.dirname(file), { recursive: true }, (err) => {
10004
+ fs77.mkdir(path87.dirname(file), { recursive: true }, (err) => {
9984
10005
  if (err) return fileOpened(err);
9985
10006
  fs77.open(file, flags, mode, fileOpened);
9986
10007
  });
@@ -12840,7 +12861,7 @@ var require_multistream = __commonJS({
12840
12861
  var require_pino = __commonJS({
12841
12862
  "../node_modules/.pnpm/pino@9.14.0/node_modules/pino/pino.js"(exports2, module2) {
12842
12863
  "use strict";
12843
- var os28 = require("os");
12864
+ var os29 = require("os");
12844
12865
  var stdSerializers = require_pino_std_serializers();
12845
12866
  var caller = require_caller();
12846
12867
  var redaction = require_redaction();
@@ -12887,7 +12908,7 @@ var require_pino = __commonJS({
12887
12908
  } = symbols;
12888
12909
  var { epochTime, nullTime } = time;
12889
12910
  var { pid } = process;
12890
- var hostname = os28.hostname();
12911
+ var hostname = os29.hostname();
12891
12912
  var defaultErrorSerializer = stdSerializers.err;
12892
12913
  var defaultOptions2 = {
12893
12914
  level: "info",
@@ -13611,11 +13632,11 @@ var init_lib = __esm({
13611
13632
  }
13612
13633
  }
13613
13634
  },
13614
- addToPath: function addToPath(path86, added, removed, oldPosInc, options) {
13615
- var last = path86.lastComponent;
13635
+ addToPath: function addToPath(path87, added, removed, oldPosInc, options) {
13636
+ var last = path87.lastComponent;
13616
13637
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
13617
13638
  return {
13618
- oldPos: path86.oldPos + oldPosInc,
13639
+ oldPos: path87.oldPos + oldPosInc,
13619
13640
  lastComponent: {
13620
13641
  count: last.count + 1,
13621
13642
  added,
@@ -13625,7 +13646,7 @@ var init_lib = __esm({
13625
13646
  };
13626
13647
  } else {
13627
13648
  return {
13628
- oldPos: path86.oldPos + oldPosInc,
13649
+ oldPos: path87.oldPos + oldPosInc,
13629
13650
  lastComponent: {
13630
13651
  count: 1,
13631
13652
  added,
@@ -14157,10 +14178,10 @@ function attachmentToHistoryMessage(o, ts) {
14157
14178
  const memories = raw.map((m2) => {
14158
14179
  if (!m2 || typeof m2 !== "object") return null;
14159
14180
  const rec4 = m2;
14160
- const path86 = typeof rec4.path === "string" ? rec4.path : null;
14181
+ const path87 = typeof rec4.path === "string" ? rec4.path : null;
14161
14182
  const content = typeof rec4.content === "string" ? rec4.content : null;
14162
- if (!path86 || content == null) return null;
14163
- const entry = { path: path86, content };
14183
+ if (!path87 || content == null) return null;
14184
+ const entry = { path: path87, content };
14164
14185
  if (typeof rec4.mtimeMs === "number") entry.mtimeMs = rec4.mtimeMs;
14165
14186
  return entry;
14166
14187
  }).filter((m2) => m2 !== null);
@@ -15011,10 +15032,10 @@ function parseAttachment(obj) {
15011
15032
  const memories = raw.map((m2) => {
15012
15033
  if (!m2 || typeof m2 !== "object") return null;
15013
15034
  const rec4 = m2;
15014
- const path86 = typeof rec4.path === "string" ? rec4.path : null;
15035
+ const path87 = typeof rec4.path === "string" ? rec4.path : null;
15015
15036
  const content = typeof rec4.content === "string" ? rec4.content : null;
15016
- if (!path86 || content == null) return null;
15017
- const out = { path: path86, content };
15037
+ if (!path87 || content == null) return null;
15038
+ const out = { path: path87, content };
15018
15039
  if (typeof rec4.mtimeMs === "number") out.mtimeMs = rec4.mtimeMs;
15019
15040
  return out;
15020
15041
  }).filter((m2) => m2 !== null);
@@ -35375,8 +35396,8 @@ var require_lib2 = __commonJS({
35375
35396
  return this;
35376
35397
  }
35377
35398
  var p2 = this.constructor;
35378
- return this.then(resolve9, reject2);
35379
- function resolve9(value) {
35399
+ return this.then(resolve10, reject2);
35400
+ function resolve10(value) {
35380
35401
  function yes() {
35381
35402
  return value;
35382
35403
  }
@@ -35529,8 +35550,8 @@ var require_lib2 = __commonJS({
35529
35550
  }
35530
35551
  return out;
35531
35552
  }
35532
- Promise2.resolve = resolve8;
35533
- function resolve8(value) {
35553
+ Promise2.resolve = resolve9;
35554
+ function resolve9(value) {
35534
35555
  if (value instanceof this) {
35535
35556
  return value;
35536
35557
  }
@@ -35988,8 +36009,8 @@ var require_utils = __commonJS({
35988
36009
  var result = transform[inputType][outputType](input);
35989
36010
  return result;
35990
36011
  };
35991
- exports2.resolve = function(path86) {
35992
- var parts = path86.split("/");
36012
+ exports2.resolve = function(path87) {
36013
+ var parts = path87.split("/");
35993
36014
  var result = [];
35994
36015
  for (var index = 0; index < parts.length; index++) {
35995
36016
  var part = parts[index];
@@ -36062,10 +36083,10 @@ var require_utils = __commonJS({
36062
36083
  var promise = external.Promise.resolve(inputData).then(function(data) {
36063
36084
  var isBlob = support.blob && (data instanceof Blob || ["[object File]", "[object Blob]"].indexOf(Object.prototype.toString.call(data)) !== -1);
36064
36085
  if (isBlob && typeof FileReader !== "undefined") {
36065
- return new external.Promise(function(resolve8, reject) {
36086
+ return new external.Promise(function(resolve9, reject) {
36066
36087
  var reader = new FileReader();
36067
36088
  reader.onload = function(e) {
36068
- resolve8(e.target.result);
36089
+ resolve9(e.target.result);
36069
36090
  };
36070
36091
  reader.onerror = function(e) {
36071
36092
  reject(e.target.error);
@@ -36620,7 +36641,7 @@ var require_StreamHelper = __commonJS({
36620
36641
  }
36621
36642
  }
36622
36643
  function accumulate(helper, updateCallback) {
36623
- return new external.Promise(function(resolve8, reject) {
36644
+ return new external.Promise(function(resolve9, reject) {
36624
36645
  var dataArray = [];
36625
36646
  var chunkType = helper._internalType, resultType = helper._outputType, mimeType = helper._mimeType;
36626
36647
  helper.on("data", function(data, meta) {
@@ -36634,7 +36655,7 @@ var require_StreamHelper = __commonJS({
36634
36655
  }).on("end", function() {
36635
36656
  try {
36636
36657
  var result = transformZipOutput(resultType, concat(chunkType, dataArray), mimeType);
36637
- resolve8(result);
36658
+ resolve9(result);
36638
36659
  } catch (e) {
36639
36660
  reject(e);
36640
36661
  }
@@ -41842,18 +41863,18 @@ var require_object = __commonJS({
41842
41863
  var object = new ZipObject(name, zipObjectContent, o);
41843
41864
  this.files[name] = object;
41844
41865
  };
41845
- var parentFolder = function(path86) {
41846
- if (path86.slice(-1) === "/") {
41847
- path86 = path86.substring(0, path86.length - 1);
41866
+ var parentFolder = function(path87) {
41867
+ if (path87.slice(-1) === "/") {
41868
+ path87 = path87.substring(0, path87.length - 1);
41848
41869
  }
41849
- var lastSlash = path86.lastIndexOf("/");
41850
- return lastSlash > 0 ? path86.substring(0, lastSlash) : "";
41870
+ var lastSlash = path87.lastIndexOf("/");
41871
+ return lastSlash > 0 ? path87.substring(0, lastSlash) : "";
41851
41872
  };
41852
- var forceTrailingSlash = function(path86) {
41853
- if (path86.slice(-1) !== "/") {
41854
- path86 += "/";
41873
+ var forceTrailingSlash = function(path87) {
41874
+ if (path87.slice(-1) !== "/") {
41875
+ path87 += "/";
41855
41876
  }
41856
- return path86;
41877
+ return path87;
41857
41878
  };
41858
41879
  var folderAdd = function(name, createFolders) {
41859
41880
  createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
@@ -42747,7 +42768,7 @@ var require_load = __commonJS({
42747
42768
  var Crc32Probe = require_Crc32Probe();
42748
42769
  var nodejsUtils = require_nodejsUtils();
42749
42770
  function checkEntryCRC32(zipEntry) {
42750
- return new external.Promise(function(resolve8, reject) {
42771
+ return new external.Promise(function(resolve9, reject) {
42751
42772
  var worker = zipEntry.decompressed.getContentWorker().pipe(new Crc32Probe());
42752
42773
  worker.on("error", function(e) {
42753
42774
  reject(e);
@@ -42755,7 +42776,7 @@ var require_load = __commonJS({
42755
42776
  if (worker.streamInfo.crc32 !== zipEntry.decompressed.crc32) {
42756
42777
  reject(new Error("Corrupted zip : CRC32 mismatch"));
42757
42778
  } else {
42758
- resolve8();
42779
+ resolve9();
42759
42780
  }
42760
42781
  }).resume();
42761
42782
  });
@@ -42860,11 +42881,11 @@ function startRunCaseRecorder(opts) {
42860
42881
  let closing = false;
42861
42882
  let closedSettled = false;
42862
42883
  let closedResolve;
42863
- const closed = new Promise((resolve8) => {
42884
+ const closed = new Promise((resolve9) => {
42864
42885
  closedResolve = () => {
42865
42886
  if (closedSettled) return;
42866
42887
  closedSettled = true;
42867
- resolve8();
42888
+ resolve9();
42868
42889
  };
42869
42890
  });
42870
42891
  const ensureStream = () => {
@@ -42956,8 +42977,8 @@ async function runController(opts) {
42956
42977
  let exitCode = null;
42957
42978
  let procExited = false;
42958
42979
  let resolveProcExit;
42959
- const procExitPromise = new Promise((resolve8) => {
42960
- resolveProcExit = resolve8;
42980
+ const procExitPromise = new Promise((resolve9) => {
42981
+ resolveProcExit = resolve9;
42961
42982
  });
42962
42983
  const writeEvent = (event) => {
42963
42984
  try {
@@ -45395,8 +45416,8 @@ function startRecorder(opts) {
45395
45416
  const filePath = import_node_path6.default.join(dir, `${tsForFilename(now())}.jsonl`);
45396
45417
  let stream = null;
45397
45418
  let closedResolve;
45398
- const closed = new Promise((resolve8) => {
45399
- closedResolve = resolve8;
45419
+ const closed = new Promise((resolve9) => {
45420
+ closedResolve = resolve9;
45400
45421
  });
45401
45422
  let exited = false;
45402
45423
  const ensureStream = () => {
@@ -45529,13 +45550,13 @@ var SessionRunner = class {
45529
45550
  // 已经停止则立即 resolve;超时(默认 3000ms)抛错由上层透传成 RPC error
45530
45551
  async waitUntilStopped(timeoutMs = DEFAULT_WAIT_STOP_TIMEOUT_MS) {
45531
45552
  if (!this.state.procAlive) return;
45532
- return new Promise((resolve8, reject) => {
45553
+ return new Promise((resolve9, reject) => {
45533
45554
  let settled = false;
45534
45555
  const onStop = () => {
45535
45556
  if (settled) return;
45536
45557
  settled = true;
45537
45558
  clearTimeout(timer);
45538
- resolve8();
45559
+ resolve9();
45539
45560
  };
45540
45561
  const timer = setTimeout(() => {
45541
45562
  if (settled) return;
@@ -45635,7 +45656,7 @@ var SessionRunner = class {
45635
45656
  };
45636
45657
  const payload = JSON.stringify(frame) + "\n";
45637
45658
  const timeoutMs = opts.timeoutMs ?? DEFAULT_CONTROL_REQUEST_TIMEOUT_MS;
45638
- return new Promise((resolve8, reject) => {
45659
+ return new Promise((resolve9, reject) => {
45639
45660
  const timer = setTimeout(() => {
45640
45661
  const pending = this.pendingControlRequests.get(requestId);
45641
45662
  if (!pending) return;
@@ -45643,7 +45664,7 @@ var SessionRunner = class {
45643
45664
  reject(new Error(`control_request timeout: ${subtype}`));
45644
45665
  }, timeoutMs);
45645
45666
  timer.unref?.();
45646
- this.pendingControlRequests.set(requestId, { resolve: resolve8, reject, timer });
45667
+ this.pendingControlRequests.set(requestId, { resolve: resolve9, reject, timer });
45647
45668
  try {
45648
45669
  proc.stdin?.write(payload);
45649
45670
  this.recorder?.tapStdinWrite(payload);
@@ -48188,12 +48209,19 @@ var SessionManager = class {
48188
48209
 
48189
48210
  // src/projects/store.ts
48190
48211
  var fs11 = __toESM(require("fs"), 1);
48191
- var os5 = __toESM(require("os"), 1);
48192
- var path12 = __toESM(require("path"), 1);
48212
+ var os6 = __toESM(require("os"), 1);
48213
+ var path13 = __toESM(require("path"), 1);
48193
48214
  init_protocol();
48194
48215
 
48195
48216
  // src/projects/codex-registry.ts
48196
48217
  var fs10 = __toESM(require("fs"), 1);
48218
+ var os5 = __toESM(require("os"), 1);
48219
+ var path12 = __toESM(require("path"), 1);
48220
+ function normalizeProjectPath(p2) {
48221
+ const home = os5.homedir();
48222
+ const expanded = p2 === "~" ? home : p2.startsWith("~/") ? path12.join(home, p2.slice(2)) : p2;
48223
+ return path12.resolve(expanded);
48224
+ }
48197
48225
  function readCodexProjects(opts) {
48198
48226
  let raw;
48199
48227
  try {
@@ -48231,6 +48259,8 @@ var ProjectsStore = class {
48231
48259
  }
48232
48260
  opts;
48233
48261
  entries = [];
48262
+ /** 见 ProjectAnnotation;与 entries 一起持久化在 projects.json */
48263
+ annotations = {};
48234
48264
  load() {
48235
48265
  let raw;
48236
48266
  try {
@@ -48241,26 +48271,29 @@ var ProjectsStore = class {
48241
48271
  try {
48242
48272
  const parsed = JSON.parse(raw);
48243
48273
  this.entries = (parsed.projects ?? []).map((p2) => ProjectEntry.parse(p2)).filter((e) => this.isProjectablePath(e.path));
48274
+ this.annotations = typeof parsed.annotations === "object" && parsed.annotations !== null ? parsed.annotations : {};
48244
48275
  } catch (err) {
48245
48276
  this.opts.logger?.warn("projects.json corrupt, rebuilding", { err: String(err) });
48246
48277
  this.entries = [];
48278
+ this.annotations = {};
48247
48279
  }
48248
48280
  }
48249
48281
  save() {
48250
- fs11.mkdirSync(path12.dirname(this.opts.file), { recursive: true });
48251
- fs11.writeFileSync(this.opts.file, JSON.stringify({ projects: this.entries }, null, 2));
48282
+ fs11.mkdirSync(path13.dirname(this.opts.file), { recursive: true });
48283
+ fs11.writeFileSync(
48284
+ this.opts.file,
48285
+ JSON.stringify({ projects: this.entries, annotations: this.annotations }, null, 2)
48286
+ );
48252
48287
  }
48253
48288
  normalize(p2) {
48254
- const home = os5.homedir();
48255
- const expanded = p2 === "~" ? home : p2.startsWith("~/") ? path12.join(home, p2.slice(2)) : p2;
48256
- return path12.resolve(expanded);
48289
+ return normalizeProjectPath(p2);
48257
48290
  }
48258
48291
  isProjectablePath(p2) {
48259
48292
  const abs = this.normalize(p2);
48260
- const rel = path12.relative(path12.resolve(this.opts.clawdDir), abs);
48261
- const insideClawd = !(rel.startsWith("..") || path12.isAbsolute(rel));
48293
+ const rel = path13.relative(path13.resolve(this.opts.clawdDir), abs);
48294
+ const insideClawd = !(rel.startsWith("..") || path13.isAbsolute(rel));
48262
48295
  if (insideClawd) return false;
48263
- if (abs === path12.resolve(os5.homedir()) || abs === path12.parse(abs).root) return false;
48296
+ if (abs === path13.resolve(os6.homedir()) || abs === path13.parse(abs).root) return false;
48264
48297
  return true;
48265
48298
  }
48266
48299
  list() {
@@ -48296,7 +48329,27 @@ var ProjectsStore = class {
48296
48329
  });
48297
48330
  }
48298
48331
  }
48299
- return [...byPath.values()];
48332
+ return [...byPath.entries()].map(([abs, e]) => {
48333
+ const ann = this.annotations[abs];
48334
+ if (!ann || ann.pinnedAt === void 0) return e;
48335
+ return { ...e, pinnedAt: ann.pinnedAt };
48336
+ });
48337
+ }
48338
+ codexHasPath(abs) {
48339
+ if (!this.opts.codexStateFile) return false;
48340
+ return readCodexProjects({ stateFile: this.opts.codexStateFile, logger: this.opts.logger }).some(
48341
+ (c) => this.normalize(c.path) === abs
48342
+ );
48343
+ }
48344
+ /** 置顶 / 取消置顶(null)。clawd-local,不写 Codex。false = 路径不在项目列表里 */
48345
+ patch(rawPath, fields) {
48346
+ const abs = this.normalize(rawPath);
48347
+ const row = this.entries.find((e) => e.path === abs);
48348
+ if (!row && !this.codexHasPath(abs)) return false;
48349
+ if (fields.pinnedAt === null) delete this.annotations[abs];
48350
+ else this.annotations[abs] = { pinnedAt: fields.pinnedAt };
48351
+ this.save();
48352
+ return true;
48300
48353
  }
48301
48354
  upsert(rawPath, name) {
48302
48355
  const entry = this.add(rawPath, name);
@@ -48311,7 +48364,7 @@ var ProjectsStore = class {
48311
48364
  if (existing) return existing;
48312
48365
  const entry = {
48313
48366
  path: abs,
48314
- name: name ?? path12.basename(abs),
48367
+ name: name ?? path13.basename(abs),
48315
48368
  createdAt: (this.opts.now ?? (() => (/* @__PURE__ */ new Date()).toISOString()))()
48316
48369
  };
48317
48370
  this.entries.push(entry);
@@ -48320,12 +48373,12 @@ var ProjectsStore = class {
48320
48373
  };
48321
48374
 
48322
48375
  // src/tools/codex-home.ts
48323
- var path13 = __toESM(require("path"), 1);
48324
- var norm = (p2) => path13.resolve(p2);
48376
+ var path14 = __toESM(require("path"), 1);
48377
+ var norm = (p2) => path14.resolve(p2);
48325
48378
  function resolveCodexHome(input) {
48326
48379
  const cwd = norm(input.cwd);
48327
- const rel = path13.relative(norm(input.personaRoot), cwd);
48328
- const isPersonaRoot = rel !== "" && !rel.startsWith("..") && !path13.isAbsolute(rel) && !rel.includes(path13.sep);
48380
+ const rel = path14.relative(norm(input.personaRoot), cwd);
48381
+ const isPersonaRoot = rel !== "" && !rel.startsWith("..") && !path14.isAbsolute(rel) && !rel.includes(path14.sep);
48329
48382
  if (isPersonaRoot) return input.sharedHome;
48330
48383
  if (input.projectPaths.some((p2) => norm(p2) === cwd)) return input.sharedHome;
48331
48384
  return input.isolatedHome;
@@ -48333,7 +48386,7 @@ function resolveCodexHome(input) {
48333
48386
 
48334
48387
  // src/persona/store.ts
48335
48388
  var fs12 = __toESM(require("fs"), 1);
48336
- var path14 = __toESM(require("path"), 1);
48389
+ var path15 = __toESM(require("path"), 1);
48337
48390
  init_protocol();
48338
48391
  var PersonaStore = class {
48339
48392
  constructor(root) {
@@ -48342,18 +48395,18 @@ var PersonaStore = class {
48342
48395
  }
48343
48396
  root;
48344
48397
  personaDir(personaId2) {
48345
- return path14.join(this.root, safeFileName(personaId2));
48398
+ return path15.join(this.root, safeFileName(personaId2));
48346
48399
  }
48347
48400
  metaPath(personaId2) {
48348
- return path14.join(this.personaDir(personaId2), ".clawd", "persona.json");
48401
+ return path15.join(this.personaDir(personaId2), ".clawd", "persona.json");
48349
48402
  }
48350
48403
  claudeMdPath(personaId2) {
48351
- return path14.join(this.personaDir(personaId2), "CLAUDE.md");
48404
+ return path15.join(this.personaDir(personaId2), "CLAUDE.md");
48352
48405
  }
48353
48406
  // codex 原生读 cwd 的 AGENTS.md。人格双写镜像:claude 读 CLAUDE.md、codex 读 AGENTS.md,
48354
48407
  // 两份内容恒一致,persona 切 tool 零迁移。
48355
48408
  agentsMdPath(personaId2) {
48356
- return path14.join(this.personaDir(personaId2), "AGENTS.md");
48409
+ return path15.join(this.personaDir(personaId2), "AGENTS.md");
48357
48410
  }
48358
48411
  /**
48359
48412
  * persona 级 sandbox base 落盘路径 —— 故意放 `.clawd/` 而非 `.claude/`,让 CC 的 project
@@ -48362,11 +48415,11 @@ var PersonaStore = class {
48362
48415
  * spawn 前 per-guest 动态拼到各自 session 目录的那份(base + 强制底座 + 本 guest userWorkDir carve)。
48363
48416
  */
48364
48417
  sandboxSettingsPath(personaId2) {
48365
- return path14.join(this.personaDir(personaId2), ".clawd", "sandbox-settings.json");
48418
+ return path15.join(this.personaDir(personaId2), ".clawd", "sandbox-settings.json");
48366
48419
  }
48367
48420
  write(persona, personality) {
48368
48421
  const dir = this.personaDir(persona.personaId);
48369
- fs12.mkdirSync(path14.join(dir, ".clawd"), { recursive: true });
48422
+ fs12.mkdirSync(path15.join(dir, ".clawd"), { recursive: true });
48370
48423
  this.atomicWrite(this.claudeMdPath(persona.personaId), personality);
48371
48424
  this.atomicWrite(this.agentsMdPath(persona.personaId), personality);
48372
48425
  this.writeSandboxSettings(persona.personaId, buildGuestSettingsV1());
@@ -48437,7 +48490,7 @@ var PersonaStore = class {
48437
48490
  };
48438
48491
  }
48439
48492
  codexSandboxSettingsPath(personaId2) {
48440
- return path14.join(this.personaDir(personaId2), ".clawd", "codex-sandbox.json");
48493
+ return path15.join(this.personaDir(personaId2), ".clawd", "codex-sandbox.json");
48441
48494
  }
48442
48495
  /** 读 codex-sandbox.json;不存在/损坏 → null。 */
48443
48496
  readCodexSandboxSettings(personaId2) {
@@ -48451,7 +48504,7 @@ var PersonaStore = class {
48451
48504
  }
48452
48505
  /** 覆盖写 codex-sandbox.json(seed/migrate 用)。 */
48453
48506
  writeCodexSandboxSettings(personaId2, settings) {
48454
- const dir = path14.join(this.personaDir(personaId2), ".clawd");
48507
+ const dir = path15.join(this.personaDir(personaId2), ".clawd");
48455
48508
  fs12.mkdirSync(dir, { recursive: true });
48456
48509
  this.atomicWrite(this.codexSandboxSettingsPath(personaId2), JSON.stringify(settings, null, 2));
48457
48510
  }
@@ -48493,14 +48546,14 @@ var PersonaStore = class {
48493
48546
  }
48494
48547
  /** Persona 私有 skills 目录路径:<personaDir>/.claude/skills */
48495
48548
  skillsDir(personaId2) {
48496
- return path14.join(this.personaDir(personaId2), ".claude", "skills");
48549
+ return path15.join(this.personaDir(personaId2), ".claude", "skills");
48497
48550
  }
48498
48551
  /**
48499
48552
  * Claude Code 项目级 settings 路径:`<personaDir>/.claude/settings.json`。
48500
48553
  * 这里只读 `enabledPlugins` 字段,由 owner 通过 CC `/plugin` 之类命令维护,daemon 不写。
48501
48554
  */
48502
48555
  claudeSettingsPath(personaId2) {
48503
- return path14.join(this.personaDir(personaId2), ".claude", "settings.json");
48556
+ return path15.join(this.personaDir(personaId2), ".claude", "settings.json");
48504
48557
  }
48505
48558
  /**
48506
48559
  * 读取 persona 的 `.claude/settings.json` 中 `enabledPlugins` map,把 value === true
@@ -48534,7 +48587,7 @@ var PersonaStore = class {
48534
48587
  list() {
48535
48588
  if (!fs12.existsSync(this.root)) return [];
48536
48589
  return fs12.readdirSync(this.root).filter((name) => {
48537
- return fs12.existsSync(path14.join(this.root, name, ".clawd", "persona.json"));
48590
+ return fs12.existsSync(path15.join(this.root, name, ".clawd", "persona.json"));
48538
48591
  });
48539
48592
  }
48540
48593
  remove(personaId2) {
@@ -48960,7 +49013,7 @@ var PersonaManager = class {
48960
49013
 
48961
49014
  // src/persona/seed.ts
48962
49015
  var fs14 = __toESM(require("fs"), 1);
48963
- var path16 = __toESM(require("path"), 1);
49016
+ var path17 = __toESM(require("path"), 1);
48964
49017
  var import_node_url = require("url");
48965
49018
  var import_meta = {};
48966
49019
  var DEFAULT_BYPASS_PROFILE = {
@@ -49139,14 +49192,14 @@ function bundleSiblingFromArgv(argv1, sibling) {
49139
49192
  real = fs14.realpathSync(argv1);
49140
49193
  } catch {
49141
49194
  }
49142
- return path16.resolve(path16.dirname(real), sibling);
49195
+ return path17.resolve(path17.dirname(real), sibling);
49143
49196
  }
49144
49197
  function findDefaultsRoot(logger) {
49145
49198
  const candidates = [];
49146
49199
  try {
49147
- const here = path16.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
49148
- candidates.push(path16.resolve(here, "defaults"));
49149
- candidates.push(path16.resolve(here, "persona-defaults"));
49200
+ const here = path17.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
49201
+ candidates.push(path17.resolve(here, "defaults"));
49202
+ candidates.push(path17.resolve(here, "persona-defaults"));
49150
49203
  } catch {
49151
49204
  }
49152
49205
  const fromArgv = bundleSiblingFromArgv(process.argv[1], "persona-defaults");
@@ -49170,7 +49223,7 @@ function seedDefaultPersonas(args) {
49170
49223
  args.logger.info("persona.seed.skip", { personaId: entry.personaId, reason: "exists" });
49171
49224
  continue;
49172
49225
  }
49173
- const bundleDir = path16.join(args.defaultsRoot, entry.personaId);
49226
+ const bundleDir = path17.join(args.defaultsRoot, entry.personaId);
49174
49227
  if (!fs14.existsSync(bundleDir)) {
49175
49228
  args.logger.warn("persona.seed.skip", {
49176
49229
  personaId: entry.personaId,
@@ -49179,7 +49232,7 @@ function seedDefaultPersonas(args) {
49179
49232
  });
49180
49233
  continue;
49181
49234
  }
49182
- const claudeMdPath = path16.join(bundleDir, "CLAUDE.md");
49235
+ const claudeMdPath = path17.join(bundleDir, "CLAUDE.md");
49183
49236
  if (!fs14.existsSync(claudeMdPath)) {
49184
49237
  args.logger.warn("persona.seed.skip", {
49185
49238
  personaId: entry.personaId,
@@ -49215,13 +49268,13 @@ function seedDefaultPersonas(args) {
49215
49268
  }
49216
49269
  }
49217
49270
  function skipNodeModulesUnder(srcRoot) {
49218
- return (src) => !path16.relative(srcRoot, src).split(path16.sep).includes("node_modules");
49271
+ return (src) => !path17.relative(srcRoot, src).split(path17.sep).includes("node_modules");
49219
49272
  }
49220
49273
  function copyBundleExtras(srcDir, dstDir) {
49221
49274
  for (const entry of fs14.readdirSync(srcDir, { withFileTypes: true })) {
49222
49275
  if (entry.name === "CLAUDE.md" || entry.name === ".clawd") continue;
49223
- const srcPath = path16.join(srcDir, entry.name);
49224
- const dstPath = path16.join(dstDir, entry.name);
49276
+ const srcPath = path17.join(srcDir, entry.name);
49277
+ const dstPath = path17.join(dstDir, entry.name);
49225
49278
  if (entry.isDirectory()) {
49226
49279
  fs14.cpSync(srcPath, dstPath, { recursive: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
49227
49280
  } else if (entry.isFile()) {
@@ -49232,7 +49285,7 @@ function copyBundleExtras(srcDir, dstDir) {
49232
49285
  var DAEMON_MANAGED_PATHS = ["extension-kit", "CLAUDE.md", ".mcp.json", ".claude/skills"];
49233
49286
  function replaceManagedPath(src, dst) {
49234
49287
  if (!fs14.statSync(src).isDirectory()) {
49235
- fs14.mkdirSync(path16.dirname(dst), { recursive: true });
49288
+ fs14.mkdirSync(path17.dirname(dst), { recursive: true });
49236
49289
  fs14.rmSync(dst, { recursive: true, force: true });
49237
49290
  fs14.cpSync(src, dst, { dereference: true });
49238
49291
  return;
@@ -49240,26 +49293,26 @@ function replaceManagedPath(src, dst) {
49240
49293
  fs14.mkdirSync(dst, { recursive: true });
49241
49294
  for (const e of fs14.readdirSync(src, { withFileTypes: true })) {
49242
49295
  if (e.name === "node_modules") continue;
49243
- const child = path16.join(dst, e.name);
49296
+ const child = path17.join(dst, e.name);
49244
49297
  fs14.rmSync(child, { recursive: true, force: true });
49245
- fs14.cpSync(path16.join(src, e.name), child, { recursive: true, dereference: true });
49298
+ fs14.cpSync(path17.join(src, e.name), child, { recursive: true, dereference: true });
49246
49299
  }
49247
49300
  }
49248
49301
  function refreshDaemonManagedDirs(args) {
49249
49302
  const entries = args.entries ?? DEFAULT_PERSONAS;
49250
49303
  for (const entry of entries) {
49251
- const bundleDir = path16.join(args.defaultsRoot, entry.personaId);
49304
+ const bundleDir = path17.join(args.defaultsRoot, entry.personaId);
49252
49305
  if (!fs14.existsSync(bundleDir)) continue;
49253
49306
  const personaDir = args.store.personaDirPath(entry.personaId);
49254
49307
  if (!fs14.existsSync(personaDir)) continue;
49255
49308
  for (const relPath of DAEMON_MANAGED_PATHS) {
49256
- const srcPath = path16.join(bundleDir, relPath);
49309
+ const srcPath = path17.join(bundleDir, relPath);
49257
49310
  if (!fs14.existsSync(srcPath)) continue;
49258
- const dstPath = path16.join(personaDir, relPath);
49311
+ const dstPath = path17.join(personaDir, relPath);
49259
49312
  try {
49260
49313
  replaceManagedPath(srcPath, dstPath);
49261
49314
  if (relPath === "CLAUDE.md") {
49262
- replaceManagedPath(srcPath, path16.join(personaDir, "AGENTS.md"));
49315
+ replaceManagedPath(srcPath, path17.join(personaDir, "AGENTS.md"));
49263
49316
  }
49264
49317
  args.logger.info("persona.refresh.synced", {
49265
49318
  personaId: entry.personaId,
@@ -49408,7 +49461,7 @@ function containsAnyFile(dir) {
49408
49461
  }
49409
49462
  for (const e of entries) {
49410
49463
  if (e.isDirectory()) {
49411
- if (containsAnyFile(path16.join(dir, e.name))) return true;
49464
+ if (containsAnyFile(path17.join(dir, e.name))) return true;
49412
49465
  } else {
49413
49466
  return true;
49414
49467
  }
@@ -49419,7 +49472,7 @@ function retirePersonaBuilder(args) {
49419
49472
  const dir = args.store.personaDirPath(PERSONA_BUILDER_ID);
49420
49473
  if (!fs14.existsSync(dir)) return;
49421
49474
  try {
49422
- const used = containsAnyFile(path16.join(dir, ".clawd", "sessions")) || containsAnyFile(path16.join(dir, ".claude", "skills")) || containsAnyFile(path16.join(dir, "projects"));
49475
+ const used = containsAnyFile(path17.join(dir, ".clawd", "sessions")) || containsAnyFile(path17.join(dir, ".claude", "skills")) || containsAnyFile(path17.join(dir, "projects"));
49423
49476
  if (!used) {
49424
49477
  args.store.remove(PERSONA_BUILDER_ID);
49425
49478
  args.logger.info("persona.retire-builder.removed", { personaId: PERSONA_BUILDER_ID });
@@ -49427,7 +49480,7 @@ function retirePersonaBuilder(args) {
49427
49480
  }
49428
49481
  let wrote = false;
49429
49482
  for (const name of ["CLAUDE.md", "AGENTS.md"]) {
49430
- const p2 = path16.join(dir, name);
49483
+ const p2 = path17.join(dir, name);
49431
49484
  const cur = fs14.existsSync(p2) ? fs14.readFileSync(p2, "utf8") : null;
49432
49485
  if (cur?.startsWith(PERSONA_BUILDER_TOMBSTONE_MARKER)) continue;
49433
49486
  fs14.writeFileSync(p2, PERSONA_BUILDER_TOMBSTONE);
@@ -49444,8 +49497,8 @@ function retirePersonaBuilder(args) {
49444
49497
  function findDeployKitRoot(logger) {
49445
49498
  const candidates = [];
49446
49499
  try {
49447
- const here = path16.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
49448
- candidates.push(path16.resolve(here, "..", "deploy-kit"));
49500
+ const here = path17.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
49501
+ candidates.push(path17.resolve(here, "..", "deploy-kit"));
49449
49502
  } catch {
49450
49503
  }
49451
49504
  const fromArgv = bundleSiblingFromArgv(process.argv[1], "deploy-kit");
@@ -49463,7 +49516,7 @@ function findDeployKitRoot(logger) {
49463
49516
  return null;
49464
49517
  }
49465
49518
  function seedDeployKit(args) {
49466
- const dst = path16.join(args.dataDir, "deploy-kit");
49519
+ const dst = path17.join(args.dataDir, "deploy-kit");
49467
49520
  fs14.cpSync(args.deployKitBundleRoot, dst, {
49468
49521
  recursive: true,
49469
49522
  dereference: true,
@@ -49473,23 +49526,23 @@ function seedDeployKit(args) {
49473
49526
  args.logger.info("deploy-kit.seed.done", { dst });
49474
49527
  }
49475
49528
  function refreshDeployKit(args) {
49476
- const dst = path16.join(args.dataDir, "deploy-kit");
49529
+ const dst = path17.join(args.dataDir, "deploy-kit");
49477
49530
  if (!fs14.existsSync(dst)) {
49478
49531
  seedDeployKit(args);
49479
49532
  return;
49480
49533
  }
49481
49534
  for (const sub of ["scripts", "contract"]) {
49482
- const s = path16.join(args.deployKitBundleRoot, sub);
49535
+ const s = path17.join(args.deployKitBundleRoot, sub);
49483
49536
  if (fs14.existsSync(s)) {
49484
- fs14.cpSync(s, path16.join(dst, sub), { recursive: true, force: true, dereference: true });
49537
+ fs14.cpSync(s, path17.join(dst, sub), { recursive: true, force: true, dereference: true });
49485
49538
  }
49486
49539
  }
49487
- const secretsSrc = path16.join(args.deployKitBundleRoot, ".secrets");
49540
+ const secretsSrc = path17.join(args.deployKitBundleRoot, ".secrets");
49488
49541
  if (fs14.existsSync(secretsSrc)) {
49489
- fs14.mkdirSync(path16.join(dst, ".secrets"), { recursive: true });
49542
+ fs14.mkdirSync(path17.join(dst, ".secrets"), { recursive: true });
49490
49543
  for (const f of fs14.readdirSync(secretsSrc)) {
49491
49544
  if (f.endsWith(".local")) continue;
49492
- fs14.copyFileSync(path16.join(secretsSrc, f), path16.join(dst, ".secrets", f));
49545
+ fs14.copyFileSync(path17.join(secretsSrc, f), path17.join(dst, ".secrets", f));
49493
49546
  }
49494
49547
  }
49495
49548
  args.logger.info("deploy-kit.refresh.done", { dst });
@@ -49780,8 +49833,8 @@ var CodexAppServerClient = class {
49780
49833
  pending = /* @__PURE__ */ new Map();
49781
49834
  request(method, params) {
49782
49835
  const id = this.nextId++;
49783
- return new Promise((resolve8, reject) => {
49784
- this.pending.set(id, { resolve: resolve8, reject });
49836
+ return new Promise((resolve9, reject) => {
49837
+ this.pending.set(id, { resolve: resolve9, reject });
49785
49838
  this.write({ jsonrpc: "2.0", method, id, params });
49786
49839
  });
49787
49840
  }
@@ -50214,8 +50267,8 @@ function turnStartInput(text) {
50214
50267
  const items = [];
50215
50268
  let leftover = text;
50216
50269
  for (const m2 of text.matchAll(SKILL_RE)) {
50217
- const [marker, name, path86] = m2;
50218
- items.push({ type: "skill", name, path: path86 });
50270
+ const [marker, name, path87] = m2;
50271
+ items.push({ type: "skill", name, path: path87 });
50219
50272
  leftover = leftover.replace(marker, "");
50220
50273
  }
50221
50274
  for (const m2 of text.matchAll(ATTACHMENT_RE2)) {
@@ -51300,10 +51353,10 @@ function createTerminalSurface(opts) {
51300
51353
  },
51301
51354
  writeBytes(data, seq) {
51302
51355
  pendingParse++;
51303
- return new Promise((resolve8) => {
51356
+ return new Promise((resolve9) => {
51304
51357
  term.write(data, () => {
51305
51358
  if (disposed) {
51306
- resolve8();
51359
+ resolve9();
51307
51360
  return;
51308
51361
  }
51309
51362
  if (typeof seq === "number" && seq > parseSeq) parseSeq = seq;
@@ -51317,14 +51370,14 @@ function createTerminalSurface(opts) {
51317
51370
  drainWaiters = [];
51318
51371
  for (const w2 of waiters) w2();
51319
51372
  }
51320
- resolve8();
51373
+ resolve9();
51321
51374
  });
51322
51375
  });
51323
51376
  },
51324
51377
  drain() {
51325
51378
  if (pendingParse === 0) return Promise.resolve();
51326
- return new Promise((resolve8) => {
51327
- drainWaiters.push(resolve8);
51379
+ return new Promise((resolve9) => {
51380
+ drainWaiters.push(resolve9);
51328
51381
  });
51329
51382
  },
51330
51383
  resize(cols, rows) {
@@ -51365,7 +51418,7 @@ function inputBoxContent(lines) {
51365
51418
  function waitInputEcho(surface, opts = {}) {
51366
51419
  const stableMs = opts.stableMs ?? 150;
51367
51420
  const maxMs = opts.maxMs ?? 5e3;
51368
- return new Promise((resolve8) => {
51421
+ return new Promise((resolve9) => {
51369
51422
  let settled = false;
51370
51423
  let stableTimer = null;
51371
51424
  const finish = () => {
@@ -51374,7 +51427,7 @@ function waitInputEcho(surface, opts = {}) {
51374
51427
  unsub();
51375
51428
  if (stableTimer) clearTimeout(stableTimer);
51376
51429
  clearTimeout(maxTimer);
51377
- resolve8();
51430
+ resolve9();
51378
51431
  };
51379
51432
  const unsub = surface.onTick((lines) => {
51380
51433
  if (!stableTimer && inputBoxContent(lines).length > 0) {
@@ -52494,13 +52547,13 @@ function createGhRunner(defaults) {
52494
52547
  const baseTimeoutMs = defaults?.timeoutMs ?? DEFAULT_TIMEOUT_MS2;
52495
52548
  return {
52496
52549
  run(args, opts) {
52497
- return new Promise((resolve8, reject) => {
52550
+ return new Promise((resolve9, reject) => {
52498
52551
  (0, import_node_child_process7.execFile)(
52499
52552
  "gh",
52500
52553
  args,
52501
52554
  { timeout: opts?.timeoutMs ?? baseTimeoutMs, maxBuffer: MAX_BUFFER },
52502
52555
  (err, stdout, stderr) => {
52503
- if (!err) return resolve8(stdout);
52556
+ if (!err) return resolve9(stdout);
52504
52557
  if (err.code === "ENOENT") {
52505
52558
  return reject(new GhError("gh-missing", "GitHub CLI (gh) \u672A\u5B89\u88C5"));
52506
52559
  }
@@ -54372,13 +54425,13 @@ function mapSkillsListResponse(res) {
54372
54425
  const r = s ?? {};
54373
54426
  const name = str3(r.name);
54374
54427
  if (!name) continue;
54375
- const path86 = str3(r.path);
54428
+ const path87 = str3(r.path);
54376
54429
  const description = str3(r.description);
54377
54430
  const isPlugin = name.includes(":");
54378
54431
  out.push({
54379
54432
  name,
54380
54433
  source: isPlugin ? "plugin" : "project",
54381
- ...path86 ? { path: path86 } : {},
54434
+ ...path87 ? { path: path87 } : {},
54382
54435
  ...description ? { description } : {},
54383
54436
  ...isPlugin ? { plugin: name.split(":")[0] } : {}
54384
54437
  });
@@ -55245,14 +55298,14 @@ async function generateSessionTitle(tool, firstMessage, deps = {}) {
55245
55298
  const args = tool === "claude" ? buildClaudeTitleArgs(buildClaudeTitlePrompt(text)) : buildCodexTitleArgs(buildTitlePrompt(text), outFile, schemaFile);
55246
55299
  const doSpawn = deps.spawnOverride ?? ((c, a, o) => (0, import_node_child_process8.spawn)(c, a, { ...o, stdio: ["ignore", "pipe", "pipe"] }));
55247
55300
  const timeoutMs = deps.timeoutMs ?? DEFAULT_TITLE_GEN_TIMEOUT_MS;
55248
- return await new Promise((resolve8) => {
55301
+ return await new Promise((resolve9) => {
55249
55302
  let proc;
55250
55303
  try {
55251
55304
  proc = doSpawn(cmd, args, { cwd: workDir });
55252
55305
  } catch (err) {
55253
55306
  deps.logger?.warn("title-gen spawn failed", { tool, message: err.message });
55254
55307
  cleanupWorkDir();
55255
- return resolve8(null);
55308
+ return resolve9(null);
55256
55309
  }
55257
55310
  let stdout = "";
55258
55311
  let settled = false;
@@ -55262,7 +55315,7 @@ async function generateSessionTitle(tool, firstMessage, deps = {}) {
55262
55315
  clearTimeout(timer);
55263
55316
  if (proc.exitCode === null && proc.signalCode === null) proc.kill("SIGKILL");
55264
55317
  cleanupWorkDir();
55265
- resolve8(title);
55318
+ resolve9(title);
55266
55319
  };
55267
55320
  const timer = setTimeout(() => {
55268
55321
  deps.logger?.warn("title-gen timed out", { tool, timeoutMs });
@@ -55320,13 +55373,13 @@ function isPreviewPortAllowed(port, cfg) {
55320
55373
  return cfg.allowedPorts.includes(port);
55321
55374
  }
55322
55375
  function proxyPreviewHttp(req, res, port) {
55323
- return new Promise((resolve8) => {
55376
+ return new Promise((resolve9) => {
55324
55377
  const upstream = import_node_http.default.request(
55325
55378
  { host: "localhost", port, method: req.method, path: req.url, headers: req.headers },
55326
55379
  (upRes) => {
55327
55380
  res.writeHead(upRes.statusCode || 502, upRes.headers);
55328
55381
  upRes.pipe(res);
55329
- upRes.on("end", () => resolve8());
55382
+ upRes.on("end", () => resolve9());
55330
55383
  }
55331
55384
  );
55332
55385
  upstream.on("error", (e) => {
@@ -55334,7 +55387,7 @@ function proxyPreviewHttp(req, res, port) {
55334
55387
  res.writeHead(502, { "content-type": "text/plain; charset=utf-8" });
55335
55388
  }
55336
55389
  res.end(`preview upstream error: ${e.message}`);
55337
- resolve8();
55390
+ resolve9();
55338
55391
  });
55339
55392
  req.pipe(upstream);
55340
55393
  });
@@ -55377,7 +55430,7 @@ var LocalWsServer = class {
55377
55430
  pingIntervalMs;
55378
55431
  async start() {
55379
55432
  const host = this.opts.host ?? "127.0.0.1";
55380
- await new Promise((resolve8, reject) => {
55433
+ await new Promise((resolve9, reject) => {
55381
55434
  const httpServer = import_node_http2.default.createServer((req, res) => this.handleHttpRequest(req, res));
55382
55435
  const wss = new import_websocket_server.default({ noServer: true, clientTracking: true });
55383
55436
  httpServer.on("upgrade", (req, socket, head) => {
@@ -55403,7 +55456,7 @@ var LocalWsServer = class {
55403
55456
  });
55404
55457
  httpServer.on("listening", () => {
55405
55458
  this.logger?.info("ws listening", { host, port: this.opts.port });
55406
- resolve8();
55459
+ resolve9();
55407
55460
  });
55408
55461
  httpServer.on("error", (err) => {
55409
55462
  this.logger?.error("ws server error", { err: err.message });
@@ -55424,11 +55477,11 @@ var LocalWsServer = class {
55424
55477
  if (c.pingTimer) clearInterval(c.pingTimer);
55425
55478
  }
55426
55479
  this.clients.clear();
55427
- await new Promise((resolve8) => {
55428
- this.wss?.close(() => resolve8());
55480
+ await new Promise((resolve9) => {
55481
+ this.wss?.close(() => resolve9());
55429
55482
  });
55430
- await new Promise((resolve8) => {
55431
- this.httpServer?.close(() => resolve8());
55483
+ await new Promise((resolve9) => {
55484
+ this.httpServer?.close(() => resolve9());
55432
55485
  });
55433
55486
  this.wss = null;
55434
55487
  this.httpServer = null;
@@ -55971,7 +56024,7 @@ async function authenticate(token, deps) {
55971
56024
 
55972
56025
  // src/legacy-cleanup.ts
55973
56026
  var fs40 = __toESM(require("fs/promises"), 1);
55974
- var path41 = __toESM(require("path"), 1);
56027
+ var path42 = __toESM(require("path"), 1);
55975
56028
  var LEGACY_FILES = [
55976
56029
  "personal-capability.json",
55977
56030
  "received-capabilities.json",
@@ -55980,7 +56033,7 @@ var LEGACY_FILES = [
55980
56033
  async function cleanupLegacyCapabilityFiles(dataDir, logger) {
55981
56034
  const removed = [];
55982
56035
  for (const name of LEGACY_FILES) {
55983
- const p2 = path41.join(dataDir, name);
56036
+ const p2 = path42.join(dataDir, name);
55984
56037
  try {
55985
56038
  await fs40.unlink(p2);
55986
56039
  removed.push(name);
@@ -55995,7 +56048,7 @@ async function cleanupLegacyCapabilityFiles(dataDir, logger) {
55995
56048
 
55996
56049
  // src/inbox/inbox-store.ts
55997
56050
  var fs41 = __toESM(require("fs"), 1);
55998
- var path42 = __toESM(require("path"), 1);
56051
+ var path43 = __toESM(require("path"), 1);
55999
56052
  var INBOX_SUBDIR = "inbox";
56000
56053
  var InboxStore = class {
56001
56054
  constructor(dataDir) {
@@ -56093,10 +56146,10 @@ var InboxStore = class {
56093
56146
  }
56094
56147
  }
56095
56148
  dirPath() {
56096
- return path42.join(this.dataDir, INBOX_SUBDIR);
56149
+ return path43.join(this.dataDir, INBOX_SUBDIR);
56097
56150
  }
56098
56151
  filePath(peerDeviceId) {
56099
- return path42.join(this.dirPath(), `${peerDeviceId}.jsonl`);
56152
+ return path43.join(this.dirPath(), `${peerDeviceId}.jsonl`);
56100
56153
  }
56101
56154
  };
56102
56155
  function parseAllLines(raw) {
@@ -56185,7 +56238,7 @@ var InboxManager = class {
56185
56238
 
56186
56239
  // src/state/contact-store.ts
56187
56240
  var fs42 = __toESM(require("fs"), 1);
56188
- var path43 = __toESM(require("path"), 1);
56241
+ var path44 = __toESM(require("path"), 1);
56189
56242
  var FILE_NAME = "contacts.json";
56190
56243
  var ContactStore = class {
56191
56244
  constructor(dataDir) {
@@ -56195,7 +56248,7 @@ var ContactStore = class {
56195
56248
  contacts = /* @__PURE__ */ new Map();
56196
56249
  load() {
56197
56250
  this.contacts.clear();
56198
- const file = path43.join(this.dataDir, FILE_NAME);
56251
+ const file = path44.join(this.dataDir, FILE_NAME);
56199
56252
  let raw;
56200
56253
  try {
56201
56254
  raw = fs42.readFileSync(file, "utf8");
@@ -56267,7 +56320,7 @@ var ContactStore = class {
56267
56320
  return true;
56268
56321
  }
56269
56322
  flush() {
56270
- const file = path43.join(this.dataDir, FILE_NAME);
56323
+ const file = path44.join(this.dataDir, FILE_NAME);
56271
56324
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
56272
56325
  const content = JSON.stringify(
56273
56326
  { contacts: Array.from(this.contacts.values()) },
@@ -56293,16 +56346,16 @@ var HANDSHAKE_TIMEOUT_MS = 5e3;
56293
56346
  var RPC_TIMEOUT_MS = 5e3;
56294
56347
  async function connectRemote(args) {
56295
56348
  const ws = new wrapper_default(args.url);
56296
- await new Promise((resolve8, reject) => {
56349
+ await new Promise((resolve9, reject) => {
56297
56350
  const onError = (e) => reject(e);
56298
56351
  ws.once("open", () => {
56299
56352
  ws.off("error", onError);
56300
- resolve8();
56353
+ resolve9();
56301
56354
  });
56302
56355
  ws.once("error", onError);
56303
56356
  });
56304
56357
  ws.send(JSON.stringify({ type: "auth", token: args.token }));
56305
- await new Promise((resolve8, reject) => {
56358
+ await new Promise((resolve9, reject) => {
56306
56359
  const onMessage = (raw) => {
56307
56360
  let f;
56308
56361
  try {
@@ -56312,7 +56365,7 @@ async function connectRemote(args) {
56312
56365
  }
56313
56366
  if (f.type === "auth:ok") {
56314
56367
  finish();
56315
- resolve8();
56368
+ resolve9();
56316
56369
  return;
56317
56370
  }
56318
56371
  if (f.type === "auth:error" || f.code === 4401) {
@@ -56343,7 +56396,7 @@ async function connectRemote(args) {
56343
56396
  });
56344
56397
  function call(method, payload) {
56345
56398
  const requestId = crypto5.randomUUID();
56346
- return new Promise((resolve8, reject) => {
56399
+ return new Promise((resolve9, reject) => {
56347
56400
  const onMessage = (raw) => {
56348
56401
  let f;
56349
56402
  try {
@@ -56356,7 +56409,7 @@ async function connectRemote(args) {
56356
56409
  if (f.error || f.type === "error" || f.type?.endsWith(":error")) {
56357
56410
  reject(new Error(f.message ?? f.error ?? "rpc error"));
56358
56411
  } else {
56359
- resolve8(f);
56412
+ resolve9(f);
56360
56413
  }
56361
56414
  };
56362
56415
  ws.on("message", onMessage);
@@ -56389,52 +56442,52 @@ async function connectRemote(args) {
56389
56442
 
56390
56443
  // src/migrations/2026-05-20-flatten-sessions.ts
56391
56444
  var fs43 = __toESM(require("fs"), 1);
56392
- var path44 = __toESM(require("path"), 1);
56445
+ var path45 = __toESM(require("path"), 1);
56393
56446
  var MIGRATION_FLAG_NAME = ".migration.v1.done";
56394
56447
  function migrateFlattenSessions(opts) {
56395
56448
  const dataDir = opts.dataDir;
56396
56449
  const now = opts.now ?? Date.now;
56397
- const sessionsDir = path44.join(dataDir, "sessions");
56398
- const flagPath = path44.join(sessionsDir, MIGRATION_FLAG_NAME);
56450
+ const sessionsDir = path45.join(dataDir, "sessions");
56451
+ const flagPath = path45.join(sessionsDir, MIGRATION_FLAG_NAME);
56399
56452
  if (existsSync3(flagPath)) {
56400
56453
  return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
56401
56454
  }
56402
56455
  let movedBare = 0;
56403
56456
  let movedVmOwner = 0;
56404
56457
  let archivedListener = 0;
56405
- const defaultDir = path44.join(sessionsDir, "default");
56458
+ const defaultDir = path45.join(sessionsDir, "default");
56406
56459
  if (existsSync3(defaultDir)) {
56407
56460
  for (const entry of readdirSafe(defaultDir)) {
56408
56461
  if (!entry.endsWith(".json")) continue;
56409
- const src = path44.join(defaultDir, entry);
56410
- const dst = path44.join(sessionsDir, entry);
56462
+ const src = path45.join(defaultDir, entry);
56463
+ const dst = path45.join(sessionsDir, entry);
56411
56464
  fs43.renameSync(src, dst);
56412
56465
  movedBare += 1;
56413
56466
  }
56414
56467
  rmdirIfEmpty(defaultDir);
56415
56468
  }
56416
56469
  for (const pid of readdirSafe(sessionsDir)) {
56417
- const personaDir = path44.join(sessionsDir, pid);
56470
+ const personaDir = path45.join(sessionsDir, pid);
56418
56471
  if (!isDir(personaDir)) continue;
56419
56472
  if (pid === "default") continue;
56420
- const ownerSrc = path44.join(personaDir, "owner");
56473
+ const ownerSrc = path45.join(personaDir, "owner");
56421
56474
  if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
56422
- const ownerDst = path44.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
56475
+ const ownerDst = path45.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
56423
56476
  fs43.mkdirSync(ownerDst, { recursive: true });
56424
56477
  for (const file of readdirSafe(ownerSrc)) {
56425
56478
  if (!file.endsWith(".json")) continue;
56426
- fs43.renameSync(path44.join(ownerSrc, file), path44.join(ownerDst, file));
56479
+ fs43.renameSync(path45.join(ownerSrc, file), path45.join(ownerDst, file));
56427
56480
  movedVmOwner += 1;
56428
56481
  }
56429
56482
  rmdirIfEmpty(ownerSrc);
56430
56483
  }
56431
- const listenerSrc = path44.join(personaDir, "listener");
56484
+ const listenerSrc = path45.join(personaDir, "listener");
56432
56485
  if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
56433
- const archiveDst = path44.join(dataDir, ".legacy", `listener-${pid}`);
56486
+ const archiveDst = path45.join(dataDir, ".legacy", `listener-${pid}`);
56434
56487
  fs43.mkdirSync(archiveDst, { recursive: true });
56435
56488
  for (const file of readdirSafe(listenerSrc)) {
56436
56489
  if (!file.endsWith(".json")) continue;
56437
- fs43.renameSync(path44.join(listenerSrc, file), path44.join(archiveDst, file));
56490
+ fs43.renameSync(path45.join(listenerSrc, file), path45.join(archiveDst, file));
56438
56491
  archivedListener += 1;
56439
56492
  }
56440
56493
  rmdirIfEmpty(listenerSrc);
@@ -56482,13 +56535,13 @@ function rmdirIfEmpty(p2) {
56482
56535
 
56483
56536
  // src/migrations/2026-08-18-drop-seeded-projects.ts
56484
56537
  var fs44 = __toESM(require("fs"), 1);
56485
- var path45 = __toESM(require("path"), 1);
56538
+ var path46 = __toESM(require("path"), 1);
56486
56539
  var DROP_SEEDED_PROJECTS_FLAG = ".projects-seed-dropped.v1.done";
56487
56540
  function dropSeededProjects(opts) {
56488
56541
  fs44.mkdirSync(opts.dataDir, { recursive: true });
56489
- const flag = path45.join(opts.dataDir, DROP_SEEDED_PROJECTS_FLAG);
56542
+ const flag = path46.join(opts.dataDir, DROP_SEEDED_PROJECTS_FLAG);
56490
56543
  if (fs44.existsSync(flag)) return { skipped: true, dropped: 0, backup: null };
56491
- const file = path45.join(opts.dataDir, "projects.json");
56544
+ const file = path46.join(opts.dataDir, "projects.json");
56492
56545
  let raw = null;
56493
56546
  let dropped = 0;
56494
56547
  try {
@@ -56498,9 +56551,9 @@ function dropSeededProjects(opts) {
56498
56551
  }
56499
56552
  let backup = null;
56500
56553
  if (raw != null && dropped > 0) {
56501
- const dir = path45.join(opts.dataDir, "backups");
56554
+ const dir = path46.join(opts.dataDir, "backups");
56502
56555
  fs44.mkdirSync(dir, { recursive: true });
56503
- backup = path45.join(dir, `projects.seed-dropped.${(opts.now ?? Date.now)()}.json`);
56556
+ backup = path46.join(dir, `projects.seed-dropped.${(opts.now ?? Date.now)()}.json`);
56504
56557
  fs44.writeFileSync(backup, raw);
56505
56558
  }
56506
56559
  if (raw != null || dropped > 0) {
@@ -56923,7 +56976,7 @@ function authedRpcErrorStatus(code) {
56923
56976
  }
56924
56977
  var LARK_BOT_EVENT_MAX_BYTES = 64 * 1024;
56925
56978
  async function readRawBody(req, max) {
56926
- return await new Promise((resolve8, reject) => {
56979
+ return await new Promise((resolve9, reject) => {
56927
56980
  let size = 0;
56928
56981
  const chunks = [];
56929
56982
  req.on("data", (c) => {
@@ -56935,12 +56988,12 @@ async function readRawBody(req, max) {
56935
56988
  }
56936
56989
  chunks.push(c);
56937
56990
  });
56938
- req.on("end", () => resolve8(Buffer.concat(chunks).toString("utf8")));
56991
+ req.on("end", () => resolve9(Buffer.concat(chunks).toString("utf8")));
56939
56992
  req.on("error", reject);
56940
56993
  });
56941
56994
  }
56942
56995
  async function readJsonBody(req, max) {
56943
- return await new Promise((resolve8, reject) => {
56996
+ return await new Promise((resolve9, reject) => {
56944
56997
  let size = 0;
56945
56998
  const chunks = [];
56946
56999
  req.on("data", (c) => {
@@ -56954,9 +57007,9 @@ async function readJsonBody(req, max) {
56954
57007
  });
56955
57008
  req.on("end", () => {
56956
57009
  const raw = Buffer.concat(chunks).toString("utf8");
56957
- if (!raw) return resolve8({});
57010
+ if (!raw) return resolve9({});
56958
57011
  try {
56959
- resolve8(JSON.parse(raw));
57012
+ resolve9(JSON.parse(raw));
56960
57013
  } catch {
56961
57014
  reject(new Error("invalid JSON body"));
56962
57015
  }
@@ -58001,10 +58054,10 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
58001
58054
  const work = import_node_path43.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
58002
58055
  import_node_fs39.default.mkdirSync(work, { recursive: true });
58003
58056
  try {
58004
- await new Promise((resolve8, reject) => {
58057
+ await new Promise((resolve9, reject) => {
58005
58058
  const proc = (0, import_node_child_process9.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
58006
58059
  proc.on("error", reject);
58007
- proc.on("exit", (code) => code === 0 ? resolve8() : reject(new Error(`tar exited ${code}`)));
58060
+ proc.on("exit", (code) => code === 0 ? resolve9() : reject(new Error(`tar exited ${code}`)));
58008
58061
  });
58009
58062
  const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
58010
58063
  const src = import_node_path43.default.join(work, dirName, "frpc");
@@ -58105,7 +58158,7 @@ async function killStaleFrpc(deps) {
58105
58158
  }
58106
58159
  async function defaultScanFrpcPidsByCmdline(tomlPath, logger) {
58107
58160
  if (process.platform === "win32") return [];
58108
- return new Promise((resolve8) => {
58161
+ return new Promise((resolve9) => {
58109
58162
  const ps = (0, import_node_child_process10.spawn)("ps", ["-axo", "pid=,command="], { stdio: ["ignore", "pipe", "ignore"] });
58110
58163
  let buf = "";
58111
58164
  ps.stdout.on("data", (c) => {
@@ -58122,11 +58175,11 @@ async function defaultScanFrpcPidsByCmdline(tomlPath, logger) {
58122
58175
  const pid = parseInt(m2[1], 10);
58123
58176
  if (Number.isFinite(pid) && pid > 0) pids.push(pid);
58124
58177
  }
58125
- resolve8(pids);
58178
+ resolve9(pids);
58126
58179
  });
58127
58180
  ps.on("error", (e) => {
58128
58181
  logger?.warn("tunnel: ps scan failed", { err: e.message });
58129
- resolve8([]);
58182
+ resolve9([]);
58130
58183
  });
58131
58184
  });
58132
58185
  }
@@ -58204,17 +58257,17 @@ var TunnelManager = class {
58204
58257
  return;
58205
58258
  }
58206
58259
  proc.kill("SIGTERM");
58207
- await new Promise((resolve8) => {
58260
+ await new Promise((resolve9) => {
58208
58261
  const t = setTimeout(() => {
58209
58262
  try {
58210
58263
  proc.kill("SIGKILL");
58211
58264
  } catch {
58212
58265
  }
58213
- resolve8();
58266
+ resolve9();
58214
58267
  }, 5e3);
58215
58268
  proc.once("exit", () => {
58216
58269
  clearTimeout(t);
58217
- resolve8();
58270
+ resolve9();
58218
58271
  });
58219
58272
  });
58220
58273
  clearFrpcPid(this.deps.dataDir);
@@ -58320,14 +58373,14 @@ function formatFrpcTail(raw, maxLines = 12) {
58320
58373
  return ["\u2500\u2500\u2500 frpc output (last lines) \u2500\u2500\u2500", tail, "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"].join("\n");
58321
58374
  }
58322
58375
  async function waitForFrpcReady(proc, timeoutMs) {
58323
- return new Promise((resolve8) => {
58376
+ return new Promise((resolve9) => {
58324
58377
  let settled = false;
58325
58378
  let buf = "";
58326
58379
  const finish = (r) => {
58327
58380
  if (settled) return;
58328
58381
  settled = true;
58329
58382
  cleanup();
58330
- resolve8(r);
58383
+ resolve9(r);
58331
58384
  };
58332
58385
  const onData = (chunk) => {
58333
58386
  buf += String(chunk);
@@ -58672,9 +58725,9 @@ var CentralClientError = class extends Error {
58672
58725
  code;
58673
58726
  cause;
58674
58727
  };
58675
- async function centralRequest(opts, path86, init) {
58728
+ async function centralRequest(opts, path87, init) {
58676
58729
  const f = opts.fetchImpl ?? globalThis.fetch;
58677
- const url = `${opts.api.replace(/\/+$/, "")}${path86}`;
58730
+ const url = `${opts.api.replace(/\/+$/, "")}${path87}`;
58678
58731
  const ctrl = new AbortController();
58679
58732
  const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
58680
58733
  let res;
@@ -58869,7 +58922,7 @@ function verifyConnectToken(args) {
58869
58922
 
58870
58923
  // src/feishu-auth/server-key.ts
58871
58924
  var fs58 = __toESM(require("fs"), 1);
58872
- var path61 = __toESM(require("path"), 1);
58925
+ var path62 = __toESM(require("path"), 1);
58873
58926
  var FILE_NAME2 = "server-signing-key.json";
58874
58927
  var ServerKeyStore = class {
58875
58928
  constructor(dataDir) {
@@ -58877,7 +58930,7 @@ var ServerKeyStore = class {
58877
58930
  }
58878
58931
  dataDir;
58879
58932
  filePath() {
58880
- return path61.join(this.dataDir, FILE_NAME2);
58933
+ return path62.join(this.dataDir, FILE_NAME2);
58881
58934
  }
58882
58935
  /** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
58883
58936
  read() {
@@ -59751,7 +59804,7 @@ function buildPermissionHandlers(deps) {
59751
59804
  }
59752
59805
 
59753
59806
  // src/handlers/history.ts
59754
- var path66 = __toESM(require("path"), 1);
59807
+ var path67 = __toESM(require("path"), 1);
59755
59808
  init_protocol();
59756
59809
 
59757
59810
  // src/session/recent-dirs.ts
@@ -59769,7 +59822,7 @@ function listRecentDirs(store, limit = 50) {
59769
59822
  }
59770
59823
 
59771
59824
  // src/permission/persona-paths.ts
59772
- var path65 = __toESM(require("path"), 1);
59825
+ var path66 = __toESM(require("path"), 1);
59773
59826
  function getAllowedPersonaIds(grants, action) {
59774
59827
  const ids = /* @__PURE__ */ new Set();
59775
59828
  for (const g2 of grants) {
@@ -59782,42 +59835,42 @@ function getAllowedPersonaIds(grants, action) {
59782
59835
  return ids;
59783
59836
  }
59784
59837
  function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
59785
- const target = path65.resolve(absPath);
59838
+ const target = path66.resolve(absPath);
59786
59839
  if (userWorkDir) {
59787
- const u = path65.resolve(userWorkDir);
59788
- const usep = u.endsWith(path65.sep) ? "" : path65.sep;
59840
+ const u = path66.resolve(userWorkDir);
59841
+ const usep = u.endsWith(path66.sep) ? "" : path66.sep;
59789
59842
  if (target === u || target.startsWith(u + usep)) return true;
59790
59843
  }
59791
- const root = path65.resolve(personaRoot);
59792
- const sep4 = root.endsWith(path65.sep) ? "" : path65.sep;
59844
+ const root = path66.resolve(personaRoot);
59845
+ const sep4 = root.endsWith(path66.sep) ? "" : path66.sep;
59793
59846
  if (!target.startsWith(root + sep4)) return false;
59794
- const rel = path65.relative(root, target);
59847
+ const rel = path66.relative(root, target);
59795
59848
  if (!rel || rel.startsWith("..")) return false;
59796
- const personaId2 = rel.split(path65.sep)[0];
59849
+ const personaId2 = rel.split(path66.sep)[0];
59797
59850
  if (!personaId2) return false;
59798
59851
  const allowed = getAllowedPersonaIds(grants, action);
59799
59852
  if (allowed === "*") return true;
59800
59853
  return allowed.has(personaId2);
59801
59854
  }
59802
59855
  function personaIdFromPath(absPath, personaRoot) {
59803
- const root = path65.resolve(personaRoot);
59804
- const target = path65.resolve(absPath);
59805
- const sep4 = root.endsWith(path65.sep) ? "" : path65.sep;
59856
+ const root = path66.resolve(personaRoot);
59857
+ const target = path66.resolve(absPath);
59858
+ const sep4 = root.endsWith(path66.sep) ? "" : path66.sep;
59806
59859
  if (!target.startsWith(root + sep4)) return null;
59807
- const rel = path65.relative(root, target);
59860
+ const rel = path66.relative(root, target);
59808
59861
  if (!rel || rel.startsWith("..")) return null;
59809
- const id = rel.split(path65.sep)[0];
59862
+ const id = rel.split(path66.sep)[0];
59810
59863
  return id || null;
59811
59864
  }
59812
59865
  function isPathWithin(dir, absPath) {
59813
- const d = path65.resolve(dir);
59814
- const t = path65.resolve(absPath);
59815
- const sep4 = d.endsWith(path65.sep) ? "" : path65.sep;
59866
+ const d = path66.resolve(dir);
59867
+ const t = path66.resolve(absPath);
59868
+ const sep4 = d.endsWith(path66.sep) ? "" : path66.sep;
59816
59869
  return t === d || t.startsWith(d + sep4);
59817
59870
  }
59818
59871
  function isPathInGuestBoundary(personaRoot, personaId2, userWorkDir, absPath) {
59819
59872
  if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
59820
- return personaIdFromPath(path65.resolve(absPath), personaRoot) === personaId2;
59873
+ return personaIdFromPath(path66.resolve(absPath), personaRoot) === personaId2;
59821
59874
  }
59822
59875
 
59823
59876
  // src/handlers/history.ts
@@ -59870,7 +59923,7 @@ function buildHistoryHandlers(deps) {
59870
59923
  if (!pid) return false;
59871
59924
  return isGuestPathAllowed(
59872
59925
  ctx.grants,
59873
- path66.join(personaRoot, pid),
59926
+ path67.join(personaRoot, pid),
59874
59927
  personaRoot,
59875
59928
  "read",
59876
59929
  userWorkDir
@@ -59882,7 +59935,7 @@ function buildHistoryHandlers(deps) {
59882
59935
  };
59883
59936
  const list = async (frame, _client, ctx) => {
59884
59937
  const args = HistoryListArgs.parse(frame);
59885
- assertGuestPath(ctx, path66.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
59938
+ assertGuestPath(ctx, path67.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
59886
59939
  const sessions = await history.listSessions(args);
59887
59940
  return { response: { type: "history:list", sessions } };
59888
59941
  };
@@ -59930,14 +59983,14 @@ function buildHistoryHandlers(deps) {
59930
59983
  };
59931
59984
  const subagents = async (frame, _client, ctx) => {
59932
59985
  const args = HistorySubagentsArgs.parse(frame);
59933
- assertGuestPath(ctx, path66.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
59986
+ assertGuestPath(ctx, path67.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
59934
59987
  assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagents");
59935
59988
  const subs = await historyReaderForToolSession(args.toolSessionId).listSubagents(args);
59936
59989
  return { response: { type: "history:subagents", subagents: subs } };
59937
59990
  };
59938
59991
  const subagentRead = async (frame, _client, ctx) => {
59939
59992
  const args = HistorySubagentReadArgs.parse(frame);
59940
- assertGuestPath(ctx, path66.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
59993
+ assertGuestPath(ctx, path67.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
59941
59994
  assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagent-read");
59942
59995
  const res = await historyReaderForToolSession(args.toolSessionId).readSubagent(args);
59943
59996
  return { response: { type: "history:subagent-read", ...res } };
@@ -59947,7 +60000,7 @@ function buildHistoryHandlers(deps) {
59947
60000
  if (ctx?.principal.kind === "guest" && personaRoot) {
59948
60001
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
59949
60002
  const filtered = dirs.filter(
59950
- (d) => isGuestPathAllowed(ctx.grants, path66.resolve(d.cwd), personaRoot, "read", userWorkDir)
60003
+ (d) => isGuestPathAllowed(ctx.grants, path67.resolve(d.cwd), personaRoot, "read", userWorkDir)
59951
60004
  );
59952
60005
  return { response: { type: "history:recentDirs", dirs: filtered } };
59953
60006
  }
@@ -59965,16 +60018,16 @@ function buildHistoryHandlers(deps) {
59965
60018
 
59966
60019
  // src/handlers/projects.ts
59967
60020
  var fs62 = __toESM(require("fs"), 1);
59968
- var os19 = __toESM(require("os"), 1);
59969
- var path67 = __toESM(require("path"), 1);
60021
+ var os20 = __toESM(require("os"), 1);
60022
+ var path68 = __toESM(require("path"), 1);
59970
60023
  var import_node_child_process13 = require("child_process");
59971
60024
  init_protocol();
59972
- var DEFAULT_PROJECTS_ROOT = path67.join(os19.homedir(), "Documents", "ChatGPT");
60025
+ var DEFAULT_PROJECTS_ROOT = path68.join(os20.homedir(), "Documents", "ChatGPT");
59973
60026
  function allocateDir(root, name) {
59974
- let candidate = path67.join(root, name);
60027
+ let candidate = path68.join(root, name);
59975
60028
  let n = 2;
59976
60029
  while (fs62.existsSync(candidate)) {
59977
- candidate = path67.join(root, `${name} ${n}`);
60030
+ candidate = path68.join(root, `${name} ${n}`);
59978
60031
  n += 1;
59979
60032
  }
59980
60033
  return candidate;
@@ -59989,6 +60042,29 @@ function buildProjectHandlers(deps) {
59989
60042
  const list = async () => ({
59990
60043
  response: { type: "project:list", projects: store().listMerged() }
59991
60044
  });
60045
+ const patch = async (frame) => {
60046
+ const args = ProjectPatchArgs.parse(frame);
60047
+ if (!store().patch(args.path, { pinnedAt: args.pinnedAt })) {
60048
+ throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a listed project: ${args.path}`);
60049
+ }
60050
+ return { response: { type: "project:patch" } };
60051
+ };
60052
+ const reveal = async (frame) => {
60053
+ const args = ProjectRevealArgs.parse(frame);
60054
+ if (process.platform !== "darwin") {
60055
+ throw new ClawdError(ERROR_CODES.INVALID_CWD, "project:reveal \u4EC5\u652F\u6301 macOS");
60056
+ }
60057
+ try {
60058
+ if (!fs62.statSync(args.path).isDirectory()) throw new Error("not dir");
60059
+ } catch {
60060
+ throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
60061
+ }
60062
+ const r = (0, import_node_child_process13.spawnSync)("open", ["-R", args.path], { stdio: "ignore" });
60063
+ if (r.status !== 0) {
60064
+ throw new ClawdError(ERROR_CODES.INVALID_CWD, `open -R \u5931\u8D25: exit ${r.status}`);
60065
+ }
60066
+ return { response: { type: "project:reveal" } };
60067
+ };
59992
60068
  const create = async (frame) => {
59993
60069
  const args = ProjectCreateArgs.parse(frame);
59994
60070
  const root = deps.projectsRoot ?? DEFAULT_PROJECTS_ROOT;
@@ -60027,12 +60103,17 @@ function buildProjectHandlers(deps) {
60027
60103
  }
60028
60104
  return { response: { type: "project:create", project: entry } };
60029
60105
  };
60030
- return { "project:list": list, "project:create": create };
60106
+ return {
60107
+ "project:list": list,
60108
+ "project:create": create,
60109
+ "project:patch": patch,
60110
+ "project:reveal": reveal
60111
+ };
60031
60112
  }
60032
60113
 
60033
60114
  // src/handlers/workspace.ts
60034
- var path68 = __toESM(require("path"), 1);
60035
- var os20 = __toESM(require("os"), 1);
60115
+ var path69 = __toESM(require("path"), 1);
60116
+ var os21 = __toESM(require("os"), 1);
60036
60117
  init_protocol();
60037
60118
  init_protocol();
60038
60119
  function buildEnabledPluginNames(personaManager, personaId2) {
@@ -60072,23 +60153,23 @@ function buildWorkspaceHandlers(deps) {
60072
60153
  const list = async (frame, _client, ctx) => {
60073
60154
  const args = WorkspaceListArgs.parse(frame);
60074
60155
  const isGuest = ctx?.principal.kind === "guest";
60075
- const fallbackCwd = isGuest && personaRoot ? personaRoot : os20.homedir();
60076
- const resolvedCwd = path68.resolve(args.cwd ?? fallbackCwd);
60077
- const target = args.path ? path68.resolve(resolvedCwd, args.path) : resolvedCwd;
60156
+ const fallbackCwd = isGuest && personaRoot ? personaRoot : os21.homedir();
60157
+ const resolvedCwd = path69.resolve(args.cwd ?? fallbackCwd);
60158
+ const target = args.path ? path69.resolve(resolvedCwd, args.path) : resolvedCwd;
60078
60159
  assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
60079
60160
  const res = workspace.list({ ...args, cwd: resolvedCwd });
60080
60161
  return { response: { type: "workspace:list", ...res } };
60081
60162
  };
60082
60163
  const read = async (frame, _client, ctx) => {
60083
60164
  const args = WorkspaceReadArgs.parse(frame);
60084
- const target = path68.isAbsolute(args.path) ? path68.resolve(args.path) : path68.resolve(args.cwd, args.path);
60165
+ const target = path69.isAbsolute(args.path) ? path69.resolve(args.path) : path69.resolve(args.cwd, args.path);
60085
60166
  assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
60086
60167
  const res = workspace.read(args);
60087
60168
  return { response: { type: "workspace:read", ...res } };
60088
60169
  };
60089
60170
  const skillsList = async (frame, _client, ctx) => {
60090
60171
  const args = SkillsListArgs.parse(frame);
60091
- const cwdAbs = path68.resolve(args.cwd);
60172
+ const cwdAbs = path69.resolve(args.cwd);
60092
60173
  assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
60093
60174
  const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
60094
60175
  if (ctx?.principal.kind === "guest" && personaRoot) {
@@ -60100,7 +60181,7 @@ function buildWorkspaceHandlers(deps) {
60100
60181
  };
60101
60182
  const agentsList = async (frame, _client, ctx) => {
60102
60183
  const args = AgentsListArgs.parse(frame);
60103
- const cwdAbs = path68.resolve(args.cwd);
60184
+ const cwdAbs = path69.resolve(args.cwd);
60104
60185
  assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
60105
60186
  if (args.tool === "codex") {
60106
60187
  return { response: { type: "agents:list", agents: [] } };
@@ -60122,7 +60203,7 @@ function buildWorkspaceHandlers(deps) {
60122
60203
  }
60123
60204
 
60124
60205
  // src/handlers/git.ts
60125
- var path70 = __toESM(require("path"), 1);
60206
+ var path71 = __toESM(require("path"), 1);
60126
60207
  init_protocol();
60127
60208
  init_protocol();
60128
60209
 
@@ -60209,7 +60290,7 @@ async function listGitBranches(cwd) {
60209
60290
  function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
60210
60291
  if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
60211
60292
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
60212
- if (!isGuestPathAllowed(ctx.grants, path70.resolve(cwd), personaRoot, "read", userWorkDir)) {
60293
+ if (!isGuestPathAllowed(ctx.grants, path71.resolve(cwd), personaRoot, "read", userWorkDir)) {
60213
60294
  throw new ClawdError(
60214
60295
  ERROR_CODES.UNAUTHORIZED,
60215
60296
  `guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
@@ -60950,6 +61031,8 @@ var METHOD_GRANT_MAP = {
60950
61031
  // project:*(sidebar 项目分区,spec 2026-08-17):registry 是 owner 本机资源,owner-only 一刀切
60951
61032
  "project:list": ADMIN_ANY,
60952
61033
  "project:create": ADMIN_ANY,
61034
+ "project:patch": ADMIN_ANY,
61035
+ "project:reveal": ADMIN_ANY,
60953
61036
  // github:*(PR 收件箱,spec 2026-08-11):走 owner 本机 gh 凭据,owner-only 一刀切
60954
61037
  "github:status": ADMIN_ANY,
60955
61038
  "github:prList": ADMIN_ANY,
@@ -61110,21 +61193,21 @@ function computeMethodAccess(args) {
61110
61193
  }
61111
61194
 
61112
61195
  // src/version.ts
61113
- var version = "0.2.376".length > 0 ? "0.2.376" : "dev";
61196
+ var version = "0.2.378".length > 0 ? "0.2.378" : "dev";
61114
61197
 
61115
61198
  // src/cli-probe/probe.ts
61116
61199
  var fs64 = __toESM(require("fs"), 1);
61117
- var path71 = __toESM(require("path"), 1);
61200
+ var path72 = __toESM(require("path"), 1);
61118
61201
  var PKG_NAME = "@clawos-dev/clawd";
61119
61202
  var BIN_NAME = "clawd";
61120
61203
  var MAX_PARENT_HOPS = 5;
61121
61204
  function probeGlobalCli(pathEnv) {
61122
61205
  if (!pathEnv) return null;
61123
- for (const dir of pathEnv.split(path71.delimiter)) {
61206
+ for (const dir of pathEnv.split(path72.delimiter)) {
61124
61207
  if (!dir) continue;
61125
61208
  let real;
61126
61209
  try {
61127
- real = fs64.realpathSync(path71.join(dir, BIN_NAME));
61210
+ real = fs64.realpathSync(path72.join(dir, BIN_NAME));
61128
61211
  } catch {
61129
61212
  continue;
61130
61213
  }
@@ -61134,15 +61217,15 @@ function probeGlobalCli(pathEnv) {
61134
61217
  return null;
61135
61218
  }
61136
61219
  function readOwnPackageVersion(entryPath) {
61137
- let dir = path71.dirname(entryPath);
61220
+ let dir = path72.dirname(entryPath);
61138
61221
  for (let i = 0; i < MAX_PARENT_HOPS; i++) {
61139
61222
  try {
61140
- const raw = fs64.readFileSync(path71.join(dir, "package.json"), "utf8");
61223
+ const raw = fs64.readFileSync(path72.join(dir, "package.json"), "utf8");
61141
61224
  const pkg = JSON.parse(raw);
61142
61225
  if (pkg.name !== PKG_NAME) return null;
61143
61226
  return typeof pkg.version === "string" && pkg.version ? pkg.version : null;
61144
61227
  } catch {
61145
- const parent = path71.dirname(dir);
61228
+ const parent = path72.dirname(dir);
61146
61229
  if (parent === dir) return null;
61147
61230
  dir = parent;
61148
61231
  }
@@ -62235,7 +62318,7 @@ var ProjectStore = class {
62235
62318
  */
62236
62319
  async scaffold(name, templateSrcDir, scaffoldScriptPath) {
62237
62320
  const destDir = this.projectDir(name);
62238
- return await new Promise((resolve8, reject) => {
62321
+ return await new Promise((resolve9, reject) => {
62239
62322
  const child = (0, import_node_child_process15.spawn)("bash", [scaffoldScriptPath, name, templateSrcDir, destDir], {
62240
62323
  env: { ...process.env, PATH: process.env.PATH ?? "" },
62241
62324
  stdio: ["ignore", "pipe", "pipe"]
@@ -62258,7 +62341,7 @@ var ProjectStore = class {
62258
62341
  });
62259
62342
  child.on("exit", (code, signal) => {
62260
62343
  clearTimeout(timer);
62261
- if (code === 0) resolve8({ stdout, stderr });
62344
+ if (code === 0) resolve9({ stdout, stderr });
62262
62345
  else reject(new Error(`scaffold exit ${code ?? signal}: ${stderr.slice(0, 500)}`));
62263
62346
  });
62264
62347
  });
@@ -62381,7 +62464,7 @@ async function killPortOccupants(port, ownedPids, logger) {
62381
62464
  }
62382
62465
  }
62383
62466
  function listPidsOnPort(port) {
62384
- return new Promise((resolve8, reject) => {
62467
+ return new Promise((resolve9, reject) => {
62385
62468
  (0, import_node_child_process16.execFile)(
62386
62469
  "lsof",
62387
62470
  ["-ti", `:${port}`],
@@ -62393,11 +62476,11 @@ function listPidsOnPort(port) {
62393
62476
  }
62394
62477
  const text = (stdout ?? "").toString().trim();
62395
62478
  if (!text) {
62396
- resolve8([]);
62479
+ resolve9([]);
62397
62480
  return;
62398
62481
  }
62399
62482
  const list = text.split("\n").map((s) => Number(s.trim())).filter((n) => Number.isInteger(n) && n > 0);
62400
- resolve8(list);
62483
+ resolve9(list);
62401
62484
  }
62402
62485
  );
62403
62486
  });
@@ -63621,7 +63704,7 @@ var MAX_TIMEOUT_MS = 3e5;
63621
63704
  var MAX_OUTPUT_BYTES = 1048576;
63622
63705
  function runCommand(command, opts = {}) {
63623
63706
  const timeoutMs = Math.min(opts.timeoutMs ?? DEFAULT_TIMEOUT_MS4, MAX_TIMEOUT_MS);
63624
- return new Promise((resolve8) => {
63707
+ return new Promise((resolve9) => {
63625
63708
  const child = (0, import_node_child_process18.spawn)("bash", ["-c", command], { cwd: import_node_os23.default.homedir() });
63626
63709
  const out = [];
63627
63710
  const err = [];
@@ -63662,7 +63745,7 @@ function runCommand(command, opts = {}) {
63662
63745
  }, timeoutMs);
63663
63746
  child.on("close", (code) => {
63664
63747
  clearTimeout(timer);
63665
- resolve8({
63748
+ resolve9({
63666
63749
  stdout: Buffer.concat(out).toString("utf8"),
63667
63750
  stderr: Buffer.concat(err).toString("utf8"),
63668
63751
  exitCode: timedOut ? null : code,
@@ -63673,7 +63756,7 @@ function runCommand(command, opts = {}) {
63673
63756
  });
63674
63757
  child.on("error", () => {
63675
63758
  clearTimeout(timer);
63676
- resolve8({
63759
+ resolve9({
63677
63760
  stdout: Buffer.concat(out).toString("utf8"),
63678
63761
  stderr: Buffer.concat(err).toString("utf8"),
63679
63762
  exitCode: null,
@@ -63848,10 +63931,10 @@ function parseVersionOutput(out) {
63848
63931
  return /(\d+\.\d+\.\d+)/.exec(out)?.[1];
63849
63932
  }
63850
63933
  function execVersion(bin) {
63851
- return new Promise((resolve8, reject) => {
63934
+ return new Promise((resolve9, reject) => {
63852
63935
  (0, import_node_child_process19.execFile)(bin, ["--version"], { timeout: 5e3 }, (err, stdout) => {
63853
63936
  if (err) reject(err);
63854
- else resolve8(String(stdout));
63937
+ else resolve9(String(stdout));
63855
63938
  });
63856
63939
  });
63857
63940
  }
@@ -64005,8 +64088,8 @@ var DevServerSupervisor = class extends import_node_events2.EventEmitter {
64005
64088
  });
64006
64089
  let readyResolve;
64007
64090
  let readyReject;
64008
- const readyPromise = new Promise((resolve8, reject) => {
64009
- readyResolve = resolve8;
64091
+ const readyPromise = new Promise((resolve9, reject) => {
64092
+ readyResolve = resolve9;
64010
64093
  readyReject = reject;
64011
64094
  });
64012
64095
  readyPromise.catch(() => {
@@ -64085,7 +64168,7 @@ var DevServerSupervisor = class extends import_node_events2.EventEmitter {
64085
64168
  if (!entry.ready) {
64086
64169
  entry.readyReject(new Error("dev server stopped before ready"));
64087
64170
  }
64088
- return new Promise((resolve8) => {
64171
+ return new Promise((resolve9) => {
64089
64172
  let settled = false;
64090
64173
  let killTimer;
64091
64174
  const cleanup = () => {
@@ -64093,7 +64176,7 @@ var DevServerSupervisor = class extends import_node_events2.EventEmitter {
64093
64176
  settled = true;
64094
64177
  if (killTimer) clearTimeout(killTimer);
64095
64178
  this.running.delete(sessionId);
64096
- resolve8();
64179
+ resolve9();
64097
64180
  };
64098
64181
  entry.process.once("exit", cleanup);
64099
64182
  const pid = entry.process.pid;
@@ -64175,7 +64258,7 @@ var DevServerSupervisor = class extends import_node_events2.EventEmitter {
64175
64258
  if (!entry) {
64176
64259
  return Promise.reject(new Error(`dev server for project "${projectName}" not running`));
64177
64260
  }
64178
- return new Promise((resolve8, reject) => {
64261
+ return new Promise((resolve9, reject) => {
64179
64262
  let settled = false;
64180
64263
  let timer;
64181
64264
  const finish = (err) => {
@@ -64183,7 +64266,7 @@ var DevServerSupervisor = class extends import_node_events2.EventEmitter {
64183
64266
  settled = true;
64184
64267
  if (timer) clearTimeout(timer);
64185
64268
  if (opts.signal) opts.signal.removeEventListener("abort", onAbort);
64186
- err ? reject(err) : resolve8();
64269
+ err ? reject(err) : resolve9();
64187
64270
  };
64188
64271
  const onAbort = () => finish(new Error("awaitReady aborted via signal"));
64189
64272
  entry.readyPromise.then(() => finish(), (err) => finish(err));
@@ -64266,16 +64349,16 @@ var PortExhaustedError = class extends Error {
64266
64349
  code = "PORT_EXHAUSTED";
64267
64350
  };
64268
64351
  function probe(port) {
64269
- return new Promise((resolve8) => {
64352
+ return new Promise((resolve9) => {
64270
64353
  const srv = import_node_net2.default.createServer();
64271
- srv.once("error", () => resolve8(false));
64354
+ srv.once("error", () => resolve9(false));
64272
64355
  srv.once("listening", () => {
64273
- srv.close(() => resolve8(true));
64356
+ srv.close(() => resolve9(true));
64274
64357
  });
64275
64358
  try {
64276
64359
  srv.listen({ port, host: "127.0.0.1", exclusive: true });
64277
64360
  } catch {
64278
- resolve8(false);
64361
+ resolve9(false);
64279
64362
  }
64280
64363
  });
64281
64364
  }
@@ -64370,7 +64453,7 @@ var Runtime = class {
64370
64453
  child.stdout.on("data", () => {
64371
64454
  });
64372
64455
  let earlyExit = null;
64373
- const exitPromise = new Promise((resolve8) => {
64456
+ const exitPromise = new Promise((resolve9) => {
64374
64457
  child.once("exit", (code, signal) => {
64375
64458
  earlyExit = { code, signal };
64376
64459
  const wasUnexpected = this.handles.get(extId) === handle;
@@ -64378,7 +64461,7 @@ var Runtime = class {
64378
64461
  this.handles.delete(extId);
64379
64462
  this.crashed.add(extId);
64380
64463
  }
64381
- resolve8();
64464
+ resolve9();
64382
64465
  });
64383
64466
  });
64384
64467
  this.handles.set(extId, handle);
@@ -64451,7 +64534,7 @@ ${handle.stderrTail}`
64451
64534
  }
64452
64535
  };
64453
64536
  killGroup("SIGTERM");
64454
- const exited = new Promise((resolve8) => child.once("exit", () => resolve8()));
64537
+ const exited = new Promise((resolve9) => child.once("exit", () => resolve9()));
64455
64538
  const timed = (0, import_promises14.setTimeout)(5e3).then(() => "timeout");
64456
64539
  const winner = await Promise.race([exited.then(() => "exited"), timed]);
64457
64540
  if (winner === "timeout" && child.exitCode === null) {