@clawos-dev/clawd 0.2.375 → 0.2.377

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 {
@@ -44402,6 +44423,12 @@ function buildConnectionPrompt(args) {
44402
44423
  }
44403
44424
  parts.push(line);
44404
44425
  }
44426
+ if (args.mode === "guest" && args.guestDeviceId) {
44427
+ parts.push("");
44428
+ parts.push(
44429
+ `\u5BF9\u65B9\u8BF4\u7684\u300C\u6211\u7684\u684C\u9762 / \u6211\u672C\u5730\u7684\u2026\u300D\u662F\u4ED6\u90A3\u53F0\u8BBE\u5907\u3001\u4E0D\u662F\u672C\u673A\uFF1B\u8981\u5728\u90A3\u8FB9\u770B\u6587\u4EF6\u6216\u8DD1\u547D\u4EE4\uFF0C\u7528 peer-ops \u7684 exec\uFF0CpeerDeviceId \u586B ${args.guestDeviceId}\u3002`
44430
+ );
44431
+ }
44405
44432
  parts.push("");
44406
44433
  if (args.mode === "owner") {
44407
44434
  parts.push("\u81EA\u6211\u4ECB\u7ECD\u65F6\u4F7F\u7528\u7B2C\u4E00/\u7B2C\u4E8C\u4EBA\u79F0\uFF0C\u4F8B\u5982\u300C\u6211\u662F\u60A8\u7684 xxx \u52A9\u624B\u300D\u3002");
@@ -45389,8 +45416,8 @@ function startRecorder(opts) {
45389
45416
  const filePath = import_node_path6.default.join(dir, `${tsForFilename(now())}.jsonl`);
45390
45417
  let stream = null;
45391
45418
  let closedResolve;
45392
- const closed = new Promise((resolve8) => {
45393
- closedResolve = resolve8;
45419
+ const closed = new Promise((resolve9) => {
45420
+ closedResolve = resolve9;
45394
45421
  });
45395
45422
  let exited = false;
45396
45423
  const ensureStream = () => {
@@ -45523,13 +45550,13 @@ var SessionRunner = class {
45523
45550
  // 已经停止则立即 resolve;超时(默认 3000ms)抛错由上层透传成 RPC error
45524
45551
  async waitUntilStopped(timeoutMs = DEFAULT_WAIT_STOP_TIMEOUT_MS) {
45525
45552
  if (!this.state.procAlive) return;
45526
- return new Promise((resolve8, reject) => {
45553
+ return new Promise((resolve9, reject) => {
45527
45554
  let settled = false;
45528
45555
  const onStop = () => {
45529
45556
  if (settled) return;
45530
45557
  settled = true;
45531
45558
  clearTimeout(timer);
45532
- resolve8();
45559
+ resolve9();
45533
45560
  };
45534
45561
  const timer = setTimeout(() => {
45535
45562
  if (settled) return;
@@ -45629,7 +45656,7 @@ var SessionRunner = class {
45629
45656
  };
45630
45657
  const payload = JSON.stringify(frame) + "\n";
45631
45658
  const timeoutMs = opts.timeoutMs ?? DEFAULT_CONTROL_REQUEST_TIMEOUT_MS;
45632
- return new Promise((resolve8, reject) => {
45659
+ return new Promise((resolve9, reject) => {
45633
45660
  const timer = setTimeout(() => {
45634
45661
  const pending = this.pendingControlRequests.get(requestId);
45635
45662
  if (!pending) return;
@@ -45637,7 +45664,7 @@ var SessionRunner = class {
45637
45664
  reject(new Error(`control_request timeout: ${subtype}`));
45638
45665
  }, timeoutMs);
45639
45666
  timer.unref?.();
45640
- this.pendingControlRequests.set(requestId, { resolve: resolve8, reject, timer });
45667
+ this.pendingControlRequests.set(requestId, { resolve: resolve9, reject, timer });
45641
45668
  try {
45642
45669
  proc.stdin?.write(payload);
45643
45670
  this.recorder?.tapStdinWrite(payload);
@@ -48182,12 +48209,19 @@ var SessionManager = class {
48182
48209
 
48183
48210
  // src/projects/store.ts
48184
48211
  var fs11 = __toESM(require("fs"), 1);
48185
- var os5 = __toESM(require("os"), 1);
48186
- var path12 = __toESM(require("path"), 1);
48212
+ var os6 = __toESM(require("os"), 1);
48213
+ var path13 = __toESM(require("path"), 1);
48187
48214
  init_protocol();
48188
48215
 
48189
48216
  // src/projects/codex-registry.ts
48190
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
+ }
48191
48225
  function readCodexProjects(opts) {
48192
48226
  let raw;
48193
48227
  try {
@@ -48225,6 +48259,8 @@ var ProjectsStore = class {
48225
48259
  }
48226
48260
  opts;
48227
48261
  entries = [];
48262
+ /** 见 ProjectAnnotation;与 entries 一起持久化在 projects.json */
48263
+ annotations = {};
48228
48264
  load() {
48229
48265
  let raw;
48230
48266
  try {
@@ -48235,26 +48271,29 @@ var ProjectsStore = class {
48235
48271
  try {
48236
48272
  const parsed = JSON.parse(raw);
48237
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 : {};
48238
48275
  } catch (err) {
48239
48276
  this.opts.logger?.warn("projects.json corrupt, rebuilding", { err: String(err) });
48240
48277
  this.entries = [];
48278
+ this.annotations = {};
48241
48279
  }
48242
48280
  }
48243
48281
  save() {
48244
- fs11.mkdirSync(path12.dirname(this.opts.file), { recursive: true });
48245
- 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
+ );
48246
48287
  }
48247
48288
  normalize(p2) {
48248
- const home = os5.homedir();
48249
- const expanded = p2 === "~" ? home : p2.startsWith("~/") ? path12.join(home, p2.slice(2)) : p2;
48250
- return path12.resolve(expanded);
48289
+ return normalizeProjectPath(p2);
48251
48290
  }
48252
48291
  isProjectablePath(p2) {
48253
48292
  const abs = this.normalize(p2);
48254
- const rel = path12.relative(path12.resolve(this.opts.clawdDir), abs);
48255
- 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));
48256
48295
  if (insideClawd) return false;
48257
- 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;
48258
48297
  return true;
48259
48298
  }
48260
48299
  list() {
@@ -48290,7 +48329,27 @@ var ProjectsStore = class {
48290
48329
  });
48291
48330
  }
48292
48331
  }
48293
- 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;
48294
48353
  }
48295
48354
  upsert(rawPath, name) {
48296
48355
  const entry = this.add(rawPath, name);
@@ -48305,7 +48364,7 @@ var ProjectsStore = class {
48305
48364
  if (existing) return existing;
48306
48365
  const entry = {
48307
48366
  path: abs,
48308
- name: name ?? path12.basename(abs),
48367
+ name: name ?? path13.basename(abs),
48309
48368
  createdAt: (this.opts.now ?? (() => (/* @__PURE__ */ new Date()).toISOString()))()
48310
48369
  };
48311
48370
  this.entries.push(entry);
@@ -48314,12 +48373,12 @@ var ProjectsStore = class {
48314
48373
  };
48315
48374
 
48316
48375
  // src/tools/codex-home.ts
48317
- var path13 = __toESM(require("path"), 1);
48318
- var norm = (p2) => path13.resolve(p2);
48376
+ var path14 = __toESM(require("path"), 1);
48377
+ var norm = (p2) => path14.resolve(p2);
48319
48378
  function resolveCodexHome(input) {
48320
48379
  const cwd = norm(input.cwd);
48321
- const rel = path13.relative(norm(input.personaRoot), cwd);
48322
- 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);
48323
48382
  if (isPersonaRoot) return input.sharedHome;
48324
48383
  if (input.projectPaths.some((p2) => norm(p2) === cwd)) return input.sharedHome;
48325
48384
  return input.isolatedHome;
@@ -48327,7 +48386,7 @@ function resolveCodexHome(input) {
48327
48386
 
48328
48387
  // src/persona/store.ts
48329
48388
  var fs12 = __toESM(require("fs"), 1);
48330
- var path14 = __toESM(require("path"), 1);
48389
+ var path15 = __toESM(require("path"), 1);
48331
48390
  init_protocol();
48332
48391
  var PersonaStore = class {
48333
48392
  constructor(root) {
@@ -48336,18 +48395,18 @@ var PersonaStore = class {
48336
48395
  }
48337
48396
  root;
48338
48397
  personaDir(personaId2) {
48339
- return path14.join(this.root, safeFileName(personaId2));
48398
+ return path15.join(this.root, safeFileName(personaId2));
48340
48399
  }
48341
48400
  metaPath(personaId2) {
48342
- return path14.join(this.personaDir(personaId2), ".clawd", "persona.json");
48401
+ return path15.join(this.personaDir(personaId2), ".clawd", "persona.json");
48343
48402
  }
48344
48403
  claudeMdPath(personaId2) {
48345
- return path14.join(this.personaDir(personaId2), "CLAUDE.md");
48404
+ return path15.join(this.personaDir(personaId2), "CLAUDE.md");
48346
48405
  }
48347
48406
  // codex 原生读 cwd 的 AGENTS.md。人格双写镜像:claude 读 CLAUDE.md、codex 读 AGENTS.md,
48348
48407
  // 两份内容恒一致,persona 切 tool 零迁移。
48349
48408
  agentsMdPath(personaId2) {
48350
- return path14.join(this.personaDir(personaId2), "AGENTS.md");
48409
+ return path15.join(this.personaDir(personaId2), "AGENTS.md");
48351
48410
  }
48352
48411
  /**
48353
48412
  * persona 级 sandbox base 落盘路径 —— 故意放 `.clawd/` 而非 `.claude/`,让 CC 的 project
@@ -48356,11 +48415,11 @@ var PersonaStore = class {
48356
48415
  * spawn 前 per-guest 动态拼到各自 session 目录的那份(base + 强制底座 + 本 guest userWorkDir carve)。
48357
48416
  */
48358
48417
  sandboxSettingsPath(personaId2) {
48359
- return path14.join(this.personaDir(personaId2), ".clawd", "sandbox-settings.json");
48418
+ return path15.join(this.personaDir(personaId2), ".clawd", "sandbox-settings.json");
48360
48419
  }
48361
48420
  write(persona, personality) {
48362
48421
  const dir = this.personaDir(persona.personaId);
48363
- fs12.mkdirSync(path14.join(dir, ".clawd"), { recursive: true });
48422
+ fs12.mkdirSync(path15.join(dir, ".clawd"), { recursive: true });
48364
48423
  this.atomicWrite(this.claudeMdPath(persona.personaId), personality);
48365
48424
  this.atomicWrite(this.agentsMdPath(persona.personaId), personality);
48366
48425
  this.writeSandboxSettings(persona.personaId, buildGuestSettingsV1());
@@ -48431,7 +48490,7 @@ var PersonaStore = class {
48431
48490
  };
48432
48491
  }
48433
48492
  codexSandboxSettingsPath(personaId2) {
48434
- return path14.join(this.personaDir(personaId2), ".clawd", "codex-sandbox.json");
48493
+ return path15.join(this.personaDir(personaId2), ".clawd", "codex-sandbox.json");
48435
48494
  }
48436
48495
  /** 读 codex-sandbox.json;不存在/损坏 → null。 */
48437
48496
  readCodexSandboxSettings(personaId2) {
@@ -48445,7 +48504,7 @@ var PersonaStore = class {
48445
48504
  }
48446
48505
  /** 覆盖写 codex-sandbox.json(seed/migrate 用)。 */
48447
48506
  writeCodexSandboxSettings(personaId2, settings) {
48448
- const dir = path14.join(this.personaDir(personaId2), ".clawd");
48507
+ const dir = path15.join(this.personaDir(personaId2), ".clawd");
48449
48508
  fs12.mkdirSync(dir, { recursive: true });
48450
48509
  this.atomicWrite(this.codexSandboxSettingsPath(personaId2), JSON.stringify(settings, null, 2));
48451
48510
  }
@@ -48487,14 +48546,14 @@ var PersonaStore = class {
48487
48546
  }
48488
48547
  /** Persona 私有 skills 目录路径:<personaDir>/.claude/skills */
48489
48548
  skillsDir(personaId2) {
48490
- return path14.join(this.personaDir(personaId2), ".claude", "skills");
48549
+ return path15.join(this.personaDir(personaId2), ".claude", "skills");
48491
48550
  }
48492
48551
  /**
48493
48552
  * Claude Code 项目级 settings 路径:`<personaDir>/.claude/settings.json`。
48494
48553
  * 这里只读 `enabledPlugins` 字段,由 owner 通过 CC `/plugin` 之类命令维护,daemon 不写。
48495
48554
  */
48496
48555
  claudeSettingsPath(personaId2) {
48497
- return path14.join(this.personaDir(personaId2), ".claude", "settings.json");
48556
+ return path15.join(this.personaDir(personaId2), ".claude", "settings.json");
48498
48557
  }
48499
48558
  /**
48500
48559
  * 读取 persona 的 `.claude/settings.json` 中 `enabledPlugins` map,把 value === true
@@ -48528,7 +48587,7 @@ var PersonaStore = class {
48528
48587
  list() {
48529
48588
  if (!fs12.existsSync(this.root)) return [];
48530
48589
  return fs12.readdirSync(this.root).filter((name) => {
48531
- return fs12.existsSync(path14.join(this.root, name, ".clawd", "persona.json"));
48590
+ return fs12.existsSync(path15.join(this.root, name, ".clawd", "persona.json"));
48532
48591
  });
48533
48592
  }
48534
48593
  remove(personaId2) {
@@ -48954,7 +49013,7 @@ var PersonaManager = class {
48954
49013
 
48955
49014
  // src/persona/seed.ts
48956
49015
  var fs14 = __toESM(require("fs"), 1);
48957
- var path16 = __toESM(require("path"), 1);
49016
+ var path17 = __toESM(require("path"), 1);
48958
49017
  var import_node_url = require("url");
48959
49018
  var import_meta = {};
48960
49019
  var DEFAULT_BYPASS_PROFILE = {
@@ -49133,14 +49192,14 @@ function bundleSiblingFromArgv(argv1, sibling) {
49133
49192
  real = fs14.realpathSync(argv1);
49134
49193
  } catch {
49135
49194
  }
49136
- return path16.resolve(path16.dirname(real), sibling);
49195
+ return path17.resolve(path17.dirname(real), sibling);
49137
49196
  }
49138
49197
  function findDefaultsRoot(logger) {
49139
49198
  const candidates = [];
49140
49199
  try {
49141
- const here = path16.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
49142
- candidates.push(path16.resolve(here, "defaults"));
49143
- 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"));
49144
49203
  } catch {
49145
49204
  }
49146
49205
  const fromArgv = bundleSiblingFromArgv(process.argv[1], "persona-defaults");
@@ -49164,7 +49223,7 @@ function seedDefaultPersonas(args) {
49164
49223
  args.logger.info("persona.seed.skip", { personaId: entry.personaId, reason: "exists" });
49165
49224
  continue;
49166
49225
  }
49167
- const bundleDir = path16.join(args.defaultsRoot, entry.personaId);
49226
+ const bundleDir = path17.join(args.defaultsRoot, entry.personaId);
49168
49227
  if (!fs14.existsSync(bundleDir)) {
49169
49228
  args.logger.warn("persona.seed.skip", {
49170
49229
  personaId: entry.personaId,
@@ -49173,7 +49232,7 @@ function seedDefaultPersonas(args) {
49173
49232
  });
49174
49233
  continue;
49175
49234
  }
49176
- const claudeMdPath = path16.join(bundleDir, "CLAUDE.md");
49235
+ const claudeMdPath = path17.join(bundleDir, "CLAUDE.md");
49177
49236
  if (!fs14.existsSync(claudeMdPath)) {
49178
49237
  args.logger.warn("persona.seed.skip", {
49179
49238
  personaId: entry.personaId,
@@ -49209,13 +49268,13 @@ function seedDefaultPersonas(args) {
49209
49268
  }
49210
49269
  }
49211
49270
  function skipNodeModulesUnder(srcRoot) {
49212
- 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");
49213
49272
  }
49214
49273
  function copyBundleExtras(srcDir, dstDir) {
49215
49274
  for (const entry of fs14.readdirSync(srcDir, { withFileTypes: true })) {
49216
49275
  if (entry.name === "CLAUDE.md" || entry.name === ".clawd") continue;
49217
- const srcPath = path16.join(srcDir, entry.name);
49218
- const dstPath = path16.join(dstDir, entry.name);
49276
+ const srcPath = path17.join(srcDir, entry.name);
49277
+ const dstPath = path17.join(dstDir, entry.name);
49219
49278
  if (entry.isDirectory()) {
49220
49279
  fs14.cpSync(srcPath, dstPath, { recursive: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
49221
49280
  } else if (entry.isFile()) {
@@ -49226,7 +49285,7 @@ function copyBundleExtras(srcDir, dstDir) {
49226
49285
  var DAEMON_MANAGED_PATHS = ["extension-kit", "CLAUDE.md", ".mcp.json", ".claude/skills"];
49227
49286
  function replaceManagedPath(src, dst) {
49228
49287
  if (!fs14.statSync(src).isDirectory()) {
49229
- fs14.mkdirSync(path16.dirname(dst), { recursive: true });
49288
+ fs14.mkdirSync(path17.dirname(dst), { recursive: true });
49230
49289
  fs14.rmSync(dst, { recursive: true, force: true });
49231
49290
  fs14.cpSync(src, dst, { dereference: true });
49232
49291
  return;
@@ -49234,26 +49293,26 @@ function replaceManagedPath(src, dst) {
49234
49293
  fs14.mkdirSync(dst, { recursive: true });
49235
49294
  for (const e of fs14.readdirSync(src, { withFileTypes: true })) {
49236
49295
  if (e.name === "node_modules") continue;
49237
- const child = path16.join(dst, e.name);
49296
+ const child = path17.join(dst, e.name);
49238
49297
  fs14.rmSync(child, { recursive: true, force: true });
49239
- 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 });
49240
49299
  }
49241
49300
  }
49242
49301
  function refreshDaemonManagedDirs(args) {
49243
49302
  const entries = args.entries ?? DEFAULT_PERSONAS;
49244
49303
  for (const entry of entries) {
49245
- const bundleDir = path16.join(args.defaultsRoot, entry.personaId);
49304
+ const bundleDir = path17.join(args.defaultsRoot, entry.personaId);
49246
49305
  if (!fs14.existsSync(bundleDir)) continue;
49247
49306
  const personaDir = args.store.personaDirPath(entry.personaId);
49248
49307
  if (!fs14.existsSync(personaDir)) continue;
49249
49308
  for (const relPath of DAEMON_MANAGED_PATHS) {
49250
- const srcPath = path16.join(bundleDir, relPath);
49309
+ const srcPath = path17.join(bundleDir, relPath);
49251
49310
  if (!fs14.existsSync(srcPath)) continue;
49252
- const dstPath = path16.join(personaDir, relPath);
49311
+ const dstPath = path17.join(personaDir, relPath);
49253
49312
  try {
49254
49313
  replaceManagedPath(srcPath, dstPath);
49255
49314
  if (relPath === "CLAUDE.md") {
49256
- replaceManagedPath(srcPath, path16.join(personaDir, "AGENTS.md"));
49315
+ replaceManagedPath(srcPath, path17.join(personaDir, "AGENTS.md"));
49257
49316
  }
49258
49317
  args.logger.info("persona.refresh.synced", {
49259
49318
  personaId: entry.personaId,
@@ -49402,7 +49461,7 @@ function containsAnyFile(dir) {
49402
49461
  }
49403
49462
  for (const e of entries) {
49404
49463
  if (e.isDirectory()) {
49405
- if (containsAnyFile(path16.join(dir, e.name))) return true;
49464
+ if (containsAnyFile(path17.join(dir, e.name))) return true;
49406
49465
  } else {
49407
49466
  return true;
49408
49467
  }
@@ -49413,7 +49472,7 @@ function retirePersonaBuilder(args) {
49413
49472
  const dir = args.store.personaDirPath(PERSONA_BUILDER_ID);
49414
49473
  if (!fs14.existsSync(dir)) return;
49415
49474
  try {
49416
- 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"));
49417
49476
  if (!used) {
49418
49477
  args.store.remove(PERSONA_BUILDER_ID);
49419
49478
  args.logger.info("persona.retire-builder.removed", { personaId: PERSONA_BUILDER_ID });
@@ -49421,7 +49480,7 @@ function retirePersonaBuilder(args) {
49421
49480
  }
49422
49481
  let wrote = false;
49423
49482
  for (const name of ["CLAUDE.md", "AGENTS.md"]) {
49424
- const p2 = path16.join(dir, name);
49483
+ const p2 = path17.join(dir, name);
49425
49484
  const cur = fs14.existsSync(p2) ? fs14.readFileSync(p2, "utf8") : null;
49426
49485
  if (cur?.startsWith(PERSONA_BUILDER_TOMBSTONE_MARKER)) continue;
49427
49486
  fs14.writeFileSync(p2, PERSONA_BUILDER_TOMBSTONE);
@@ -49438,8 +49497,8 @@ function retirePersonaBuilder(args) {
49438
49497
  function findDeployKitRoot(logger) {
49439
49498
  const candidates = [];
49440
49499
  try {
49441
- const here = path16.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
49442
- 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"));
49443
49502
  } catch {
49444
49503
  }
49445
49504
  const fromArgv = bundleSiblingFromArgv(process.argv[1], "deploy-kit");
@@ -49457,7 +49516,7 @@ function findDeployKitRoot(logger) {
49457
49516
  return null;
49458
49517
  }
49459
49518
  function seedDeployKit(args) {
49460
- const dst = path16.join(args.dataDir, "deploy-kit");
49519
+ const dst = path17.join(args.dataDir, "deploy-kit");
49461
49520
  fs14.cpSync(args.deployKitBundleRoot, dst, {
49462
49521
  recursive: true,
49463
49522
  dereference: true,
@@ -49467,23 +49526,23 @@ function seedDeployKit(args) {
49467
49526
  args.logger.info("deploy-kit.seed.done", { dst });
49468
49527
  }
49469
49528
  function refreshDeployKit(args) {
49470
- const dst = path16.join(args.dataDir, "deploy-kit");
49529
+ const dst = path17.join(args.dataDir, "deploy-kit");
49471
49530
  if (!fs14.existsSync(dst)) {
49472
49531
  seedDeployKit(args);
49473
49532
  return;
49474
49533
  }
49475
49534
  for (const sub of ["scripts", "contract"]) {
49476
- const s = path16.join(args.deployKitBundleRoot, sub);
49535
+ const s = path17.join(args.deployKitBundleRoot, sub);
49477
49536
  if (fs14.existsSync(s)) {
49478
- 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 });
49479
49538
  }
49480
49539
  }
49481
- const secretsSrc = path16.join(args.deployKitBundleRoot, ".secrets");
49540
+ const secretsSrc = path17.join(args.deployKitBundleRoot, ".secrets");
49482
49541
  if (fs14.existsSync(secretsSrc)) {
49483
- fs14.mkdirSync(path16.join(dst, ".secrets"), { recursive: true });
49542
+ fs14.mkdirSync(path17.join(dst, ".secrets"), { recursive: true });
49484
49543
  for (const f of fs14.readdirSync(secretsSrc)) {
49485
49544
  if (f.endsWith(".local")) continue;
49486
- fs14.copyFileSync(path16.join(secretsSrc, f), path16.join(dst, ".secrets", f));
49545
+ fs14.copyFileSync(path17.join(secretsSrc, f), path17.join(dst, ".secrets", f));
49487
49546
  }
49488
49547
  }
49489
49548
  args.logger.info("deploy-kit.refresh.done", { dst });
@@ -49774,8 +49833,8 @@ var CodexAppServerClient = class {
49774
49833
  pending = /* @__PURE__ */ new Map();
49775
49834
  request(method, params) {
49776
49835
  const id = this.nextId++;
49777
- return new Promise((resolve8, reject) => {
49778
- this.pending.set(id, { resolve: resolve8, reject });
49836
+ return new Promise((resolve9, reject) => {
49837
+ this.pending.set(id, { resolve: resolve9, reject });
49779
49838
  this.write({ jsonrpc: "2.0", method, id, params });
49780
49839
  });
49781
49840
  }
@@ -50208,8 +50267,8 @@ function turnStartInput(text) {
50208
50267
  const items = [];
50209
50268
  let leftover = text;
50210
50269
  for (const m2 of text.matchAll(SKILL_RE)) {
50211
- const [marker, name, path86] = m2;
50212
- items.push({ type: "skill", name, path: path86 });
50270
+ const [marker, name, path87] = m2;
50271
+ items.push({ type: "skill", name, path: path87 });
50213
50272
  leftover = leftover.replace(marker, "");
50214
50273
  }
50215
50274
  for (const m2 of text.matchAll(ATTACHMENT_RE2)) {
@@ -51294,10 +51353,10 @@ function createTerminalSurface(opts) {
51294
51353
  },
51295
51354
  writeBytes(data, seq) {
51296
51355
  pendingParse++;
51297
- return new Promise((resolve8) => {
51356
+ return new Promise((resolve9) => {
51298
51357
  term.write(data, () => {
51299
51358
  if (disposed) {
51300
- resolve8();
51359
+ resolve9();
51301
51360
  return;
51302
51361
  }
51303
51362
  if (typeof seq === "number" && seq > parseSeq) parseSeq = seq;
@@ -51311,14 +51370,14 @@ function createTerminalSurface(opts) {
51311
51370
  drainWaiters = [];
51312
51371
  for (const w2 of waiters) w2();
51313
51372
  }
51314
- resolve8();
51373
+ resolve9();
51315
51374
  });
51316
51375
  });
51317
51376
  },
51318
51377
  drain() {
51319
51378
  if (pendingParse === 0) return Promise.resolve();
51320
- return new Promise((resolve8) => {
51321
- drainWaiters.push(resolve8);
51379
+ return new Promise((resolve9) => {
51380
+ drainWaiters.push(resolve9);
51322
51381
  });
51323
51382
  },
51324
51383
  resize(cols, rows) {
@@ -51359,7 +51418,7 @@ function inputBoxContent(lines) {
51359
51418
  function waitInputEcho(surface, opts = {}) {
51360
51419
  const stableMs = opts.stableMs ?? 150;
51361
51420
  const maxMs = opts.maxMs ?? 5e3;
51362
- return new Promise((resolve8) => {
51421
+ return new Promise((resolve9) => {
51363
51422
  let settled = false;
51364
51423
  let stableTimer = null;
51365
51424
  const finish = () => {
@@ -51368,7 +51427,7 @@ function waitInputEcho(surface, opts = {}) {
51368
51427
  unsub();
51369
51428
  if (stableTimer) clearTimeout(stableTimer);
51370
51429
  clearTimeout(maxTimer);
51371
- resolve8();
51430
+ resolve9();
51372
51431
  };
51373
51432
  const unsub = surface.onTick((lines) => {
51374
51433
  if (!stableTimer && inputBoxContent(lines).length > 0) {
@@ -52488,13 +52547,13 @@ function createGhRunner(defaults) {
52488
52547
  const baseTimeoutMs = defaults?.timeoutMs ?? DEFAULT_TIMEOUT_MS2;
52489
52548
  return {
52490
52549
  run(args, opts) {
52491
- return new Promise((resolve8, reject) => {
52550
+ return new Promise((resolve9, reject) => {
52492
52551
  (0, import_node_child_process7.execFile)(
52493
52552
  "gh",
52494
52553
  args,
52495
52554
  { timeout: opts?.timeoutMs ?? baseTimeoutMs, maxBuffer: MAX_BUFFER },
52496
52555
  (err, stdout, stderr) => {
52497
- if (!err) return resolve8(stdout);
52556
+ if (!err) return resolve9(stdout);
52498
52557
  if (err.code === "ENOENT") {
52499
52558
  return reject(new GhError("gh-missing", "GitHub CLI (gh) \u672A\u5B89\u88C5"));
52500
52559
  }
@@ -54366,13 +54425,13 @@ function mapSkillsListResponse(res) {
54366
54425
  const r = s ?? {};
54367
54426
  const name = str3(r.name);
54368
54427
  if (!name) continue;
54369
- const path86 = str3(r.path);
54428
+ const path87 = str3(r.path);
54370
54429
  const description = str3(r.description);
54371
54430
  const isPlugin = name.includes(":");
54372
54431
  out.push({
54373
54432
  name,
54374
54433
  source: isPlugin ? "plugin" : "project",
54375
- ...path86 ? { path: path86 } : {},
54434
+ ...path87 ? { path: path87 } : {},
54376
54435
  ...description ? { description } : {},
54377
54436
  ...isPlugin ? { plugin: name.split(":")[0] } : {}
54378
54437
  });
@@ -55239,14 +55298,14 @@ async function generateSessionTitle(tool, firstMessage, deps = {}) {
55239
55298
  const args = tool === "claude" ? buildClaudeTitleArgs(buildClaudeTitlePrompt(text)) : buildCodexTitleArgs(buildTitlePrompt(text), outFile, schemaFile);
55240
55299
  const doSpawn = deps.spawnOverride ?? ((c, a, o) => (0, import_node_child_process8.spawn)(c, a, { ...o, stdio: ["ignore", "pipe", "pipe"] }));
55241
55300
  const timeoutMs = deps.timeoutMs ?? DEFAULT_TITLE_GEN_TIMEOUT_MS;
55242
- return await new Promise((resolve8) => {
55301
+ return await new Promise((resolve9) => {
55243
55302
  let proc;
55244
55303
  try {
55245
55304
  proc = doSpawn(cmd, args, { cwd: workDir });
55246
55305
  } catch (err) {
55247
55306
  deps.logger?.warn("title-gen spawn failed", { tool, message: err.message });
55248
55307
  cleanupWorkDir();
55249
- return resolve8(null);
55308
+ return resolve9(null);
55250
55309
  }
55251
55310
  let stdout = "";
55252
55311
  let settled = false;
@@ -55256,7 +55315,7 @@ async function generateSessionTitle(tool, firstMessage, deps = {}) {
55256
55315
  clearTimeout(timer);
55257
55316
  if (proc.exitCode === null && proc.signalCode === null) proc.kill("SIGKILL");
55258
55317
  cleanupWorkDir();
55259
- resolve8(title);
55318
+ resolve9(title);
55260
55319
  };
55261
55320
  const timer = setTimeout(() => {
55262
55321
  deps.logger?.warn("title-gen timed out", { tool, timeoutMs });
@@ -55314,13 +55373,13 @@ function isPreviewPortAllowed(port, cfg) {
55314
55373
  return cfg.allowedPorts.includes(port);
55315
55374
  }
55316
55375
  function proxyPreviewHttp(req, res, port) {
55317
- return new Promise((resolve8) => {
55376
+ return new Promise((resolve9) => {
55318
55377
  const upstream = import_node_http.default.request(
55319
55378
  { host: "localhost", port, method: req.method, path: req.url, headers: req.headers },
55320
55379
  (upRes) => {
55321
55380
  res.writeHead(upRes.statusCode || 502, upRes.headers);
55322
55381
  upRes.pipe(res);
55323
- upRes.on("end", () => resolve8());
55382
+ upRes.on("end", () => resolve9());
55324
55383
  }
55325
55384
  );
55326
55385
  upstream.on("error", (e) => {
@@ -55328,7 +55387,7 @@ function proxyPreviewHttp(req, res, port) {
55328
55387
  res.writeHead(502, { "content-type": "text/plain; charset=utf-8" });
55329
55388
  }
55330
55389
  res.end(`preview upstream error: ${e.message}`);
55331
- resolve8();
55390
+ resolve9();
55332
55391
  });
55333
55392
  req.pipe(upstream);
55334
55393
  });
@@ -55371,7 +55430,7 @@ var LocalWsServer = class {
55371
55430
  pingIntervalMs;
55372
55431
  async start() {
55373
55432
  const host = this.opts.host ?? "127.0.0.1";
55374
- await new Promise((resolve8, reject) => {
55433
+ await new Promise((resolve9, reject) => {
55375
55434
  const httpServer = import_node_http2.default.createServer((req, res) => this.handleHttpRequest(req, res));
55376
55435
  const wss = new import_websocket_server.default({ noServer: true, clientTracking: true });
55377
55436
  httpServer.on("upgrade", (req, socket, head) => {
@@ -55397,7 +55456,7 @@ var LocalWsServer = class {
55397
55456
  });
55398
55457
  httpServer.on("listening", () => {
55399
55458
  this.logger?.info("ws listening", { host, port: this.opts.port });
55400
- resolve8();
55459
+ resolve9();
55401
55460
  });
55402
55461
  httpServer.on("error", (err) => {
55403
55462
  this.logger?.error("ws server error", { err: err.message });
@@ -55418,11 +55477,11 @@ var LocalWsServer = class {
55418
55477
  if (c.pingTimer) clearInterval(c.pingTimer);
55419
55478
  }
55420
55479
  this.clients.clear();
55421
- await new Promise((resolve8) => {
55422
- this.wss?.close(() => resolve8());
55480
+ await new Promise((resolve9) => {
55481
+ this.wss?.close(() => resolve9());
55423
55482
  });
55424
- await new Promise((resolve8) => {
55425
- this.httpServer?.close(() => resolve8());
55483
+ await new Promise((resolve9) => {
55484
+ this.httpServer?.close(() => resolve9());
55426
55485
  });
55427
55486
  this.wss = null;
55428
55487
  this.httpServer = null;
@@ -55965,7 +56024,7 @@ async function authenticate(token, deps) {
55965
56024
 
55966
56025
  // src/legacy-cleanup.ts
55967
56026
  var fs40 = __toESM(require("fs/promises"), 1);
55968
- var path41 = __toESM(require("path"), 1);
56027
+ var path42 = __toESM(require("path"), 1);
55969
56028
  var LEGACY_FILES = [
55970
56029
  "personal-capability.json",
55971
56030
  "received-capabilities.json",
@@ -55974,7 +56033,7 @@ var LEGACY_FILES = [
55974
56033
  async function cleanupLegacyCapabilityFiles(dataDir, logger) {
55975
56034
  const removed = [];
55976
56035
  for (const name of LEGACY_FILES) {
55977
- const p2 = path41.join(dataDir, name);
56036
+ const p2 = path42.join(dataDir, name);
55978
56037
  try {
55979
56038
  await fs40.unlink(p2);
55980
56039
  removed.push(name);
@@ -55989,7 +56048,7 @@ async function cleanupLegacyCapabilityFiles(dataDir, logger) {
55989
56048
 
55990
56049
  // src/inbox/inbox-store.ts
55991
56050
  var fs41 = __toESM(require("fs"), 1);
55992
- var path42 = __toESM(require("path"), 1);
56051
+ var path43 = __toESM(require("path"), 1);
55993
56052
  var INBOX_SUBDIR = "inbox";
55994
56053
  var InboxStore = class {
55995
56054
  constructor(dataDir) {
@@ -56087,10 +56146,10 @@ var InboxStore = class {
56087
56146
  }
56088
56147
  }
56089
56148
  dirPath() {
56090
- return path42.join(this.dataDir, INBOX_SUBDIR);
56149
+ return path43.join(this.dataDir, INBOX_SUBDIR);
56091
56150
  }
56092
56151
  filePath(peerDeviceId) {
56093
- return path42.join(this.dirPath(), `${peerDeviceId}.jsonl`);
56152
+ return path43.join(this.dirPath(), `${peerDeviceId}.jsonl`);
56094
56153
  }
56095
56154
  };
56096
56155
  function parseAllLines(raw) {
@@ -56179,7 +56238,7 @@ var InboxManager = class {
56179
56238
 
56180
56239
  // src/state/contact-store.ts
56181
56240
  var fs42 = __toESM(require("fs"), 1);
56182
- var path43 = __toESM(require("path"), 1);
56241
+ var path44 = __toESM(require("path"), 1);
56183
56242
  var FILE_NAME = "contacts.json";
56184
56243
  var ContactStore = class {
56185
56244
  constructor(dataDir) {
@@ -56189,7 +56248,7 @@ var ContactStore = class {
56189
56248
  contacts = /* @__PURE__ */ new Map();
56190
56249
  load() {
56191
56250
  this.contacts.clear();
56192
- const file = path43.join(this.dataDir, FILE_NAME);
56251
+ const file = path44.join(this.dataDir, FILE_NAME);
56193
56252
  let raw;
56194
56253
  try {
56195
56254
  raw = fs42.readFileSync(file, "utf8");
@@ -56261,7 +56320,7 @@ var ContactStore = class {
56261
56320
  return true;
56262
56321
  }
56263
56322
  flush() {
56264
- const file = path43.join(this.dataDir, FILE_NAME);
56323
+ const file = path44.join(this.dataDir, FILE_NAME);
56265
56324
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
56266
56325
  const content = JSON.stringify(
56267
56326
  { contacts: Array.from(this.contacts.values()) },
@@ -56287,16 +56346,16 @@ var HANDSHAKE_TIMEOUT_MS = 5e3;
56287
56346
  var RPC_TIMEOUT_MS = 5e3;
56288
56347
  async function connectRemote(args) {
56289
56348
  const ws = new wrapper_default(args.url);
56290
- await new Promise((resolve8, reject) => {
56349
+ await new Promise((resolve9, reject) => {
56291
56350
  const onError = (e) => reject(e);
56292
56351
  ws.once("open", () => {
56293
56352
  ws.off("error", onError);
56294
- resolve8();
56353
+ resolve9();
56295
56354
  });
56296
56355
  ws.once("error", onError);
56297
56356
  });
56298
56357
  ws.send(JSON.stringify({ type: "auth", token: args.token }));
56299
- await new Promise((resolve8, reject) => {
56358
+ await new Promise((resolve9, reject) => {
56300
56359
  const onMessage = (raw) => {
56301
56360
  let f;
56302
56361
  try {
@@ -56306,7 +56365,7 @@ async function connectRemote(args) {
56306
56365
  }
56307
56366
  if (f.type === "auth:ok") {
56308
56367
  finish();
56309
- resolve8();
56368
+ resolve9();
56310
56369
  return;
56311
56370
  }
56312
56371
  if (f.type === "auth:error" || f.code === 4401) {
@@ -56337,7 +56396,7 @@ async function connectRemote(args) {
56337
56396
  });
56338
56397
  function call(method, payload) {
56339
56398
  const requestId = crypto5.randomUUID();
56340
- return new Promise((resolve8, reject) => {
56399
+ return new Promise((resolve9, reject) => {
56341
56400
  const onMessage = (raw) => {
56342
56401
  let f;
56343
56402
  try {
@@ -56350,7 +56409,7 @@ async function connectRemote(args) {
56350
56409
  if (f.error || f.type === "error" || f.type?.endsWith(":error")) {
56351
56410
  reject(new Error(f.message ?? f.error ?? "rpc error"));
56352
56411
  } else {
56353
- resolve8(f);
56412
+ resolve9(f);
56354
56413
  }
56355
56414
  };
56356
56415
  ws.on("message", onMessage);
@@ -56383,52 +56442,52 @@ async function connectRemote(args) {
56383
56442
 
56384
56443
  // src/migrations/2026-05-20-flatten-sessions.ts
56385
56444
  var fs43 = __toESM(require("fs"), 1);
56386
- var path44 = __toESM(require("path"), 1);
56445
+ var path45 = __toESM(require("path"), 1);
56387
56446
  var MIGRATION_FLAG_NAME = ".migration.v1.done";
56388
56447
  function migrateFlattenSessions(opts) {
56389
56448
  const dataDir = opts.dataDir;
56390
56449
  const now = opts.now ?? Date.now;
56391
- const sessionsDir = path44.join(dataDir, "sessions");
56392
- const flagPath = path44.join(sessionsDir, MIGRATION_FLAG_NAME);
56450
+ const sessionsDir = path45.join(dataDir, "sessions");
56451
+ const flagPath = path45.join(sessionsDir, MIGRATION_FLAG_NAME);
56393
56452
  if (existsSync3(flagPath)) {
56394
56453
  return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
56395
56454
  }
56396
56455
  let movedBare = 0;
56397
56456
  let movedVmOwner = 0;
56398
56457
  let archivedListener = 0;
56399
- const defaultDir = path44.join(sessionsDir, "default");
56458
+ const defaultDir = path45.join(sessionsDir, "default");
56400
56459
  if (existsSync3(defaultDir)) {
56401
56460
  for (const entry of readdirSafe(defaultDir)) {
56402
56461
  if (!entry.endsWith(".json")) continue;
56403
- const src = path44.join(defaultDir, entry);
56404
- const dst = path44.join(sessionsDir, entry);
56462
+ const src = path45.join(defaultDir, entry);
56463
+ const dst = path45.join(sessionsDir, entry);
56405
56464
  fs43.renameSync(src, dst);
56406
56465
  movedBare += 1;
56407
56466
  }
56408
56467
  rmdirIfEmpty(defaultDir);
56409
56468
  }
56410
56469
  for (const pid of readdirSafe(sessionsDir)) {
56411
- const personaDir = path44.join(sessionsDir, pid);
56470
+ const personaDir = path45.join(sessionsDir, pid);
56412
56471
  if (!isDir(personaDir)) continue;
56413
56472
  if (pid === "default") continue;
56414
- const ownerSrc = path44.join(personaDir, "owner");
56473
+ const ownerSrc = path45.join(personaDir, "owner");
56415
56474
  if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
56416
- const ownerDst = path44.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
56475
+ const ownerDst = path45.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
56417
56476
  fs43.mkdirSync(ownerDst, { recursive: true });
56418
56477
  for (const file of readdirSafe(ownerSrc)) {
56419
56478
  if (!file.endsWith(".json")) continue;
56420
- fs43.renameSync(path44.join(ownerSrc, file), path44.join(ownerDst, file));
56479
+ fs43.renameSync(path45.join(ownerSrc, file), path45.join(ownerDst, file));
56421
56480
  movedVmOwner += 1;
56422
56481
  }
56423
56482
  rmdirIfEmpty(ownerSrc);
56424
56483
  }
56425
- const listenerSrc = path44.join(personaDir, "listener");
56484
+ const listenerSrc = path45.join(personaDir, "listener");
56426
56485
  if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
56427
- const archiveDst = path44.join(dataDir, ".legacy", `listener-${pid}`);
56486
+ const archiveDst = path45.join(dataDir, ".legacy", `listener-${pid}`);
56428
56487
  fs43.mkdirSync(archiveDst, { recursive: true });
56429
56488
  for (const file of readdirSafe(listenerSrc)) {
56430
56489
  if (!file.endsWith(".json")) continue;
56431
- fs43.renameSync(path44.join(listenerSrc, file), path44.join(archiveDst, file));
56490
+ fs43.renameSync(path45.join(listenerSrc, file), path45.join(archiveDst, file));
56432
56491
  archivedListener += 1;
56433
56492
  }
56434
56493
  rmdirIfEmpty(listenerSrc);
@@ -56476,13 +56535,13 @@ function rmdirIfEmpty(p2) {
56476
56535
 
56477
56536
  // src/migrations/2026-08-18-drop-seeded-projects.ts
56478
56537
  var fs44 = __toESM(require("fs"), 1);
56479
- var path45 = __toESM(require("path"), 1);
56538
+ var path46 = __toESM(require("path"), 1);
56480
56539
  var DROP_SEEDED_PROJECTS_FLAG = ".projects-seed-dropped.v1.done";
56481
56540
  function dropSeededProjects(opts) {
56482
56541
  fs44.mkdirSync(opts.dataDir, { recursive: true });
56483
- const flag = path45.join(opts.dataDir, DROP_SEEDED_PROJECTS_FLAG);
56542
+ const flag = path46.join(opts.dataDir, DROP_SEEDED_PROJECTS_FLAG);
56484
56543
  if (fs44.existsSync(flag)) return { skipped: true, dropped: 0, backup: null };
56485
- const file = path45.join(opts.dataDir, "projects.json");
56544
+ const file = path46.join(opts.dataDir, "projects.json");
56486
56545
  let raw = null;
56487
56546
  let dropped = 0;
56488
56547
  try {
@@ -56492,9 +56551,9 @@ function dropSeededProjects(opts) {
56492
56551
  }
56493
56552
  let backup = null;
56494
56553
  if (raw != null && dropped > 0) {
56495
- const dir = path45.join(opts.dataDir, "backups");
56554
+ const dir = path46.join(opts.dataDir, "backups");
56496
56555
  fs44.mkdirSync(dir, { recursive: true });
56497
- 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`);
56498
56557
  fs44.writeFileSync(backup, raw);
56499
56558
  }
56500
56559
  if (raw != null || dropped > 0) {
@@ -56917,7 +56976,7 @@ function authedRpcErrorStatus(code) {
56917
56976
  }
56918
56977
  var LARK_BOT_EVENT_MAX_BYTES = 64 * 1024;
56919
56978
  async function readRawBody(req, max) {
56920
- return await new Promise((resolve8, reject) => {
56979
+ return await new Promise((resolve9, reject) => {
56921
56980
  let size = 0;
56922
56981
  const chunks = [];
56923
56982
  req.on("data", (c) => {
@@ -56929,12 +56988,12 @@ async function readRawBody(req, max) {
56929
56988
  }
56930
56989
  chunks.push(c);
56931
56990
  });
56932
- req.on("end", () => resolve8(Buffer.concat(chunks).toString("utf8")));
56991
+ req.on("end", () => resolve9(Buffer.concat(chunks).toString("utf8")));
56933
56992
  req.on("error", reject);
56934
56993
  });
56935
56994
  }
56936
56995
  async function readJsonBody(req, max) {
56937
- return await new Promise((resolve8, reject) => {
56996
+ return await new Promise((resolve9, reject) => {
56938
56997
  let size = 0;
56939
56998
  const chunks = [];
56940
56999
  req.on("data", (c) => {
@@ -56948,9 +57007,9 @@ async function readJsonBody(req, max) {
56948
57007
  });
56949
57008
  req.on("end", () => {
56950
57009
  const raw = Buffer.concat(chunks).toString("utf8");
56951
- if (!raw) return resolve8({});
57010
+ if (!raw) return resolve9({});
56952
57011
  try {
56953
- resolve8(JSON.parse(raw));
57012
+ resolve9(JSON.parse(raw));
56954
57013
  } catch {
56955
57014
  reject(new Error("invalid JSON body"));
56956
57015
  }
@@ -57995,10 +58054,10 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
57995
58054
  const work = import_node_path43.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
57996
58055
  import_node_fs39.default.mkdirSync(work, { recursive: true });
57997
58056
  try {
57998
- await new Promise((resolve8, reject) => {
58057
+ await new Promise((resolve9, reject) => {
57999
58058
  const proc = (0, import_node_child_process9.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
58000
58059
  proc.on("error", reject);
58001
- 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}`)));
58002
58061
  });
58003
58062
  const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
58004
58063
  const src = import_node_path43.default.join(work, dirName, "frpc");
@@ -58099,7 +58158,7 @@ async function killStaleFrpc(deps) {
58099
58158
  }
58100
58159
  async function defaultScanFrpcPidsByCmdline(tomlPath, logger) {
58101
58160
  if (process.platform === "win32") return [];
58102
- return new Promise((resolve8) => {
58161
+ return new Promise((resolve9) => {
58103
58162
  const ps = (0, import_node_child_process10.spawn)("ps", ["-axo", "pid=,command="], { stdio: ["ignore", "pipe", "ignore"] });
58104
58163
  let buf = "";
58105
58164
  ps.stdout.on("data", (c) => {
@@ -58116,11 +58175,11 @@ async function defaultScanFrpcPidsByCmdline(tomlPath, logger) {
58116
58175
  const pid = parseInt(m2[1], 10);
58117
58176
  if (Number.isFinite(pid) && pid > 0) pids.push(pid);
58118
58177
  }
58119
- resolve8(pids);
58178
+ resolve9(pids);
58120
58179
  });
58121
58180
  ps.on("error", (e) => {
58122
58181
  logger?.warn("tunnel: ps scan failed", { err: e.message });
58123
- resolve8([]);
58182
+ resolve9([]);
58124
58183
  });
58125
58184
  });
58126
58185
  }
@@ -58198,17 +58257,17 @@ var TunnelManager = class {
58198
58257
  return;
58199
58258
  }
58200
58259
  proc.kill("SIGTERM");
58201
- await new Promise((resolve8) => {
58260
+ await new Promise((resolve9) => {
58202
58261
  const t = setTimeout(() => {
58203
58262
  try {
58204
58263
  proc.kill("SIGKILL");
58205
58264
  } catch {
58206
58265
  }
58207
- resolve8();
58266
+ resolve9();
58208
58267
  }, 5e3);
58209
58268
  proc.once("exit", () => {
58210
58269
  clearTimeout(t);
58211
- resolve8();
58270
+ resolve9();
58212
58271
  });
58213
58272
  });
58214
58273
  clearFrpcPid(this.deps.dataDir);
@@ -58314,14 +58373,14 @@ function formatFrpcTail(raw, maxLines = 12) {
58314
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");
58315
58374
  }
58316
58375
  async function waitForFrpcReady(proc, timeoutMs) {
58317
- return new Promise((resolve8) => {
58376
+ return new Promise((resolve9) => {
58318
58377
  let settled = false;
58319
58378
  let buf = "";
58320
58379
  const finish = (r) => {
58321
58380
  if (settled) return;
58322
58381
  settled = true;
58323
58382
  cleanup();
58324
- resolve8(r);
58383
+ resolve9(r);
58325
58384
  };
58326
58385
  const onData = (chunk) => {
58327
58386
  buf += String(chunk);
@@ -58666,9 +58725,9 @@ var CentralClientError = class extends Error {
58666
58725
  code;
58667
58726
  cause;
58668
58727
  };
58669
- async function centralRequest(opts, path86, init) {
58728
+ async function centralRequest(opts, path87, init) {
58670
58729
  const f = opts.fetchImpl ?? globalThis.fetch;
58671
- const url = `${opts.api.replace(/\/+$/, "")}${path86}`;
58730
+ const url = `${opts.api.replace(/\/+$/, "")}${path87}`;
58672
58731
  const ctrl = new AbortController();
58673
58732
  const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
58674
58733
  let res;
@@ -58863,7 +58922,7 @@ function verifyConnectToken(args) {
58863
58922
 
58864
58923
  // src/feishu-auth/server-key.ts
58865
58924
  var fs58 = __toESM(require("fs"), 1);
58866
- var path61 = __toESM(require("path"), 1);
58925
+ var path62 = __toESM(require("path"), 1);
58867
58926
  var FILE_NAME2 = "server-signing-key.json";
58868
58927
  var ServerKeyStore = class {
58869
58928
  constructor(dataDir) {
@@ -58871,7 +58930,7 @@ var ServerKeyStore = class {
58871
58930
  }
58872
58931
  dataDir;
58873
58932
  filePath() {
58874
- return path61.join(this.dataDir, FILE_NAME2);
58933
+ return path62.join(this.dataDir, FILE_NAME2);
58875
58934
  }
58876
58935
  /** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
58877
58936
  read() {
@@ -59745,7 +59804,7 @@ function buildPermissionHandlers(deps) {
59745
59804
  }
59746
59805
 
59747
59806
  // src/handlers/history.ts
59748
- var path66 = __toESM(require("path"), 1);
59807
+ var path67 = __toESM(require("path"), 1);
59749
59808
  init_protocol();
59750
59809
 
59751
59810
  // src/session/recent-dirs.ts
@@ -59763,7 +59822,7 @@ function listRecentDirs(store, limit = 50) {
59763
59822
  }
59764
59823
 
59765
59824
  // src/permission/persona-paths.ts
59766
- var path65 = __toESM(require("path"), 1);
59825
+ var path66 = __toESM(require("path"), 1);
59767
59826
  function getAllowedPersonaIds(grants, action) {
59768
59827
  const ids = /* @__PURE__ */ new Set();
59769
59828
  for (const g2 of grants) {
@@ -59776,42 +59835,42 @@ function getAllowedPersonaIds(grants, action) {
59776
59835
  return ids;
59777
59836
  }
59778
59837
  function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
59779
- const target = path65.resolve(absPath);
59838
+ const target = path66.resolve(absPath);
59780
59839
  if (userWorkDir) {
59781
- const u = path65.resolve(userWorkDir);
59782
- const usep = u.endsWith(path65.sep) ? "" : path65.sep;
59840
+ const u = path66.resolve(userWorkDir);
59841
+ const usep = u.endsWith(path66.sep) ? "" : path66.sep;
59783
59842
  if (target === u || target.startsWith(u + usep)) return true;
59784
59843
  }
59785
- const root = path65.resolve(personaRoot);
59786
- const sep4 = root.endsWith(path65.sep) ? "" : path65.sep;
59844
+ const root = path66.resolve(personaRoot);
59845
+ const sep4 = root.endsWith(path66.sep) ? "" : path66.sep;
59787
59846
  if (!target.startsWith(root + sep4)) return false;
59788
- const rel = path65.relative(root, target);
59847
+ const rel = path66.relative(root, target);
59789
59848
  if (!rel || rel.startsWith("..")) return false;
59790
- const personaId2 = rel.split(path65.sep)[0];
59849
+ const personaId2 = rel.split(path66.sep)[0];
59791
59850
  if (!personaId2) return false;
59792
59851
  const allowed = getAllowedPersonaIds(grants, action);
59793
59852
  if (allowed === "*") return true;
59794
59853
  return allowed.has(personaId2);
59795
59854
  }
59796
59855
  function personaIdFromPath(absPath, personaRoot) {
59797
- const root = path65.resolve(personaRoot);
59798
- const target = path65.resolve(absPath);
59799
- 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;
59800
59859
  if (!target.startsWith(root + sep4)) return null;
59801
- const rel = path65.relative(root, target);
59860
+ const rel = path66.relative(root, target);
59802
59861
  if (!rel || rel.startsWith("..")) return null;
59803
- const id = rel.split(path65.sep)[0];
59862
+ const id = rel.split(path66.sep)[0];
59804
59863
  return id || null;
59805
59864
  }
59806
59865
  function isPathWithin(dir, absPath) {
59807
- const d = path65.resolve(dir);
59808
- const t = path65.resolve(absPath);
59809
- 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;
59810
59869
  return t === d || t.startsWith(d + sep4);
59811
59870
  }
59812
59871
  function isPathInGuestBoundary(personaRoot, personaId2, userWorkDir, absPath) {
59813
59872
  if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
59814
- return personaIdFromPath(path65.resolve(absPath), personaRoot) === personaId2;
59873
+ return personaIdFromPath(path66.resolve(absPath), personaRoot) === personaId2;
59815
59874
  }
59816
59875
 
59817
59876
  // src/handlers/history.ts
@@ -59864,7 +59923,7 @@ function buildHistoryHandlers(deps) {
59864
59923
  if (!pid) return false;
59865
59924
  return isGuestPathAllowed(
59866
59925
  ctx.grants,
59867
- path66.join(personaRoot, pid),
59926
+ path67.join(personaRoot, pid),
59868
59927
  personaRoot,
59869
59928
  "read",
59870
59929
  userWorkDir
@@ -59876,7 +59935,7 @@ function buildHistoryHandlers(deps) {
59876
59935
  };
59877
59936
  const list = async (frame, _client, ctx) => {
59878
59937
  const args = HistoryListArgs.parse(frame);
59879
- assertGuestPath(ctx, path66.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
59938
+ assertGuestPath(ctx, path67.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
59880
59939
  const sessions = await history.listSessions(args);
59881
59940
  return { response: { type: "history:list", sessions } };
59882
59941
  };
@@ -59924,14 +59983,14 @@ function buildHistoryHandlers(deps) {
59924
59983
  };
59925
59984
  const subagents = async (frame, _client, ctx) => {
59926
59985
  const args = HistorySubagentsArgs.parse(frame);
59927
- assertGuestPath(ctx, path66.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
59986
+ assertGuestPath(ctx, path67.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
59928
59987
  assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagents");
59929
59988
  const subs = await historyReaderForToolSession(args.toolSessionId).listSubagents(args);
59930
59989
  return { response: { type: "history:subagents", subagents: subs } };
59931
59990
  };
59932
59991
  const subagentRead = async (frame, _client, ctx) => {
59933
59992
  const args = HistorySubagentReadArgs.parse(frame);
59934
- assertGuestPath(ctx, path66.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
59993
+ assertGuestPath(ctx, path67.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
59935
59994
  assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagent-read");
59936
59995
  const res = await historyReaderForToolSession(args.toolSessionId).readSubagent(args);
59937
59996
  return { response: { type: "history:subagent-read", ...res } };
@@ -59941,7 +60000,7 @@ function buildHistoryHandlers(deps) {
59941
60000
  if (ctx?.principal.kind === "guest" && personaRoot) {
59942
60001
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
59943
60002
  const filtered = dirs.filter(
59944
- (d) => isGuestPathAllowed(ctx.grants, path66.resolve(d.cwd), personaRoot, "read", userWorkDir)
60003
+ (d) => isGuestPathAllowed(ctx.grants, path67.resolve(d.cwd), personaRoot, "read", userWorkDir)
59945
60004
  );
59946
60005
  return { response: { type: "history:recentDirs", dirs: filtered } };
59947
60006
  }
@@ -59959,16 +60018,16 @@ function buildHistoryHandlers(deps) {
59959
60018
 
59960
60019
  // src/handlers/projects.ts
59961
60020
  var fs62 = __toESM(require("fs"), 1);
59962
- var os19 = __toESM(require("os"), 1);
59963
- var path67 = __toESM(require("path"), 1);
60021
+ var os20 = __toESM(require("os"), 1);
60022
+ var path68 = __toESM(require("path"), 1);
59964
60023
  var import_node_child_process13 = require("child_process");
59965
60024
  init_protocol();
59966
- var DEFAULT_PROJECTS_ROOT = path67.join(os19.homedir(), "Documents", "ChatGPT");
60025
+ var DEFAULT_PROJECTS_ROOT = path68.join(os20.homedir(), "Documents", "ChatGPT");
59967
60026
  function allocateDir(root, name) {
59968
- let candidate = path67.join(root, name);
60027
+ let candidate = path68.join(root, name);
59969
60028
  let n = 2;
59970
60029
  while (fs62.existsSync(candidate)) {
59971
- candidate = path67.join(root, `${name} ${n}`);
60030
+ candidate = path68.join(root, `${name} ${n}`);
59972
60031
  n += 1;
59973
60032
  }
59974
60033
  return candidate;
@@ -59983,6 +60042,29 @@ function buildProjectHandlers(deps) {
59983
60042
  const list = async () => ({
59984
60043
  response: { type: "project:list", projects: store().listMerged() }
59985
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
+ };
59986
60068
  const create = async (frame) => {
59987
60069
  const args = ProjectCreateArgs.parse(frame);
59988
60070
  const root = deps.projectsRoot ?? DEFAULT_PROJECTS_ROOT;
@@ -60021,12 +60103,17 @@ function buildProjectHandlers(deps) {
60021
60103
  }
60022
60104
  return { response: { type: "project:create", project: entry } };
60023
60105
  };
60024
- 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
+ };
60025
60112
  }
60026
60113
 
60027
60114
  // src/handlers/workspace.ts
60028
- var path68 = __toESM(require("path"), 1);
60029
- var os20 = __toESM(require("os"), 1);
60115
+ var path69 = __toESM(require("path"), 1);
60116
+ var os21 = __toESM(require("os"), 1);
60030
60117
  init_protocol();
60031
60118
  init_protocol();
60032
60119
  function buildEnabledPluginNames(personaManager, personaId2) {
@@ -60066,23 +60153,23 @@ function buildWorkspaceHandlers(deps) {
60066
60153
  const list = async (frame, _client, ctx) => {
60067
60154
  const args = WorkspaceListArgs.parse(frame);
60068
60155
  const isGuest = ctx?.principal.kind === "guest";
60069
- const fallbackCwd = isGuest && personaRoot ? personaRoot : os20.homedir();
60070
- const resolvedCwd = path68.resolve(args.cwd ?? fallbackCwd);
60071
- 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;
60072
60159
  assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
60073
60160
  const res = workspace.list({ ...args, cwd: resolvedCwd });
60074
60161
  return { response: { type: "workspace:list", ...res } };
60075
60162
  };
60076
60163
  const read = async (frame, _client, ctx) => {
60077
60164
  const args = WorkspaceReadArgs.parse(frame);
60078
- 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);
60079
60166
  assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
60080
60167
  const res = workspace.read(args);
60081
60168
  return { response: { type: "workspace:read", ...res } };
60082
60169
  };
60083
60170
  const skillsList = async (frame, _client, ctx) => {
60084
60171
  const args = SkillsListArgs.parse(frame);
60085
- const cwdAbs = path68.resolve(args.cwd);
60172
+ const cwdAbs = path69.resolve(args.cwd);
60086
60173
  assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
60087
60174
  const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
60088
60175
  if (ctx?.principal.kind === "guest" && personaRoot) {
@@ -60094,7 +60181,7 @@ function buildWorkspaceHandlers(deps) {
60094
60181
  };
60095
60182
  const agentsList = async (frame, _client, ctx) => {
60096
60183
  const args = AgentsListArgs.parse(frame);
60097
- const cwdAbs = path68.resolve(args.cwd);
60184
+ const cwdAbs = path69.resolve(args.cwd);
60098
60185
  assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
60099
60186
  if (args.tool === "codex") {
60100
60187
  return { response: { type: "agents:list", agents: [] } };
@@ -60116,7 +60203,7 @@ function buildWorkspaceHandlers(deps) {
60116
60203
  }
60117
60204
 
60118
60205
  // src/handlers/git.ts
60119
- var path70 = __toESM(require("path"), 1);
60206
+ var path71 = __toESM(require("path"), 1);
60120
60207
  init_protocol();
60121
60208
  init_protocol();
60122
60209
 
@@ -60203,7 +60290,7 @@ async function listGitBranches(cwd) {
60203
60290
  function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
60204
60291
  if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
60205
60292
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
60206
- if (!isGuestPathAllowed(ctx.grants, path70.resolve(cwd), personaRoot, "read", userWorkDir)) {
60293
+ if (!isGuestPathAllowed(ctx.grants, path71.resolve(cwd), personaRoot, "read", userWorkDir)) {
60207
60294
  throw new ClawdError(
60208
60295
  ERROR_CODES.UNAUTHORIZED,
60209
60296
  `guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
@@ -60944,6 +61031,8 @@ var METHOD_GRANT_MAP = {
60944
61031
  // project:*(sidebar 项目分区,spec 2026-08-17):registry 是 owner 本机资源,owner-only 一刀切
60945
61032
  "project:list": ADMIN_ANY,
60946
61033
  "project:create": ADMIN_ANY,
61034
+ "project:patch": ADMIN_ANY,
61035
+ "project:reveal": ADMIN_ANY,
60947
61036
  // github:*(PR 收件箱,spec 2026-08-11):走 owner 本机 gh 凭据,owner-only 一刀切
60948
61037
  "github:status": ADMIN_ANY,
60949
61038
  "github:prList": ADMIN_ANY,
@@ -61104,21 +61193,21 @@ function computeMethodAccess(args) {
61104
61193
  }
61105
61194
 
61106
61195
  // src/version.ts
61107
- var version = "0.2.375".length > 0 ? "0.2.375" : "dev";
61196
+ var version = "0.2.377".length > 0 ? "0.2.377" : "dev";
61108
61197
 
61109
61198
  // src/cli-probe/probe.ts
61110
61199
  var fs64 = __toESM(require("fs"), 1);
61111
- var path71 = __toESM(require("path"), 1);
61200
+ var path72 = __toESM(require("path"), 1);
61112
61201
  var PKG_NAME = "@clawos-dev/clawd";
61113
61202
  var BIN_NAME = "clawd";
61114
61203
  var MAX_PARENT_HOPS = 5;
61115
61204
  function probeGlobalCli(pathEnv) {
61116
61205
  if (!pathEnv) return null;
61117
- for (const dir of pathEnv.split(path71.delimiter)) {
61206
+ for (const dir of pathEnv.split(path72.delimiter)) {
61118
61207
  if (!dir) continue;
61119
61208
  let real;
61120
61209
  try {
61121
- real = fs64.realpathSync(path71.join(dir, BIN_NAME));
61210
+ real = fs64.realpathSync(path72.join(dir, BIN_NAME));
61122
61211
  } catch {
61123
61212
  continue;
61124
61213
  }
@@ -61128,15 +61217,15 @@ function probeGlobalCli(pathEnv) {
61128
61217
  return null;
61129
61218
  }
61130
61219
  function readOwnPackageVersion(entryPath) {
61131
- let dir = path71.dirname(entryPath);
61220
+ let dir = path72.dirname(entryPath);
61132
61221
  for (let i = 0; i < MAX_PARENT_HOPS; i++) {
61133
61222
  try {
61134
- const raw = fs64.readFileSync(path71.join(dir, "package.json"), "utf8");
61223
+ const raw = fs64.readFileSync(path72.join(dir, "package.json"), "utf8");
61135
61224
  const pkg = JSON.parse(raw);
61136
61225
  if (pkg.name !== PKG_NAME) return null;
61137
61226
  return typeof pkg.version === "string" && pkg.version ? pkg.version : null;
61138
61227
  } catch {
61139
- const parent = path71.dirname(dir);
61228
+ const parent = path72.dirname(dir);
61140
61229
  if (parent === dir) return null;
61141
61230
  dir = parent;
61142
61231
  }
@@ -62229,7 +62318,7 @@ var ProjectStore = class {
62229
62318
  */
62230
62319
  async scaffold(name, templateSrcDir, scaffoldScriptPath) {
62231
62320
  const destDir = this.projectDir(name);
62232
- return await new Promise((resolve8, reject) => {
62321
+ return await new Promise((resolve9, reject) => {
62233
62322
  const child = (0, import_node_child_process15.spawn)("bash", [scaffoldScriptPath, name, templateSrcDir, destDir], {
62234
62323
  env: { ...process.env, PATH: process.env.PATH ?? "" },
62235
62324
  stdio: ["ignore", "pipe", "pipe"]
@@ -62252,7 +62341,7 @@ var ProjectStore = class {
62252
62341
  });
62253
62342
  child.on("exit", (code, signal) => {
62254
62343
  clearTimeout(timer);
62255
- if (code === 0) resolve8({ stdout, stderr });
62344
+ if (code === 0) resolve9({ stdout, stderr });
62256
62345
  else reject(new Error(`scaffold exit ${code ?? signal}: ${stderr.slice(0, 500)}`));
62257
62346
  });
62258
62347
  });
@@ -62375,7 +62464,7 @@ async function killPortOccupants(port, ownedPids, logger) {
62375
62464
  }
62376
62465
  }
62377
62466
  function listPidsOnPort(port) {
62378
- return new Promise((resolve8, reject) => {
62467
+ return new Promise((resolve9, reject) => {
62379
62468
  (0, import_node_child_process16.execFile)(
62380
62469
  "lsof",
62381
62470
  ["-ti", `:${port}`],
@@ -62387,11 +62476,11 @@ function listPidsOnPort(port) {
62387
62476
  }
62388
62477
  const text = (stdout ?? "").toString().trim();
62389
62478
  if (!text) {
62390
- resolve8([]);
62479
+ resolve9([]);
62391
62480
  return;
62392
62481
  }
62393
62482
  const list = text.split("\n").map((s) => Number(s.trim())).filter((n) => Number.isInteger(n) && n > 0);
62394
- resolve8(list);
62483
+ resolve9(list);
62395
62484
  }
62396
62485
  );
62397
62486
  });
@@ -63615,7 +63704,7 @@ var MAX_TIMEOUT_MS = 3e5;
63615
63704
  var MAX_OUTPUT_BYTES = 1048576;
63616
63705
  function runCommand(command, opts = {}) {
63617
63706
  const timeoutMs = Math.min(opts.timeoutMs ?? DEFAULT_TIMEOUT_MS4, MAX_TIMEOUT_MS);
63618
- return new Promise((resolve8) => {
63707
+ return new Promise((resolve9) => {
63619
63708
  const child = (0, import_node_child_process18.spawn)("bash", ["-c", command], { cwd: import_node_os23.default.homedir() });
63620
63709
  const out = [];
63621
63710
  const err = [];
@@ -63656,7 +63745,7 @@ function runCommand(command, opts = {}) {
63656
63745
  }, timeoutMs);
63657
63746
  child.on("close", (code) => {
63658
63747
  clearTimeout(timer);
63659
- resolve8({
63748
+ resolve9({
63660
63749
  stdout: Buffer.concat(out).toString("utf8"),
63661
63750
  stderr: Buffer.concat(err).toString("utf8"),
63662
63751
  exitCode: timedOut ? null : code,
@@ -63667,7 +63756,7 @@ function runCommand(command, opts = {}) {
63667
63756
  });
63668
63757
  child.on("error", () => {
63669
63758
  clearTimeout(timer);
63670
- resolve8({
63759
+ resolve9({
63671
63760
  stdout: Buffer.concat(out).toString("utf8"),
63672
63761
  stderr: Buffer.concat(err).toString("utf8"),
63673
63762
  exitCode: null,
@@ -63842,10 +63931,10 @@ function parseVersionOutput(out) {
63842
63931
  return /(\d+\.\d+\.\d+)/.exec(out)?.[1];
63843
63932
  }
63844
63933
  function execVersion(bin) {
63845
- return new Promise((resolve8, reject) => {
63934
+ return new Promise((resolve9, reject) => {
63846
63935
  (0, import_node_child_process19.execFile)(bin, ["--version"], { timeout: 5e3 }, (err, stdout) => {
63847
63936
  if (err) reject(err);
63848
- else resolve8(String(stdout));
63937
+ else resolve9(String(stdout));
63849
63938
  });
63850
63939
  });
63851
63940
  }
@@ -63999,8 +64088,8 @@ var DevServerSupervisor = class extends import_node_events2.EventEmitter {
63999
64088
  });
64000
64089
  let readyResolve;
64001
64090
  let readyReject;
64002
- const readyPromise = new Promise((resolve8, reject) => {
64003
- readyResolve = resolve8;
64091
+ const readyPromise = new Promise((resolve9, reject) => {
64092
+ readyResolve = resolve9;
64004
64093
  readyReject = reject;
64005
64094
  });
64006
64095
  readyPromise.catch(() => {
@@ -64079,7 +64168,7 @@ var DevServerSupervisor = class extends import_node_events2.EventEmitter {
64079
64168
  if (!entry.ready) {
64080
64169
  entry.readyReject(new Error("dev server stopped before ready"));
64081
64170
  }
64082
- return new Promise((resolve8) => {
64171
+ return new Promise((resolve9) => {
64083
64172
  let settled = false;
64084
64173
  let killTimer;
64085
64174
  const cleanup = () => {
@@ -64087,7 +64176,7 @@ var DevServerSupervisor = class extends import_node_events2.EventEmitter {
64087
64176
  settled = true;
64088
64177
  if (killTimer) clearTimeout(killTimer);
64089
64178
  this.running.delete(sessionId);
64090
- resolve8();
64179
+ resolve9();
64091
64180
  };
64092
64181
  entry.process.once("exit", cleanup);
64093
64182
  const pid = entry.process.pid;
@@ -64169,7 +64258,7 @@ var DevServerSupervisor = class extends import_node_events2.EventEmitter {
64169
64258
  if (!entry) {
64170
64259
  return Promise.reject(new Error(`dev server for project "${projectName}" not running`));
64171
64260
  }
64172
- return new Promise((resolve8, reject) => {
64261
+ return new Promise((resolve9, reject) => {
64173
64262
  let settled = false;
64174
64263
  let timer;
64175
64264
  const finish = (err) => {
@@ -64177,7 +64266,7 @@ var DevServerSupervisor = class extends import_node_events2.EventEmitter {
64177
64266
  settled = true;
64178
64267
  if (timer) clearTimeout(timer);
64179
64268
  if (opts.signal) opts.signal.removeEventListener("abort", onAbort);
64180
- err ? reject(err) : resolve8();
64269
+ err ? reject(err) : resolve9();
64181
64270
  };
64182
64271
  const onAbort = () => finish(new Error("awaitReady aborted via signal"));
64183
64272
  entry.readyPromise.then(() => finish(), (err) => finish(err));
@@ -64260,16 +64349,16 @@ var PortExhaustedError = class extends Error {
64260
64349
  code = "PORT_EXHAUSTED";
64261
64350
  };
64262
64351
  function probe(port) {
64263
- return new Promise((resolve8) => {
64352
+ return new Promise((resolve9) => {
64264
64353
  const srv = import_node_net2.default.createServer();
64265
- srv.once("error", () => resolve8(false));
64354
+ srv.once("error", () => resolve9(false));
64266
64355
  srv.once("listening", () => {
64267
- srv.close(() => resolve8(true));
64356
+ srv.close(() => resolve9(true));
64268
64357
  });
64269
64358
  try {
64270
64359
  srv.listen({ port, host: "127.0.0.1", exclusive: true });
64271
64360
  } catch {
64272
- resolve8(false);
64361
+ resolve9(false);
64273
64362
  }
64274
64363
  });
64275
64364
  }
@@ -64364,7 +64453,7 @@ var Runtime = class {
64364
64453
  child.stdout.on("data", () => {
64365
64454
  });
64366
64455
  let earlyExit = null;
64367
- const exitPromise = new Promise((resolve8) => {
64456
+ const exitPromise = new Promise((resolve9) => {
64368
64457
  child.once("exit", (code, signal) => {
64369
64458
  earlyExit = { code, signal };
64370
64459
  const wasUnexpected = this.handles.get(extId) === handle;
@@ -64372,7 +64461,7 @@ var Runtime = class {
64372
64461
  this.handles.delete(extId);
64373
64462
  this.crashed.add(extId);
64374
64463
  }
64375
- resolve8();
64464
+ resolve9();
64376
64465
  });
64377
64466
  });
64378
64467
  this.handles.set(extId, handle);
@@ -64445,7 +64534,7 @@ ${handle.stderrTail}`
64445
64534
  }
64446
64535
  };
64447
64536
  killGroup("SIGTERM");
64448
- const exited = new Promise((resolve8) => child.once("exit", () => resolve8()));
64537
+ const exited = new Promise((resolve9) => child.once("exit", () => resolve9()));
64449
64538
  const timed = (0, import_promises14.setTimeout)(5e3).then(() => "timeout");
64450
64539
  const winner = await Promise.race([exited.then(() => "exited"), timed]);
64451
64540
  if (winner === "timeout" && child.exitCode === null) {