@clawos-dev/clawd 0.2.439 → 0.2.440

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: path89, errorMaps, issueData } = params;
454
- const fullPath = [...path89, ...issueData.path || []];
453
+ const { data, path: path91, errorMaps, issueData } = params;
454
+ const fullPath = [...path91, ...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, path89, key) {
765
+ constructor(parent, value, path91, key) {
766
766
  this._cachedPath = [];
767
767
  this.parent = parent;
768
768
  this.data = value;
769
- this._path = path89;
769
+ this._path = path91;
770
770
  this._key = key;
771
771
  }
772
772
  get path() {
@@ -7285,7 +7285,7 @@ var init_principal = __esm({
7285
7285
  });
7286
7286
 
7287
7287
  // ../protocol/src/schemas.ts
7288
- var SessionStatusSchema, 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, QueuedMessage, SessionSendArgs, SessionDequeueArgs, SessionRewindArgs, SessionRewindResponseSchema, SessionRewindDiffArgs, RewindDiffHunkSchema, RewindDiffFileSchema, SessionRewindDiffResponseSchema, 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, 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;
7288
+ var SessionStatusSchema, 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, QueuedMessage, SessionSendArgs, SessionDequeueArgs, SessionRewindArgs, SessionRewindResponseSchema, SessionRewindDiffArgs, RewindDiffHunkSchema, RewindDiffFileSchema, SessionRewindDiffResponseSchema, SessionRewindableMessageIdsResponseSchema, SessionResumeArgs, SessionForkArgs, SessionForkResponseSchema, SessionObserveArgs, SessionEventsArgs, PermissionRespondArgs, HistoryListArgs, HistoryReadArgs, HistorySubagentsArgs, HistorySubagentReadArgs, WorkspaceListArgs, WorkspaceReadArgs, SkillsListArgs, SkillEntrySchema, AgentEntrySchema, AgentsListArgs, AgentsListResponseSchema, SessionCurrentTurnSenderArgs, SessionSubscribeArgs, SessionPinArgs, SessionArchiveArgs, SessionSearchContentArgs, SessionSearchMatchSchema, SessionSearchContentResponseSchema, PeerSessionUpsertArgs, PeerSessionUpsertResponseSchema, PeerSessionRemoveArgs, PeerSessionRemoveResponseSchema, SessionReorderPinsArgs, GitRootArgs, GitRootResponseSchema, GitBranchArgs, GitBranchResponseSchema, GitBranchesArgs, GitBranchesResponseSchema, 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;
7289
7289
  var init_schemas = __esm({
7290
7290
  "../protocol/src/schemas.ts"() {
7291
7291
  "use strict";
@@ -8029,6 +8029,22 @@ var init_schemas = __esm({
8029
8029
  sessionId: external_exports.string().min(1),
8030
8030
  archived: external_exports.boolean()
8031
8031
  });
8032
+ SessionSearchContentArgs = external_exports.object({
8033
+ query: external_exports.string().min(1),
8034
+ // 扫描顺序 = 数组顺序(调用方按 updatedAt 倒序传),攒够 limit 即停
8035
+ sessionIds: external_exports.array(external_exports.string().min(1)),
8036
+ limit: external_exports.number().int().positive().max(50).optional()
8037
+ });
8038
+ SessionSearchMatchSchema = external_exports.object({
8039
+ sessionId: external_exports.string().min(1),
8040
+ // 命中处上下文片段,已单行化。**不回高亮 offset**:调用方手里有 query,
8041
+ // 自己在 snippet 里 indexOf 就能高亮,wire 上少一组坐标少一处漂
8042
+ snippet: external_exports.string()
8043
+ });
8044
+ SessionSearchContentResponseSchema = external_exports.object({
8045
+ type: external_exports.literal("session:searchContent"),
8046
+ matches: external_exports.array(SessionSearchMatchSchema)
8047
+ });
8032
8048
  PeerSessionUpsertArgs = SessionFileSchema;
8033
8049
  PeerSessionUpsertResponseSchema = external_exports.object({
8034
8050
  type: external_exports.literal("peerSession:upsert:ok")
@@ -8515,6 +8531,10 @@ var init_methods = __esm({
8515
8531
  summary: "\u5F52\u6863 / \u53D6\u6D88\u5F52\u6863\u4F1A\u8BDD\uFF08\u5F52\u6863 = \u5168\u5C40\u6536\u7EB3\u6001\uFF1A\u9000\u51FA sidebar\u3001\u539F\u5B50\u6E05 pinnedAt\uFF09",
8516
8532
  args: SessionArchiveArgs
8517
8533
  },
8534
+ "session:searchContent": {
8535
+ summary: '\u5728 sessionIds \u7ED9\u5B9A\u7684\u8FD9\u6279\u4F1A\u8BDD\u91CC\u641C\u6B63\u6587\u5185\u5BB9\uFF08user / assistant \u7684\u6587\u672C\u6D88\u606F\uFF1B\u5DE5\u5177\u5165\u53C2\u51FA\u53C2\u4E0E\u7CFB\u7EDF\u6CE8\u5165\u4E0D\u7B97\uFF09\uFF0C\u547D\u4E2D\u8FD4\u56DE\u4E0A\u4E0B\u6587\u7247\u6BB5\u3002**\u626B\u63CF\u987A\u5E8F = sessionIds \u6570\u7EC4\u987A\u5E8F\uFF0C\u6512\u591F limit \u5C31\u505C**\uFF08\u8C03\u7528\u65B9\u6309 updatedAt \u5012\u5E8F\u4F20 \u2192 \u65E9\u505C\u7ED3\u679C\u5373"\u6700\u8FD1 N \u6761"\uFF09\uFF1Blimit \u7F3A\u7701 9\u3002\u5019\u9009\u7531\u8C03\u7528\u65B9\u7ED9\u5B9A\uFF0Cdaemon \u4E0D\u81EA\u5DF1\u6309 archivedAt \u7B5B\uFF08\u8BDD\u9898\u5F52\u6863\u53EA\u6253\u5728 Master \u4F1A\u8BDD\u4E0A\uFF0Cworker \u4F1A\u8BDD\u6CA1\u6807\u8BB0\uFF09\uFF1B\u65E0\u6743\u8BFB / \u5B9A\u4F4D\u4E0D\u5230 transcript / transcript \u5DF2\u88AB CC \u6E05\u7406\u7684\u4F1A\u8BDD\u9759\u9ED8\u8DF3\u8FC7\uFF0C\u4E0D\u62A5\u9519',
8536
+ args: SessionSearchContentArgs
8537
+ },
8518
8538
  "session:markRead": {
8519
8539
  summary: "\u6E05\u6389\u4F1A\u8BDD\u7684\u5171\u4EAB\u672A\u8BFB\u6807\u8BB0\u5E76\u5E7F\u64AD session:info\uFF1B\u5E42\u7B49",
8520
8540
  args: SessionIdArgs
@@ -9574,8 +9594,8 @@ var require_req = __commonJS({
9574
9594
  if (req.originalUrl) {
9575
9595
  _req.url = req.originalUrl;
9576
9596
  } else {
9577
- const path89 = req.path;
9578
- _req.url = typeof path89 === "string" ? path89 : req.url ? req.url.path || req.url : void 0;
9597
+ const path91 = req.path;
9598
+ _req.url = typeof path91 === "string" ? path91 : req.url ? req.url.path || req.url : void 0;
9579
9599
  }
9580
9600
  if (req.query) {
9581
9601
  _req.query = req.query;
@@ -9740,14 +9760,14 @@ var require_redact = __commonJS({
9740
9760
  }
9741
9761
  return obj;
9742
9762
  }
9743
- function parsePath(path89) {
9763
+ function parsePath(path91) {
9744
9764
  const parts = [];
9745
9765
  let current = "";
9746
9766
  let inBrackets = false;
9747
9767
  let inQuotes = false;
9748
9768
  let quoteChar = "";
9749
- for (let i = 0; i < path89.length; i++) {
9750
- const char = path89[i];
9769
+ for (let i = 0; i < path91.length; i++) {
9770
+ const char = path91[i];
9751
9771
  if (!inBrackets && char === ".") {
9752
9772
  if (current) {
9753
9773
  parts.push(current);
@@ -9878,10 +9898,10 @@ var require_redact = __commonJS({
9878
9898
  return current;
9879
9899
  }
9880
9900
  function redactPaths(obj, paths, censor, remove = false) {
9881
- for (const path89 of paths) {
9882
- const parts = parsePath(path89);
9901
+ for (const path91 of paths) {
9902
+ const parts = parsePath(path91);
9883
9903
  if (parts.includes("*")) {
9884
- redactWildcardPath(obj, parts, censor, path89, remove);
9904
+ redactWildcardPath(obj, parts, censor, path91, remove);
9885
9905
  } else {
9886
9906
  if (remove) {
9887
9907
  removeKey(obj, parts);
@@ -9966,8 +9986,8 @@ var require_redact = __commonJS({
9966
9986
  }
9967
9987
  } else {
9968
9988
  if (afterWildcard.includes("*")) {
9969
- const wrappedCensor = typeof censor === "function" ? (value, path89) => {
9970
- const fullPath = [...pathArray.slice(0, pathLength), ...path89];
9989
+ const wrappedCensor = typeof censor === "function" ? (value, path91) => {
9990
+ const fullPath = [...pathArray.slice(0, pathLength), ...path91];
9971
9991
  return censor(value, fullPath);
9972
9992
  } : censor;
9973
9993
  redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
@@ -10002,8 +10022,8 @@ var require_redact = __commonJS({
10002
10022
  return null;
10003
10023
  }
10004
10024
  const pathStructure = /* @__PURE__ */ new Map();
10005
- for (const path89 of pathsToClone) {
10006
- const parts = parsePath(path89);
10025
+ for (const path91 of pathsToClone) {
10026
+ const parts = parsePath(path91);
10007
10027
  let current = pathStructure;
10008
10028
  for (let i = 0; i < parts.length; i++) {
10009
10029
  const part = parts[i];
@@ -10055,24 +10075,24 @@ var require_redact = __commonJS({
10055
10075
  }
10056
10076
  return cloneSelectively(obj, pathStructure);
10057
10077
  }
10058
- function validatePath(path89) {
10059
- if (typeof path89 !== "string") {
10078
+ function validatePath(path91) {
10079
+ if (typeof path91 !== "string") {
10060
10080
  throw new Error("Paths must be (non-empty) strings");
10061
10081
  }
10062
- if (path89 === "") {
10082
+ if (path91 === "") {
10063
10083
  throw new Error("Invalid redaction path ()");
10064
10084
  }
10065
- if (path89.includes("..")) {
10066
- throw new Error(`Invalid redaction path (${path89})`);
10085
+ if (path91.includes("..")) {
10086
+ throw new Error(`Invalid redaction path (${path91})`);
10067
10087
  }
10068
- if (path89.includes(",")) {
10069
- throw new Error(`Invalid redaction path (${path89})`);
10088
+ if (path91.includes(",")) {
10089
+ throw new Error(`Invalid redaction path (${path91})`);
10070
10090
  }
10071
10091
  let bracketCount = 0;
10072
10092
  let inQuotes = false;
10073
10093
  let quoteChar = "";
10074
- for (let i = 0; i < path89.length; i++) {
10075
- const char = path89[i];
10094
+ for (let i = 0; i < path91.length; i++) {
10095
+ const char = path91[i];
10076
10096
  if ((char === '"' || char === "'") && bracketCount > 0) {
10077
10097
  if (!inQuotes) {
10078
10098
  inQuotes = true;
@@ -10086,20 +10106,20 @@ var require_redact = __commonJS({
10086
10106
  } else if (char === "]" && !inQuotes) {
10087
10107
  bracketCount--;
10088
10108
  if (bracketCount < 0) {
10089
- throw new Error(`Invalid redaction path (${path89})`);
10109
+ throw new Error(`Invalid redaction path (${path91})`);
10090
10110
  }
10091
10111
  }
10092
10112
  }
10093
10113
  if (bracketCount !== 0) {
10094
- throw new Error(`Invalid redaction path (${path89})`);
10114
+ throw new Error(`Invalid redaction path (${path91})`);
10095
10115
  }
10096
10116
  }
10097
10117
  function validatePaths(paths) {
10098
10118
  if (!Array.isArray(paths)) {
10099
10119
  throw new TypeError("paths must be an array");
10100
10120
  }
10101
- for (const path89 of paths) {
10102
- validatePath(path89);
10121
+ for (const path91 of paths) {
10122
+ validatePath(path91);
10103
10123
  }
10104
10124
  }
10105
10125
  function slowRedact(options = {}) {
@@ -10267,8 +10287,8 @@ var require_redaction = __commonJS({
10267
10287
  if (shape[k2] === null) {
10268
10288
  o[k2] = (value) => topCensor(value, [k2]);
10269
10289
  } else {
10270
- const wrappedCensor = typeof censor === "function" ? (value, path89) => {
10271
- return censor(value, [k2, ...path89]);
10290
+ const wrappedCensor = typeof censor === "function" ? (value, path91) => {
10291
+ return censor(value, [k2, ...path91]);
10272
10292
  } : censor;
10273
10293
  o[k2] = Redact({
10274
10294
  paths: shape[k2],
@@ -10486,10 +10506,10 @@ var require_atomic_sleep = __commonJS({
10486
10506
  var require_sonic_boom = __commonJS({
10487
10507
  "../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
10488
10508
  "use strict";
10489
- var fs79 = require("fs");
10509
+ var fs80 = require("fs");
10490
10510
  var EventEmitter3 = require("events");
10491
10511
  var inherits = require("util").inherits;
10492
- var path89 = require("path");
10512
+ var path91 = require("path");
10493
10513
  var sleep2 = require_atomic_sleep();
10494
10514
  var assert = require("assert");
10495
10515
  var BUSY_WRITE_TIMEOUT = 100;
@@ -10543,20 +10563,20 @@ var require_sonic_boom = __commonJS({
10543
10563
  const mode = sonic.mode;
10544
10564
  if (sonic.sync) {
10545
10565
  try {
10546
- if (sonic.mkdir) fs79.mkdirSync(path89.dirname(file), { recursive: true });
10547
- const fd = fs79.openSync(file, flags, mode);
10566
+ if (sonic.mkdir) fs80.mkdirSync(path91.dirname(file), { recursive: true });
10567
+ const fd = fs80.openSync(file, flags, mode);
10548
10568
  fileOpened(null, fd);
10549
10569
  } catch (err) {
10550
10570
  fileOpened(err);
10551
10571
  throw err;
10552
10572
  }
10553
10573
  } else if (sonic.mkdir) {
10554
- fs79.mkdir(path89.dirname(file), { recursive: true }, (err) => {
10574
+ fs80.mkdir(path91.dirname(file), { recursive: true }, (err) => {
10555
10575
  if (err) return fileOpened(err);
10556
- fs79.open(file, flags, mode, fileOpened);
10576
+ fs80.open(file, flags, mode, fileOpened);
10557
10577
  });
10558
10578
  } else {
10559
- fs79.open(file, flags, mode, fileOpened);
10579
+ fs80.open(file, flags, mode, fileOpened);
10560
10580
  }
10561
10581
  }
10562
10582
  function SonicBoom(opts) {
@@ -10597,8 +10617,8 @@ var require_sonic_boom = __commonJS({
10597
10617
  this.flush = flushBuffer;
10598
10618
  this.flushSync = flushBufferSync;
10599
10619
  this._actualWrite = actualWriteBuffer;
10600
- fsWriteSync = () => fs79.writeSync(this.fd, this._writingBuf);
10601
- fsWrite = () => fs79.write(this.fd, this._writingBuf, this.release);
10620
+ fsWriteSync = () => fs80.writeSync(this.fd, this._writingBuf);
10621
+ fsWrite = () => fs80.write(this.fd, this._writingBuf, this.release);
10602
10622
  } else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
10603
10623
  this._writingBuf = "";
10604
10624
  this.write = write;
@@ -10607,15 +10627,15 @@ var require_sonic_boom = __commonJS({
10607
10627
  this._actualWrite = actualWrite;
10608
10628
  fsWriteSync = () => {
10609
10629
  if (Buffer.isBuffer(this._writingBuf)) {
10610
- return fs79.writeSync(this.fd, this._writingBuf);
10630
+ return fs80.writeSync(this.fd, this._writingBuf);
10611
10631
  }
10612
- return fs79.writeSync(this.fd, this._writingBuf, "utf8");
10632
+ return fs80.writeSync(this.fd, this._writingBuf, "utf8");
10613
10633
  };
10614
10634
  fsWrite = () => {
10615
10635
  if (Buffer.isBuffer(this._writingBuf)) {
10616
- return fs79.write(this.fd, this._writingBuf, this.release);
10636
+ return fs80.write(this.fd, this._writingBuf, this.release);
10617
10637
  }
10618
- return fs79.write(this.fd, this._writingBuf, "utf8", this.release);
10638
+ return fs80.write(this.fd, this._writingBuf, "utf8", this.release);
10619
10639
  };
10620
10640
  } else {
10621
10641
  throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
@@ -10672,7 +10692,7 @@ var require_sonic_boom = __commonJS({
10672
10692
  }
10673
10693
  }
10674
10694
  if (this._fsync) {
10675
- fs79.fsyncSync(this.fd);
10695
+ fs80.fsyncSync(this.fd);
10676
10696
  }
10677
10697
  const len = this._len;
10678
10698
  if (this._reopening) {
@@ -10786,7 +10806,7 @@ var require_sonic_boom = __commonJS({
10786
10806
  const onDrain = () => {
10787
10807
  if (!this._fsync) {
10788
10808
  try {
10789
- fs79.fsync(this.fd, (err) => {
10809
+ fs80.fsync(this.fd, (err) => {
10790
10810
  this._flushPending = false;
10791
10811
  cb(err);
10792
10812
  });
@@ -10888,7 +10908,7 @@ var require_sonic_boom = __commonJS({
10888
10908
  const fd = this.fd;
10889
10909
  this.once("ready", () => {
10890
10910
  if (fd !== this.fd) {
10891
- fs79.close(fd, (err) => {
10911
+ fs80.close(fd, (err) => {
10892
10912
  if (err) {
10893
10913
  return this.emit("error", err);
10894
10914
  }
@@ -10937,7 +10957,7 @@ var require_sonic_boom = __commonJS({
10937
10957
  buf = this._bufs[0];
10938
10958
  }
10939
10959
  try {
10940
- const n = Buffer.isBuffer(buf) ? fs79.writeSync(this.fd, buf) : fs79.writeSync(this.fd, buf, "utf8");
10960
+ const n = Buffer.isBuffer(buf) ? fs80.writeSync(this.fd, buf) : fs80.writeSync(this.fd, buf, "utf8");
10941
10961
  const releasedBufObj = releaseWritingBuf(buf, this._len, n);
10942
10962
  buf = releasedBufObj.writingBuf;
10943
10963
  this._len = releasedBufObj.len;
@@ -10953,7 +10973,7 @@ var require_sonic_boom = __commonJS({
10953
10973
  }
10954
10974
  }
10955
10975
  try {
10956
- fs79.fsyncSync(this.fd);
10976
+ fs80.fsyncSync(this.fd);
10957
10977
  } catch {
10958
10978
  }
10959
10979
  }
@@ -10974,7 +10994,7 @@ var require_sonic_boom = __commonJS({
10974
10994
  buf = mergeBuf(this._bufs[0], this._lens[0]);
10975
10995
  }
10976
10996
  try {
10977
- const n = fs79.writeSync(this.fd, buf);
10997
+ const n = fs80.writeSync(this.fd, buf);
10978
10998
  buf = buf.subarray(n);
10979
10999
  this._len = Math.max(this._len - n, 0);
10980
11000
  if (buf.length <= 0) {
@@ -11002,13 +11022,13 @@ var require_sonic_boom = __commonJS({
11002
11022
  this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
11003
11023
  if (this.sync) {
11004
11024
  try {
11005
- const written = Buffer.isBuffer(this._writingBuf) ? fs79.writeSync(this.fd, this._writingBuf) : fs79.writeSync(this.fd, this._writingBuf, "utf8");
11025
+ const written = Buffer.isBuffer(this._writingBuf) ? fs80.writeSync(this.fd, this._writingBuf) : fs80.writeSync(this.fd, this._writingBuf, "utf8");
11006
11026
  release(null, written);
11007
11027
  } catch (err) {
11008
11028
  release(err);
11009
11029
  }
11010
11030
  } else {
11011
- fs79.write(this.fd, this._writingBuf, release);
11031
+ fs80.write(this.fd, this._writingBuf, release);
11012
11032
  }
11013
11033
  }
11014
11034
  function actualWriteBuffer() {
@@ -11017,7 +11037,7 @@ var require_sonic_boom = __commonJS({
11017
11037
  this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
11018
11038
  if (this.sync) {
11019
11039
  try {
11020
- const written = fs79.writeSync(this.fd, this._writingBuf);
11040
+ const written = fs80.writeSync(this.fd, this._writingBuf);
11021
11041
  release(null, written);
11022
11042
  } catch (err) {
11023
11043
  release(err);
@@ -11026,7 +11046,7 @@ var require_sonic_boom = __commonJS({
11026
11046
  if (kCopyBuffer) {
11027
11047
  this._writingBuf = Buffer.from(this._writingBuf);
11028
11048
  }
11029
- fs79.write(this.fd, this._writingBuf, release);
11049
+ fs80.write(this.fd, this._writingBuf, release);
11030
11050
  }
11031
11051
  }
11032
11052
  function actualClose(sonic) {
@@ -11042,12 +11062,12 @@ var require_sonic_boom = __commonJS({
11042
11062
  sonic._lens = [];
11043
11063
  assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
11044
11064
  try {
11045
- fs79.fsync(sonic.fd, closeWrapped);
11065
+ fs80.fsync(sonic.fd, closeWrapped);
11046
11066
  } catch {
11047
11067
  }
11048
11068
  function closeWrapped() {
11049
11069
  if (sonic.fd !== 1 && sonic.fd !== 2) {
11050
- fs79.close(sonic.fd, done);
11070
+ fs80.close(sonic.fd, done);
11051
11071
  } else {
11052
11072
  done();
11053
11073
  }
@@ -13411,7 +13431,7 @@ var require_multistream = __commonJS({
13411
13431
  var require_pino = __commonJS({
13412
13432
  "../node_modules/.pnpm/pino@9.14.0/node_modules/pino/pino.js"(exports2, module2) {
13413
13433
  "use strict";
13414
- var os30 = require("os");
13434
+ var os31 = require("os");
13415
13435
  var stdSerializers = require_pino_std_serializers();
13416
13436
  var caller = require_caller();
13417
13437
  var redaction = require_redaction();
@@ -13458,7 +13478,7 @@ var require_pino = __commonJS({
13458
13478
  } = symbols;
13459
13479
  var { epochTime, nullTime } = time;
13460
13480
  var { pid } = process;
13461
- var hostname = os30.hostname();
13481
+ var hostname = os31.hostname();
13462
13482
  var defaultErrorSerializer = stdSerializers.err;
13463
13483
  var defaultOptions2 = {
13464
13484
  level: "info",
@@ -14182,11 +14202,11 @@ var init_lib = __esm({
14182
14202
  }
14183
14203
  }
14184
14204
  },
14185
- addToPath: function addToPath(path89, added, removed, oldPosInc, options) {
14186
- var last = path89.lastComponent;
14205
+ addToPath: function addToPath(path91, added, removed, oldPosInc, options) {
14206
+ var last = path91.lastComponent;
14187
14207
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
14188
14208
  return {
14189
- oldPos: path89.oldPos + oldPosInc,
14209
+ oldPos: path91.oldPos + oldPosInc,
14190
14210
  lastComponent: {
14191
14211
  count: last.count + 1,
14192
14212
  added,
@@ -14196,7 +14216,7 @@ var init_lib = __esm({
14196
14216
  };
14197
14217
  } else {
14198
14218
  return {
14199
- oldPos: path89.oldPos + oldPosInc,
14219
+ oldPos: path91.oldPos + oldPosInc,
14200
14220
  lastComponent: {
14201
14221
  count: 1,
14202
14222
  added,
@@ -14778,10 +14798,10 @@ function attachmentToHistoryMessage(o, ts) {
14778
14798
  const memories = raw.map((m2) => {
14779
14799
  if (!m2 || typeof m2 !== "object") return null;
14780
14800
  const rec4 = m2;
14781
- const path89 = typeof rec4.path === "string" ? rec4.path : null;
14801
+ const path91 = typeof rec4.path === "string" ? rec4.path : null;
14782
14802
  const content = typeof rec4.content === "string" ? rec4.content : null;
14783
- if (!path89 || content == null) return null;
14784
- const entry = { path: path89, content };
14803
+ if (!path91 || content == null) return null;
14804
+ const entry = { path: path91, content };
14785
14805
  if (typeof rec4.mtimeMs === "number") entry.mtimeMs = rec4.mtimeMs;
14786
14806
  return entry;
14787
14807
  }).filter((m2) => m2 !== null);
@@ -15647,10 +15667,10 @@ function parseAttachment(obj) {
15647
15667
  const memories = raw.map((m2) => {
15648
15668
  if (!m2 || typeof m2 !== "object") return null;
15649
15669
  const rec4 = m2;
15650
- const path89 = typeof rec4.path === "string" ? rec4.path : null;
15670
+ const path91 = typeof rec4.path === "string" ? rec4.path : null;
15651
15671
  const content = typeof rec4.content === "string" ? rec4.content : null;
15652
- if (!path89 || content == null) return null;
15653
- const out = { path: path89, content };
15672
+ if (!path91 || content == null) return null;
15673
+ const out = { path: path91, content };
15654
15674
  if (typeof rec4.mtimeMs === "number") out.mtimeMs = rec4.mtimeMs;
15655
15675
  return out;
15656
15676
  }).filter((m2) => m2 !== null);
@@ -36624,8 +36644,8 @@ var require_utils = __commonJS({
36624
36644
  var result = transform[inputType][outputType](input);
36625
36645
  return result;
36626
36646
  };
36627
- exports2.resolve = function(path89) {
36628
- var parts = path89.split("/");
36647
+ exports2.resolve = function(path91) {
36648
+ var parts = path91.split("/");
36629
36649
  var result = [];
36630
36650
  for (var index = 0; index < parts.length; index++) {
36631
36651
  var part = parts[index];
@@ -42478,18 +42498,18 @@ var require_object = __commonJS({
42478
42498
  var object = new ZipObject(name, zipObjectContent, o);
42479
42499
  this.files[name] = object;
42480
42500
  };
42481
- var parentFolder = function(path89) {
42482
- if (path89.slice(-1) === "/") {
42483
- path89 = path89.substring(0, path89.length - 1);
42501
+ var parentFolder = function(path91) {
42502
+ if (path91.slice(-1) === "/") {
42503
+ path91 = path91.substring(0, path91.length - 1);
42484
42504
  }
42485
- var lastSlash = path89.lastIndexOf("/");
42486
- return lastSlash > 0 ? path89.substring(0, lastSlash) : "";
42505
+ var lastSlash = path91.lastIndexOf("/");
42506
+ return lastSlash > 0 ? path91.substring(0, lastSlash) : "";
42487
42507
  };
42488
- var forceTrailingSlash = function(path89) {
42489
- if (path89.slice(-1) !== "/") {
42490
- path89 += "/";
42508
+ var forceTrailingSlash = function(path91) {
42509
+ if (path91.slice(-1) !== "/") {
42510
+ path91 += "/";
42491
42511
  }
42492
- return path89;
42512
+ return path91;
42493
42513
  };
42494
42514
  var folderAdd = function(name, createFolders) {
42495
42515
  createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
@@ -43491,7 +43511,7 @@ var require_lib3 = __commonJS({
43491
43511
  // src/run-case/recorder.ts
43492
43512
  function startRunCaseRecorder(opts) {
43493
43513
  const now = opts.now ?? Date.now;
43494
- const dir = import_node_path71.default.dirname(opts.recordPath);
43514
+ const dir = import_node_path73.default.dirname(opts.recordPath);
43495
43515
  let stream = null;
43496
43516
  let closing = false;
43497
43517
  let closedSettled = false;
@@ -43505,8 +43525,8 @@ function startRunCaseRecorder(opts) {
43505
43525
  });
43506
43526
  const ensureStream = () => {
43507
43527
  if (stream) return stream;
43508
- import_node_fs53.default.mkdirSync(dir, { recursive: true });
43509
- stream = import_node_fs53.default.createWriteStream(opts.recordPath, { flags: "a" });
43528
+ import_node_fs54.default.mkdirSync(dir, { recursive: true });
43529
+ stream = import_node_fs54.default.createWriteStream(opts.recordPath, { flags: "a" });
43510
43530
  stream.on("close", () => closedResolve());
43511
43531
  return stream;
43512
43532
  };
@@ -43531,12 +43551,12 @@ function startRunCaseRecorder(opts) {
43531
43551
  };
43532
43552
  return { tap, close, closed };
43533
43553
  }
43534
- var import_node_fs53, import_node_path71;
43554
+ var import_node_fs54, import_node_path73;
43535
43555
  var init_recorder = __esm({
43536
43556
  "src/run-case/recorder.ts"() {
43537
43557
  "use strict";
43538
- import_node_fs53 = __toESM(require("fs"), 1);
43539
- import_node_path71 = __toESM(require("path"), 1);
43558
+ import_node_fs54 = __toESM(require("fs"), 1);
43559
+ import_node_path73 = __toESM(require("path"), 1);
43540
43560
  }
43541
43561
  });
43542
43562
 
@@ -43579,7 +43599,7 @@ var init_wire = __esm({
43579
43599
  // src/run-case/controller.ts
43580
43600
  async function runController(opts) {
43581
43601
  const now = opts.now ?? Date.now;
43582
- const cwd = opts.cwd ?? (0, import_node_fs54.mkdtempSync)(import_node_path72.default.join(import_node_os26.default.tmpdir(), "clawd-runcase-"));
43602
+ const cwd = opts.cwd ?? (0, import_node_fs55.mkdtempSync)(import_node_path74.default.join(import_node_os27.default.tmpdir(), "clawd-runcase-"));
43583
43603
  const ownsCwd = opts.cwd === void 0;
43584
43604
  const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
43585
43605
  const spawnCtx = { cwd };
@@ -43740,19 +43760,19 @@ async function runController(opts) {
43740
43760
  if (sigintHandler) process.off("SIGINT", sigintHandler);
43741
43761
  if (ownsCwd) {
43742
43762
  try {
43743
- (0, import_node_fs54.rmSync)(cwd, { recursive: true, force: true });
43763
+ (0, import_node_fs55.rmSync)(cwd, { recursive: true, force: true });
43744
43764
  } catch {
43745
43765
  }
43746
43766
  }
43747
43767
  return exitCode ?? 0;
43748
43768
  }
43749
- var import_node_fs54, import_node_os26, import_node_path72;
43769
+ var import_node_fs55, import_node_os27, import_node_path74;
43750
43770
  var init_controller = __esm({
43751
43771
  "src/run-case/controller.ts"() {
43752
43772
  "use strict";
43753
- import_node_fs54 = require("fs");
43754
- import_node_os26 = __toESM(require("os"), 1);
43755
- import_node_path72 = __toESM(require("path"), 1);
43773
+ import_node_fs55 = require("fs");
43774
+ import_node_os27 = __toESM(require("os"), 1);
43775
+ import_node_path74 = __toESM(require("path"), 1);
43756
43776
  init_claude();
43757
43777
  init_stdout_splitter();
43758
43778
  init_permission_stdio();
@@ -44027,9 +44047,9 @@ Env (advanced):
44027
44047
  `;
44028
44048
 
44029
44049
  // src/index.ts
44030
- var import_node_path70 = __toESM(require("path"), 1);
44031
- var import_node_fs52 = __toESM(require("fs"), 1);
44032
- var import_node_os25 = __toESM(require("os"), 1);
44050
+ var import_node_path72 = __toESM(require("path"), 1);
44051
+ var import_node_fs53 = __toESM(require("fs"), 1);
44052
+ var import_node_os26 = __toESM(require("os"), 1);
44033
44053
  var import_node_crypto22 = require("crypto");
44034
44054
  var import_node_url4 = require("url");
44035
44055
 
@@ -51154,8 +51174,8 @@ function turnStartInput(text) {
51154
51174
  const items = [];
51155
51175
  let leftover = text;
51156
51176
  for (const m2 of text.matchAll(SKILL_RE)) {
51157
- const [marker, name, path89] = m2;
51158
- items.push({ type: "skill", name, path: path89 });
51177
+ const [marker, name, path91] = m2;
51178
+ items.push({ type: "skill", name, path: path91 });
51159
51179
  leftover = leftover.replace(marker, "");
51160
51180
  }
51161
51181
  for (const m2 of text.matchAll(ATTACHMENT_RE2)) {
@@ -55842,13 +55862,13 @@ function mapSkillsListResponse(res) {
55842
55862
  const r = s ?? {};
55843
55863
  const name = str3(r.name);
55844
55864
  if (!name) continue;
55845
- const path89 = str3(r.path);
55865
+ const path91 = str3(r.path);
55846
55866
  const description = str3(r.description);
55847
55867
  const isPlugin = name.includes(":");
55848
55868
  out.push({
55849
55869
  name,
55850
55870
  source: isPlugin ? "plugin" : "project",
55851
- ...path89 ? { path: path89 } : {},
55871
+ ...path91 ? { path: path91 } : {},
55852
55872
  ...description ? { description } : {},
55853
55873
  ...isPlugin ? { plugin: name.split(":")[0] } : {}
55854
55874
  });
@@ -60170,9 +60190,9 @@ var CentralClientError = class extends Error {
60170
60190
  code;
60171
60191
  cause;
60172
60192
  };
60173
- async function centralRequest(opts, path89, init) {
60193
+ async function centralRequest(opts, path91, init) {
60174
60194
  const f = opts.fetchImpl ?? globalThis.fetch;
60175
- const url = `${opts.api.replace(/\/+$/, "")}${path89}`;
60195
+ const url = `${opts.api.replace(/\/+$/, "")}${path91}`;
60176
60196
  const ctrl = new AbortController();
60177
60197
  const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
60178
60198
  let res;
@@ -60653,7 +60673,7 @@ var ServerKeyStore = class {
60653
60673
  init_protocol();
60654
60674
 
60655
60675
  // src/handlers/index.ts
60656
- var import_node_path66 = __toESM(require("path"), 1);
60676
+ var import_node_path68 = __toESM(require("path"), 1);
60657
60677
 
60658
60678
  // src/handlers/session.ts
60659
60679
  init_protocol();
@@ -60996,8 +61016,133 @@ function appendImportLedger(dataDir, entry) {
60996
61016
  import_node_fs47.default.writeFileSync(file, JSON.stringify(entries, null, 2), { encoding: "utf8", mode: 384 });
60997
61017
  }
60998
61018
 
61019
+ // src/tools/transcript-search.ts
61020
+ var import_node_fs48 = __toESM(require("fs"), 1);
61021
+ var import_node_path54 = __toESM(require("path"), 1);
61022
+ var SNIPPET_PAD = 60;
61023
+ var INJECTED_ENVELOPE_RE = /^<(system-reminder|command-name|command-message|command-args|local-command-stdout|local-command-stderr|task-notification|user-prompt-submit-hook|environment_context|user_instructions)\b/;
61024
+ var CODEX_WRAPPER_RE = /<(related-dir|environment_context|user_instructions)>[\s\S]*?<\/\1>/g;
61025
+ function asRecord(v2) {
61026
+ return typeof v2 === "object" && v2 !== null ? v2 : null;
61027
+ }
61028
+ function textOfBlocks(content, types) {
61029
+ if (!Array.isArray(content)) return null;
61030
+ const parts = [];
61031
+ for (const block of content) {
61032
+ const b2 = asRecord(block);
61033
+ if (!b2 || typeof b2.type !== "string" || !types.includes(b2.type)) continue;
61034
+ const text = b2.text;
61035
+ if (typeof text === "string" && text !== "") parts.push(text);
61036
+ }
61037
+ return parts.length > 0 ? parts.join("\n") : null;
61038
+ }
61039
+ function lineToSearchableText(raw) {
61040
+ const line = asRecord(raw);
61041
+ if (!line) return null;
61042
+ if (line.type === "response_item") {
61043
+ const payload = asRecord(line.payload);
61044
+ if (!payload || payload.type !== "message") return null;
61045
+ const role = payload.role;
61046
+ if (role !== "user" && role !== "assistant") return null;
61047
+ const text2 = textOfBlocks(payload.content, ["input_text", "output_text"]);
61048
+ if (text2 === null) return null;
61049
+ if (role !== "user") return text2;
61050
+ const stripped = text2.replace(CODEX_WRAPPER_RE, "").trim();
61051
+ if (stripped === "") return null;
61052
+ return INJECTED_ENVELOPE_RE.test(stripped) ? null : stripped;
61053
+ }
61054
+ if (line.type !== "user" && line.type !== "assistant") return null;
61055
+ const message = asRecord(line.message);
61056
+ if (!message) return null;
61057
+ const content = message.content;
61058
+ const text = typeof content === "string" && content !== "" ? content : textOfBlocks(content, ["text"]);
61059
+ if (text === null) return null;
61060
+ if (line.type === "user" && (line.isMeta === true || line.isSynthetic === true)) return null;
61061
+ if (line.type === "user" && INJECTED_ENVELOPE_RE.test(text.trimStart())) return null;
61062
+ return text;
61063
+ }
61064
+ function escapeRegExp(s) {
61065
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
61066
+ }
61067
+ function makeSnippet(text, at, needleLength) {
61068
+ const from = Math.max(0, at - SNIPPET_PAD);
61069
+ const to = Math.min(text.length, at + needleLength + SNIPPET_PAD);
61070
+ const body = text.slice(from, to).replace(/\s+/g, " ").trim();
61071
+ return `${from > 0 ? "\u2026 " : ""}${body}${to < text.length ? " \u2026" : ""}`;
61072
+ }
61073
+ function searchTranscriptFile(file, query) {
61074
+ let buf;
61075
+ try {
61076
+ buf = import_node_fs48.default.readFileSync(file);
61077
+ } catch {
61078
+ return null;
61079
+ }
61080
+ const haystack = buf.toString("latin1");
61081
+ const needle = Buffer.from(query, "utf8").toString("latin1");
61082
+ const re = new RegExp(escapeRegExp(needle), "gi");
61083
+ let m2;
61084
+ while ((m2 = re.exec(haystack)) !== null) {
61085
+ const lineStart = haystack.lastIndexOf("\n", m2.index) + 1;
61086
+ let lineEnd = haystack.indexOf("\n", m2.index);
61087
+ if (lineEnd < 0) lineEnd = haystack.length;
61088
+ re.lastIndex = lineEnd + 1;
61089
+ let parsed;
61090
+ try {
61091
+ parsed = JSON.parse(Buffer.from(haystack.slice(lineStart, lineEnd), "latin1").toString("utf8"));
61092
+ } catch {
61093
+ continue;
61094
+ }
61095
+ const text = lineToSearchableText(parsed);
61096
+ if (text === null) continue;
61097
+ const at = text.toLowerCase().indexOf(query.toLowerCase());
61098
+ if (at < 0) continue;
61099
+ return makeSnippet(text, at, query.length);
61100
+ }
61101
+ return null;
61102
+ }
61103
+ var ROLLOUT_NAME_RE = /-([0-9a-fA-F-]{36})\.jsonl$/;
61104
+ function createCodexRolloutLocator(roots) {
61105
+ let index = null;
61106
+ const walk2 = (dir, into) => {
61107
+ let entries;
61108
+ try {
61109
+ entries = import_node_fs48.default.readdirSync(dir, { withFileTypes: true });
61110
+ } catch {
61111
+ return;
61112
+ }
61113
+ for (const entry of entries) {
61114
+ const full = import_node_path54.default.join(dir, entry.name);
61115
+ if (entry.isDirectory()) {
61116
+ walk2(full, into);
61117
+ continue;
61118
+ }
61119
+ const matched = ROLLOUT_NAME_RE.exec(entry.name);
61120
+ if (matched) into.set(matched[1].toLowerCase(), full);
61121
+ }
61122
+ };
61123
+ return (toolSessionId) => {
61124
+ if (index === null) {
61125
+ index = /* @__PURE__ */ new Map();
61126
+ for (const root of roots) walk2(root, index);
61127
+ }
61128
+ return index.get(toolSessionId.toLowerCase()) ?? null;
61129
+ };
61130
+ }
61131
+
60999
61132
  // src/handlers/session.ts
61000
61133
  init_protocol();
61134
+ var import_node_os19 = __toESM(require("os"), 1);
61135
+ var import_node_path55 = __toESM(require("path"), 1);
61136
+ function canReadSearchHit(ctx, file) {
61137
+ if (!ctx || ctx.principal.kind === "owner") return true;
61138
+ return canAccessPersona(ctx.grants, file.ownerPersonaId, "read") && file.creatorPrincipalId === ctx.principal.id;
61139
+ }
61140
+ var DEFAULT_SEARCH_LIMIT = 9;
61141
+ function codexRolloutRoots(dataDir) {
61142
+ const roots = [import_node_path55.default.join(import_node_os19.default.homedir(), ".codex", "sessions")];
61143
+ if (dataDir) roots.push(import_node_path55.default.join(dataDir, "codex-home", "sessions"));
61144
+ return roots;
61145
+ }
61001
61146
  function buildSessionHandlers(deps) {
61002
61147
  const { manager, observer, getAdapter: getAdapter2, store, ownerPrincipalId } = deps;
61003
61148
  const ensureSessionAccess = (ctx, sessionId, action) => {
@@ -61373,6 +61518,23 @@ ${attribution}` } : args;
61373
61518
  const { response, broadcast } = manager.markRead(args);
61374
61519
  return { response: { type: "session:info", ...response }, broadcast };
61375
61520
  };
61521
+ const searchContent = async (frame, _client, ctx) => {
61522
+ const args = SessionSearchContentArgs.parse(frame);
61523
+ const limit = args.limit ?? DEFAULT_SEARCH_LIMIT;
61524
+ const locateCodexRollout = createCodexRolloutLocator(codexRolloutRoots(deps.dataDir));
61525
+ const matches = [];
61526
+ for (const sessionId of args.sessionIds) {
61527
+ if (matches.length >= limit) break;
61528
+ const file = manager.findOwnedSession(sessionId);
61529
+ if (!file?.toolSessionId) continue;
61530
+ if (!canReadSearchHit(ctx, file)) continue;
61531
+ const transcript = file.tool === "codex" ? locateCodexRollout(file.toolSessionId) : deps.history?.resolveTranscriptFile(file.cwd, file.toolSessionId) ?? null;
61532
+ if (!transcript) continue;
61533
+ const snippet = searchTranscriptFile(transcript, args.query);
61534
+ if (snippet !== null) matches.push({ sessionId, snippet });
61535
+ }
61536
+ return { response: { type: "session:searchContent", matches } };
61537
+ };
61376
61538
  const reorderPins = async (frame) => {
61377
61539
  const args = SessionReorderPinsArgs.parse(frame);
61378
61540
  const { response, broadcast } = manager.reorderPins(args);
@@ -61493,6 +61655,7 @@ ${attribution}` } : args;
61493
61655
  "session:pin": pin,
61494
61656
  "session:archive": archive,
61495
61657
  "session:markRead": markRead,
61658
+ "session:searchContent": searchContent,
61496
61659
  "session:reorderPins": reorderPins,
61497
61660
  "session:answerQuestion": answerQuestion,
61498
61661
  "session:cancelQuestion": cancelQuestion,
@@ -61519,7 +61682,7 @@ function buildPermissionHandlers(deps) {
61519
61682
  }
61520
61683
 
61521
61684
  // src/handlers/history.ts
61522
- var path68 = __toESM(require("path"), 1);
61685
+ var path70 = __toESM(require("path"), 1);
61523
61686
  init_protocol();
61524
61687
 
61525
61688
  // src/session/recent-dirs.ts
@@ -61537,7 +61700,7 @@ function listRecentDirs(store, limit = 50) {
61537
61700
  }
61538
61701
 
61539
61702
  // src/permission/persona-paths.ts
61540
- var path67 = __toESM(require("path"), 1);
61703
+ var path69 = __toESM(require("path"), 1);
61541
61704
  function getAllowedPersonaIds(grants, action) {
61542
61705
  const ids = /* @__PURE__ */ new Set();
61543
61706
  for (const g2 of grants) {
@@ -61550,42 +61713,42 @@ function getAllowedPersonaIds(grants, action) {
61550
61713
  return ids;
61551
61714
  }
61552
61715
  function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
61553
- const target = path67.resolve(absPath);
61716
+ const target = path69.resolve(absPath);
61554
61717
  if (userWorkDir) {
61555
- const u = path67.resolve(userWorkDir);
61556
- const usep = u.endsWith(path67.sep) ? "" : path67.sep;
61718
+ const u = path69.resolve(userWorkDir);
61719
+ const usep = u.endsWith(path69.sep) ? "" : path69.sep;
61557
61720
  if (target === u || target.startsWith(u + usep)) return true;
61558
61721
  }
61559
- const root = path67.resolve(personaRoot);
61560
- const sep4 = root.endsWith(path67.sep) ? "" : path67.sep;
61722
+ const root = path69.resolve(personaRoot);
61723
+ const sep4 = root.endsWith(path69.sep) ? "" : path69.sep;
61561
61724
  if (!target.startsWith(root + sep4)) return false;
61562
- const rel = path67.relative(root, target);
61725
+ const rel = path69.relative(root, target);
61563
61726
  if (!rel || rel.startsWith("..")) return false;
61564
- const personaId2 = rel.split(path67.sep)[0];
61727
+ const personaId2 = rel.split(path69.sep)[0];
61565
61728
  if (!personaId2) return false;
61566
61729
  const allowed = getAllowedPersonaIds(grants, action);
61567
61730
  if (allowed === "*") return true;
61568
61731
  return allowed.has(personaId2);
61569
61732
  }
61570
61733
  function personaIdFromPath(absPath, personaRoot) {
61571
- const root = path67.resolve(personaRoot);
61572
- const target = path67.resolve(absPath);
61573
- const sep4 = root.endsWith(path67.sep) ? "" : path67.sep;
61734
+ const root = path69.resolve(personaRoot);
61735
+ const target = path69.resolve(absPath);
61736
+ const sep4 = root.endsWith(path69.sep) ? "" : path69.sep;
61574
61737
  if (!target.startsWith(root + sep4)) return null;
61575
- const rel = path67.relative(root, target);
61738
+ const rel = path69.relative(root, target);
61576
61739
  if (!rel || rel.startsWith("..")) return null;
61577
- const id = rel.split(path67.sep)[0];
61740
+ const id = rel.split(path69.sep)[0];
61578
61741
  return id || null;
61579
61742
  }
61580
61743
  function isPathWithin(dir, absPath) {
61581
- const d = path67.resolve(dir);
61582
- const t = path67.resolve(absPath);
61583
- const sep4 = d.endsWith(path67.sep) ? "" : path67.sep;
61744
+ const d = path69.resolve(dir);
61745
+ const t = path69.resolve(absPath);
61746
+ const sep4 = d.endsWith(path69.sep) ? "" : path69.sep;
61584
61747
  return t === d || t.startsWith(d + sep4);
61585
61748
  }
61586
61749
  function isPathInGuestBoundary(personaRoot, personaId2, userWorkDir, absPath) {
61587
61750
  if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
61588
- return personaIdFromPath(path67.resolve(absPath), personaRoot) === personaId2;
61751
+ return personaIdFromPath(path69.resolve(absPath), personaRoot) === personaId2;
61589
61752
  }
61590
61753
 
61591
61754
  // src/handlers/history.ts
@@ -61638,7 +61801,7 @@ function buildHistoryHandlers(deps) {
61638
61801
  if (!pid) return false;
61639
61802
  return isGuestPathAllowed(
61640
61803
  ctx.grants,
61641
- path68.join(personaRoot, pid),
61804
+ path70.join(personaRoot, pid),
61642
61805
  personaRoot,
61643
61806
  "read",
61644
61807
  userWorkDir
@@ -61650,7 +61813,7 @@ function buildHistoryHandlers(deps) {
61650
61813
  };
61651
61814
  const list = async (frame, _client, ctx) => {
61652
61815
  const args = HistoryListArgs.parse(frame);
61653
- assertGuestPath(ctx, path68.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
61816
+ assertGuestPath(ctx, path70.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
61654
61817
  const sessions = await history.listSessions(args);
61655
61818
  return { response: { type: "history:list", sessions } };
61656
61819
  };
@@ -61698,14 +61861,14 @@ function buildHistoryHandlers(deps) {
61698
61861
  };
61699
61862
  const subagents = async (frame, _client, ctx) => {
61700
61863
  const args = HistorySubagentsArgs.parse(frame);
61701
- assertGuestPath(ctx, path68.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
61864
+ assertGuestPath(ctx, path70.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
61702
61865
  assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagents");
61703
61866
  const subs = await historyReaderForToolSession(args.toolSessionId).listSubagents(args);
61704
61867
  return { response: { type: "history:subagents", subagents: subs } };
61705
61868
  };
61706
61869
  const subagentRead = async (frame, _client, ctx) => {
61707
61870
  const args = HistorySubagentReadArgs.parse(frame);
61708
- assertGuestPath(ctx, path68.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
61871
+ assertGuestPath(ctx, path70.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
61709
61872
  assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagent-read");
61710
61873
  const res = await historyReaderForToolSession(args.toolSessionId).readSubagent(args);
61711
61874
  return { response: { type: "history:subagent-read", ...res } };
@@ -61715,7 +61878,7 @@ function buildHistoryHandlers(deps) {
61715
61878
  if (ctx?.principal.kind === "guest" && personaRoot) {
61716
61879
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
61717
61880
  const filtered = dirs.filter(
61718
- (d) => isGuestPathAllowed(ctx.grants, path68.resolve(d.cwd), personaRoot, "read", userWorkDir)
61881
+ (d) => isGuestPathAllowed(ctx.grants, path70.resolve(d.cwd), personaRoot, "read", userWorkDir)
61719
61882
  );
61720
61883
  return { response: { type: "history:recentDirs", dirs: filtered } };
61721
61884
  }
@@ -61732,17 +61895,17 @@ function buildHistoryHandlers(deps) {
61732
61895
  }
61733
61896
 
61734
61897
  // src/handlers/projects.ts
61735
- var fs63 = __toESM(require("fs"), 1);
61736
- var os20 = __toESM(require("os"), 1);
61737
- var path69 = __toESM(require("path"), 1);
61898
+ var fs64 = __toESM(require("fs"), 1);
61899
+ var os21 = __toESM(require("os"), 1);
61900
+ var path71 = __toESM(require("path"), 1);
61738
61901
  var import_node_child_process13 = require("child_process");
61739
61902
  init_protocol();
61740
- var DEFAULT_PROJECTS_ROOT = path69.join(os20.homedir(), "Documents", "ChatGPT");
61903
+ var DEFAULT_PROJECTS_ROOT = path71.join(os21.homedir(), "Documents", "ChatGPT");
61741
61904
  function allocateDir(root, name) {
61742
- let candidate = path69.join(root, name);
61905
+ let candidate = path71.join(root, name);
61743
61906
  let n = 2;
61744
- while (fs63.existsSync(candidate)) {
61745
- candidate = path69.join(root, `${name} ${n}`);
61907
+ while (fs64.existsSync(candidate)) {
61908
+ candidate = path71.join(root, `${name} ${n}`);
61746
61909
  n += 1;
61747
61910
  }
61748
61911
  return candidate;
@@ -61770,7 +61933,7 @@ function buildProjectHandlers(deps) {
61770
61933
  throw new ClawdError(ERROR_CODES.INVALID_CWD, "project:reveal \u4EC5\u652F\u6301 macOS");
61771
61934
  }
61772
61935
  try {
61773
- if (!fs63.statSync(args.path).isDirectory()) throw new Error("not dir");
61936
+ if (!fs64.statSync(args.path).isDirectory()) throw new Error("not dir");
61774
61937
  } catch {
61775
61938
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
61776
61939
  }
@@ -61786,7 +61949,7 @@ function buildProjectHandlers(deps) {
61786
61949
  let target;
61787
61950
  if (args.path) {
61788
61951
  try {
61789
- if (!fs63.statSync(args.path).isDirectory()) throw new Error("not dir");
61952
+ if (!fs64.statSync(args.path).isDirectory()) throw new Error("not dir");
61790
61953
  } catch {
61791
61954
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
61792
61955
  }
@@ -61794,15 +61957,15 @@ function buildProjectHandlers(deps) {
61794
61957
  } else {
61795
61958
  const name = args.name;
61796
61959
  try {
61797
- fs63.mkdirSync(root, { recursive: true });
61960
+ fs64.mkdirSync(root, { recursive: true });
61798
61961
  target = allocateDir(root, name);
61799
- fs63.mkdirSync(target);
61962
+ fs64.mkdirSync(target);
61800
61963
  } catch (err) {
61801
61964
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `\u521B\u5EFA\u9879\u76EE\u76EE\u5F55\u5931\u8D25: ${String(err)}`);
61802
61965
  }
61803
61966
  const git = (0, import_node_child_process13.spawnSync)("git", ["init"], { cwd: target, stdio: "ignore" });
61804
61967
  if (git.status !== 0) {
61805
- fs63.rmSync(target, { recursive: true, force: true });
61968
+ fs64.rmSync(target, { recursive: true, force: true });
61806
61969
  throw new ClawdError(
61807
61970
  ERROR_CODES.INVALID_CWD,
61808
61971
  `git init \u5931\u8D25\uFF08${git.error ? String(git.error) : `exit ${git.status}`}\uFF09: ${target}`
@@ -61827,8 +61990,8 @@ function buildProjectHandlers(deps) {
61827
61990
  }
61828
61991
 
61829
61992
  // src/handlers/workspace.ts
61830
- var path70 = __toESM(require("path"), 1);
61831
- var os21 = __toESM(require("os"), 1);
61993
+ var path72 = __toESM(require("path"), 1);
61994
+ var os22 = __toESM(require("os"), 1);
61832
61995
  init_protocol();
61833
61996
  init_protocol();
61834
61997
  function buildEnabledPluginNames(personaManager, personaId2) {
@@ -61868,23 +62031,23 @@ function buildWorkspaceHandlers(deps) {
61868
62031
  const list = async (frame, _client, ctx) => {
61869
62032
  const args = WorkspaceListArgs.parse(frame);
61870
62033
  const isGuest = ctx?.principal.kind === "guest";
61871
- const fallbackCwd = isGuest && personaRoot ? personaRoot : os21.homedir();
61872
- const resolvedCwd = path70.resolve(args.cwd ?? fallbackCwd);
61873
- const target = args.path ? path70.resolve(resolvedCwd, args.path) : resolvedCwd;
62034
+ const fallbackCwd = isGuest && personaRoot ? personaRoot : os22.homedir();
62035
+ const resolvedCwd = path72.resolve(args.cwd ?? fallbackCwd);
62036
+ const target = args.path ? path72.resolve(resolvedCwd, args.path) : resolvedCwd;
61874
62037
  assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
61875
62038
  const res = workspace.list({ ...args, cwd: resolvedCwd });
61876
62039
  return { response: { type: "workspace:list", ...res } };
61877
62040
  };
61878
62041
  const read = async (frame, _client, ctx) => {
61879
62042
  const args = WorkspaceReadArgs.parse(frame);
61880
- const target = path70.isAbsolute(args.path) ? path70.resolve(args.path) : path70.resolve(args.cwd, args.path);
62043
+ const target = path72.isAbsolute(args.path) ? path72.resolve(args.path) : path72.resolve(args.cwd, args.path);
61881
62044
  assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
61882
62045
  const res = workspace.read(args);
61883
62046
  return { response: { type: "workspace:read", ...res } };
61884
62047
  };
61885
62048
  const skillsList = async (frame, _client, ctx) => {
61886
62049
  const args = SkillsListArgs.parse(frame);
61887
- const cwdAbs = path70.resolve(args.cwd);
62050
+ const cwdAbs = path72.resolve(args.cwd);
61888
62051
  assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
61889
62052
  const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
61890
62053
  if (ctx?.principal.kind === "guest" && personaRoot) {
@@ -61896,7 +62059,7 @@ function buildWorkspaceHandlers(deps) {
61896
62059
  };
61897
62060
  const agentsList = async (frame, _client, ctx) => {
61898
62061
  const args = AgentsListArgs.parse(frame);
61899
- const cwdAbs = path70.resolve(args.cwd);
62062
+ const cwdAbs = path72.resolve(args.cwd);
61900
62063
  assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
61901
62064
  if (args.tool === "codex") {
61902
62065
  return { response: { type: "agents:list", agents: [] } };
@@ -61918,20 +62081,20 @@ function buildWorkspaceHandlers(deps) {
61918
62081
  }
61919
62082
 
61920
62083
  // src/handlers/git.ts
61921
- var path72 = __toESM(require("path"), 1);
62084
+ var path74 = __toESM(require("path"), 1);
61922
62085
  init_protocol();
61923
62086
  init_protocol();
61924
62087
 
61925
62088
  // src/workspace/git.ts
61926
62089
  var import_node_child_process14 = require("child_process");
61927
- var import_node_fs48 = __toESM(require("fs"), 1);
61928
- var import_node_path54 = __toESM(require("path"), 1);
62090
+ var import_node_fs49 = __toESM(require("fs"), 1);
62091
+ var import_node_path56 = __toESM(require("path"), 1);
61929
62092
  var import_node_util = require("util");
61930
62093
  var pexec = (0, import_node_util.promisify)(import_node_child_process14.execFile);
61931
62094
  function normalizePath(p2) {
61932
- const resolved = import_node_path54.default.resolve(p2);
62095
+ const resolved = import_node_path56.default.resolve(p2);
61933
62096
  try {
61934
- return import_node_fs48.default.realpathSync(resolved);
62097
+ return import_node_fs49.default.realpathSync(resolved);
61935
62098
  } catch {
61936
62099
  return resolved;
61937
62100
  }
@@ -62005,7 +62168,7 @@ async function listGitBranches(cwd) {
62005
62168
  function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
62006
62169
  if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
62007
62170
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
62008
- if (!isGuestPathAllowed(ctx.grants, path72.resolve(cwd), personaRoot, "read", userWorkDir)) {
62171
+ if (!isGuestPathAllowed(ctx.grants, path74.resolve(cwd), personaRoot, "read", userWorkDir)) {
62009
62172
  throw new ClawdError(
62010
62173
  ERROR_CODES.UNAUTHORIZED,
62011
62174
  `guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
@@ -62550,7 +62713,7 @@ function buildFeishuAuthHandlers(deps) {
62550
62713
  }
62551
62714
 
62552
62715
  // src/handlers/meta.ts
62553
- var import_node_os19 = __toESM(require("os"), 1);
62716
+ var import_node_os20 = __toESM(require("os"), 1);
62554
62717
  init_protocol();
62555
62718
 
62556
62719
  // src/handlers/method-grants.ts
@@ -62626,6 +62789,9 @@ var METHOD_GRANT_MAP = {
62626
62789
  "session:pin": CAPABILITY_SCOPED,
62627
62790
  "session:archive": CAPABILITY_SCOPED,
62628
62791
  "session:markRead": CAPABILITY_SCOPED,
62792
+ // 全局搜索扫 transcript 正文。与 history:read 同档:guest 进 persona VM 后要能搜自己的会话,
62793
+ // handler 内仍逐条 ensureSessionAccess,可见面不因 sessionIds 由客户端给定而放大
62794
+ "session:searchContent": CAPABILITY_SCOPED,
62629
62795
  "session:reorderPins": ADMIN_ANY,
62630
62796
  // owner 全局操作,无 personaId 维度
62631
62797
  // mirror peer sessions (2026-05-26):owner-only — guest 不应能写/删本机 mirror SessionFile
@@ -62837,21 +63003,21 @@ function computeMethodAccess(args) {
62837
63003
  }
62838
63004
 
62839
63005
  // src/version.ts
62840
- var version = "0.2.439".length > 0 ? "0.2.439" : "dev";
63006
+ var version = "0.2.440".length > 0 ? "0.2.440" : "dev";
62841
63007
 
62842
63008
  // src/cli-probe/probe.ts
62843
- var fs65 = __toESM(require("fs"), 1);
62844
- var path73 = __toESM(require("path"), 1);
63009
+ var fs66 = __toESM(require("fs"), 1);
63010
+ var path75 = __toESM(require("path"), 1);
62845
63011
  var PKG_NAME = "@clawos-dev/clawd";
62846
63012
  var BIN_NAME = "clawd";
62847
63013
  var MAX_PARENT_HOPS = 5;
62848
63014
  function probeGlobalCli(pathEnv) {
62849
63015
  if (!pathEnv) return null;
62850
- for (const dir of pathEnv.split(path73.delimiter)) {
63016
+ for (const dir of pathEnv.split(path75.delimiter)) {
62851
63017
  if (!dir) continue;
62852
63018
  let real;
62853
63019
  try {
62854
- real = fs65.realpathSync(path73.join(dir, BIN_NAME));
63020
+ real = fs66.realpathSync(path75.join(dir, BIN_NAME));
62855
63021
  } catch {
62856
63022
  continue;
62857
63023
  }
@@ -62861,15 +63027,15 @@ function probeGlobalCli(pathEnv) {
62861
63027
  return null;
62862
63028
  }
62863
63029
  function readOwnPackageVersion(entryPath) {
62864
- let dir = path73.dirname(entryPath);
63030
+ let dir = path75.dirname(entryPath);
62865
63031
  for (let i = 0; i < MAX_PARENT_HOPS; i++) {
62866
63032
  try {
62867
- const raw = fs65.readFileSync(path73.join(dir, "package.json"), "utf8");
63033
+ const raw = fs66.readFileSync(path75.join(dir, "package.json"), "utf8");
62868
63034
  const pkg = JSON.parse(raw);
62869
63035
  if (pkg.name !== PKG_NAME) return null;
62870
63036
  return typeof pkg.version === "string" && pkg.version ? pkg.version : null;
62871
63037
  } catch {
62872
- const parent = path73.dirname(dir);
63038
+ const parent = path75.dirname(dir);
62873
63039
  if (parent === dir) return null;
62874
63040
  dir = parent;
62875
63041
  }
@@ -62905,7 +63071,7 @@ function buildReadyFrame(deps, client) {
62905
63071
  return {
62906
63072
  version,
62907
63073
  protocolVersion: PROTOCOL_VERSION,
62908
- hostname: import_node_os19.default.hostname(),
63074
+ hostname: import_node_os20.default.hostname(),
62909
63075
  os: process.platform,
62910
63076
  tools,
62911
63077
  runningSessions: info.runningSessions,
@@ -63049,7 +63215,7 @@ function buildPersonaHandlers(deps) {
63049
63215
  }
63050
63216
 
63051
63217
  // src/handlers/attachment.ts
63052
- var import_node_path55 = __toESM(require("path"), 1);
63218
+ var import_node_path57 = __toESM(require("path"), 1);
63053
63219
  init_protocol();
63054
63220
  init_protocol();
63055
63221
  var DEFAULT_TTL_SECONDS = 24 * 3600;
@@ -63129,12 +63295,12 @@ function buildAttachmentHandlers(deps) {
63129
63295
  `session ${args.sessionId} scope unresolved`
63130
63296
  );
63131
63297
  }
63132
- const cwdAbs = import_node_path55.default.resolve(sessionFile.cwd);
63133
- const candidateAbs = import_node_path55.default.isAbsolute(args.relPath) ? import_node_path55.default.resolve(args.relPath) : import_node_path55.default.resolve(cwdAbs, args.relPath);
63298
+ const cwdAbs = import_node_path57.default.resolve(sessionFile.cwd);
63299
+ const candidateAbs = import_node_path57.default.isAbsolute(args.relPath) ? import_node_path57.default.resolve(args.relPath) : import_node_path57.default.resolve(cwdAbs, args.relPath);
63134
63300
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
63135
63301
  const entries = deps.groupFileStore.list(scope, args.sessionId);
63136
63302
  const entry = entries.find((e) => {
63137
- const storedAbs = import_node_path55.default.isAbsolute(e.relPath) ? import_node_path55.default.resolve(e.relPath) : import_node_path55.default.resolve(cwdAbs, e.relPath);
63303
+ const storedAbs = import_node_path57.default.isAbsolute(e.relPath) ? import_node_path57.default.resolve(e.relPath) : import_node_path57.default.resolve(cwdAbs, e.relPath);
63138
63304
  return storedAbs === candidateAbs && !e.stale;
63139
63305
  });
63140
63306
  if (!entry) {
@@ -63159,7 +63325,7 @@ function buildAttachmentHandlers(deps) {
63159
63325
  if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
63160
63326
  const f = deps.sessionStore.read(sessionId);
63161
63327
  if (!f) return;
63162
- assertGuestAttachmentPath(ctx, import_node_path55.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
63328
+ assertGuestAttachmentPath(ctx, import_node_path57.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
63163
63329
  }
63164
63330
  const groupAdd = async (frame, _client, ctx) => {
63165
63331
  if (!deps.groupFileStore || !deps.getSessionScope) {
@@ -63174,8 +63340,8 @@ function buildAttachmentHandlers(deps) {
63174
63340
  if (!scope) {
63175
63341
  throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
63176
63342
  }
63177
- const cwdAbs = import_node_path55.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
63178
- const candidateAbs = import_node_path55.default.isAbsolute(args.relPath) ? import_node_path55.default.resolve(args.relPath) : import_node_path55.default.resolve(cwdAbs, args.relPath);
63343
+ const cwdAbs = import_node_path57.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
63344
+ const candidateAbs = import_node_path57.default.isAbsolute(args.relPath) ? import_node_path57.default.resolve(args.relPath) : import_node_path57.default.resolve(cwdAbs, args.relPath);
63179
63345
  guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
63180
63346
  const from = args.origin === "agent" ? "agent" : ctx?.principal.kind === "owner" ? "owner" : "agent";
63181
63347
  const size = 0;
@@ -63234,19 +63400,19 @@ function buildAttachmentHandlers(deps) {
63234
63400
 
63235
63401
  // src/handlers/extension.ts
63236
63402
  var import_promises12 = __toESM(require("fs/promises"), 1);
63237
- var import_node_path60 = __toESM(require("path"), 1);
63403
+ var import_node_path62 = __toESM(require("path"), 1);
63238
63404
  init_protocol();
63239
63405
 
63240
63406
  // src/extension/bundle-zip.ts
63241
63407
  var import_promises9 = __toESM(require("fs/promises"), 1);
63242
- var import_node_path56 = __toESM(require("path"), 1);
63408
+ var import_node_path58 = __toESM(require("path"), 1);
63243
63409
  var import_node_crypto17 = __toESM(require("crypto"), 1);
63244
63410
  var import_jszip2 = __toESM(require_lib3(), 1);
63245
63411
  async function bundleExtensionDir(dir) {
63246
63412
  const entries = await listFilesSorted(dir);
63247
63413
  const zip = new import_jszip2.default();
63248
63414
  for (const rel of entries) {
63249
- const abs = import_node_path56.default.join(dir, rel);
63415
+ const abs = import_node_path58.default.join(dir, rel);
63250
63416
  const content = await import_promises9.default.readFile(abs);
63251
63417
  zip.file(rel, content, { date: FIXED_DATE });
63252
63418
  }
@@ -63267,7 +63433,7 @@ async function listFilesSorted(rootDir) {
63267
63433
  return out;
63268
63434
  }
63269
63435
  async function walk(absRoot, relPrefix, out) {
63270
- const dirAbs = import_node_path56.default.join(absRoot, relPrefix);
63436
+ const dirAbs = import_node_path58.default.join(absRoot, relPrefix);
63271
63437
  const entries = await import_promises9.default.readdir(dirAbs, { withFileTypes: true });
63272
63438
  for (const e of entries) {
63273
63439
  if (IGNORE_BASENAMES.has(e.name)) continue;
@@ -63321,25 +63487,25 @@ function computePublishCheck(args) {
63321
63487
 
63322
63488
  // src/extension/install-flow.ts
63323
63489
  var import_promises10 = __toESM(require("fs/promises"), 1);
63324
- var import_node_path58 = __toESM(require("path"), 1);
63325
- var import_node_os21 = __toESM(require("os"), 1);
63490
+ var import_node_path60 = __toESM(require("path"), 1);
63491
+ var import_node_os22 = __toESM(require("os"), 1);
63326
63492
  var import_node_crypto18 = __toESM(require("crypto"), 1);
63327
63493
  var import_jszip3 = __toESM(require_lib3(), 1);
63328
63494
 
63329
63495
  // src/extension/paths.ts
63330
- var import_node_os20 = __toESM(require("os"), 1);
63331
- var import_node_path57 = __toESM(require("path"), 1);
63496
+ var import_node_os21 = __toESM(require("os"), 1);
63497
+ var import_node_path59 = __toESM(require("path"), 1);
63332
63498
  function clawdHomeRoot(override) {
63333
- return override ?? process.env.CLAWD_HOME ?? import_node_path57.default.join(import_node_os20.default.homedir(), ".clawd");
63499
+ return override ?? process.env.CLAWD_HOME ?? import_node_path59.default.join(import_node_os21.default.homedir(), ".clawd");
63334
63500
  }
63335
63501
  function extensionsRoot(override) {
63336
- return import_node_path57.default.join(clawdHomeRoot(override), "extensions");
63502
+ return import_node_path59.default.join(clawdHomeRoot(override), "extensions");
63337
63503
  }
63338
63504
  function publishedChannelsFile(override) {
63339
- return import_node_path57.default.join(clawdHomeRoot(override), "extensions-published.json");
63505
+ return import_node_path59.default.join(clawdHomeRoot(override), "extensions-published.json");
63340
63506
  }
63341
63507
  function bundleCacheRoot(override) {
63342
- return import_node_path57.default.join(clawdHomeRoot(override), "extension-bundles");
63508
+ return import_node_path59.default.join(clawdHomeRoot(override), "extension-bundles");
63343
63509
  }
63344
63510
 
63345
63511
  // src/extension/install-flow.ts
@@ -63366,7 +63532,7 @@ async function installFromChannel(args, deps) {
63366
63532
  throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
63367
63533
  }
63368
63534
  for (const name of Object.keys(zip.files)) {
63369
- if (name.includes("..") || name.startsWith("/") || import_node_path58.default.isAbsolute(name)) {
63535
+ if (name.includes("..") || name.startsWith("/") || import_node_path60.default.isAbsolute(name)) {
63370
63536
  throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
63371
63537
  }
63372
63538
  }
@@ -63398,7 +63564,7 @@ async function installFromChannel(args, deps) {
63398
63564
  );
63399
63565
  }
63400
63566
  const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
63401
- const destDir = import_node_path58.default.join(deps.extensionsRoot, localExtId);
63567
+ const destDir = import_node_path60.default.join(deps.extensionsRoot, localExtId);
63402
63568
  let destExists = false;
63403
63569
  try {
63404
63570
  await import_promises10.default.access(destDir);
@@ -63412,16 +63578,16 @@ async function installFromChannel(args, deps) {
63412
63578
  );
63413
63579
  }
63414
63580
  const stage = await import_promises10.default.mkdtemp(
63415
- import_node_path58.default.join(import_node_os21.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
63581
+ import_node_path60.default.join(import_node_os22.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
63416
63582
  );
63417
63583
  try {
63418
63584
  for (const [name, entry] of Object.entries(zip.files)) {
63419
- const dest = import_node_path58.default.join(stage, name);
63585
+ const dest = import_node_path60.default.join(stage, name);
63420
63586
  if (entry.dir) {
63421
63587
  await import_promises10.default.mkdir(dest, { recursive: true });
63422
63588
  continue;
63423
63589
  }
63424
- await import_promises10.default.mkdir(import_node_path58.default.dirname(dest), { recursive: true });
63590
+ await import_promises10.default.mkdir(import_node_path60.default.dirname(dest), { recursive: true });
63425
63591
  if (name === "manifest.json") {
63426
63592
  const rewritten = { ...parsed.data, id: localExtId };
63427
63593
  await import_promises10.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -63442,8 +63608,8 @@ async function installFromChannel(args, deps) {
63442
63608
 
63443
63609
  // src/extension/update-flow.ts
63444
63610
  var import_promises11 = __toESM(require("fs/promises"), 1);
63445
- var import_node_path59 = __toESM(require("path"), 1);
63446
- var import_node_os22 = __toESM(require("os"), 1);
63611
+ var import_node_path61 = __toESM(require("path"), 1);
63612
+ var import_node_os23 = __toESM(require("os"), 1);
63447
63613
  var import_node_crypto19 = __toESM(require("crypto"), 1);
63448
63614
  var import_jszip4 = __toESM(require_lib3(), 1);
63449
63615
  var UpdateError = class extends Error {
@@ -63459,11 +63625,11 @@ async function updateFromChannel(args, deps) {
63459
63625
  channelRef.extId,
63460
63626
  channelRef.ownerPrincipalId
63461
63627
  );
63462
- const liveDir = import_node_path59.default.join(deps.extensionsRoot, localExtId);
63628
+ const liveDir = import_node_path61.default.join(deps.extensionsRoot, localExtId);
63463
63629
  const prevDir = `${liveDir}.prev`;
63464
63630
  let existingVersion;
63465
63631
  try {
63466
- const raw = await import_promises11.default.readFile(import_node_path59.default.join(liveDir, "manifest.json"), "utf8");
63632
+ const raw = await import_promises11.default.readFile(import_node_path61.default.join(liveDir, "manifest.json"), "utf8");
63467
63633
  const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
63468
63634
  if (!parsed2.success) {
63469
63635
  throw new UpdateError(
@@ -63496,7 +63662,7 @@ async function updateFromChannel(args, deps) {
63496
63662
  throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
63497
63663
  }
63498
63664
  for (const name of Object.keys(zip.files)) {
63499
- if (name.includes("..") || name.startsWith("/") || import_node_path59.default.isAbsolute(name)) {
63665
+ if (name.includes("..") || name.startsWith("/") || import_node_path61.default.isAbsolute(name)) {
63500
63666
  throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
63501
63667
  }
63502
63668
  }
@@ -63531,16 +63697,16 @@ async function updateFromChannel(args, deps) {
63531
63697
  await import_promises11.default.rm(prevDir, { recursive: true, force: true });
63532
63698
  await import_promises11.default.rename(liveDir, prevDir);
63533
63699
  const stage = await import_promises11.default.mkdtemp(
63534
- import_node_path59.default.join(import_node_os22.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
63700
+ import_node_path61.default.join(import_node_os23.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
63535
63701
  );
63536
63702
  try {
63537
63703
  for (const [name, entry] of Object.entries(zip.files)) {
63538
- const dest = import_node_path59.default.join(stage, name);
63704
+ const dest = import_node_path61.default.join(stage, name);
63539
63705
  if (entry.dir) {
63540
63706
  await import_promises11.default.mkdir(dest, { recursive: true });
63541
63707
  continue;
63542
63708
  }
63543
- await import_promises11.default.mkdir(import_node_path59.default.dirname(dest), { recursive: true });
63709
+ await import_promises11.default.mkdir(import_node_path61.default.dirname(dest), { recursive: true });
63544
63710
  if (name === "manifest.json") {
63545
63711
  const rewritten = { ...parsed.data, id: localExtId };
63546
63712
  await import_promises11.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -63607,7 +63773,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
63607
63773
  );
63608
63774
  }
63609
63775
  }
63610
- const manifestPath = import_node_path60.default.join(root, extId, "manifest.json");
63776
+ const manifestPath = import_node_path62.default.join(root, extId, "manifest.json");
63611
63777
  const manifest = await readManifest(root, extId);
63612
63778
  const next = { ...manifest, version: newVersion };
63613
63779
  const tmp = `${manifestPath}.tmp`;
@@ -63615,7 +63781,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
63615
63781
  await import_promises12.default.rename(tmp, manifestPath);
63616
63782
  }
63617
63783
  async function readManifest(root, extId) {
63618
- const file = import_node_path60.default.join(root, extId, "manifest.json");
63784
+ const file = import_node_path62.default.join(root, extId, "manifest.json");
63619
63785
  let raw;
63620
63786
  try {
63621
63787
  raw = await import_promises12.default.readFile(file, "utf8");
@@ -63699,7 +63865,7 @@ function buildExtensionHandlers(deps) {
63699
63865
  };
63700
63866
  async function buildSnapshotMeta(extId) {
63701
63867
  const manifest = await readManifest(deps.root, extId);
63702
- const { sha256, buffer } = await bundleExtensionDir(import_node_path60.default.join(deps.root, extId));
63868
+ const { sha256, buffer } = await bundleExtensionDir(import_node_path62.default.join(deps.root, extId));
63703
63869
  return { manifest, contentHash: sha256, buffer };
63704
63870
  }
63705
63871
  const publish = async (frame, _client, ctx) => {
@@ -63874,9 +64040,9 @@ function buildExtensionHandlers(deps) {
63874
64040
  }
63875
64041
 
63876
64042
  // src/app-builder/project-store.ts
63877
- var import_node_fs49 = require("fs");
64043
+ var import_node_fs50 = require("fs");
63878
64044
  var import_node_child_process15 = require("child_process");
63879
- var import_node_path61 = require("path");
64045
+ var import_node_path63 = require("path");
63880
64046
  init_protocol();
63881
64047
  var PROJECTS_DIR = "projects";
63882
64048
  var META_FILE = ".clawd-project.json";
@@ -63890,19 +64056,19 @@ var ProjectStore = class {
63890
64056
  root;
63891
64057
  /** projects/<name>/.clawd-project.json 路径 */
63892
64058
  metaPath(name) {
63893
- return (0, import_node_path61.join)(this.projectsRoot(), name, META_FILE);
64059
+ return (0, import_node_path63.join)(this.projectsRoot(), name, META_FILE);
63894
64060
  }
63895
64061
  /** projects/<name>/ 目录路径(cwd 用) */
63896
64062
  projectDir(name) {
63897
- return (0, import_node_path61.join)(this.projectsRoot(), name);
64063
+ return (0, import_node_path63.join)(this.projectsRoot(), name);
63898
64064
  }
63899
64065
  projectsRoot() {
63900
- return (0, import_node_path61.join)(this.root, PROJECTS_DIR);
64066
+ return (0, import_node_path63.join)(this.root, PROJECTS_DIR);
63901
64067
  }
63902
64068
  async list() {
63903
64069
  let entries;
63904
64070
  try {
63905
- entries = await import_node_fs49.promises.readdir(this.projectsRoot());
64071
+ entries = await import_node_fs50.promises.readdir(this.projectsRoot());
63906
64072
  } catch (err) {
63907
64073
  if (err.code === "ENOENT") return [];
63908
64074
  throw err;
@@ -63910,7 +64076,7 @@ var ProjectStore = class {
63910
64076
  const out = [];
63911
64077
  for (const name of entries) {
63912
64078
  try {
63913
- const raw = await import_node_fs49.promises.readFile(this.metaPath(name), "utf8");
64079
+ const raw = await import_node_fs50.promises.readFile(this.metaPath(name), "utf8");
63914
64080
  const json = JSON.parse(raw);
63915
64081
  let migrated = false;
63916
64082
  if (typeof json.devCommand !== "string" || json.devCommand.length === 0) {
@@ -63921,7 +64087,7 @@ var ProjectStore = class {
63921
64087
  if (parsed.success) {
63922
64088
  out.push(parsed.data);
63923
64089
  if (migrated) {
63924
- void import_node_fs49.promises.writeFile(this.metaPath(name), JSON.stringify(parsed.data, null, 2) + "\n", "utf8").catch(() => {
64090
+ void import_node_fs50.promises.writeFile(this.metaPath(name), JSON.stringify(parsed.data, null, 2) + "\n", "utf8").catch(() => {
63925
64091
  });
63926
64092
  }
63927
64093
  }
@@ -63965,8 +64131,8 @@ var ProjectStore = class {
63965
64131
  throw new Error(`invalid name "${name}": ${validated.error.message}`);
63966
64132
  }
63967
64133
  const dir = this.projectDir(name);
63968
- await import_node_fs49.promises.mkdir(dir, { recursive: true });
63969
- await import_node_fs49.promises.writeFile(this.metaPath(name), JSON.stringify(meta, null, 2) + "\n", "utf8");
64134
+ await import_node_fs50.promises.mkdir(dir, { recursive: true });
64135
+ await import_node_fs50.promises.writeFile(this.metaPath(name), JSON.stringify(meta, null, 2) + "\n", "utf8");
63970
64136
  return meta;
63971
64137
  }
63972
64138
  /**
@@ -64009,7 +64175,7 @@ var ProjectStore = class {
64009
64175
  }
64010
64176
  async delete(name) {
64011
64177
  const dir = this.projectDir(name);
64012
- await import_node_fs49.promises.rm(dir, { recursive: true, force: true });
64178
+ await import_node_fs50.promises.rm(dir, { recursive: true, force: true });
64013
64179
  }
64014
64180
  async updatePort(name, newPort) {
64015
64181
  if (newPort < PROJECT_PORT_MIN || newPort > PROJECT_PORT_MAX) {
@@ -64025,7 +64191,7 @@ var ProjectStore = class {
64025
64191
  throw new Error(`port ${newPort} already used / \u5DF2\u88AB project "${conflict.name}" \u5360\u7528`);
64026
64192
  }
64027
64193
  const updated = { ...target, port: newPort };
64028
- await import_node_fs49.promises.writeFile(this.metaPath(name), JSON.stringify(updated, null, 2) + "\n", "utf8");
64194
+ await import_node_fs50.promises.writeFile(this.metaPath(name), JSON.stringify(updated, null, 2) + "\n", "utf8");
64029
64195
  return updated;
64030
64196
  }
64031
64197
  /**
@@ -64042,7 +64208,7 @@ var ProjectStore = class {
64042
64208
  if (!validated.success) {
64043
64209
  throw new Error(`invalid prodUrl "${url}": ${validated.error.message}`);
64044
64210
  }
64045
- await import_node_fs49.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
64211
+ await import_node_fs50.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
64046
64212
  return validated.data;
64047
64213
  }
64048
64214
  /**
@@ -64063,7 +64229,7 @@ var ProjectStore = class {
64063
64229
  if (!validated.success) {
64064
64230
  throw new Error(`invalid publishJob: ${validated.error.message}`);
64065
64231
  }
64066
- await import_node_fs49.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
64232
+ await import_node_fs50.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
64067
64233
  return validated.data;
64068
64234
  }
64069
64235
  /** 清掉 .clawd-project.json.publishJob 字段。其他字段保持原样。 */
@@ -64078,7 +64244,7 @@ var ProjectStore = class {
64078
64244
  if (!validated.success) {
64079
64245
  throw new Error(`failed to clear publishJob: ${validated.error.message}`);
64080
64246
  }
64081
- await import_node_fs49.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
64247
+ await import_node_fs50.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
64082
64248
  return validated.data;
64083
64249
  }
64084
64250
  };
@@ -64199,8 +64365,8 @@ var PublishJobRegistry = class {
64199
64365
 
64200
64366
  // src/app-builder/publish-job-runner.ts
64201
64367
  var import_node_child_process17 = require("child_process");
64202
- var import_node_fs50 = require("fs");
64203
- var import_node_path62 = require("path");
64368
+ var import_node_fs51 = require("fs");
64369
+ var import_node_path64 = require("path");
64204
64370
 
64205
64371
  // src/app-builder/publish-stage-parser.ts
64206
64372
  var STAGE_RE = /^\s*::stage::(build|deploy|verify)\s*$/;
@@ -64232,10 +64398,10 @@ async function startPublishJob(deps, args) {
64232
64398
  return { jobId: registry2.get(args.name).jobId, status: "already-publishing" };
64233
64399
  }
64234
64400
  const projDir = projectDir(args.name);
64235
- const logPath = (0, import_node_path62.join)(projDir, ".publish.log");
64401
+ const logPath = (0, import_node_path64.join)(projDir, ".publish.log");
64236
64402
  let logStream = null;
64237
64403
  try {
64238
- logStream = (0, import_node_fs50.createWriteStream)(logPath, { flags: "w" });
64404
+ logStream = (0, import_node_fs51.createWriteStream)(logPath, { flags: "w" });
64239
64405
  } catch {
64240
64406
  logStream = null;
64241
64407
  }
@@ -64492,8 +64658,8 @@ async function recoverInterruptedJobs(deps) {
64492
64658
 
64493
64659
  // src/handlers/app-builder.ts
64494
64660
  init_protocol();
64495
- var import_node_path63 = require("path");
64496
- var import_node_fs51 = require("fs");
64661
+ var import_node_path65 = require("path");
64662
+ var import_node_fs52 = require("fs");
64497
64663
  var APP_BUILDER_PERSONAS = ["persona-app-builder", "persona-dataclaw-builder"];
64498
64664
  var DEV_SERVER_READY_TIMEOUT_MS = 3e4;
64499
64665
  async function recoverInterruptedPublishJobs(store, logger) {
@@ -64574,7 +64740,7 @@ function buildAppBuilderHandlers(deps) {
64574
64740
  async function listAllUsersProjects() {
64575
64741
  if (!deps.usersRoot || !deps.getStore) return [];
64576
64742
  const getStore = deps.getStore;
64577
- const userIds = await import_node_fs51.promises.readdir(deps.usersRoot).catch(() => []);
64743
+ const userIds = await import_node_fs52.promises.readdir(deps.usersRoot).catch(() => []);
64578
64744
  const perUser = await Promise.all(
64579
64745
  userIds.map((uid) => getStore(uid).list().catch(() => []))
64580
64746
  );
@@ -64643,8 +64809,8 @@ function buildAppBuilderHandlers(deps) {
64643
64809
  const project = await userStore.create(f.name, reservedPorts);
64644
64810
  try {
64645
64811
  const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(session.ownerPersonaId ?? "") : deps.personaRoot;
64646
- const templateSrcDir = (0, import_node_path63.join)(personaRoot, "extension-kit", "examples", DEFAULT_TEMPLATE);
64647
- const scaffoldScript = (0, import_node_path63.join)(deps.deployKitRoot, "scripts", "new-extension.sh");
64812
+ const templateSrcDir = (0, import_node_path65.join)(personaRoot, "extension-kit", "examples", DEFAULT_TEMPLATE);
64813
+ const scaffoldScript = (0, import_node_path65.join)(deps.deployKitRoot, "scripts", "new-extension.sh");
64648
64814
  const scaffoldResult = await userStore.scaffold(project.name, templateSrcDir, scaffoldScript);
64649
64815
  deps.logger?.info("app-builder.scaffold.done", {
64650
64816
  name: project.name,
@@ -64848,7 +65014,7 @@ function buildAppBuilderHandlers(deps) {
64848
65014
  await userStore.clearPublishJob(args.name);
64849
65015
  }
64850
65016
  const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(boundSession.ownerPersonaId ?? "") : deps.personaRoot;
64851
- const scriptPath = (0, import_node_path63.join)(deps.deployKitRoot, "scripts", "publish.sh");
65017
+ const scriptPath = (0, import_node_path65.join)(deps.deployKitRoot, "scripts", "publish.sh");
64852
65018
  deps.logger?.info("app-builder.publish.start", {
64853
65019
  name: args.name,
64854
65020
  sessionId: boundSession.sessionId,
@@ -65404,20 +65570,20 @@ function mapPrState(state, isDraft) {
65404
65570
  if (state === "CLOSED") return "closed";
65405
65571
  return isDraft === true ? "draft" : "open";
65406
65572
  }
65407
- function asRecord(v2) {
65573
+ function asRecord2(v2) {
65408
65574
  return typeof v2 === "object" && v2 !== null ? v2 : {};
65409
65575
  }
65410
65576
  function lastCommitRollup(node) {
65411
- const first = asRecord(node.commits).nodes?.[0];
65412
- return asRecord(asRecord(first).commit).statusCheckRollup;
65577
+ const first = asRecord2(node.commits).nodes?.[0];
65578
+ return asRecord2(asRecord2(first).commit).statusCheckRollup;
65413
65579
  }
65414
65580
  function parsePrListResponse(json) {
65415
- const nodes = asRecord(asRecord(asRecord(json).data).search).nodes ?? [];
65581
+ const nodes = asRecord2(asRecord2(asRecord2(json).data).search).nodes ?? [];
65416
65582
  const items = [];
65417
65583
  for (const raw of nodes) {
65418
- const n = asRecord(raw);
65584
+ const n = asRecord2(raw);
65419
65585
  if (typeof n.number !== "number") continue;
65420
- const nameWithOwner = String(asRecord(n.repository).nameWithOwner ?? "");
65586
+ const nameWithOwner = String(asRecord2(n.repository).nameWithOwner ?? "");
65421
65587
  const slash = nameWithOwner.indexOf("/");
65422
65588
  if (slash <= 0) continue;
65423
65589
  const rollup = lastCommitRollup(n);
@@ -65431,27 +65597,27 @@ function parsePrListResponse(json) {
65431
65597
  additions: typeof n.additions === "number" ? n.additions : 0,
65432
65598
  deletions: typeof n.deletions === "number" ? n.deletions : 0,
65433
65599
  updatedAt: String(n.updatedAt ?? ""),
65434
- author: String(asRecord(n.author).login ?? ""),
65435
- checksRollup: rollup == null ? "none" : mapRollupState(asRecord(rollup).state)
65600
+ author: String(asRecord2(n.author).login ?? ""),
65601
+ checksRollup: rollup == null ? "none" : mapRollupState(asRecord2(rollup).state)
65436
65602
  });
65437
65603
  }
65438
65604
  return items;
65439
65605
  }
65440
65606
  function parsePrDetailResponse(json, repoRef) {
65441
- const pr = asRecord(asRecord(asRecord(json).data).repository).pullRequest;
65607
+ const pr = asRecord2(asRecord2(asRecord2(json).data).repository).pullRequest;
65442
65608
  if (pr == null || typeof pr !== "object") return null;
65443
- const n = asRecord(pr);
65609
+ const n = asRecord2(pr);
65444
65610
  const rollup = lastCommitRollup(n);
65445
- const contextNodes = asRecord(asRecord(rollup).contexts).nodes ?? [];
65611
+ const contextNodes = asRecord2(asRecord2(rollup).contexts).nodes ?? [];
65446
65612
  const checks = [];
65447
65613
  for (const c of contextNodes) {
65448
- const mapped = mapCheckNode(asRecord(c));
65614
+ const mapped = mapCheckNode(asRecord2(c));
65449
65615
  if (mapped) checks.push(mapped);
65450
65616
  }
65451
- const reviewerNodes = asRecord(n.reviewRequests).nodes ?? [];
65452
- const reviewers = reviewerNodes.map((r) => String(asRecord(asRecord(r).requestedReviewer).login ?? "")).filter((s) => s !== "");
65617
+ const reviewerNodes = asRecord2(n.reviewRequests).nodes ?? [];
65618
+ const reviewers = reviewerNodes.map((r) => String(asRecord2(asRecord2(r).requestedReviewer).login ?? "")).filter((s) => s !== "");
65453
65619
  const mergeable = n.mergeable === "MERGEABLE" ? "mergeable" : n.mergeable === "CONFLICTING" ? "conflicting" : "unknown";
65454
- const commentCountRaw = asRecord(n.comments).totalCount;
65620
+ const commentCountRaw = asRecord2(n.comments).totalCount;
65455
65621
  return {
65456
65622
  owner: repoRef.owner,
65457
65623
  repo: repoRef.repo,
@@ -65459,7 +65625,7 @@ function parsePrDetailResponse(json, repoRef) {
65459
65625
  title: String(n.title ?? ""),
65460
65626
  body: String(n.body ?? ""),
65461
65627
  state: mapPrState(n.state, n.isDraft),
65462
- author: String(asRecord(n.author).login ?? ""),
65628
+ author: String(asRecord2(n.author).login ?? ""),
65463
65629
  updatedAt: String(n.updatedAt ?? ""),
65464
65630
  headRef: String(n.headRefName ?? ""),
65465
65631
  baseRef: String(n.baseRefName ?? ""),
@@ -65469,7 +65635,7 @@ function parsePrDetailResponse(json, repoRef) {
65469
65635
  mergeable,
65470
65636
  reviewers,
65471
65637
  commentCount: typeof commentCountRaw === "number" ? commentCountRaw : 0,
65472
- checksRollup: rollup == null ? "none" : mapRollupState(asRecord(rollup).state),
65638
+ checksRollup: rollup == null ? "none" : mapRollupState(asRecord2(rollup).state),
65473
65639
  checks
65474
65640
  };
65475
65641
  }
@@ -65607,7 +65773,7 @@ function buildVisitorHandlers(deps) {
65607
65773
 
65608
65774
  // src/extension/registry.ts
65609
65775
  var import_promises14 = __toESM(require("fs/promises"), 1);
65610
- var import_node_path64 = __toESM(require("path"), 1);
65776
+ var import_node_path66 = __toESM(require("path"), 1);
65611
65777
  async function loadAll(root) {
65612
65778
  let entries;
65613
65779
  try {
@@ -65620,13 +65786,13 @@ async function loadAll(root) {
65620
65786
  for (const ent of entries) {
65621
65787
  if (!ent.isDirectory()) continue;
65622
65788
  if (ent.name.startsWith(".")) continue;
65623
- records.push(await loadOne(import_node_path64.default.join(root, ent.name), ent.name));
65789
+ records.push(await loadOne(import_node_path66.default.join(root, ent.name), ent.name));
65624
65790
  }
65625
65791
  records.sort((a, b2) => a.extId < b2.extId ? -1 : a.extId > b2.extId ? 1 : 0);
65626
65792
  return records;
65627
65793
  }
65628
65794
  async function loadOne(dir, dirName) {
65629
- const manifestPath = import_node_path64.default.join(dir, "manifest.json");
65795
+ const manifestPath = import_node_path66.default.join(dir, "manifest.json");
65630
65796
  let raw;
65631
65797
  try {
65632
65798
  raw = await import_promises14.default.readFile(manifestPath, "utf8");
@@ -65671,7 +65837,7 @@ async function loadOne(dir, dirName) {
65671
65837
 
65672
65838
  // src/extension/uninstall.ts
65673
65839
  var import_promises15 = __toESM(require("fs/promises"), 1);
65674
- var import_node_path65 = __toESM(require("path"), 1);
65840
+ var import_node_path67 = __toESM(require("path"), 1);
65675
65841
  var UninstallError = class extends Error {
65676
65842
  constructor(code, message) {
65677
65843
  super(message);
@@ -65680,7 +65846,7 @@ var UninstallError = class extends Error {
65680
65846
  code;
65681
65847
  };
65682
65848
  async function uninstall(deps) {
65683
- const dir = import_node_path65.default.join(deps.root, deps.extId);
65849
+ const dir = import_node_path67.default.join(deps.root, deps.extId);
65684
65850
  try {
65685
65851
  await import_promises15.default.access(dir);
65686
65852
  } catch {
@@ -65698,14 +65864,14 @@ init_protocol();
65698
65864
 
65699
65865
  // src/peer-ops/run-command.ts
65700
65866
  var import_node_child_process18 = require("child_process");
65701
- var import_node_os23 = __toESM(require("os"), 1);
65867
+ var import_node_os24 = __toESM(require("os"), 1);
65702
65868
  var DEFAULT_TIMEOUT_MS5 = 3e4;
65703
65869
  var MAX_TIMEOUT_MS = 3e5;
65704
65870
  var MAX_OUTPUT_BYTES = 1048576;
65705
65871
  function runCommand(command, opts = {}) {
65706
65872
  const timeoutMs = Math.min(opts.timeoutMs ?? DEFAULT_TIMEOUT_MS5, MAX_TIMEOUT_MS);
65707
65873
  return new Promise((resolve9) => {
65708
- const child = (0, import_node_child_process18.spawn)("bash", ["-c", command], { cwd: import_node_os23.default.homedir() });
65874
+ const child = (0, import_node_child_process18.spawn)("bash", ["-c", command], { cwd: import_node_os24.default.homedir() });
65709
65875
  const out = [];
65710
65876
  const err = [];
65711
65877
  let outBytes = 0;
@@ -65913,7 +66079,7 @@ function buildMethodHandlers(deps) {
65913
66079
  broadcast: deps.broadcastToOwners
65914
66080
  }),
65915
66081
  ...buildMasterHandlers({
65916
- authorityTablePath: import_node_path66.default.join(deps.masterDataDir, "master-authority.json")
66082
+ authorityTablePath: import_node_path68.default.join(deps.masterDataDir, "master-authority.json")
65917
66083
  }),
65918
66084
  ...buildTopicHandlers({
65919
66085
  topicStore: deps.topicStore,
@@ -65949,18 +66115,18 @@ init_claude();
65949
66115
 
65950
66116
  // src/tools/shell-path.ts
65951
66117
  var import_node_child_process19 = require("child_process");
65952
- var import_node_os24 = __toESM(require("os"), 1);
66118
+ var import_node_os25 = __toESM(require("os"), 1);
65953
66119
  function refreshPathFromLoginShell() {
65954
66120
  if (process.platform === "win32") return;
65955
- const shell = process.env.SHELL ?? import_node_os24.default.userInfo().shell ?? "/bin/zsh";
66121
+ const shell = process.env.SHELL ?? import_node_os25.default.userInfo().shell ?? "/bin/zsh";
65956
66122
  try {
65957
66123
  const out = (0, import_node_child_process19.execFileSync)(shell, ["-ilc", 'command echo -n "$PATH"'], {
65958
66124
  encoding: "utf8",
65959
66125
  timeout: 3e3,
65960
66126
  stdio: ["ignore", "pipe", "ignore"]
65961
66127
  });
65962
- const path89 = out.trim();
65963
- if (path89) process.env.PATH = path89;
66128
+ const path91 = out.trim();
66129
+ if (path91) process.env.PATH = path91;
65964
66130
  } catch {
65965
66131
  }
65966
66132
  }
@@ -66374,7 +66540,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
66374
66540
 
66375
66541
  // src/extension/runtime.ts
66376
66542
  var import_node_child_process22 = require("child_process");
66377
- var import_node_path67 = __toESM(require("path"), 1);
66543
+ var import_node_path69 = __toESM(require("path"), 1);
66378
66544
  var import_promises16 = require("timers/promises");
66379
66545
 
66380
66546
  // src/extension/port-allocator.ts
@@ -66475,7 +66641,7 @@ var Runtime = class {
66475
66641
  /\$CLAWOS_EXT_PORT/g,
66476
66642
  String(port)
66477
66643
  );
66478
- const dir = import_node_path67.default.join(this.root, extId);
66644
+ const dir = import_node_path69.default.join(this.root, extId);
66479
66645
  const env = {
66480
66646
  ...process.env,
66481
66647
  CLAWOS_EXT_PORT: String(port),
@@ -66587,7 +66753,7 @@ ${handle.stderrTail}`
66587
66753
 
66588
66754
  // src/extension/published-channels.ts
66589
66755
  var import_promises17 = __toESM(require("fs/promises"), 1);
66590
- var import_node_path68 = __toESM(require("path"), 1);
66756
+ var import_node_path70 = __toESM(require("path"), 1);
66591
66757
  init_zod();
66592
66758
  var PublishedChannelsError = class extends Error {
66593
66759
  constructor(code, message) {
@@ -66686,7 +66852,7 @@ var PublishedChannelStore = class {
66686
66852
  )
66687
66853
  };
66688
66854
  const tmp = `${this.filePath}.tmp`;
66689
- await import_promises17.default.mkdir(import_node_path68.default.dirname(this.filePath), { recursive: true });
66855
+ await import_promises17.default.mkdir(import_node_path70.default.dirname(this.filePath), { recursive: true });
66690
66856
  await import_promises17.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
66691
66857
  await import_promises17.default.rename(tmp, this.filePath);
66692
66858
  }
@@ -66694,7 +66860,7 @@ var PublishedChannelStore = class {
66694
66860
 
66695
66861
  // src/extension/bundle-cache.ts
66696
66862
  var import_promises18 = __toESM(require("fs/promises"), 1);
66697
- var import_node_path69 = __toESM(require("path"), 1);
66863
+ var import_node_path71 = __toESM(require("path"), 1);
66698
66864
  var BundleCache = class {
66699
66865
  constructor(rootDir) {
66700
66866
  this.rootDir = rootDir;
@@ -66703,14 +66869,14 @@ var BundleCache = class {
66703
66869
  /** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
66704
66870
  async write(snapshotHash, buffer) {
66705
66871
  await import_promises18.default.mkdir(this.rootDir, { recursive: true });
66706
- const file = import_node_path69.default.join(this.rootDir, `${snapshotHash}.zip`);
66872
+ const file = import_node_path71.default.join(this.rootDir, `${snapshotHash}.zip`);
66707
66873
  const tmp = `${file}.tmp`;
66708
66874
  await import_promises18.default.writeFile(tmp, buffer, { mode: 384 });
66709
66875
  await import_promises18.default.rename(tmp, file);
66710
66876
  }
66711
66877
  /** Returns the bundle bytes, or null when the file doesn't exist. */
66712
66878
  async read(snapshotHash) {
66713
- const file = import_node_path69.default.join(this.rootDir, `${snapshotHash}.zip`);
66879
+ const file = import_node_path71.default.join(this.rootDir, `${snapshotHash}.zip`);
66714
66880
  try {
66715
66881
  return await import_promises18.default.readFile(file);
66716
66882
  } catch (e) {
@@ -66720,7 +66886,7 @@ var BundleCache = class {
66720
66886
  }
66721
66887
  /** Idempotent — missing file is not an error. */
66722
66888
  async delete(snapshotHash) {
66723
- const file = import_node_path69.default.join(this.rootDir, `${snapshotHash}.zip`);
66889
+ const file = import_node_path71.default.join(this.rootDir, `${snapshotHash}.zip`);
66724
66890
  await import_promises18.default.rm(file, { force: true });
66725
66891
  }
66726
66892
  };
@@ -66741,26 +66907,26 @@ async function startDaemon(config) {
66741
66907
  },
66742
66908
  source: "daemon",
66743
66909
  sampling: logShippingCfg.sampling,
66744
- homeDir: import_node_os25.default.homedir()
66910
+ homeDir: import_node_os26.default.homedir()
66745
66911
  });
66746
- const logDir = import_node_path70.default.join(config.dataDir, "log");
66747
- import_node_fs52.default.mkdirSync(logDir, { recursive: true });
66912
+ const logDir = import_node_path72.default.join(config.dataDir, "log");
66913
+ import_node_fs53.default.mkdirSync(logDir, { recursive: true });
66748
66914
  const logger = createLogger({
66749
66915
  level: config.logLevel,
66750
- file: import_node_path70.default.join(logDir, "clawd.log"),
66916
+ file: import_node_path72.default.join(logDir, "clawd.log"),
66751
66917
  logClient
66752
66918
  });
66753
66919
  logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
66754
66920
  const screenIdleProbeLogger = createFileOnlyLogger({
66755
- file: import_node_path70.default.join(logDir, "screen-idle-probe.log"),
66921
+ file: import_node_path72.default.join(logDir, "screen-idle-probe.log"),
66756
66922
  level: "debug"
66757
66923
  });
66758
66924
  logger.info("screen-idle probe logger enabled", {
66759
- file: import_node_path70.default.join(logDir, "screen-idle-probe.log")
66925
+ file: import_node_path72.default.join(logDir, "screen-idle-probe.log")
66760
66926
  });
66761
66927
  const CAP_TARGETS = [
66762
- import_node_path70.default.join(logDir, "clawd.log"),
66763
- import_node_path70.default.join(logDir, "screen-idle-probe.log")
66928
+ import_node_path72.default.join(logDir, "clawd.log"),
66929
+ import_node_path72.default.join(logDir, "screen-idle-probe.log")
66764
66930
  ];
66765
66931
  const LOG_CAP_MAX_BYTES = 10 * 1024 * 1024;
66766
66932
  const LOG_CAP_KEEP_BYTES = 5 * 1024 * 1024;
@@ -66882,8 +67048,8 @@ async function startDaemon(config) {
66882
67048
  const agents = new AgentsScanner();
66883
67049
  const history = new ClaudeHistoryReader();
66884
67050
  let transport = null;
66885
- const personaStore = new PersonaStore(import_node_path70.default.join(config.dataDir, "personas"));
66886
- const usersRoot = import_node_path70.default.join(config.dataDir, "users");
67051
+ const personaStore = new PersonaStore(import_node_path72.default.join(config.dataDir, "personas"));
67052
+ const usersRoot = import_node_path72.default.join(config.dataDir, "users");
66887
67053
  const defaultsRoot = findDefaultsRoot(logger);
66888
67054
  if (defaultsRoot) {
66889
67055
  seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
@@ -66907,7 +67073,7 @@ async function startDaemon(config) {
66907
67073
  retirePersonaBuilder({ store: personaStore, logger });
66908
67074
  const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
66909
67075
  const dispatchStore = createDispatchStore({
66910
- filePath: import_node_path70.default.join(config.dataDir, "dispatch.json"),
67076
+ filePath: import_node_path72.default.join(config.dataDir, "dispatch.json"),
66911
67077
  now: () => Date.now(),
66912
67078
  onFlushError: (err) => logger.error("dispatch store flush failed", {
66913
67079
  reason: err instanceof Error ? err.message : String(err)
@@ -66916,7 +67082,7 @@ async function startDaemon(config) {
66916
67082
  await dispatchStore.load();
66917
67083
  dispatchStore.markInterruptedAsFailed((/* @__PURE__ */ new Date()).toISOString());
66918
67084
  const channelStore = createChannelStore({
66919
- filePath: import_node_path70.default.join(config.dataDir, "channels.json"),
67085
+ filePath: import_node_path72.default.join(config.dataDir, "channels.json"),
66920
67086
  now: () => Date.now(),
66921
67087
  genId: () => `ch-${(0, import_node_crypto22.randomUUID)().slice(0, 8)}`,
66922
67088
  onFlushError: (err) => logger.error("channel store flush failed", {
@@ -66925,7 +67091,7 @@ async function startDaemon(config) {
66925
67091
  });
66926
67092
  await channelStore.load();
66927
67093
  const topicStore = createTopicStore({
66928
- filePath: import_node_path70.default.join(config.dataDir, "topics.json"),
67094
+ filePath: import_node_path72.default.join(config.dataDir, "topics.json"),
66929
67095
  now: () => Date.now(),
66930
67096
  genId: () => `tp-${(0, import_node_crypto22.randomUUID)().slice(0, 8)}`,
66931
67097
  onFlushError: (err) => logger.error("topic store flush failed", {
@@ -66952,18 +67118,18 @@ async function startDaemon(config) {
66952
67118
  });
66953
67119
  }
66954
67120
  });
66955
- const here = typeof __dirname === "string" ? __dirname : import_node_path70.default.dirname((0, import_node_url4.fileURLToPath)(import_meta7.url));
67121
+ const here = typeof __dirname === "string" ? __dirname : import_node_path72.default.dirname((0, import_node_url4.fileURLToPath)(import_meta7.url));
66956
67122
  const mcpConfigs = [];
66957
67123
  const mcpDaemonUrl = `http://127.0.0.1:${config.port}`;
66958
67124
  const dispatchServerCandidates = [
66959
- import_node_path70.default.join(here, "dispatch", "mcp-server.cjs"),
67125
+ import_node_path72.default.join(here, "dispatch", "mcp-server.cjs"),
66960
67126
  // 生产 dist/index → dist/dispatch/mcp-server.cjs
66961
- import_node_path70.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
67127
+ import_node_path72.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
66962
67128
  // dev tsx src/index → ../dist/dispatch/mcp-server.cjs
66963
67129
  ];
66964
- const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs52.default.existsSync(p2));
67130
+ const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs53.default.existsSync(p2));
66965
67131
  if (dispatchServerScriptPath) {
66966
- const dispatchLogPath = import_node_path70.default.join(logDir, "dispatch-mcp-server.log");
67132
+ const dispatchLogPath = import_node_path72.default.join(logDir, "dispatch-mcp-server.log");
66967
67133
  const dispatchCfgPath = writeDispatchMcpConfig({
66968
67134
  dataDir: config.dataDir,
66969
67135
  serverScriptPath: dispatchServerScriptPath,
@@ -66983,12 +67149,12 @@ async function startDaemon(config) {
66983
67149
  });
66984
67150
  }
66985
67151
  const ticketServerCandidates = [
66986
- import_node_path70.default.join(here, "ticket", "mcp-server.cjs"),
66987
- import_node_path70.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
67152
+ import_node_path72.default.join(here, "ticket", "mcp-server.cjs"),
67153
+ import_node_path72.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
66988
67154
  ];
66989
- const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs52.default.existsSync(p2));
67155
+ const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs53.default.existsSync(p2));
66990
67156
  if (ticketServerScriptPath) {
66991
- const ticketLogPath = import_node_path70.default.join(logDir, "ticket-mcp-server.log");
67157
+ const ticketLogPath = import_node_path72.default.join(logDir, "ticket-mcp-server.log");
66992
67158
  const ticketCfgPath = writeTicketMcpConfig({
66993
67159
  dataDir: config.dataDir,
66994
67160
  serverScriptPath: ticketServerScriptPath,
@@ -67010,12 +67176,12 @@ async function startDaemon(config) {
67010
67176
  });
67011
67177
  }
67012
67178
  const shiftServerCandidates = [
67013
- import_node_path70.default.join(here, "shift", "mcp-server.cjs"),
67014
- import_node_path70.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
67179
+ import_node_path72.default.join(here, "shift", "mcp-server.cjs"),
67180
+ import_node_path72.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
67015
67181
  ];
67016
- const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs52.default.existsSync(p2));
67182
+ const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs53.default.existsSync(p2));
67017
67183
  if (shiftServerScriptPath) {
67018
- const shiftLogPath = import_node_path70.default.join(logDir, "shift-mcp-server.log");
67184
+ const shiftLogPath = import_node_path72.default.join(logDir, "shift-mcp-server.log");
67019
67185
  const shiftCfgPath = await writeShiftMcpConfig({
67020
67186
  dataDir: config.dataDir,
67021
67187
  serverScriptPath: shiftServerScriptPath,
@@ -67036,12 +67202,12 @@ async function startDaemon(config) {
67036
67202
  );
67037
67203
  }
67038
67204
  const inboxServerCandidates = [
67039
- import_node_path70.default.join(here, "inbox", "mcp-server.cjs"),
67040
- import_node_path70.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
67205
+ import_node_path72.default.join(here, "inbox", "mcp-server.cjs"),
67206
+ import_node_path72.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
67041
67207
  ];
67042
- const inboxServerScriptPath = inboxServerCandidates.find((p2) => import_node_fs52.default.existsSync(p2));
67208
+ const inboxServerScriptPath = inboxServerCandidates.find((p2) => import_node_fs53.default.existsSync(p2));
67043
67209
  if (inboxServerScriptPath) {
67044
- const inboxLogPath = import_node_path70.default.join(logDir, "inbox-mcp-server.log");
67210
+ const inboxLogPath = import_node_path72.default.join(logDir, "inbox-mcp-server.log");
67045
67211
  const inboxCfgPath = await writeInboxMcpConfig({
67046
67212
  dataDir: config.dataDir,
67047
67213
  serverScriptPath: inboxServerScriptPath,
@@ -67062,10 +67228,10 @@ async function startDaemon(config) {
67062
67228
  );
67063
67229
  }
67064
67230
  const peerOpsServerCandidates = [
67065
- import_node_path70.default.join(here, "peer-ops", "mcp-server.cjs"),
67066
- import_node_path70.default.join(here, "..", "dist", "peer-ops", "mcp-server.cjs")
67231
+ import_node_path72.default.join(here, "peer-ops", "mcp-server.cjs"),
67232
+ import_node_path72.default.join(here, "..", "dist", "peer-ops", "mcp-server.cjs")
67067
67233
  ];
67068
- const peerOpsServerScriptPath = peerOpsServerCandidates.find((p2) => import_node_fs52.default.existsSync(p2));
67234
+ const peerOpsServerScriptPath = peerOpsServerCandidates.find((p2) => import_node_fs53.default.existsSync(p2));
67069
67235
  if (peerOpsServerScriptPath) {
67070
67236
  const peerOpsCfgPath = writePeerOpsMcpConfig({
67071
67237
  dataDir: config.dataDir,
@@ -67085,12 +67251,12 @@ async function startDaemon(config) {
67085
67251
  );
67086
67252
  }
67087
67253
  const rpcToolServerCandidates = [
67088
- import_node_path70.default.join(here, "rpc-tool", "mcp-server.cjs"),
67089
- import_node_path70.default.join(here, "..", "dist", "rpc-tool", "mcp-server.cjs")
67254
+ import_node_path72.default.join(here, "rpc-tool", "mcp-server.cjs"),
67255
+ import_node_path72.default.join(here, "..", "dist", "rpc-tool", "mcp-server.cjs")
67090
67256
  ];
67091
- const rpcToolServerScriptPath = rpcToolServerCandidates.find((p2) => import_node_fs52.default.existsSync(p2));
67257
+ const rpcToolServerScriptPath = rpcToolServerCandidates.find((p2) => import_node_fs53.default.existsSync(p2));
67092
67258
  if (rpcToolServerScriptPath) {
67093
- const rpcToolLogPath = import_node_path70.default.join(logDir, "rpc-tool-mcp-server.log");
67259
+ const rpcToolLogPath = import_node_path72.default.join(logDir, "rpc-tool-mcp-server.log");
67094
67260
  const rpcToolCfgPath = writeRpcToolMcpConfig({
67095
67261
  dataDir: config.dataDir,
67096
67262
  serverScriptPath: rpcToolServerScriptPath,
@@ -67111,7 +67277,7 @@ async function startDaemon(config) {
67111
67277
  );
67112
67278
  }
67113
67279
  const shiftStore = createShiftStore({
67114
- filePath: import_node_path70.default.join(config.dataDir, "shift.json"),
67280
+ filePath: import_node_path72.default.join(config.dataDir, "shift.json"),
67115
67281
  ownerIdProvider: () => ownerPrincipalId,
67116
67282
  now: () => Date.now()
67117
67283
  });
@@ -67133,7 +67299,7 @@ async function startDaemon(config) {
67133
67299
  getAdapter,
67134
67300
  historyReader: history,
67135
67301
  dataDir: config.dataDir,
67136
- personaRoot: import_node_path70.default.join(config.dataDir, "personas"),
67302
+ personaRoot: import_node_path72.default.join(config.dataDir, "personas"),
67137
67303
  // dispatch / shift 自动化 spawn 按 persona 绑定 tool 起 B session(codex persona 用 codex)。
67138
67304
  // personaRegistry 声明在 manager 之后(同作用域 const,调用时机在启动完成后,无 TDZ 风险)。
67139
67305
  getPersonaDefaults: (personaId2) => personaRegistry.get(personaId2),
@@ -67187,10 +67353,10 @@ async function startDaemon(config) {
67187
67353
  // 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
67188
67354
  attachmentGroup: {
67189
67355
  onFileEdit: (input) => {
67190
- const absPath = import_node_path70.default.isAbsolute(input.relPath) ? input.relPath : import_node_path70.default.join(input.cwd, input.relPath);
67356
+ const absPath = import_node_path72.default.isAbsolute(input.relPath) ? input.relPath : import_node_path72.default.join(input.cwd, input.relPath);
67191
67357
  let size = 0;
67192
67358
  try {
67193
- size = import_node_fs52.default.statSync(absPath).size;
67359
+ size = import_node_fs53.default.statSync(absPath).size;
67194
67360
  } catch (err) {
67195
67361
  logger.warn("attachment.onFileEdit stat failed", {
67196
67362
  sessionId: input.sessionId,
@@ -67220,9 +67386,9 @@ async function startDaemon(config) {
67220
67386
  logger.info("projects.seed-dropped", { dropped: droppedSeed.dropped, backup: droppedSeed.backup });
67221
67387
  }
67222
67388
  const projectsStore = new ProjectsStore({
67223
- file: import_node_path70.default.join(config.dataDir, "projects.json"),
67389
+ file: import_node_path72.default.join(config.dataDir, "projects.json"),
67224
67390
  clawdDir: config.dataDir,
67225
- codexStateFile: import_node_path70.default.join(import_node_os25.default.homedir(), ".codex", ".codex-global-state.json"),
67391
+ codexStateFile: import_node_path72.default.join(import_node_os26.default.homedir(), ".codex", ".codex-global-state.json"),
67226
67392
  logger
67227
67393
  });
67228
67394
  const observer = new SessionObserver({
@@ -67282,13 +67448,13 @@ async function startDaemon(config) {
67282
67448
  screenIdleProbeLogger
67283
67449
  }) : new ClaudeAdapter({ logger, historyReader: new ClaudeHistoryReader() });
67284
67450
  registerAdapter("claude", claudeAdapter);
67285
- const codexIsolatedHome = import_node_path70.default.join(config.dataDir, "codex-home");
67451
+ const codexIsolatedHome = import_node_path72.default.join(config.dataDir, "codex-home");
67286
67452
  try {
67287
- import_node_fs52.default.mkdirSync(codexIsolatedHome, { recursive: true });
67453
+ import_node_fs53.default.mkdirSync(codexIsolatedHome, { recursive: true });
67288
67454
  for (const f of ["auth.json", "config.toml"]) {
67289
- const link = import_node_path70.default.join(codexIsolatedHome, f);
67290
- const target = import_node_path70.default.join(import_node_os25.default.homedir(), ".codex", f);
67291
- if (!import_node_fs52.default.existsSync(link) && import_node_fs52.default.existsSync(target)) import_node_fs52.default.symlinkSync(target, link);
67455
+ const link = import_node_path72.default.join(codexIsolatedHome, f);
67456
+ const target = import_node_path72.default.join(import_node_os26.default.homedir(), ".codex", f);
67457
+ if (!import_node_fs53.default.existsSync(link) && import_node_fs53.default.existsSync(target)) import_node_fs53.default.symlinkSync(target, link);
67292
67458
  }
67293
67459
  } catch (err) {
67294
67460
  logger.warn("codex isolated home setup failed", { err: String(err) });
@@ -67301,11 +67467,11 @@ async function startDaemon(config) {
67301
67467
  // projectPaths 每次调用现取 —— 用户新建 project 后立即生效,不用重启 daemon
67302
67468
  codexHomeFor: (cwd) => resolveCodexHome({
67303
67469
  cwd,
67304
- personaRoot: import_node_path70.default.join(config.dataDir, "personas"),
67470
+ personaRoot: import_node_path72.default.join(config.dataDir, "personas"),
67305
67471
  // 必须用 listMerged(Codex registry ∪ 叠加层):只用本地 list() 的话,用户在
67306
67472
  // Codex 里建的 project 不在表里,在它下面开的会话会被误判成隔离 → Codex 侧看不到
67307
67473
  projectPaths: projectsStore.listMerged().map((x) => x.path),
67308
- sharedHome: import_node_path70.default.join(import_node_os25.default.homedir(), ".codex"),
67474
+ sharedHome: import_node_path72.default.join(import_node_os26.default.homedir(), ".codex"),
67309
67475
  isolatedHome: codexIsolatedHome
67310
67476
  })
67311
67477
  })
@@ -67589,11 +67755,11 @@ async function startDaemon(config) {
67589
67755
  // 'persona/<pid>/owner',default 走 'default'。
67590
67756
  getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
67591
67757
  // guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
67592
- personaRoot: import_node_path70.default.join(config.dataDir, "personas"),
67758
+ personaRoot: import_node_path72.default.join(config.dataDir, "personas"),
67593
67759
  usersRoot
67594
67760
  },
67595
67761
  // workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
67596
- personaRoot: import_node_path70.default.join(config.dataDir, "personas"),
67762
+ personaRoot: import_node_path72.default.join(config.dataDir, "personas"),
67597
67763
  // v2 多人 persona 隔离:handler 派生 guest user-dir 放行
67598
67764
  usersRoot,
67599
67765
  // v2 Phase 6: whoami handler 装在 owner principal.displayName + persona 解析
@@ -67692,11 +67858,11 @@ async function startDaemon(config) {
67692
67858
  // 发布上线脚手架化 (spec 2026-06-03 §5.2):
67693
67859
  // appBuilderPersonaRoot 用于拼 publish.sh 绝对路径(persona-app-builder 安装在
67694
67860
  // dataDir/personas/persona-app-builder 之下,extension-kit/scripts/publish.sh 是相对路径)。
67695
- appBuilderPersonaRoot: import_node_path70.default.join(config.dataDir, "personas", "persona-app-builder"),
67861
+ appBuilderPersonaRoot: import_node_path72.default.join(config.dataDir, "personas", "persona-app-builder"),
67696
67862
  // 共享 deploy-kit 根:scaffold/publish 脚本骨架 + 阿里云凭证单一真源。
67697
- deployKitRoot: import_node_path70.default.join(config.dataDir, "deploy-kit"),
67863
+ deployKitRoot: import_node_path72.default.join(config.dataDir, "deploy-kit"),
67698
67864
  // scaffold/publish 按当前 session 的 persona 解析其安装根,让每个 persona 用自己的模板/注入配置。
67699
- resolvePersonaRoot: (personaId2) => import_node_path70.default.join(config.dataDir, "personas", personaId2),
67865
+ resolvePersonaRoot: (personaId2) => import_node_path72.default.join(config.dataDir, "personas", personaId2),
67700
67866
  // 发布上线脚手架化 (spec 2026-06-03 §5.2.2):
67701
67867
  // 复用 SessionManagerDeps.broadcastFrame 同款 dispatch 逻辑 —— runner 调 manager.send
67702
67868
  // 取回 broadcast 帧后逐帧 push 到 transport,跟 manager 自身的 deps 一致。
@@ -67751,7 +67917,7 @@ async function startDaemon(config) {
67751
67917
  sourceSessionId: args.sourceSessionId
67752
67918
  });
67753
67919
  const sourceFile = manager.findOwnedSession(args.sourceSessionId);
67754
- const sourceJsonlPath = resolveSourceJsonlPath(sourceFile, import_node_os25.default.homedir());
67920
+ const sourceJsonlPath = resolveSourceJsonlPath(sourceFile, import_node_os26.default.homedir());
67755
67921
  logger.info("dispatch.spawnB.source-resolved", {
67756
67922
  dispatchId: args.dispatchId,
67757
67923
  sourceJsonlPath,
@@ -67817,7 +67983,7 @@ async function startDaemon(config) {
67817
67983
  });
67818
67984
  shiftScheduler.start();
67819
67985
  logger.info("shift scheduler started", { shiftCount: shiftStore.list().length });
67820
- const larkBotStore = createLarkBotBindingStore(import_node_path70.default.join(config.dataDir, "personas"));
67986
+ const larkBotStore = createLarkBotBindingStore(import_node_path72.default.join(config.dataDir, "personas"));
67821
67987
  const larkBotCloud = createLarkBotCloudClient({
67822
67988
  api: config.clawosApi ?? DEFAULT_CLAWOS_API,
67823
67989
  apiKey: resolveClawdTicketsApiKey(),
@@ -67831,7 +67997,7 @@ async function startDaemon(config) {
67831
67997
  store: larkBotStore,
67832
67998
  fetchResource: (appId, messageId, fileKey, maxBytes, type) => larkBotCloud.fetchResource(appId, messageId, fileKey, maxBytes, type),
67833
67999
  // 图片落 guest userWorkDir 下(capId = lark-<chat_id>):CC 经 --add-dir + allowRead carve 可 Read
67834
- mediaRootFor: (chatId) => import_node_path70.default.join(deriveUserWorkDir(`lark-${chatId}`, usersRoot), "lark-media"),
68000
+ mediaRootFor: (chatId) => import_node_path72.default.join(deriveUserWorkDir(`lark-${chatId}`, usersRoot), "lark-media"),
67835
68001
  isShuttingDown: () => larkDraining,
67836
68002
  logger: {
67837
68003
  warn: (msg) => logger.warn(msg),
@@ -68136,8 +68302,8 @@ async function startDaemon(config) {
68136
68302
  const lines = [
68137
68303
  `Tunnel: ${r.url}`,
68138
68304
  ...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
68139
- `Frpc config: ${import_node_path70.default.join(config.dataDir, "frpc.toml")}`,
68140
- `Frpc log: ${import_node_path70.default.join(logDir, "frpc.log")}`
68305
+ `Frpc config: ${import_node_path72.default.join(config.dataDir, "frpc.toml")}`,
68306
+ `Frpc log: ${import_node_path72.default.join(logDir, "frpc.log")}`
68141
68307
  ];
68142
68308
  const width2 = Math.max(...lines.map((l) => l.length));
68143
68309
  const bar = "\u2550".repeat(width2 + 4);
@@ -68150,8 +68316,8 @@ ${bar}
68150
68316
 
68151
68317
  `);
68152
68318
  try {
68153
- const connectPath = import_node_path70.default.join(config.dataDir, "connect.txt");
68154
- import_node_fs52.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
68319
+ const connectPath = import_node_path72.default.join(config.dataDir, "connect.txt");
68320
+ import_node_fs53.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
68155
68321
  } catch {
68156
68322
  }
68157
68323
  } catch (err) {
@@ -68238,9 +68404,9 @@ ${bar}
68238
68404
  };
68239
68405
  }
68240
68406
  function migrateDropPersonsDir(dataDir) {
68241
- const dir = import_node_path70.default.join(dataDir, "persons");
68407
+ const dir = import_node_path72.default.join(dataDir, "persons");
68242
68408
  try {
68243
- import_node_fs52.default.rmSync(dir, { recursive: true, force: true });
68409
+ import_node_fs53.default.rmSync(dir, { recursive: true, force: true });
68244
68410
  } catch {
68245
68411
  }
68246
68412
  }