@clawos-dev/clawd 0.2.134-beta.278.7c624cd → 0.2.135-beta.279.732f6db

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
@@ -4579,7 +4579,7 @@ var init_persona_schemas = __esm({
4579
4579
  });
4580
4580
 
4581
4581
  // ../protocol/src/schemas.ts
4582
- var SessionStatusSchema, UsageSchema, ContextUsageSchema, sessionMetaShape, SessionMetaSchema, ModelInfoSchema, ModeInfoSchema, ConfigFieldSchemaSchema, CapabilitiesGetArgs, CapabilitiesResponseSchema, AllowRuleSchema, SessionFileSchema, ParsedEventBase, HistoryUserMetaSchema, SubagentToolStatsSchema, StructuredPatchHunkSchema, ToolResultExtraSchema, MemoryEntrySchema, AskQuestionOptionSchema, AskQuestionItemSchema, ParsedEventSchema, SessionCreateArgs, SessionIdArgs, SessionUpdateArgs, SessionSendArgs, SessionRewindArgs, SessionRewindResponseSchema, SessionRewindDiffArgs, RewindDiffHunkSchema, RewindDiffFileSchema, SessionRewindDiffResponseSchema, SessionRewindableMessageIdsArgs, SessionRewindableMessageIdsResponseSchema, SessionResumeArgs, SessionForkArgs, SessionForkResponseSchema, SessionObserveArgs, SessionEventsArgs, PermissionRespondArgs, HistoryListArgs, HistoryReadArgs, HistorySubagentsArgs, HistorySubagentReadArgs, WorkspaceListArgs, WorkspaceReadArgs, SkillsListArgs, SkillEntrySchema, AgentEntrySchema, AgentsListArgs, AgentsListResponseSchema, SessionSubscribeArgs, SessionPinArgs, PeerSessionUpsertArgs, PeerSessionUpsertResponseSchema, PeerSessionRemoveArgs, PeerSessionRemoveResponseSchema, SessionReorderPinsArgs, GitRootArgs, GitRootResponseSchema, GitBranchArgs, GitBranchResponseSchema, GitBranchesArgs, GitBranchesResponseSchema, HistoryRecentDirsArgs, RecentDirEntrySchema, HistoryRecentDirsResponseSchema, SessionQuestionFrameSchema, SessionQuestionClearedFrameSchema, AnswerQuestionArgs, AnswerQuestionResponseSchema, CancelQuestionArgs, CancelQuestionResponseSchema, AuthRequestFrameSchema, AuthOkFrameSchema, 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;
4582
+ var SessionStatusSchema, UsageSchema, ContextUsageSchema, sessionMetaShape, SessionMetaSchema, ModelInfoSchema, ModeInfoSchema, ConfigFieldSchemaSchema, CapabilitiesGetArgs, ToolFeaturesSchema, CapabilitiesResponseSchema, AllowRuleSchema, SessionFileSchema, ParsedEventBase, HistoryUserMetaSchema, SubagentToolStatsSchema, StructuredPatchHunkSchema, ToolResultExtraSchema, MemoryEntrySchema, AskQuestionOptionSchema, AskQuestionItemSchema, ParsedEventSchema, SessionCreateArgs, SessionIdArgs, SessionUpdateArgs, SessionSendArgs, SessionRewindArgs, SessionRewindResponseSchema, SessionRewindDiffArgs, RewindDiffHunkSchema, RewindDiffFileSchema, SessionRewindDiffResponseSchema, SessionRewindableMessageIdsArgs, SessionRewindableMessageIdsResponseSchema, SessionResumeArgs, SessionForkArgs, SessionForkResponseSchema, SessionObserveArgs, SessionEventsArgs, PermissionRespondArgs, HistoryListArgs, HistoryReadArgs, HistorySubagentsArgs, HistorySubagentReadArgs, WorkspaceListArgs, WorkspaceReadArgs, SkillsListArgs, SkillEntrySchema, AgentEntrySchema, AgentsListArgs, AgentsListResponseSchema, SessionSubscribeArgs, SessionPinArgs, PeerSessionUpsertArgs, PeerSessionUpsertResponseSchema, PeerSessionRemoveArgs, PeerSessionRemoveResponseSchema, SessionReorderPinsArgs, GitRootArgs, GitRootResponseSchema, GitBranchArgs, GitBranchResponseSchema, GitBranchesArgs, GitBranchesResponseSchema, HistoryRecentDirsArgs, RecentDirEntrySchema, HistoryRecentDirsResponseSchema, SessionQuestionFrameSchema, SessionQuestionClearedFrameSchema, AnswerQuestionArgs, AnswerQuestionResponseSchema, CancelQuestionArgs, CancelQuestionResponseSchema, AuthRequestFrameSchema, AuthOkFrameSchema, 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;
4583
4583
  var init_schemas = __esm({
4584
4584
  "../protocol/src/schemas.ts"() {
4585
4585
  "use strict";
@@ -4637,12 +4637,23 @@ var init_schemas = __esm({
4637
4637
  CapabilitiesGetArgs = external_exports.object({
4638
4638
  tool: external_exports.string().min(1)
4639
4639
  });
4640
+ ToolFeaturesSchema = external_exports.object({
4641
+ rewind: external_exports.boolean(),
4642
+ subagents: external_exports.boolean(),
4643
+ tui: external_exports.boolean(),
4644
+ observe: external_exports.boolean(),
4645
+ fileSharing: external_exports.boolean(),
4646
+ // fork:session:fork 走 forkSession(claude jsonl 专用,派生新 jsonl)。codex 无 claude jsonl
4647
+ // → fork 不可用。UI 据此 gate assistant 消息上的 fork 按钮(codex 一轮多条消息会刷出一堆按钮且点了报错)。
4648
+ fork: external_exports.boolean()
4649
+ });
4640
4650
  CapabilitiesResponseSchema = external_exports.object({
4641
4651
  tool: external_exports.string().min(1),
4642
4652
  toolSessionIdLabel: external_exports.string().optional(),
4643
4653
  models: external_exports.array(ModelInfoSchema),
4644
4654
  permissionModes: external_exports.array(ModeInfoSchema),
4645
- configSchema: external_exports.array(ConfigFieldSchemaSchema)
4655
+ configSchema: external_exports.array(ConfigFieldSchemaSchema),
4656
+ features: ToolFeaturesSchema
4646
4657
  });
4647
4658
  AllowRuleSchema = external_exports.object({
4648
4659
  tool: external_exports.string().min(1),
@@ -5034,7 +5045,11 @@ var init_schemas = __esm({
5034
5045
  });
5035
5046
  PermissionRespondArgs = external_exports.object({
5036
5047
  sessionId: external_exports.string().min(1),
5037
- requestId: external_exports.string().min(1),
5048
+ // 权限请求 id 用 `permissionRequestId`,**不能**叫 `requestId`:WS 传输层用帧顶层的
5049
+ // `requestId` 做 RPC 请求/响应关联(daemon-client 发帧时 `{...args, type, requestId}`,
5050
+ // 传输 id 在最后会覆盖 args 同名字段)。若沿用 `requestId`,权限 id 会被传输 id(如 "r61")
5051
+ // 覆盖,daemon 查 pendingPermissions 永远 miss → 点了允许一直卡住。
5052
+ permissionRequestId: external_exports.string().min(1),
5038
5053
  allow: external_exports.boolean(),
5039
5054
  permanent: external_exports.boolean().optional(),
5040
5055
  pattern: external_exports.string().optional()
@@ -5065,7 +5080,7 @@ var init_schemas = __esm({
5065
5080
  cwd: external_exports.string().min(1),
5066
5081
  path: external_exports.string().min(1)
5067
5082
  });
5068
- SkillsListArgs = external_exports.object({ cwd: external_exports.string().min(1) });
5083
+ SkillsListArgs = external_exports.object({ cwd: external_exports.string().min(1), tool: external_exports.string().optional() });
5069
5084
  SkillEntrySchema = external_exports.object({
5070
5085
  name: external_exports.string().min(1),
5071
5086
  source: external_exports.enum(SKILL_SOURCE_VALUES),
@@ -5081,7 +5096,7 @@ var init_schemas = __esm({
5081
5096
  whenToUse: external_exports.string().optional(),
5082
5097
  plugin: external_exports.string().optional()
5083
5098
  });
5084
- AgentsListArgs = external_exports.object({ cwd: external_exports.string().min(1) });
5099
+ AgentsListArgs = external_exports.object({ cwd: external_exports.string().min(1), tool: external_exports.string().optional() });
5085
5100
  AgentsListResponseSchema = external_exports.object({
5086
5101
  agents: external_exports.array(AgentEntrySchema)
5087
5102
  });
@@ -6842,10 +6857,10 @@ var require_redaction = __commonJS({
6842
6857
  var strict = false;
6843
6858
  function redaction(opts, serialize) {
6844
6859
  const { paths, censor, remove } = handle(opts);
6845
- const shape = paths.reduce((o, str) => {
6860
+ const shape = paths.reduce((o, str4) => {
6846
6861
  rx.lastIndex = 0;
6847
- const first = rx.exec(str);
6848
- const next = rx.exec(str);
6862
+ const first = rx.exec(str4);
6863
+ const next = rx.exec(str4);
6849
6864
  let ns = first[1] !== void 0 ? first[1].replace(/^(?:"|'|`)(.*)(?:"|'|`)$/, "$1") : first[0];
6850
6865
  if (ns === "*") {
6851
6866
  ns = wildcardFirstSym;
@@ -6858,7 +6873,7 @@ var require_redaction = __commonJS({
6858
6873
  return o;
6859
6874
  }
6860
6875
  const { index } = next;
6861
- const nextPath = `${str.substr(index, str.length - 1)}`;
6876
+ const nextPath = `${str4.substr(index, str4.length - 1)}`;
6862
6877
  o[ns] = o[ns] || [];
6863
6878
  if (ns !== wildcardFirstSym && o[ns].length === 0) {
6864
6879
  o[ns].push(...o[wildcardFirstSym] || []);
@@ -6974,7 +6989,7 @@ var require_quick_format_unescaped = __commonJS({
6974
6989
  }
6975
6990
  var argLen = args.length;
6976
6991
  if (argLen === 0) return f;
6977
- var str = "";
6992
+ var str4 = "";
6978
6993
  var a = 1 - offset;
6979
6994
  var lastPos = -1;
6980
6995
  var flen = f && f.length || 0;
@@ -6989,8 +7004,8 @@ var require_quick_format_unescaped = __commonJS({
6989
7004
  break;
6990
7005
  if (args[a] == null) break;
6991
7006
  if (lastPos < i)
6992
- str += f.slice(lastPos, i);
6993
- str += Number(args[a]);
7007
+ str4 += f.slice(lastPos, i);
7008
+ str4 += Number(args[a]);
6994
7009
  lastPos = i + 2;
6995
7010
  i++;
6996
7011
  break;
@@ -6999,8 +7014,8 @@ var require_quick_format_unescaped = __commonJS({
6999
7014
  break;
7000
7015
  if (args[a] == null) break;
7001
7016
  if (lastPos < i)
7002
- str += f.slice(lastPos, i);
7003
- str += Math.floor(Number(args[a]));
7017
+ str4 += f.slice(lastPos, i);
7018
+ str4 += Math.floor(Number(args[a]));
7004
7019
  lastPos = i + 2;
7005
7020
  i++;
7006
7021
  break;
@@ -7013,21 +7028,21 @@ var require_quick_format_unescaped = __commonJS({
7013
7028
  break;
7014
7029
  if (args[a] === void 0) break;
7015
7030
  if (lastPos < i)
7016
- str += f.slice(lastPos, i);
7031
+ str4 += f.slice(lastPos, i);
7017
7032
  var type = typeof args[a];
7018
7033
  if (type === "string") {
7019
- str += "'" + args[a] + "'";
7034
+ str4 += "'" + args[a] + "'";
7020
7035
  lastPos = i + 2;
7021
7036
  i++;
7022
7037
  break;
7023
7038
  }
7024
7039
  if (type === "function") {
7025
- str += args[a].name || "<anonymous>";
7040
+ str4 += args[a].name || "<anonymous>";
7026
7041
  lastPos = i + 2;
7027
7042
  i++;
7028
7043
  break;
7029
7044
  }
7030
- str += ss(args[a]);
7045
+ str4 += ss(args[a]);
7031
7046
  lastPos = i + 2;
7032
7047
  i++;
7033
7048
  break;
@@ -7035,15 +7050,15 @@ var require_quick_format_unescaped = __commonJS({
7035
7050
  if (a >= argLen)
7036
7051
  break;
7037
7052
  if (lastPos < i)
7038
- str += f.slice(lastPos, i);
7039
- str += String(args[a]);
7053
+ str4 += f.slice(lastPos, i);
7054
+ str4 += String(args[a]);
7040
7055
  lastPos = i + 2;
7041
7056
  i++;
7042
7057
  break;
7043
7058
  case 37:
7044
7059
  if (lastPos < i)
7045
- str += f.slice(lastPos, i);
7046
- str += "%";
7060
+ str4 += f.slice(lastPos, i);
7061
+ str4 += "%";
7047
7062
  lastPos = i + 2;
7048
7063
  i++;
7049
7064
  a--;
@@ -7056,9 +7071,9 @@ var require_quick_format_unescaped = __commonJS({
7056
7071
  if (lastPos === -1)
7057
7072
  return f;
7058
7073
  else if (lastPos < flen) {
7059
- str += f.slice(lastPos);
7074
+ str4 += f.slice(lastPos);
7060
7075
  }
7061
- return str;
7076
+ return str4;
7062
7077
  }
7063
7078
  }
7064
7079
  });
@@ -7102,7 +7117,7 @@ var require_atomic_sleep = __commonJS({
7102
7117
  var require_sonic_boom = __commonJS({
7103
7118
  "../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
7104
7119
  "use strict";
7105
- var fs50 = require("fs");
7120
+ var fs51 = require("fs");
7106
7121
  var EventEmitter3 = require("events");
7107
7122
  var inherits = require("util").inherits;
7108
7123
  var path59 = require("path");
@@ -7159,20 +7174,20 @@ var require_sonic_boom = __commonJS({
7159
7174
  const mode = sonic.mode;
7160
7175
  if (sonic.sync) {
7161
7176
  try {
7162
- if (sonic.mkdir) fs50.mkdirSync(path59.dirname(file), { recursive: true });
7163
- const fd = fs50.openSync(file, flags, mode);
7177
+ if (sonic.mkdir) fs51.mkdirSync(path59.dirname(file), { recursive: true });
7178
+ const fd = fs51.openSync(file, flags, mode);
7164
7179
  fileOpened(null, fd);
7165
7180
  } catch (err) {
7166
7181
  fileOpened(err);
7167
7182
  throw err;
7168
7183
  }
7169
7184
  } else if (sonic.mkdir) {
7170
- fs50.mkdir(path59.dirname(file), { recursive: true }, (err) => {
7185
+ fs51.mkdir(path59.dirname(file), { recursive: true }, (err) => {
7171
7186
  if (err) return fileOpened(err);
7172
- fs50.open(file, flags, mode, fileOpened);
7187
+ fs51.open(file, flags, mode, fileOpened);
7173
7188
  });
7174
7189
  } else {
7175
- fs50.open(file, flags, mode, fileOpened);
7190
+ fs51.open(file, flags, mode, fileOpened);
7176
7191
  }
7177
7192
  }
7178
7193
  function SonicBoom(opts) {
@@ -7213,8 +7228,8 @@ var require_sonic_boom = __commonJS({
7213
7228
  this.flush = flushBuffer;
7214
7229
  this.flushSync = flushBufferSync;
7215
7230
  this._actualWrite = actualWriteBuffer;
7216
- fsWriteSync = () => fs50.writeSync(this.fd, this._writingBuf);
7217
- fsWrite = () => fs50.write(this.fd, this._writingBuf, this.release);
7231
+ fsWriteSync = () => fs51.writeSync(this.fd, this._writingBuf);
7232
+ fsWrite = () => fs51.write(this.fd, this._writingBuf, this.release);
7218
7233
  } else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
7219
7234
  this._writingBuf = "";
7220
7235
  this.write = write;
@@ -7223,15 +7238,15 @@ var require_sonic_boom = __commonJS({
7223
7238
  this._actualWrite = actualWrite;
7224
7239
  fsWriteSync = () => {
7225
7240
  if (Buffer.isBuffer(this._writingBuf)) {
7226
- return fs50.writeSync(this.fd, this._writingBuf);
7241
+ return fs51.writeSync(this.fd, this._writingBuf);
7227
7242
  }
7228
- return fs50.writeSync(this.fd, this._writingBuf, "utf8");
7243
+ return fs51.writeSync(this.fd, this._writingBuf, "utf8");
7229
7244
  };
7230
7245
  fsWrite = () => {
7231
7246
  if (Buffer.isBuffer(this._writingBuf)) {
7232
- return fs50.write(this.fd, this._writingBuf, this.release);
7247
+ return fs51.write(this.fd, this._writingBuf, this.release);
7233
7248
  }
7234
- return fs50.write(this.fd, this._writingBuf, "utf8", this.release);
7249
+ return fs51.write(this.fd, this._writingBuf, "utf8", this.release);
7235
7250
  };
7236
7251
  } else {
7237
7252
  throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
@@ -7288,7 +7303,7 @@ var require_sonic_boom = __commonJS({
7288
7303
  }
7289
7304
  }
7290
7305
  if (this._fsync) {
7291
- fs50.fsyncSync(this.fd);
7306
+ fs51.fsyncSync(this.fd);
7292
7307
  }
7293
7308
  const len = this._len;
7294
7309
  if (this._reopening) {
@@ -7402,7 +7417,7 @@ var require_sonic_boom = __commonJS({
7402
7417
  const onDrain = () => {
7403
7418
  if (!this._fsync) {
7404
7419
  try {
7405
- fs50.fsync(this.fd, (err) => {
7420
+ fs51.fsync(this.fd, (err) => {
7406
7421
  this._flushPending = false;
7407
7422
  cb(err);
7408
7423
  });
@@ -7504,7 +7519,7 @@ var require_sonic_boom = __commonJS({
7504
7519
  const fd = this.fd;
7505
7520
  this.once("ready", () => {
7506
7521
  if (fd !== this.fd) {
7507
- fs50.close(fd, (err) => {
7522
+ fs51.close(fd, (err) => {
7508
7523
  if (err) {
7509
7524
  return this.emit("error", err);
7510
7525
  }
@@ -7553,7 +7568,7 @@ var require_sonic_boom = __commonJS({
7553
7568
  buf = this._bufs[0];
7554
7569
  }
7555
7570
  try {
7556
- const n = Buffer.isBuffer(buf) ? fs50.writeSync(this.fd, buf) : fs50.writeSync(this.fd, buf, "utf8");
7571
+ const n = Buffer.isBuffer(buf) ? fs51.writeSync(this.fd, buf) : fs51.writeSync(this.fd, buf, "utf8");
7557
7572
  const releasedBufObj = releaseWritingBuf(buf, this._len, n);
7558
7573
  buf = releasedBufObj.writingBuf;
7559
7574
  this._len = releasedBufObj.len;
@@ -7569,7 +7584,7 @@ var require_sonic_boom = __commonJS({
7569
7584
  }
7570
7585
  }
7571
7586
  try {
7572
- fs50.fsyncSync(this.fd);
7587
+ fs51.fsyncSync(this.fd);
7573
7588
  } catch {
7574
7589
  }
7575
7590
  }
@@ -7590,7 +7605,7 @@ var require_sonic_boom = __commonJS({
7590
7605
  buf = mergeBuf(this._bufs[0], this._lens[0]);
7591
7606
  }
7592
7607
  try {
7593
- const n = fs50.writeSync(this.fd, buf);
7608
+ const n = fs51.writeSync(this.fd, buf);
7594
7609
  buf = buf.subarray(n);
7595
7610
  this._len = Math.max(this._len - n, 0);
7596
7611
  if (buf.length <= 0) {
@@ -7618,13 +7633,13 @@ var require_sonic_boom = __commonJS({
7618
7633
  this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
7619
7634
  if (this.sync) {
7620
7635
  try {
7621
- const written = Buffer.isBuffer(this._writingBuf) ? fs50.writeSync(this.fd, this._writingBuf) : fs50.writeSync(this.fd, this._writingBuf, "utf8");
7636
+ const written = Buffer.isBuffer(this._writingBuf) ? fs51.writeSync(this.fd, this._writingBuf) : fs51.writeSync(this.fd, this._writingBuf, "utf8");
7622
7637
  release(null, written);
7623
7638
  } catch (err) {
7624
7639
  release(err);
7625
7640
  }
7626
7641
  } else {
7627
- fs50.write(this.fd, this._writingBuf, release);
7642
+ fs51.write(this.fd, this._writingBuf, release);
7628
7643
  }
7629
7644
  }
7630
7645
  function actualWriteBuffer() {
@@ -7633,7 +7648,7 @@ var require_sonic_boom = __commonJS({
7633
7648
  this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
7634
7649
  if (this.sync) {
7635
7650
  try {
7636
- const written = fs50.writeSync(this.fd, this._writingBuf);
7651
+ const written = fs51.writeSync(this.fd, this._writingBuf);
7637
7652
  release(null, written);
7638
7653
  } catch (err) {
7639
7654
  release(err);
@@ -7642,7 +7657,7 @@ var require_sonic_boom = __commonJS({
7642
7657
  if (kCopyBuffer) {
7643
7658
  this._writingBuf = Buffer.from(this._writingBuf);
7644
7659
  }
7645
- fs50.write(this.fd, this._writingBuf, release);
7660
+ fs51.write(this.fd, this._writingBuf, release);
7646
7661
  }
7647
7662
  }
7648
7663
  function actualClose(sonic) {
@@ -7658,12 +7673,12 @@ var require_sonic_boom = __commonJS({
7658
7673
  sonic._lens = [];
7659
7674
  assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
7660
7675
  try {
7661
- fs50.fsync(sonic.fd, closeWrapped);
7676
+ fs51.fsync(sonic.fd, closeWrapped);
7662
7677
  } catch {
7663
7678
  }
7664
7679
  function closeWrapped() {
7665
7680
  if (sonic.fd !== 1 && sonic.fd !== 2) {
7666
- fs50.close(sonic.fd, done);
7681
+ fs51.close(sonic.fd, done);
7667
7682
  } else {
7668
7683
  done();
7669
7684
  }
@@ -8544,38 +8559,38 @@ var require_tools = __commonJS({
8544
8559
  }
8545
8560
  }
8546
8561
  }
8547
- function asString(str) {
8562
+ function asString(str4) {
8548
8563
  let result = "";
8549
8564
  let last = 0;
8550
8565
  let found = false;
8551
8566
  let point = 255;
8552
- const l = str.length;
8567
+ const l = str4.length;
8553
8568
  if (l > 100) {
8554
- return JSON.stringify(str);
8569
+ return JSON.stringify(str4);
8555
8570
  }
8556
8571
  for (var i = 0; i < l && point >= 32; i++) {
8557
- point = str.charCodeAt(i);
8572
+ point = str4.charCodeAt(i);
8558
8573
  if (point === 34 || point === 92) {
8559
- result += str.slice(last, i) + "\\";
8574
+ result += str4.slice(last, i) + "\\";
8560
8575
  last = i;
8561
8576
  found = true;
8562
8577
  }
8563
8578
  }
8564
8579
  if (!found) {
8565
- result = str;
8580
+ result = str4;
8566
8581
  } else {
8567
- result += str.slice(last);
8582
+ result += str4.slice(last);
8568
8583
  }
8569
- return point < 32 ? JSON.stringify(str) : '"' + result + '"';
8584
+ return point < 32 ? JSON.stringify(str4) : '"' + result + '"';
8570
8585
  }
8571
- function asJson(obj, msg, num, time) {
8586
+ function asJson(obj, msg, num3, time) {
8572
8587
  if (asJsonChan.hasSubscribers === false) {
8573
- return _asJson.call(this, obj, msg, num, time);
8588
+ return _asJson.call(this, obj, msg, num3, time);
8574
8589
  }
8575
8590
  const store = { instance: this, arguments };
8576
- return asJsonChan.traceSync(_asJson, store, this, obj, msg, num, time);
8591
+ return asJsonChan.traceSync(_asJson, store, this, obj, msg, num3, time);
8577
8592
  }
8578
- function _asJson(obj, msg, num, time) {
8593
+ function _asJson(obj, msg, num3, time) {
8579
8594
  const stringify2 = this[stringifySym];
8580
8595
  const stringifySafe = this[stringifySafeSym];
8581
8596
  const stringifiers = this[stringifiersSym];
@@ -8585,7 +8600,7 @@ var require_tools = __commonJS({
8585
8600
  const formatters = this[formattersSym];
8586
8601
  const messageKey = this[messageKeySym];
8587
8602
  const errorKey = this[errorKeySym];
8588
- let data = this[lsCacheSym][num] + time;
8603
+ let data = this[lsCacheSym][num3] + time;
8589
8604
  data = data + chindings;
8590
8605
  let value;
8591
8606
  if (formatters.log) {
@@ -9212,7 +9227,7 @@ var require_proto = __commonJS({
9212
9227
  function defaultMixinMergeStrategy(mergeObject, mixinObject) {
9213
9228
  return Object.assign(mixinObject, mergeObject);
9214
9229
  }
9215
- function write(_obj, msg, num) {
9230
+ function write(_obj, msg, num3) {
9216
9231
  const t = this[timeSym]();
9217
9232
  const mixin = this[mixinSym];
9218
9233
  const errorKey = this[errorKeySym];
@@ -9234,12 +9249,12 @@ var require_proto = __commonJS({
9234
9249
  }
9235
9250
  }
9236
9251
  if (mixin) {
9237
- obj = mixinMergeStrategy(obj, mixin(obj, num, this));
9252
+ obj = mixinMergeStrategy(obj, mixin(obj, num3, this));
9238
9253
  }
9239
- const s = this[asJsonSym](obj, msg, num, t);
9254
+ const s = this[asJsonSym](obj, msg, num3, t);
9240
9255
  const stream = this[streamSym];
9241
9256
  if (stream[needsMetadataGsym] === true) {
9242
- stream.lastLevel = num;
9257
+ stream.lastLevel = num3;
9243
9258
  stream.lastObj = obj;
9244
9259
  stream.lastMsg = msg;
9245
9260
  stream.lastTime = t.slice(this[timeSliceIndexSym]);
@@ -9272,11 +9287,11 @@ var require_safe_stable_stringify = __commonJS({
9272
9287
  exports2.configure = configure;
9273
9288
  module2.exports = stringify;
9274
9289
  var strEscapeSequencesRegExp = /[\u0000-\u001f\u0022\u005c\ud800-\udfff]/;
9275
- function strEscape(str) {
9276
- if (str.length < 5e3 && !strEscapeSequencesRegExp.test(str)) {
9277
- return `"${str}"`;
9290
+ function strEscape(str4) {
9291
+ if (str4.length < 5e3 && !strEscapeSequencesRegExp.test(str4)) {
9292
+ return `"${str4}"`;
9278
9293
  }
9279
- return JSON.stringify(str);
9294
+ return JSON.stringify(str4);
9280
9295
  }
9281
9296
  function sort(array, comparator) {
9282
9297
  if (array.length > 200 || comparator) {
@@ -10233,6 +10248,23 @@ var require_pino = __commonJS({
10233
10248
  }
10234
10249
  });
10235
10250
 
10251
+ // src/session/stdout-splitter.ts
10252
+ function splitStdoutChunk(buf, chunk) {
10253
+ let next = buf + (typeof chunk === "string" ? chunk : chunk.toString("utf8"));
10254
+ const lines = [];
10255
+ let idx;
10256
+ while ((idx = next.indexOf("\n")) >= 0) {
10257
+ lines.push(next.slice(0, idx));
10258
+ next = next.slice(idx + 1);
10259
+ }
10260
+ return { newBuf: next, lines };
10261
+ }
10262
+ var init_stdout_splitter = __esm({
10263
+ "src/session/stdout-splitter.ts"() {
10264
+ "use strict";
10265
+ }
10266
+ });
10267
+
10236
10268
  // src/session/permission-stdio.ts
10237
10269
  function encodePermissionResponse(requestId, approved, input, message) {
10238
10270
  const innerResponse = approved ? {
@@ -10255,23 +10287,6 @@ var init_permission_stdio = __esm({
10255
10287
  }
10256
10288
  });
10257
10289
 
10258
- // src/session/stdout-splitter.ts
10259
- function splitStdoutChunk(buf, chunk) {
10260
- let next = buf + (typeof chunk === "string" ? chunk : chunk.toString("utf8"));
10261
- const lines = [];
10262
- let idx;
10263
- while ((idx = next.indexOf("\n")) >= 0) {
10264
- lines.push(next.slice(0, idx));
10265
- next = next.slice(idx + 1);
10266
- }
10267
- return { newBuf: next, lines };
10268
- }
10269
- var init_stdout_splitter = __esm({
10270
- "src/session/stdout-splitter.ts"() {
10271
- "use strict";
10272
- }
10273
- });
10274
-
10275
10290
  // ../node_modules/.pnpm/diff@7.0.0/node_modules/diff/lib/index.mjs
10276
10291
  function Diff() {
10277
10292
  }
@@ -10310,22 +10325,22 @@ function buildValues(diff2, lastComponent, newString, oldString, useLongestToken
10310
10325
  }
10311
10326
  return components;
10312
10327
  }
10313
- function longestCommonPrefix(str1, str2) {
10328
+ function longestCommonPrefix(str1, str22) {
10314
10329
  var i;
10315
- for (i = 0; i < str1.length && i < str2.length; i++) {
10316
- if (str1[i] != str2[i]) {
10330
+ for (i = 0; i < str1.length && i < str22.length; i++) {
10331
+ if (str1[i] != str22[i]) {
10317
10332
  return str1.slice(0, i);
10318
10333
  }
10319
10334
  }
10320
10335
  return str1.slice(0, i);
10321
10336
  }
10322
- function longestCommonSuffix(str1, str2) {
10337
+ function longestCommonSuffix(str1, str22) {
10323
10338
  var i;
10324
- if (!str1 || !str2 || str1[str1.length - 1] != str2[str2.length - 1]) {
10339
+ if (!str1 || !str22 || str1[str1.length - 1] != str22[str22.length - 1]) {
10325
10340
  return "";
10326
10341
  }
10327
- for (i = 0; i < str1.length && i < str2.length; i++) {
10328
- if (str1[str1.length - (i + 1)] != str2[str2.length - (i + 1)]) {
10342
+ for (i = 0; i < str1.length && i < str22.length; i++) {
10343
+ if (str1[str1.length - (i + 1)] != str22[str22.length - (i + 1)]) {
10329
10344
  return str1.slice(-i);
10330
10345
  }
10331
10346
  }
@@ -11257,12 +11272,12 @@ function attachmentToHistoryMessage(o, ts) {
11257
11272
  const raw = Array.isArray(a.memories) ? a.memories : [];
11258
11273
  const memories = raw.map((m2) => {
11259
11274
  if (!m2 || typeof m2 !== "object") return null;
11260
- const rec = m2;
11261
- const path59 = typeof rec.path === "string" ? rec.path : null;
11262
- const content = typeof rec.content === "string" ? rec.content : null;
11275
+ const rec3 = m2;
11276
+ const path59 = typeof rec3.path === "string" ? rec3.path : null;
11277
+ const content = typeof rec3.content === "string" ? rec3.content : null;
11263
11278
  if (!path59 || content == null) return null;
11264
11279
  const entry = { path: path59, content };
11265
- if (typeof rec.mtimeMs === "number") entry.mtimeMs = rec.mtimeMs;
11280
+ if (typeof rec3.mtimeMs === "number") entry.mtimeMs = rec3.mtimeMs;
11266
11281
  return entry;
11267
11282
  }).filter((m2) => m2 !== null);
11268
11283
  if (memories.length === 0) return null;
@@ -12072,12 +12087,12 @@ function parseAttachment(obj) {
12072
12087
  const raw = Array.isArray(a.memories) ? a.memories : [];
12073
12088
  const memories = raw.map((m2) => {
12074
12089
  if (!m2 || typeof m2 !== "object") return null;
12075
- const rec = m2;
12076
- const path59 = typeof rec.path === "string" ? rec.path : null;
12077
- const content = typeof rec.content === "string" ? rec.content : null;
12090
+ const rec3 = m2;
12091
+ const path59 = typeof rec3.path === "string" ? rec3.path : null;
12092
+ const content = typeof rec3.content === "string" ? rec3.content : null;
12078
12093
  if (!path59 || content == null) return null;
12079
12094
  const out = { path: path59, content };
12080
- if (typeof rec.mtimeMs === "number") out.mtimeMs = rec.mtimeMs;
12095
+ if (typeof rec3.mtimeMs === "number") out.mtimeMs = rec3.mtimeMs;
12081
12096
  return out;
12082
12097
  }).filter((m2) => m2 !== null);
12083
12098
  if (memories.length === 0) return null;
@@ -12224,6 +12239,7 @@ var init_claude = __esm({
12224
12239
  toolSessionIdLabel: "Claude Session ID",
12225
12240
  models: CLAUDE_MODELS,
12226
12241
  permissionModes: CLAUDE_PERMISSION_MODES,
12242
+ features: { rewind: true, subagents: true, tui: true, observe: true, fileSharing: true, fork: true },
12227
12243
  configSchema: [
12228
12244
  {
12229
12245
  name: "model",
@@ -17712,26 +17728,26 @@ var require_permessage_deflate = __commonJS({
17712
17728
  value = value[0];
17713
17729
  if (key === "client_max_window_bits") {
17714
17730
  if (value !== true) {
17715
- const num = +value;
17716
- if (!Number.isInteger(num) || num < 8 || num > 15) {
17731
+ const num3 = +value;
17732
+ if (!Number.isInteger(num3) || num3 < 8 || num3 > 15) {
17717
17733
  throw new TypeError(
17718
17734
  `Invalid value for parameter "${key}": ${value}`
17719
17735
  );
17720
17736
  }
17721
- value = num;
17737
+ value = num3;
17722
17738
  } else if (!this._isServer) {
17723
17739
  throw new TypeError(
17724
17740
  `Invalid value for parameter "${key}": ${value}`
17725
17741
  );
17726
17742
  }
17727
17743
  } else if (key === "server_max_window_bits") {
17728
- const num = +value;
17729
- if (!Number.isInteger(num) || num < 8 || num > 15) {
17744
+ const num3 = +value;
17745
+ if (!Number.isInteger(num3) || num3 < 8 || num3 > 15) {
17730
17746
  throw new TypeError(
17731
17747
  `Invalid value for parameter "${key}": ${value}`
17732
17748
  );
17733
17749
  }
17734
- value = num;
17750
+ value = num3;
17735
17751
  } else if (key === "client_no_context_takeover" || key === "server_no_context_takeover") {
17736
17752
  if (value !== true) {
17737
17753
  throw new TypeError(
@@ -18426,8 +18442,8 @@ var require_receiver = __commonJS({
18426
18442
  return;
18427
18443
  }
18428
18444
  const buf = this.consume(8);
18429
- const num = buf.readUInt32BE(0);
18430
- if (num > Math.pow(2, 53 - 32) - 1) {
18445
+ const num3 = buf.readUInt32BE(0);
18446
+ if (num3 > Math.pow(2, 53 - 32) - 1) {
18431
18447
  const error = this.createError(
18432
18448
  RangeError,
18433
18449
  "Unsupported WebSocket frame: payload length > 2^53 - 1",
@@ -18438,7 +18454,7 @@ var require_receiver = __commonJS({
18438
18454
  cb(error);
18439
18455
  return;
18440
18456
  }
18441
- this._payloadLength = num * Math.pow(2, 32) + buf.readUInt32BE(4);
18457
+ this._payloadLength = num3 * Math.pow(2, 32) + buf.readUInt32BE(4);
18442
18458
  this.haveLength(cb);
18443
18459
  }
18444
18460
  /**
@@ -22752,19 +22768,19 @@ var require_stream_readable = __commonJS({
22752
22768
  var ret = p2.data;
22753
22769
  n -= ret.length;
22754
22770
  while (p2 = p2.next) {
22755
- var str = p2.data;
22756
- var nb = n > str.length ? str.length : n;
22757
- if (nb === str.length) ret += str;
22758
- else ret += str.slice(0, n);
22771
+ var str4 = p2.data;
22772
+ var nb = n > str4.length ? str4.length : n;
22773
+ if (nb === str4.length) ret += str4;
22774
+ else ret += str4.slice(0, n);
22759
22775
  n -= nb;
22760
22776
  if (n === 0) {
22761
- if (nb === str.length) {
22777
+ if (nb === str4.length) {
22762
22778
  ++c;
22763
22779
  if (p2.next) list.head = p2.next;
22764
22780
  else list.head = list.tail = null;
22765
22781
  } else {
22766
22782
  list.head = p2;
22767
- p2.data = str.slice(nb);
22783
+ p2.data = str4.slice(nb);
22768
22784
  }
22769
22785
  break;
22770
22786
  }
@@ -23660,14 +23676,14 @@ var require_utils = __commonJS({
23660
23676
  var nodejsUtils = require_nodejsUtils();
23661
23677
  var external = require_external();
23662
23678
  require_setImmediate();
23663
- function string2binary(str) {
23679
+ function string2binary(str4) {
23664
23680
  var result = null;
23665
23681
  if (support.uint8array) {
23666
- result = new Uint8Array(str.length);
23682
+ result = new Uint8Array(str4.length);
23667
23683
  } else {
23668
- result = new Array(str.length);
23684
+ result = new Array(str4.length);
23669
23685
  }
23670
- return stringToArrayLike(str, result);
23686
+ return stringToArrayLike(str4, result);
23671
23687
  }
23672
23688
  exports2.newBlob = function(part, type) {
23673
23689
  exports2.checkSupport("blob");
@@ -23689,9 +23705,9 @@ var require_utils = __commonJS({
23689
23705
  function identity(input) {
23690
23706
  return input;
23691
23707
  }
23692
- function stringToArrayLike(str, array) {
23693
- for (var i = 0; i < str.length; ++i) {
23694
- array[i] = str.charCodeAt(i) & 255;
23708
+ function stringToArrayLike(str4, array) {
23709
+ for (var i = 0; i < str4.length; ++i) {
23710
+ array[i] = str4.charCodeAt(i) & 255;
23695
23711
  }
23696
23712
  return array;
23697
23713
  }
@@ -23904,10 +23920,10 @@ var require_utils = __commonJS({
23904
23920
  };
23905
23921
  exports2.MAX_VALUE_16BITS = 65535;
23906
23922
  exports2.MAX_VALUE_32BITS = -1;
23907
- exports2.pretty = function(str) {
23923
+ exports2.pretty = function(str4) {
23908
23924
  var res = "", code, i;
23909
- for (i = 0; i < (str || "").length; i++) {
23910
- code = str.charCodeAt(i);
23925
+ for (i = 0; i < (str4 || "").length; i++) {
23926
+ code = str4.charCodeAt(i);
23911
23927
  res += "\\x" + (code < 16 ? "0" : "") + code.toString(16).toUpperCase();
23912
23928
  }
23913
23929
  return res;
@@ -24217,12 +24233,12 @@ var require_utf8 = __commonJS({
24217
24233
  }
24218
24234
  var i;
24219
24235
  _utf8len[254] = _utf8len[254] = 1;
24220
- var string2buf = function(str) {
24221
- var buf, c, c2, m_pos, i2, str_len = str.length, buf_len = 0;
24236
+ var string2buf = function(str4) {
24237
+ var buf, c, c2, m_pos, i2, str_len = str4.length, buf_len = 0;
24222
24238
  for (m_pos = 0; m_pos < str_len; m_pos++) {
24223
- c = str.charCodeAt(m_pos);
24239
+ c = str4.charCodeAt(m_pos);
24224
24240
  if ((c & 64512) === 55296 && m_pos + 1 < str_len) {
24225
- c2 = str.charCodeAt(m_pos + 1);
24241
+ c2 = str4.charCodeAt(m_pos + 1);
24226
24242
  if ((c2 & 64512) === 56320) {
24227
24243
  c = 65536 + (c - 55296 << 10) + (c2 - 56320);
24228
24244
  m_pos++;
@@ -24236,9 +24252,9 @@ var require_utf8 = __commonJS({
24236
24252
  buf = new Array(buf_len);
24237
24253
  }
24238
24254
  for (i2 = 0, m_pos = 0; i2 < buf_len; m_pos++) {
24239
- c = str.charCodeAt(m_pos);
24255
+ c = str4.charCodeAt(m_pos);
24240
24256
  if ((c & 64512) === 55296 && m_pos + 1 < str_len) {
24241
- c2 = str.charCodeAt(m_pos + 1);
24257
+ c2 = str4.charCodeAt(m_pos + 1);
24242
24258
  if ((c2 & 64512) === 56320) {
24243
24259
  c = 65536 + (c - 55296 << 10) + (c2 - 56320);
24244
24260
  m_pos++;
@@ -24322,11 +24338,11 @@ var require_utf8 = __commonJS({
24322
24338
  }
24323
24339
  return utils.applyFromCharCode(utf16buf);
24324
24340
  };
24325
- exports2.utf8encode = function utf8encode(str) {
24341
+ exports2.utf8encode = function utf8encode(str4) {
24326
24342
  if (support.nodebuffer) {
24327
- return nodejsUtils.newBufferFrom(str, "utf-8");
24343
+ return nodejsUtils.newBufferFrom(str4, "utf-8");
24328
24344
  }
24329
- return string2buf(str);
24345
+ return string2buf(str4);
24330
24346
  };
24331
24347
  exports2.utf8decode = function utf8decode(buf) {
24332
24348
  if (support.nodebuffer) {
@@ -24735,11 +24751,11 @@ var require_crc32 = __commonJS({
24735
24751
  }
24736
24752
  return crc ^ -1;
24737
24753
  }
24738
- function crc32str(crc, str, len, pos) {
24754
+ function crc32str(crc, str4, len, pos) {
24739
24755
  var t = crcTable, end = pos + len;
24740
24756
  crc = crc ^ -1;
24741
24757
  for (var i = pos; i < end; i++) {
24742
- crc = crc >>> 8 ^ t[(crc ^ str.charCodeAt(i)) & 255];
24758
+ crc = crc >>> 8 ^ t[(crc ^ str4.charCodeAt(i)) & 255];
24743
24759
  }
24744
24760
  return crc ^ -1;
24745
24761
  }
@@ -25936,7 +25952,7 @@ var require_deflate = __commonJS({
25936
25952
  }
25937
25953
  function fill_window(s) {
25938
25954
  var _w_size = s.w_size;
25939
- var p2, n, m2, more, str;
25955
+ var p2, n, m2, more, str4;
25940
25956
  do {
25941
25957
  more = s.window_size - s.lookahead - s.strstart;
25942
25958
  if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) {
@@ -25964,14 +25980,14 @@ var require_deflate = __commonJS({
25964
25980
  n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more);
25965
25981
  s.lookahead += n;
25966
25982
  if (s.lookahead + s.insert >= MIN_MATCH) {
25967
- str = s.strstart - s.insert;
25968
- s.ins_h = s.window[str];
25969
- s.ins_h = (s.ins_h << s.hash_shift ^ s.window[str + 1]) & s.hash_mask;
25983
+ str4 = s.strstart - s.insert;
25984
+ s.ins_h = s.window[str4];
25985
+ s.ins_h = (s.ins_h << s.hash_shift ^ s.window[str4 + 1]) & s.hash_mask;
25970
25986
  while (s.insert) {
25971
- s.ins_h = (s.ins_h << s.hash_shift ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask;
25972
- s.prev[str & s.w_mask] = s.head[s.ins_h];
25973
- s.head[s.ins_h] = str;
25974
- str++;
25987
+ s.ins_h = (s.ins_h << s.hash_shift ^ s.window[str4 + MIN_MATCH - 1]) & s.hash_mask;
25988
+ s.prev[str4 & s.w_mask] = s.head[s.ins_h];
25989
+ s.head[s.ins_h] = str4;
25990
+ str4++;
25975
25991
  s.insert--;
25976
25992
  if (s.lookahead + s.insert < MIN_MATCH) {
25977
25993
  break;
@@ -26747,7 +26763,7 @@ var require_deflate = __commonJS({
26747
26763
  function deflateSetDictionary(strm, dictionary) {
26748
26764
  var dictLength = dictionary.length;
26749
26765
  var s;
26750
- var str, n;
26766
+ var str4, n;
26751
26767
  var wrap2;
26752
26768
  var avail;
26753
26769
  var next;
@@ -26785,15 +26801,15 @@ var require_deflate = __commonJS({
26785
26801
  strm.input = dictionary;
26786
26802
  fill_window(s);
26787
26803
  while (s.lookahead >= MIN_MATCH) {
26788
- str = s.strstart;
26804
+ str4 = s.strstart;
26789
26805
  n = s.lookahead - (MIN_MATCH - 1);
26790
26806
  do {
26791
- s.ins_h = (s.ins_h << s.hash_shift ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask;
26792
- s.prev[str & s.w_mask] = s.head[s.ins_h];
26793
- s.head[s.ins_h] = str;
26794
- str++;
26807
+ s.ins_h = (s.ins_h << s.hash_shift ^ s.window[str4 + MIN_MATCH - 1]) & s.hash_mask;
26808
+ s.prev[str4 & s.w_mask] = s.head[s.ins_h];
26809
+ s.head[s.ins_h] = str4;
26810
+ str4++;
26795
26811
  } while (--n);
26796
- s.strstart = str;
26812
+ s.strstart = str4;
26797
26813
  s.lookahead = MIN_MATCH - 1;
26798
26814
  fill_window(s);
26799
26815
  }
@@ -26844,12 +26860,12 @@ var require_strings = __commonJS({
26844
26860
  }
26845
26861
  var q;
26846
26862
  _utf8len[254] = _utf8len[254] = 1;
26847
- exports2.string2buf = function(str) {
26848
- var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0;
26863
+ exports2.string2buf = function(str4) {
26864
+ var buf, c, c2, m_pos, i, str_len = str4.length, buf_len = 0;
26849
26865
  for (m_pos = 0; m_pos < str_len; m_pos++) {
26850
- c = str.charCodeAt(m_pos);
26866
+ c = str4.charCodeAt(m_pos);
26851
26867
  if ((c & 64512) === 55296 && m_pos + 1 < str_len) {
26852
- c2 = str.charCodeAt(m_pos + 1);
26868
+ c2 = str4.charCodeAt(m_pos + 1);
26853
26869
  if ((c2 & 64512) === 56320) {
26854
26870
  c = 65536 + (c - 55296 << 10) + (c2 - 56320);
26855
26871
  m_pos++;
@@ -26859,9 +26875,9 @@ var require_strings = __commonJS({
26859
26875
  }
26860
26876
  buf = new utils.Buf8(buf_len);
26861
26877
  for (i = 0, m_pos = 0; i < buf_len; m_pos++) {
26862
- c = str.charCodeAt(m_pos);
26878
+ c = str4.charCodeAt(m_pos);
26863
26879
  if ((c & 64512) === 55296 && m_pos + 1 < str_len) {
26864
- c2 = str.charCodeAt(m_pos + 1);
26880
+ c2 = str4.charCodeAt(m_pos + 1);
26865
26881
  if ((c2 & 64512) === 56320) {
26866
26882
  c = 65536 + (c - 55296 << 10) + (c2 - 56320);
26867
26883
  m_pos++;
@@ -26900,10 +26916,10 @@ var require_strings = __commonJS({
26900
26916
  exports2.buf2binstring = function(buf) {
26901
26917
  return buf2binstring(buf, buf.length);
26902
26918
  };
26903
- exports2.binstring2buf = function(str) {
26904
- var buf = new utils.Buf8(str.length);
26919
+ exports2.binstring2buf = function(str4) {
26920
+ var buf = new utils.Buf8(str4.length);
26905
26921
  for (var i = 0, len = buf.length; i < len; i++) {
26906
- buf[i] = str.charCodeAt(i);
26922
+ buf[i] = str4.charCodeAt(i);
26907
26923
  }
26908
26924
  return buf;
26909
26925
  };
@@ -30745,8 +30761,8 @@ function startRunCaseRecorder(opts) {
30745
30761
  });
30746
30762
  const ensureStream = () => {
30747
30763
  if (stream) return stream;
30748
- import_node_fs33.default.mkdirSync(dir, { recursive: true });
30749
- stream = import_node_fs33.default.createWriteStream(opts.recordPath, { flags: "a" });
30764
+ import_node_fs34.default.mkdirSync(dir, { recursive: true });
30765
+ stream = import_node_fs34.default.createWriteStream(opts.recordPath, { flags: "a" });
30750
30766
  stream.on("close", () => closedResolve());
30751
30767
  return stream;
30752
30768
  };
@@ -30771,11 +30787,11 @@ function startRunCaseRecorder(opts) {
30771
30787
  };
30772
30788
  return { tap, close, closed };
30773
30789
  }
30774
- var import_node_fs33, import_node_path47;
30790
+ var import_node_fs34, import_node_path47;
30775
30791
  var init_recorder = __esm({
30776
30792
  "src/run-case/recorder.ts"() {
30777
30793
  "use strict";
30778
- import_node_fs33 = __toESM(require("fs"), 1);
30794
+ import_node_fs34 = __toESM(require("fs"), 1);
30779
30795
  import_node_path47 = __toESM(require("path"), 1);
30780
30796
  }
30781
30797
  });
@@ -30819,7 +30835,7 @@ var init_wire = __esm({
30819
30835
  // src/run-case/controller.ts
30820
30836
  async function runController(opts) {
30821
30837
  const now = opts.now ?? Date.now;
30822
- const cwd = opts.cwd ?? (0, import_node_fs34.mkdtempSync)(import_node_path48.default.join(import_node_os19.default.tmpdir(), "clawd-runcase-"));
30838
+ const cwd = opts.cwd ?? (0, import_node_fs35.mkdtempSync)(import_node_path48.default.join(import_node_os19.default.tmpdir(), "clawd-runcase-"));
30823
30839
  const ownsCwd = opts.cwd === void 0;
30824
30840
  const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
30825
30841
  const spawnCtx = { cwd };
@@ -30980,17 +30996,17 @@ async function runController(opts) {
30980
30996
  if (sigintHandler) process.off("SIGINT", sigintHandler);
30981
30997
  if (ownsCwd) {
30982
30998
  try {
30983
- (0, import_node_fs34.rmSync)(cwd, { recursive: true, force: true });
30999
+ (0, import_node_fs35.rmSync)(cwd, { recursive: true, force: true });
30984
31000
  } catch {
30985
31001
  }
30986
31002
  }
30987
31003
  return exitCode ?? 0;
30988
31004
  }
30989
- var import_node_fs34, import_node_os19, import_node_path48;
31005
+ var import_node_fs35, import_node_os19, import_node_path48;
30990
31006
  var init_controller = __esm({
30991
31007
  "src/run-case/controller.ts"() {
30992
31008
  "use strict";
30993
- import_node_fs34 = require("fs");
31009
+ import_node_fs35 = require("fs");
30994
31010
  import_node_os19 = __toESM(require("os"), 1);
30995
31011
  import_node_path48 = __toESM(require("path"), 1);
30996
31012
  init_claude();
@@ -31228,7 +31244,7 @@ Env (advanced):
31228
31244
 
31229
31245
  // src/index.ts
31230
31246
  var import_node_path46 = __toESM(require("path"), 1);
31231
- var import_node_fs32 = __toESM(require("fs"), 1);
31247
+ var import_node_fs33 = __toESM(require("fs"), 1);
31232
31248
 
31233
31249
  // src/logger.ts
31234
31250
  var import_node_fs2 = __toESM(require("fs"), 1);
@@ -31625,9 +31641,6 @@ function buildRule(tool, input) {
31625
31641
  return { tool, pattern, createdAt: (/* @__PURE__ */ new Date()).toISOString() };
31626
31642
  }
31627
31643
 
31628
- // src/session/reducer.ts
31629
- init_permission_stdio();
31630
-
31631
31644
  // src/persona/connection-prompt.ts
31632
31645
  var OWNER_TEMPLATE = `# \u8FDE\u63A5\u4E0A\u4E0B\u6587
31633
31646
  \u4F60\u73B0\u5728\u4EE5 Owner \u8EAB\u4EFD\u88AB\u8FDE\u63A5\uFF0C\u5BF9\u65B9\u5C31\u662F owner \u672C\u4EBA\uFF08{ownerLabel}\uFF09\u3002
@@ -31814,10 +31827,7 @@ function applyParsedEvent(state, event, deps) {
31814
31827
  effects.push(...pushed2.effects);
31815
31828
  const hit = matchesAnyRule(next.file.permissionRules, tool, input);
31816
31829
  if (hit) {
31817
- effects.push({
31818
- kind: "write-stdin",
31819
- payload: encodePermissionResponse(requestId, true, input)
31820
- });
31830
+ effects.push({ kind: "respond-permission", requestId, allow: true, input });
31821
31831
  } else {
31822
31832
  const pending = {
31823
31833
  tool,
@@ -32210,13 +32220,11 @@ function reduceSession(state, input, deps) {
32210
32220
  next.pendingPermissions = nextPending;
32211
32221
  const effects = [
32212
32222
  {
32213
- kind: "write-stdin",
32214
- payload: encodePermissionResponse(
32215
- input.requestId,
32216
- input.allow,
32217
- pending.input,
32218
- input.message
32219
- )
32223
+ kind: "respond-permission",
32224
+ requestId: input.requestId,
32225
+ allow: input.allow,
32226
+ input: pending.input,
32227
+ message: input.message
32220
32228
  }
32221
32229
  ];
32222
32230
  if (input.allow && input.permanent) {
@@ -32356,6 +32364,7 @@ function reduceSession(state, input, deps) {
32356
32364
 
32357
32365
  // src/session/runner.ts
32358
32366
  init_stdout_splitter();
32367
+ init_permission_stdio();
32359
32368
 
32360
32369
  // src/ipc-recorder.ts
32361
32370
  var import_node_fs4 = __toESM(require("fs"), 1);
@@ -32463,6 +32472,9 @@ var SessionRunner = class {
32463
32472
  hooks;
32464
32473
  state;
32465
32474
  proc = null;
32475
+ // JSON-RPC 类 agent(codex app-server) 的 per-session 驱动器;非 null 时 runner 不用 spawn()/ChildProcess,
32476
+ // effect 路由到 session 一等方法(startTurn/respondPermission/answerQuestion/interrupt/stop)。claude 恒 null。
32477
+ session = null;
32466
32478
  stdoutBuf = "";
32467
32479
  // 未决 control_request 表;key = request_id
32468
32480
  pendingControlRequests = /* @__PURE__ */ new Map();
@@ -32571,6 +32583,15 @@ var SessionRunner = class {
32571
32583
  if (this.hooks.onFileEdit) this.observeForFileEdit(events);
32572
32584
  this.input({ kind: "inject-events", events });
32573
32585
  }
32586
+ // session:interrupt 的 SDK 通道分流:codex → AgentSession.interrupt();claude → control_request('interrupt')。
32587
+ // TUI(pty) 路径在 manager.dispatchInterrupt 里先于此处理,不进这里。
32588
+ async interrupt() {
32589
+ if (this.session) {
32590
+ this.session.interrupt();
32591
+ return;
32592
+ }
32593
+ await this.sendControlRequest("interrupt");
32594
+ }
32574
32595
  /**
32575
32596
  * file-sharing tool_use ↔ tool_result 配对(spec §6 PR 3)。
32576
32597
  *
@@ -32695,9 +32716,17 @@ var SessionRunner = class {
32695
32716
  this.doSpawn(effect.ctx);
32696
32717
  break;
32697
32718
  case "kill":
32719
+ if (this.session) {
32720
+ void this.session.stop(effect.signal);
32721
+ break;
32722
+ }
32698
32723
  this.doKill(effect.signal);
32699
32724
  break;
32700
32725
  case "write-stdin":
32726
+ if (this.session) {
32727
+ this.session.startTurn(effect.payload);
32728
+ break;
32729
+ }
32701
32730
  this.hooks.logger?.debug("[RG] write-stdin", {
32702
32731
  procAlive: !!this.proc,
32703
32732
  stdinWritable: !!this.proc?.stdin,
@@ -32707,6 +32736,16 @@ var SessionRunner = class {
32707
32736
  this.proc?.stdin?.write(effect.payload);
32708
32737
  this.recorder?.tapStdinWrite(effect.payload);
32709
32738
  break;
32739
+ case "respond-permission": {
32740
+ if (this.session) {
32741
+ this.session.respondPermission(effect.requestId, effect.allow);
32742
+ break;
32743
+ }
32744
+ const payload = encodePermissionResponse(effect.requestId, effect.allow, effect.input, effect.message);
32745
+ this.proc?.stdin?.write(payload);
32746
+ this.recorder?.tapStdinWrite(payload);
32747
+ break;
32748
+ }
32710
32749
  case "send-control-response-allow-with-input": {
32711
32750
  const payload = encodeAllowWithInputControlResponse(effect.requestId, effect.updatedInput);
32712
32751
  this.proc?.stdin?.write(payload);
@@ -32764,6 +32803,22 @@ var SessionRunner = class {
32764
32803
  }
32765
32804
  // 启动子进程,绑定 stdout line buffer → 回灌 reducer
32766
32805
  doSpawn(ctx) {
32806
+ if (this.hooks.adapter.createSession) {
32807
+ this.session = this.hooks.adapter.createSession(ctx, {
32808
+ pushEvents: (events) => {
32809
+ if (events.length === 0) return;
32810
+ const uuid = (this.hooks.genUuid ?? v4_default)();
32811
+ this.input({ kind: "inject-events", events: events.map((e) => e.uuid ? e : { ...e, uuid }) });
32812
+ },
32813
+ onExit: (code) => {
32814
+ this.session = null;
32815
+ this.clearIdleKillTimers();
32816
+ this.input({ kind: "proc-exit", code });
32817
+ },
32818
+ onError: (message) => this.input({ kind: "proc-error", message })
32819
+ });
32820
+ return;
32821
+ }
32767
32822
  const proc = this.hooks.spawnOverride ? this.hooks.spawnOverride(ctx) : this.hooks.adapter.spawn(ctx);
32768
32823
  this.proc = proc;
32769
32824
  this.stdoutBuf = "";
@@ -33634,7 +33689,7 @@ var SessionManager = class {
33634
33689
  tsid,
33635
33690
  mode: this.deps.mode
33636
33691
  });
33637
- await runner.sendControlRequest("interrupt");
33692
+ await runner.interrupt();
33638
33693
  }
33639
33694
  // 批量版本:UI 打开 session 时一次性拿到"磁盘和快照有差异"的 user message id 集合,
33640
33695
  // 用来在消息流里精准控制 rewind 按钮的显示。session 没 toolSessionId 时返回空
@@ -34192,17 +34247,17 @@ var SessionManager = class {
34192
34247
  if (!runner) {
34193
34248
  throw new ClawdError(
34194
34249
  ERROR_CODES.PERMISSION_REQUEST_STALE,
34195
- `no pending permission request: ${args.requestId}`
34250
+ `no pending permission request: ${args.permissionRequestId}`
34196
34251
  );
34197
34252
  }
34198
- const pending = runner.getState().pendingPermissions[args.requestId];
34253
+ const pending = runner.getState().pendingPermissions[args.permissionRequestId];
34199
34254
  if (!pending) {
34200
34255
  return { response: { ok: true }, broadcast: [] };
34201
34256
  }
34202
34257
  const { broadcast } = this.withCollector(() => {
34203
34258
  runner.input({
34204
34259
  kind: "permission-decision",
34205
- requestId: args.requestId,
34260
+ requestId: args.permissionRequestId,
34206
34261
  allow: args.allow,
34207
34262
  permanent: args.permanent,
34208
34263
  pattern: args.pattern,
@@ -35154,8 +35209,445 @@ function refreshDaemonManagedDirs(args) {
35154
35209
  // src/index.ts
35155
35210
  init_claude();
35156
35211
 
35157
- // src/tools/claude-tui.ts
35212
+ // src/tools/codex.ts
35213
+ var import_node_child_process4 = require("child_process");
35158
35214
  var import_node_fs10 = __toESM(require("fs"), 1);
35215
+
35216
+ // src/tools/codex-session.ts
35217
+ var import_node_child_process3 = require("child_process");
35218
+
35219
+ // src/tools/codex-app-server-client.ts
35220
+ var import_node_readline = require("readline");
35221
+ var CodexAppServerClient = class {
35222
+ constructor(proc, opts = {}) {
35223
+ this.proc = proc;
35224
+ this.opts = opts;
35225
+ const rl = (0, import_node_readline.createInterface)({ input: proc.stdout, crlfDelay: Infinity });
35226
+ rl.on("line", (l) => this.onLine(l));
35227
+ rl.on("close", () => {
35228
+ for (const p2 of this.pending.values()) p2.reject(new Error("app-server connection closed"));
35229
+ this.pending.clear();
35230
+ this.opts.onClose?.();
35231
+ });
35232
+ }
35233
+ proc;
35234
+ opts;
35235
+ nextId = 1;
35236
+ pending = /* @__PURE__ */ new Map();
35237
+ request(method, params) {
35238
+ const id = this.nextId++;
35239
+ return new Promise((resolve6, reject) => {
35240
+ this.pending.set(id, { resolve: resolve6, reject });
35241
+ this.write({ jsonrpc: "2.0", method, id, params });
35242
+ });
35243
+ }
35244
+ notify(method, params) {
35245
+ this.write({ jsonrpc: "2.0", method, params });
35246
+ }
35247
+ // server-request 的响应也必须带 jsonrpc:'2.0',否则 codex app-server 忽略它 → 审批/问答永远卡住。
35248
+ respond(id, result) {
35249
+ this.write({ jsonrpc: "2.0", id, result });
35250
+ }
35251
+ onLine(line) {
35252
+ const t = line.trim();
35253
+ if (!t) return;
35254
+ let m2;
35255
+ try {
35256
+ m2 = JSON.parse(t);
35257
+ } catch {
35258
+ return;
35259
+ }
35260
+ if (!isRecord(m2)) return;
35261
+ const hasId = typeof m2.id === "number", hasMethod = typeof m2.method === "string";
35262
+ if (hasId && !hasMethod) {
35263
+ const p2 = this.pending.get(m2.id);
35264
+ if (!p2) return;
35265
+ this.pending.delete(m2.id);
35266
+ if (m2.error) {
35267
+ const e = isRecord(m2.error) ? m2.error : {};
35268
+ p2.reject(new Error(typeof e.message === "string" ? e.message : "app-server error"));
35269
+ } else p2.resolve(m2.result);
35270
+ return;
35271
+ }
35272
+ if (hasId && hasMethod) {
35273
+ this.opts.onServerRequest?.(m2.id, m2.method, m2.params);
35274
+ return;
35275
+ }
35276
+ if (hasMethod) this.opts.onNotification?.(m2.method, m2.params);
35277
+ }
35278
+ write(o) {
35279
+ this.proc.stdin.write(JSON.stringify(o) + "\n");
35280
+ }
35281
+ };
35282
+ function isRecord(v2) {
35283
+ return typeof v2 === "object" && v2 !== null;
35284
+ }
35285
+
35286
+ // src/tools/codex-app-server-events.ts
35287
+ function translateNotification(method, params) {
35288
+ const p2 = rec(params);
35289
+ switch (method) {
35290
+ case "thread/started": {
35291
+ const id = str(rec(p2?.thread)?.id);
35292
+ return id ? [{ kind: "session_init", toolSessionId: id }] : [];
35293
+ }
35294
+ case "item/agentMessage/delta": {
35295
+ const text = str(p2?.delta);
35296
+ const id = str(p2?.itemId);
35297
+ return text ? [{ kind: "text", text, ...id ? { partialId: id } : {} }] : [];
35298
+ }
35299
+ case "item/reasoning/textDelta":
35300
+ case "item/reasoning/summaryTextDelta": {
35301
+ const text = str(p2?.delta);
35302
+ const id = str(p2?.itemId);
35303
+ return text ? [{ kind: "thinking", text, ...id ? { partialId: id } : {} }] : [];
35304
+ }
35305
+ case "item/commandExecution/outputDelta":
35306
+ return [];
35307
+ // 命令输出增量 v1 不逐字(完成时整段给)
35308
+ case "item/started":
35309
+ return itemStarted(rec(p2?.item));
35310
+ case "item/completed":
35311
+ return itemCompleted(rec(p2?.item));
35312
+ case "thread/tokenUsage/updated":
35313
+ return tokenUsage(rec(rec(p2?.tokenUsage)));
35314
+ case "turn/completed":
35315
+ return turnCompleted(rec(p2?.turn));
35316
+ default:
35317
+ return [];
35318
+ }
35319
+ }
35320
+ function itemStarted(item) {
35321
+ if (!item) return [];
35322
+ const id = str(item.id);
35323
+ if (!id) return [];
35324
+ if (item.type === "commandExecution") {
35325
+ return [{ kind: "tool_call", toolUseId: id, tool: "commandExecution", toolKind: "codex", input: { command: str(item.command) ?? "" } }];
35326
+ }
35327
+ if (item.type === "fileChange") {
35328
+ return [{ kind: "tool_call", toolUseId: id, tool: "fileChange", toolKind: "codex", input: { changes: Array.isArray(item.changes) ? item.changes : [] } }];
35329
+ }
35330
+ return [];
35331
+ }
35332
+ function itemCompleted(item) {
35333
+ if (!item) return [];
35334
+ switch (item.type) {
35335
+ case "userMessage":
35336
+ return [];
35337
+ // 用户输入回显, clawd 自己 synthesize user_text
35338
+ case "agentMessage": {
35339
+ const text = str(item.text);
35340
+ return text ? [{ kind: "text", text }] : [];
35341
+ }
35342
+ case "reasoning": {
35343
+ const text = str(item.text);
35344
+ return text ? [{ kind: "thinking", text }] : [];
35345
+ }
35346
+ case "commandExecution": {
35347
+ const id = str(item.id);
35348
+ if (!id) return [];
35349
+ const exit = num(item.exitCode);
35350
+ const ev = { kind: "tool_result", toolUseId: id, output: str(item.aggregatedOutput ?? item.output) ?? "" };
35351
+ if (exit !== void 0 && exit !== 0) ev.error = `exit ${exit}`;
35352
+ return [ev];
35353
+ }
35354
+ case "fileChange": {
35355
+ const id = str(item.id);
35356
+ if (!id) return [];
35357
+ const changes = Array.isArray(item.changes) ? item.changes : [];
35358
+ const output = changes.map((c) => str(c.diff) ?? "").filter(Boolean).join("\n");
35359
+ const ev = { kind: "tool_result", toolUseId: id, output };
35360
+ const status = str(item.status);
35361
+ if (status === "failed" || status === "declined") ev.error = `patch ${status}`;
35362
+ return [ev];
35363
+ }
35364
+ default:
35365
+ return [];
35366
+ }
35367
+ }
35368
+ function tokenUsage(usage) {
35369
+ if (!usage) return [];
35370
+ const last = rec(usage.last);
35371
+ if (!last) return [];
35372
+ const i = num(last.inputTokens), o = num(last.outputTokens);
35373
+ const patch = {};
35374
+ if (i !== void 0 && o !== void 0) patch.contextUsage = { inputTokens: i, outputTokens: o };
35375
+ const w2 = num(usage.modelContextWindow);
35376
+ if (w2 !== void 0) patch.contextWindowSize = w2;
35377
+ return Object.keys(patch).length ? [{ kind: "meta_update", patch }] : [];
35378
+ }
35379
+ function turnCompleted(turn) {
35380
+ if (turn?.status === "failed") return [{ kind: "error", message: str(rec(turn.error)?.message) ?? "codex turn failed" }, { kind: "turn_end" }];
35381
+ return [{ kind: "turn_end" }];
35382
+ }
35383
+ function rec(v2) {
35384
+ return typeof v2 === "object" && v2 !== null ? v2 : void 0;
35385
+ }
35386
+ function str(v2) {
35387
+ return typeof v2 === "string" ? v2 : void 0;
35388
+ }
35389
+ function num(v2) {
35390
+ return typeof v2 === "number" ? v2 : void 0;
35391
+ }
35392
+
35393
+ // src/tools/codex-app-server-params.ts
35394
+ function resolveSandbox(ctx) {
35395
+ if (ctx.personaMode === "guest") throw new Error("codex \u6682\u4E0D\u652F\u6301 guest persona session\uFF1B\u8BF7\u7528 claude \u6216 owner");
35396
+ return "danger-full-access";
35397
+ }
35398
+ function resolveApprovalPolicy(ctx) {
35399
+ const m2 = ctx.permissionMode ?? "";
35400
+ if (m2 === "untrusted" || m2 === "on-failure" || m2 === "on-request" || m2 === "never") return m2;
35401
+ return "on-request";
35402
+ }
35403
+ function threadStartParams(ctx) {
35404
+ return {
35405
+ cwd: ctx.cwd,
35406
+ sandbox: resolveSandbox(ctx),
35407
+ // persona 侧
35408
+ approvalPolicy: resolveApprovalPolicy(ctx),
35409
+ // 会话设置侧
35410
+ approvalsReviewer: "user",
35411
+ ...ctx.model ? { model: ctx.model } : {}
35412
+ };
35413
+ }
35414
+ var ATTACHMENT_RE2 = /\[attachment:(image|file):([^\]]+)\]/g;
35415
+ var SKILL_RE = /\[skill:(.+?):(\/[^\]]+)\]/g;
35416
+ function turnStartInput(text) {
35417
+ const items = [];
35418
+ let leftover = text;
35419
+ for (const m2 of text.matchAll(SKILL_RE)) {
35420
+ const [marker, name, path59] = m2;
35421
+ items.push({ type: "skill", name, path: path59 });
35422
+ leftover = leftover.replace(marker, "");
35423
+ }
35424
+ for (const m2 of text.matchAll(ATTACHMENT_RE2)) {
35425
+ const [marker, kind, url] = m2;
35426
+ if (kind === "image") {
35427
+ items.push({ type: "image", url });
35428
+ leftover = leftover.replace(marker, "");
35429
+ }
35430
+ }
35431
+ const trimmed = leftover.trim();
35432
+ if (trimmed || items.length === 0) items.push({ type: "text", text: trimmed, text_elements: [] });
35433
+ return items;
35434
+ }
35435
+
35436
+ // src/tools/codex-session.ts
35437
+ function createCodexSession(ctx, sink, deps = {}) {
35438
+ const cmd = process.env.CODEX_BIN ?? "codex";
35439
+ const args = ["app-server", "--listen", "stdio://"];
35440
+ const env = { ...process.env, ...ctx.env };
35441
+ const proc = deps.spawnOverride ? deps.spawnOverride(cmd, args, ctx.cwd, env) : (0, import_node_child_process3.spawn)(cmd, args, { cwd: ctx.cwd, env, stdio: ["pipe", "pipe", "pipe"] });
35442
+ let threadId = ctx.toolSessionId;
35443
+ let turnId;
35444
+ const approvalIds = /* @__PURE__ */ new Map();
35445
+ let pendingSystemPrompt = ctx.toolSessionId ? void 0 : ctx.extraSystemPrompt;
35446
+ const effort = ctx.effort;
35447
+ let exited = false;
35448
+ const finish = (code) => {
35449
+ if (exited) return;
35450
+ exited = true;
35451
+ sink.onExit(code);
35452
+ };
35453
+ const client = new CodexAppServerClient(proc, {
35454
+ onNotification: (method, params) => {
35455
+ if (method === "turn/started") {
35456
+ const id = params?.turn?.id;
35457
+ if (id) turnId = id;
35458
+ }
35459
+ const events = translateNotification(method, params);
35460
+ if (events.length) sink.pushEvents(events);
35461
+ },
35462
+ onServerRequest: (id, method, params) => {
35463
+ const p2 = params ?? {};
35464
+ if (method === "item/commandExecution/requestApproval" || method === "item/fileChange/requestApproval") {
35465
+ const reqId = String(id);
35466
+ approvalIds.set(reqId, id);
35467
+ sink.pushEvents([
35468
+ {
35469
+ kind: "permission_request",
35470
+ requestId: reqId,
35471
+ tool: method.includes("fileChange") ? "fileChange" : "commandExecution",
35472
+ input: p2,
35473
+ ...typeof p2.itemId === "string" ? { toolUseId: p2.itemId } : {}
35474
+ }
35475
+ ]);
35476
+ return;
35477
+ }
35478
+ client.respond(id, "cancel");
35479
+ },
35480
+ onClose: () => finish(proc.exitCode)
35481
+ });
35482
+ proc.stderr?.on(
35483
+ "data",
35484
+ (c) => deps.logger?.warn("codex app-server stderr", { line: c.toString().slice(0, 500) })
35485
+ );
35486
+ proc.on("error", (err) => {
35487
+ const message = err.message;
35488
+ deps.logger?.error("codex app-server spawn failed", { message });
35489
+ sink.onError(`codex app-server spawn failed: ${message}`);
35490
+ });
35491
+ proc.on("exit", (code) => finish(code));
35492
+ const ready = (async () => {
35493
+ await client.request("initialize", {
35494
+ clientInfo: { name: "clawd", title: "clawd", version: "0" },
35495
+ capabilities: null
35496
+ });
35497
+ client.notify("initialized", {});
35498
+ if (threadId) {
35499
+ await client.request("thread/resume", { threadId, ...threadStartParams(ctx) });
35500
+ } else {
35501
+ const res = await client.request("thread/start", threadStartParams(ctx));
35502
+ threadId = res?.thread?.id;
35503
+ if (threadId) sink.pushEvents([{ kind: "session_init", toolSessionId: threadId }]);
35504
+ }
35505
+ })().catch((e) => sink.onError(`codex app-server init failed: ${e.message}`));
35506
+ return {
35507
+ startTurn(text) {
35508
+ const body = pendingSystemPrompt ? `${pendingSystemPrompt}
35509
+
35510
+ ${text}` : text;
35511
+ pendingSystemPrompt = void 0;
35512
+ void ready.then(() => {
35513
+ if (threadId)
35514
+ void client.request("turn/start", {
35515
+ threadId,
35516
+ input: turnStartInput(body),
35517
+ // TurnStartParams 字段是 `effort`(不是 `reasoningEffort`,0.138 改名)——传错名字
35518
+ // codex 静默忽略, reasoning effort 改了不生效。"override for this turn and subsequent turns"。
35519
+ ...effort ? { effort } : {}
35520
+ }).catch((e) => sink.onError(`turn/start failed: ${e.message}`));
35521
+ });
35522
+ },
35523
+ respondPermission(requestId, allow) {
35524
+ const id = approvalIds.get(requestId);
35525
+ if (id === void 0) return;
35526
+ approvalIds.delete(requestId);
35527
+ client.respond(id, { decision: allow ? "accept" : "decline" });
35528
+ },
35529
+ interrupt() {
35530
+ if (threadId && turnId) {
35531
+ void client.request("turn/interrupt", { threadId, turnId }).catch(() => {
35532
+ });
35533
+ return;
35534
+ }
35535
+ if (proc.exitCode === null && proc.signalCode === null) proc.kill("SIGTERM");
35536
+ },
35537
+ // signal 由 runner 透传 reducer 的 kill effect(runtime-patch / stop 恒 SIGKILL),与 claude doKill 语义统一:
35538
+ // SIGTERM 兜底会在 app-server 卡死收不到时泄漏进程,故尊重 SIGKILL 强杀。
35539
+ async stop(signal = "SIGTERM") {
35540
+ if (threadId && turnId) void client.request("turn/interrupt", { threadId, turnId }).catch(() => {
35541
+ });
35542
+ if (proc.exitCode === null && proc.signalCode === null) proc.kill(signal);
35543
+ }
35544
+ };
35545
+ }
35546
+
35547
+ // src/tools/codex.ts
35548
+ var CODEX_MODELS = [
35549
+ { id: "", label: "Default", description: "codex config.toml \u9ED8\u8BA4", contextWindowSize: 258400, default: true },
35550
+ { id: "gpt-5.5", label: "GPT-5.5", description: "Frontier model for complex coding", contextWindowSize: 258400 },
35551
+ { id: "gpt-5.4", label: "GPT-5.4", contextWindowSize: 258400 },
35552
+ { id: "gpt-5.4-mini", label: "GPT-5.4-Mini", contextWindowSize: 258400 }
35553
+ ];
35554
+ var CODEX_EFFORTS = [
35555
+ { value: "low", label: "Low", description: "Fast responses with lighter reasoning" },
35556
+ { value: "medium", label: "Medium", description: "Balances speed and reasoning depth for everyday tasks" },
35557
+ { value: "high", label: "High", description: "Greater reasoning depth for complex problems" },
35558
+ { value: "xhigh", label: "Extra high", description: "Extra high reasoning depth for complex problems" }
35559
+ ];
35560
+ var CODEX_APPROVAL_PRESETS = [
35561
+ { id: "untrusted", label: "Ask for approval", description: "\u51E0\u4E4E\u6BCF\u6761\u547D\u4EE4\u90FD\u95EE\u4F60\uFF08\u6700\u8C28\u614E\uFF09" },
35562
+ { id: "on-request", label: "Approve for me", description: "\u6A21\u578B\u81EA\u5DF1\u5224\u65AD\uFF0C\u53EA\u5BF9\u9AD8\u98CE\u9669\u64CD\u4F5C\u95EE\u4F60\uFF08\u9ED8\u8BA4\uFF09" },
35563
+ { id: "never", label: "Full Access", description: "\u4ECE\u4E0D\u8BE2\u95EE\uFF0C\u81EA\u4E3B\u6267\u884C" }
35564
+ ];
35565
+ var CODEX_CAPABILITIES = {
35566
+ tool: "codex",
35567
+ toolSessionIdLabel: "Codex Thread ID",
35568
+ models: CODEX_MODELS,
35569
+ permissionModes: CODEX_APPROVAL_PRESETS,
35570
+ // codex 不支持这些 clawd 功能(rewind 无 file-snapshot / 无子 agent / 无 TUI pty /
35571
+ // 无 observe 推送 / 无文件分享 / fork 是 claude jsonl 专用);UI 据此 gate 入口。
35572
+ features: { rewind: false, subagents: false, tui: false, observe: false, fileSharing: false, fork: false },
35573
+ configSchema: [
35574
+ {
35575
+ name: "model",
35576
+ type: "select",
35577
+ label: "Model",
35578
+ scope: "core",
35579
+ options: CODEX_MODELS.map((m2) => ({ value: m2.id, label: m2.label, description: m2.description })),
35580
+ default: ""
35581
+ },
35582
+ {
35583
+ name: "permissionMode",
35584
+ type: "select",
35585
+ label: "Approval",
35586
+ scope: "core",
35587
+ options: CODEX_APPROVAL_PRESETS.map((m2) => ({ value: m2.id, label: m2.label, description: m2.description })),
35588
+ default: "on-request"
35589
+ },
35590
+ {
35591
+ name: "effort",
35592
+ type: "select",
35593
+ label: "Reasoning effort",
35594
+ scope: "tool-specific",
35595
+ // 渲染在 Advanced 区(与 claude effort 一致)
35596
+ options: CODEX_EFFORTS,
35597
+ default: "medium"
35598
+ }
35599
+ ]
35600
+ };
35601
+ async function probeCodex(env = process.env) {
35602
+ if (env.CODEX_BIN && import_node_fs10.default.existsSync(env.CODEX_BIN)) return { available: true, path: env.CODEX_BIN };
35603
+ try {
35604
+ const out = (0, import_node_child_process4.execFileSync)("which", ["codex"], { encoding: "utf8" }).trim();
35605
+ if (out && import_node_fs10.default.existsSync(out)) return { available: true, path: out };
35606
+ } catch {
35607
+ }
35608
+ return { available: false };
35609
+ }
35610
+ var CodexAdapter = class {
35611
+ id = "codex";
35612
+ // 历史读取器:history:read 按 session.tool 路由到这里(thread/read)。
35613
+ historyReader;
35614
+ probeCache = null;
35615
+ logger;
35616
+ probeOverride;
35617
+ constructor(opts = {}) {
35618
+ this.logger = opts.logger;
35619
+ this.probeOverride = opts.probeOverride;
35620
+ this.historyReader = opts.historyReader;
35621
+ }
35622
+ async probe() {
35623
+ if (this.probeCache) return this.probeCache;
35624
+ this.probeCache = this.probeOverride ? await this.probeOverride() : await probeCodex();
35625
+ return this.probeCache;
35626
+ }
35627
+ async capabilities() {
35628
+ return CODEX_CAPABILITIES;
35629
+ }
35630
+ resolveContextWindow(modelId) {
35631
+ return (CODEX_MODELS.find((m2) => m2.id === (modelId ?? "")) ?? CODEX_MODELS[0]).contextWindowSize;
35632
+ }
35633
+ createSession(ctx, sink) {
35634
+ return createCodexSession(ctx, sink, { logger: this.logger });
35635
+ }
35636
+ spawn(_ctx) {
35637
+ throw new Error("CodexAdapter uses createSession, not spawn");
35638
+ }
35639
+ parseLine(_line) {
35640
+ return [];
35641
+ }
35642
+ // 原样返回带 marker 的文本;附件 marker → codex image 多模态由 turnStartInput 解析
35643
+ // (codex-app-server-params.ts, PR1)。encodeStdin 不动 markers。
35644
+ encodeStdin(text, _ctx) {
35645
+ return text;
35646
+ }
35647
+ };
35648
+
35649
+ // src/tools/claude-tui.ts
35650
+ var import_node_fs11 = __toESM(require("fs"), 1);
35159
35651
  var import_node_os5 = __toESM(require("os"), 1);
35160
35652
  var import_node_path10 = __toESM(require("path"), 1);
35161
35653
  var import_headless = __toESM(require_xterm_headless(), 1);
@@ -36139,7 +36631,7 @@ function jsonlExistsForCtx(ctx) {
36139
36631
  const home = import_node_os5.default.homedir();
36140
36632
  const file = import_node_path10.default.join(home, ".claude", "projects", cwdToHashDir(ctx.cwd), `${ctx.toolSessionId}.jsonl`);
36141
36633
  try {
36142
- return import_node_fs10.default.statSync(file).isFile();
36634
+ return import_node_fs11.default.statSync(file).isFile();
36143
36635
  } catch {
36144
36636
  return false;
36145
36637
  }
@@ -36148,8 +36640,238 @@ function jsonlExistsForCtx(ctx) {
36148
36640
  // src/index.ts
36149
36641
  init_claude_history();
36150
36642
 
36643
+ // src/tools/codex-history.ts
36644
+ var import_node_child_process5 = require("child_process");
36645
+ var DEFAULT_TIMEOUT_MS = 8e3;
36646
+ function rec2(v2) {
36647
+ return v2 && typeof v2 === "object" && !Array.isArray(v2) ? v2 : void 0;
36648
+ }
36649
+ function str2(v2) {
36650
+ return typeof v2 === "string" ? v2 : void 0;
36651
+ }
36652
+ function num2(v2) {
36653
+ return typeof v2 === "number" && Number.isFinite(v2) ? v2 : void 0;
36654
+ }
36655
+ function userInputText(content) {
36656
+ if (!Array.isArray(content)) return "";
36657
+ return content.map((c) => {
36658
+ const r = rec2(c);
36659
+ return r && r.type === "text" ? str2(r.text) ?? "" : "";
36660
+ }).filter(Boolean).join("");
36661
+ }
36662
+ function threadItemToHistoryMessages(item) {
36663
+ const it = rec2(item);
36664
+ if (!it) return [];
36665
+ switch (it.type) {
36666
+ case "userMessage": {
36667
+ const text = userInputText(it.content);
36668
+ return text ? [{ kind: "user-text", text, raw: item }] : [];
36669
+ }
36670
+ case "agentMessage": {
36671
+ const text = str2(it.text);
36672
+ return text ? [{ kind: "assistant-text", text, raw: item }] : [];
36673
+ }
36674
+ case "commandExecution": {
36675
+ const id = str2(it.id);
36676
+ if (!id) return [];
36677
+ const msgs = [
36678
+ {
36679
+ kind: "tool_call",
36680
+ tool: "commandExecution",
36681
+ toolUseId: id,
36682
+ input: { command: str2(it.command) ?? "" },
36683
+ raw: item
36684
+ }
36685
+ ];
36686
+ if (it.status === "completed" || it.aggregatedOutput != null || it.exitCode != null) {
36687
+ const exit = num2(it.exitCode);
36688
+ const result = {
36689
+ kind: "tool_result",
36690
+ toolUseId: id,
36691
+ output: str2(it.aggregatedOutput) ?? "",
36692
+ raw: item
36693
+ };
36694
+ if (exit !== void 0 && exit !== 0) result.output = `${result.output ?? ""}
36695
+ (exit ${exit})`;
36696
+ msgs.push(result);
36697
+ }
36698
+ return msgs;
36699
+ }
36700
+ default:
36701
+ return [];
36702
+ }
36703
+ }
36704
+ async function queryCodexAppServer(cwd, method, params, deps) {
36705
+ const cmd = process.env.CODEX_BIN ?? "codex";
36706
+ const args = ["app-server", "--listen", "stdio://"];
36707
+ const proc = deps.spawnOverride ? deps.spawnOverride(cmd, args, cwd) : (0, import_node_child_process5.spawn)(cmd, args, { cwd, env: process.env, stdio: ["pipe", "pipe", "pipe"] });
36708
+ const client = new CodexAppServerClient(proc, {});
36709
+ const timeoutMs = deps.timeoutMs ?? DEFAULT_TIMEOUT_MS;
36710
+ let timer;
36711
+ const timeout = new Promise((_2, reject) => {
36712
+ timer = setTimeout(() => reject(new Error(`codex app-server ${method} timed out after ${timeoutMs}ms`)), timeoutMs);
36713
+ proc.on("error", (err) => reject(new Error(`codex app-server spawn failed: ${err.message}`)));
36714
+ });
36715
+ try {
36716
+ await Promise.race([
36717
+ (async () => {
36718
+ await client.request("initialize", {
36719
+ clientInfo: { name: "clawd", title: "clawd", version: "0" },
36720
+ capabilities: null
36721
+ });
36722
+ client.notify("initialized", {});
36723
+ })(),
36724
+ timeout
36725
+ ]);
36726
+ return await Promise.race([client.request(method, params), timeout]);
36727
+ } finally {
36728
+ if (timer) clearTimeout(timer);
36729
+ if (proc.exitCode === null && proc.signalCode === null) proc.kill("SIGTERM");
36730
+ }
36731
+ }
36732
+ var CodexHistoryReader = class {
36733
+ deps;
36734
+ constructor(deps = {}) {
36735
+ this.deps = deps;
36736
+ }
36737
+ // v1 先返回 []:projects/list 非 session-scoped、不知 tool,跨-tool 项目浏览器合并排后续。
36738
+ // codex 旧会话仍能经 clawd 活跃列表(session:list, tool-agnostic) + read 打开。
36739
+ async listProjects() {
36740
+ return [];
36741
+ }
36742
+ async listSessions(args) {
36743
+ const res = rec2(
36744
+ await queryCodexAppServer(
36745
+ args.projectPath,
36746
+ "thread/list",
36747
+ {
36748
+ limit: 100,
36749
+ sortKey: "updated_at",
36750
+ sortDirection: "desc",
36751
+ archived: false,
36752
+ cwd: args.projectPath,
36753
+ useStateDbOnly: true
36754
+ },
36755
+ this.deps
36756
+ )
36757
+ );
36758
+ const data = res && Array.isArray(res.data) ? res.data : [];
36759
+ const out = [];
36760
+ for (const entry of data) {
36761
+ const e = rec2(entry);
36762
+ const id = e && str2(e.id);
36763
+ if (!e || !id) continue;
36764
+ const updatedAtMs = Math.round((num2(e.updatedAt) ?? 0) * 1e3);
36765
+ out.push({
36766
+ toolSessionId: id,
36767
+ summary: str2(e.preview) || "(\u7A7A\u4F1A\u8BDD)",
36768
+ messageCount: 0,
36769
+ // thread/list 不提供条数;活跃/read 时才知
36770
+ updatedAt: new Date(updatedAtMs).toISOString()
36771
+ });
36772
+ }
36773
+ return out;
36774
+ }
36775
+ async read(args) {
36776
+ const res = rec2(
36777
+ await queryCodexAppServer(
36778
+ args.cwd,
36779
+ "thread/read",
36780
+ { threadId: args.toolSessionId, includeTurns: true },
36781
+ this.deps
36782
+ )
36783
+ );
36784
+ const thread = res && rec2(res.thread);
36785
+ const turns = thread && Array.isArray(thread.turns) ? thread.turns : [];
36786
+ const messages = [];
36787
+ for (const turn of turns) {
36788
+ const t = rec2(turn);
36789
+ const items = t && Array.isArray(t.items) ? t.items : [];
36790
+ for (const item of items) messages.push(...threadItemToHistoryMessages(item));
36791
+ }
36792
+ const total = messages.length;
36793
+ const limit = args.limit ?? total;
36794
+ const offset = typeof args.offset === "number" ? Math.min(Math.max(0, args.offset), total) : Math.max(0, total - limit);
36795
+ return { messages: messages.slice(offset, offset + limit), total, offset };
36796
+ }
36797
+ // codex 无 sidechain 子 agent / file-history-snapshot → 全 stub 空(对齐 claude-history 同方法空返回)
36798
+ async listSubagents() {
36799
+ return [];
36800
+ }
36801
+ async readSubagent() {
36802
+ return { messages: [] };
36803
+ }
36804
+ computeRewindDiff() {
36805
+ return { canRewind: false, files: [], totalInsertions: 0, totalDeletions: 0 };
36806
+ }
36807
+ listRewindableUserMessageIds() {
36808
+ return [];
36809
+ }
36810
+ };
36811
+
36812
+ // src/tools/codex-skills.ts
36813
+ var import_node_child_process6 = require("child_process");
36814
+ var DEFAULT_TIMEOUT_MS2 = 8e3;
36815
+ function str3(v2) {
36816
+ return typeof v2 === "string" ? v2 : void 0;
36817
+ }
36818
+ function mapSkillsListResponse(res) {
36819
+ const data = res?.data;
36820
+ if (!Array.isArray(data)) return [];
36821
+ const out = [];
36822
+ for (const entry of data) {
36823
+ const skills = entry?.skills;
36824
+ if (!Array.isArray(skills)) continue;
36825
+ for (const s of skills) {
36826
+ const r = s ?? {};
36827
+ const name = str3(r.name);
36828
+ if (!name) continue;
36829
+ const path59 = str3(r.path);
36830
+ const description = str3(r.description);
36831
+ const isPlugin = name.includes(":");
36832
+ out.push({
36833
+ name,
36834
+ source: isPlugin ? "plugin" : "project",
36835
+ ...path59 ? { path: path59 } : {},
36836
+ ...description ? { description } : {},
36837
+ ...isPlugin ? { plugin: name.split(":")[0] } : {}
36838
+ });
36839
+ }
36840
+ }
36841
+ return out;
36842
+ }
36843
+ async function listCodexSkills(cwd, deps = {}) {
36844
+ const cmd = process.env.CODEX_BIN ?? "codex";
36845
+ const args = ["app-server", "--listen", "stdio://"];
36846
+ const proc = deps.spawnOverride ? deps.spawnOverride(cmd, args, cwd) : (0, import_node_child_process6.spawn)(cmd, args, { cwd, env: process.env, stdio: ["pipe", "pipe", "pipe"] });
36847
+ const client = new CodexAppServerClient(proc, {});
36848
+ const timeoutMs = deps.timeoutMs ?? DEFAULT_TIMEOUT_MS2;
36849
+ let timer;
36850
+ const timeout = new Promise((_2, reject) => {
36851
+ timer = setTimeout(() => reject(new Error(`codex app-server skills/list timed out after ${timeoutMs}ms`)), timeoutMs);
36852
+ proc.on("error", (err) => reject(new Error(`codex app-server spawn failed: ${err.message}`)));
36853
+ });
36854
+ try {
36855
+ await Promise.race([
36856
+ (async () => {
36857
+ await client.request("initialize", {
36858
+ clientInfo: { name: "clawd", title: "clawd", version: "0" },
36859
+ capabilities: null
36860
+ });
36861
+ client.notify("initialized", {});
36862
+ })(),
36863
+ timeout
36864
+ ]);
36865
+ const res = await Promise.race([client.request("skills/list", { cwds: [cwd] }), timeout]);
36866
+ return mapSkillsListResponse(res);
36867
+ } finally {
36868
+ if (timer) clearTimeout(timer);
36869
+ if (proc.exitCode === null && proc.signalCode === null) proc.kill("SIGTERM");
36870
+ }
36871
+ }
36872
+
36151
36873
  // src/workspace/browser.ts
36152
- var import_node_fs11 = __toESM(require("fs"), 1);
36874
+ var import_node_fs12 = __toESM(require("fs"), 1);
36153
36875
  var import_node_os6 = __toESM(require("os"), 1);
36154
36876
  var import_node_path11 = __toESM(require("path"), 1);
36155
36877
  init_protocol();
@@ -36165,7 +36887,7 @@ function resolveInsideCwd(cwd, subpath) {
36165
36887
  }
36166
36888
  function ensureCwd(cwd) {
36167
36889
  try {
36168
- const stat = import_node_fs11.default.statSync(cwd);
36890
+ const stat = import_node_fs12.default.statSync(cwd);
36169
36891
  if (!stat.isDirectory()) {
36170
36892
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${cwd}`);
36171
36893
  }
@@ -36179,7 +36901,7 @@ var WorkspaceBrowser = class {
36179
36901
  const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os6.default.homedir();
36180
36902
  ensureCwd(cwd);
36181
36903
  const full = resolveInsideCwd(cwd, args.path);
36182
- const dirents = import_node_fs11.default.readdirSync(full, { withFileTypes: true });
36904
+ const dirents = import_node_fs12.default.readdirSync(full, { withFileTypes: true });
36183
36905
  const entries = [];
36184
36906
  for (const d of dirents) {
36185
36907
  if (!args.showHidden && d.name.startsWith(".")) continue;
@@ -36189,7 +36911,7 @@ var WorkspaceBrowser = class {
36189
36911
  mtime: ""
36190
36912
  };
36191
36913
  try {
36192
- const st = import_node_fs11.default.statSync(import_node_path11.default.join(full, d.name));
36914
+ const st = import_node_fs12.default.statSync(import_node_path11.default.join(full, d.name));
36193
36915
  entry.mtime = new Date(st.mtimeMs).toISOString();
36194
36916
  if (d.isFile()) entry.size = st.size;
36195
36917
  } catch {
@@ -36205,14 +36927,14 @@ var WorkspaceBrowser = class {
36205
36927
  read(args) {
36206
36928
  ensureCwd(args.cwd);
36207
36929
  const full = resolveInsideCwd(args.cwd, args.path);
36208
- const st = import_node_fs11.default.statSync(full);
36930
+ const st = import_node_fs12.default.statSync(full);
36209
36931
  if (!st.isFile()) {
36210
36932
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `not a file: ${args.path}`);
36211
36933
  }
36212
36934
  if (st.size > MAX_FILE_BYTES) {
36213
36935
  throw new ClawdError(ERROR_CODES.FILE_TOO_LARGE, `file > ${MAX_FILE_BYTES} bytes`);
36214
36936
  }
36215
- const buf = import_node_fs11.default.readFileSync(full);
36937
+ const buf = import_node_fs12.default.readFileSync(full);
36216
36938
  const isBinary = buf.includes(0);
36217
36939
  if (isBinary) {
36218
36940
  return {
@@ -36234,20 +36956,20 @@ var WorkspaceBrowser = class {
36234
36956
  };
36235
36957
 
36236
36958
  // src/skills/agents-scanner.ts
36237
- var import_node_fs12 = __toESM(require("fs"), 1);
36959
+ var import_node_fs13 = __toESM(require("fs"), 1);
36238
36960
  var import_node_os7 = __toESM(require("os"), 1);
36239
36961
  var import_node_path12 = __toESM(require("path"), 1);
36240
36962
  var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
36241
36963
  function isDirLikeSync2(p2) {
36242
36964
  try {
36243
- return import_node_fs12.default.statSync(p2).isDirectory();
36965
+ return import_node_fs13.default.statSync(p2).isDirectory();
36244
36966
  } catch {
36245
36967
  return false;
36246
36968
  }
36247
36969
  }
36248
36970
  function fileExistsSync(p2) {
36249
36971
  try {
36250
- return import_node_fs12.default.statSync(p2).isFile();
36972
+ return import_node_fs13.default.statSync(p2).isFile();
36251
36973
  } catch {
36252
36974
  return false;
36253
36975
  }
@@ -36255,7 +36977,7 @@ function fileExistsSync(p2) {
36255
36977
  function parseAgentFile(filePath) {
36256
36978
  let content;
36257
36979
  try {
36258
- content = import_node_fs12.default.readFileSync(filePath, "utf8");
36980
+ content = import_node_fs13.default.readFileSync(filePath, "utf8");
36259
36981
  } catch {
36260
36982
  return {};
36261
36983
  }
@@ -36268,7 +36990,7 @@ function parseAgentFile(filePath) {
36268
36990
  function scanAgentsDir(dir, source, seen, out) {
36269
36991
  let entries;
36270
36992
  try {
36271
- entries = import_node_fs12.default.readdirSync(dir, { withFileTypes: true });
36993
+ entries = import_node_fs13.default.readdirSync(dir, { withFileTypes: true });
36272
36994
  } catch {
36273
36995
  return;
36274
36996
  }
@@ -36295,7 +37017,7 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
36295
37017
  function walk2(dir, namespaces) {
36296
37018
  let entries;
36297
37019
  try {
36298
- entries = import_node_fs12.default.readdirSync(dir, { withFileTypes: true });
37020
+ entries = import_node_fs13.default.readdirSync(dir, { withFileTypes: true });
36299
37021
  } catch {
36300
37022
  return;
36301
37023
  }
@@ -36331,7 +37053,7 @@ function readInstalledPlugins2(home) {
36331
37053
  let raw = null;
36332
37054
  for (const candidate of [v2, v1]) {
36333
37055
  try {
36334
- raw = import_node_fs12.default.readFileSync(candidate, "utf8");
37056
+ raw = import_node_fs13.default.readFileSync(candidate, "utf8");
36335
37057
  break;
36336
37058
  } catch {
36337
37059
  }
@@ -36362,7 +37084,7 @@ function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
36362
37084
  scanAgentsDir(import_node_path12.default.join(cur, ".claude", "agents"), "project", seen, out);
36363
37085
  let hasGit = false;
36364
37086
  try {
36365
- hasGit = import_node_fs12.default.existsSync(import_node_path12.default.join(cur, ".git"));
37087
+ hasGit = import_node_fs13.default.existsSync(import_node_path12.default.join(cur, ".git"));
36366
37088
  } catch {
36367
37089
  }
36368
37090
  if (hasGit) return;
@@ -36425,13 +37147,13 @@ var AgentsScanner = class {
36425
37147
  };
36426
37148
 
36427
37149
  // src/observer/session-observer.ts
36428
- var import_node_fs14 = __toESM(require("fs"), 1);
37150
+ var import_node_fs15 = __toESM(require("fs"), 1);
36429
37151
  var import_node_os9 = __toESM(require("os"), 1);
36430
37152
  var import_node_path14 = __toESM(require("path"), 1);
36431
37153
  init_claude_history();
36432
37154
 
36433
37155
  // src/observer/subagent-meta-observer.ts
36434
- var import_node_fs13 = __toESM(require("fs"), 1);
37156
+ var import_node_fs14 = __toESM(require("fs"), 1);
36435
37157
  var import_node_os8 = __toESM(require("os"), 1);
36436
37158
  var import_node_path13 = __toESM(require("path"), 1);
36437
37159
  init_claude_history();
@@ -36476,7 +37198,7 @@ var SubagentMetaObserver = class {
36476
37198
  attachWatcher(w2) {
36477
37199
  if (w2.watcher) return;
36478
37200
  try {
36479
- w2.watcher = import_node_fs13.default.watch(w2.dirPath, { persistent: false }, (_evt, name) => {
37201
+ w2.watcher = import_node_fs14.default.watch(w2.dirPath, { persistent: false }, (_evt, name) => {
36480
37202
  if (!name) return;
36481
37203
  const m2 = META_RE.exec(String(name));
36482
37204
  if (!m2) return;
@@ -36488,7 +37210,7 @@ var SubagentMetaObserver = class {
36488
37210
  scan(w2) {
36489
37211
  let entries;
36490
37212
  try {
36491
- entries = import_node_fs13.default.readdirSync(w2.dirPath);
37213
+ entries = import_node_fs14.default.readdirSync(w2.dirPath);
36492
37214
  } catch {
36493
37215
  return;
36494
37216
  }
@@ -36505,7 +37227,7 @@ var SubagentMetaObserver = class {
36505
37227
  const file = import_node_path13.default.join(w2.dirPath, name);
36506
37228
  let raw;
36507
37229
  try {
36508
- raw = import_node_fs13.default.readFileSync(file, "utf8");
37230
+ raw = import_node_fs14.default.readFileSync(file, "utf8");
36509
37231
  } catch {
36510
37232
  return;
36511
37233
  }
@@ -36569,7 +37291,7 @@ var SessionObserver = class {
36569
37291
  const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
36570
37292
  let size = 0;
36571
37293
  try {
36572
- size = import_node_fs14.default.statSync(filePath).size;
37294
+ size = import_node_fs15.default.statSync(filePath).size;
36573
37295
  } catch {
36574
37296
  }
36575
37297
  const w2 = {
@@ -36583,10 +37305,10 @@ var SessionObserver = class {
36583
37305
  prevIsRejectSentinel: false
36584
37306
  };
36585
37307
  try {
36586
- import_node_fs14.default.mkdirSync(import_node_path14.default.dirname(filePath), { recursive: true });
37308
+ import_node_fs15.default.mkdirSync(import_node_path14.default.dirname(filePath), { recursive: true });
36587
37309
  } catch {
36588
37310
  }
36589
- w2.watcher = import_node_fs14.default.watch(import_node_path14.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
37311
+ w2.watcher = import_node_fs15.default.watch(import_node_path14.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
36590
37312
  if (!changedName || !filePath.endsWith(changedName)) return;
36591
37313
  this.poll(w2);
36592
37314
  });
@@ -36609,7 +37331,7 @@ var SessionObserver = class {
36609
37331
  // 异常静默吞,不阻塞 watcher 启动
36610
37332
  hydrateMetaTail(w2, maxLines = 200) {
36611
37333
  try {
36612
- const raw = import_node_fs14.default.readFileSync(w2.filePath, "utf8");
37334
+ const raw = import_node_fs15.default.readFileSync(w2.filePath, "utf8");
36613
37335
  if (!raw) return;
36614
37336
  const allLines = raw.split("\n").filter((l) => l.trim().length > 0);
36615
37337
  if (allLines.length === 0) return;
@@ -36633,7 +37355,7 @@ var SessionObserver = class {
36633
37355
  poll(w2) {
36634
37356
  let size = 0;
36635
37357
  try {
36636
- size = import_node_fs14.default.statSync(w2.filePath).size;
37358
+ size = import_node_fs15.default.statSync(w2.filePath).size;
36637
37359
  } catch {
36638
37360
  return;
36639
37361
  }
@@ -36642,11 +37364,11 @@ var SessionObserver = class {
36642
37364
  w2.buf = "";
36643
37365
  }
36644
37366
  if (size === w2.lastSize) return;
36645
- const fd = import_node_fs14.default.openSync(w2.filePath, "r");
37367
+ const fd = import_node_fs15.default.openSync(w2.filePath, "r");
36646
37368
  try {
36647
37369
  const len = size - w2.lastSize;
36648
37370
  const buf = Buffer.alloc(len);
36649
- import_node_fs14.default.readSync(fd, buf, 0, len, w2.lastSize);
37371
+ import_node_fs15.default.readSync(fd, buf, 0, len, w2.lastSize);
36650
37372
  w2.lastSize = size;
36651
37373
  w2.buf += buf.toString("utf8");
36652
37374
  let newlineIndex;
@@ -36669,7 +37391,7 @@ var SessionObserver = class {
36669
37391
  }
36670
37392
  }
36671
37393
  } finally {
36672
- import_node_fs14.default.closeSync(fd);
37394
+ import_node_fs15.default.closeSync(fd);
36673
37395
  }
36674
37396
  }
36675
37397
  // 解析 JSONL 单行:仅当是主链 user 文本行(非 sidechain / 非 sub-agent / message.role='user'
@@ -37392,14 +38114,14 @@ async function authenticate(token, deps) {
37392
38114
  }
37393
38115
 
37394
38116
  // src/permission/capability-store.ts
37395
- var fs17 = __toESM(require("fs"), 1);
38117
+ var fs18 = __toESM(require("fs"), 1);
37396
38118
  var path19 = __toESM(require("path"), 1);
37397
38119
  var CAPABILITIES_FILE_NAME = "capabilities.json";
37398
38120
  var FILE_VERSION = 1;
37399
38121
  var CapabilityStore = class {
37400
38122
  constructor(dataDir) {
37401
38123
  this.dataDir = dataDir;
37402
- fs17.mkdirSync(dataDir, { recursive: true });
38124
+ fs18.mkdirSync(dataDir, { recursive: true });
37403
38125
  this.cache = this.readFromDisk();
37404
38126
  }
37405
38127
  dataDir;
@@ -37429,7 +38151,7 @@ var CapabilityStore = class {
37429
38151
  const file = this.filePath();
37430
38152
  let raw;
37431
38153
  try {
37432
- raw = fs17.readFileSync(file, "utf8");
38154
+ raw = fs18.readFileSync(file, "utf8");
37433
38155
  } catch (err) {
37434
38156
  if (err?.code === "ENOENT") return [];
37435
38157
  return [];
@@ -37457,10 +38179,10 @@ var CapabilityStore = class {
37457
38179
  }
37458
38180
  atomicWrite(file, content) {
37459
38181
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
37460
- fs17.writeFileSync(tmp, content, { mode: 384 });
37461
- fs17.renameSync(tmp, file);
38182
+ fs18.writeFileSync(tmp, content, { mode: 384 });
38183
+ fs18.renameSync(tmp, file);
37462
38184
  try {
37463
- fs17.chmodSync(file, 384);
38185
+ fs18.chmodSync(file, 384);
37464
38186
  } catch {
37465
38187
  }
37466
38188
  }
@@ -37553,14 +38275,14 @@ var CapabilityManager = class {
37553
38275
  };
37554
38276
 
37555
38277
  // src/permission/cleanup.ts
37556
- var fs18 = __toESM(require("fs"), 1);
38278
+ var fs19 = __toESM(require("fs"), 1);
37557
38279
  function cleanupGuestSessionsForCapability(cap, factory) {
37558
38280
  const removed = [];
37559
38281
  for (const g2 of cap.grants) {
37560
38282
  if (g2.resource.type !== "persona") continue;
37561
38283
  const dir = factory.vmGuestRoot(g2.resource.id, cap.id);
37562
38284
  try {
37563
- fs18.rmSync(dir, { recursive: true, force: true });
38285
+ fs19.rmSync(dir, { recursive: true, force: true });
37564
38286
  removed.push(dir);
37565
38287
  } catch {
37566
38288
  }
@@ -37569,13 +38291,13 @@ function cleanupGuestSessionsForCapability(cap, factory) {
37569
38291
  }
37570
38292
 
37571
38293
  // src/inbox/inbox-store.ts
37572
- var fs19 = __toESM(require("fs"), 1);
38294
+ var fs20 = __toESM(require("fs"), 1);
37573
38295
  var path20 = __toESM(require("path"), 1);
37574
38296
  var INBOX_SUBDIR = "inbox";
37575
38297
  var InboxStore = class {
37576
38298
  constructor(dataDir) {
37577
38299
  this.dataDir = dataDir;
37578
- fs19.mkdirSync(this.dirPath(), { recursive: true });
38300
+ fs20.mkdirSync(this.dirPath(), { recursive: true });
37579
38301
  }
37580
38302
  dataDir;
37581
38303
  /**
@@ -37587,7 +38309,7 @@ var InboxStore = class {
37587
38309
  const file = this.filePath(peerDeviceId);
37588
38310
  let raw;
37589
38311
  try {
37590
- raw = fs19.readFileSync(file, "utf8");
38312
+ raw = fs20.readFileSync(file, "utf8");
37591
38313
  } catch (err) {
37592
38314
  if (err?.code === "ENOENT") return [];
37593
38315
  return [];
@@ -37603,7 +38325,7 @@ var InboxStore = class {
37603
38325
  const dir = this.dirPath();
37604
38326
  let entries;
37605
38327
  try {
37606
- entries = fs19.readdirSync(dir);
38328
+ entries = fs20.readdirSync(dir);
37607
38329
  } catch (err) {
37608
38330
  if (err?.code === "ENOENT") return [];
37609
38331
  return [];
@@ -37619,9 +38341,9 @@ var InboxStore = class {
37619
38341
  if (existing.some((m2) => m2.id === message.id)) return;
37620
38342
  const file = this.filePath(message.peerDeviceId);
37621
38343
  const line = JSON.stringify(message) + "\n";
37622
- fs19.appendFileSync(file, line, { mode: 384 });
38344
+ fs20.appendFileSync(file, line, { mode: 384 });
37623
38345
  try {
37624
- fs19.chmodSync(file, 384);
38346
+ fs20.chmodSync(file, 384);
37625
38347
  } catch {
37626
38348
  }
37627
38349
  }
@@ -37651,7 +38373,7 @@ var InboxStore = class {
37651
38373
  removeByPeerDeviceId(peerDeviceId) {
37652
38374
  const file = this.filePath(peerDeviceId);
37653
38375
  try {
37654
- fs19.unlinkSync(file);
38376
+ fs20.unlinkSync(file);
37655
38377
  } catch (err) {
37656
38378
  if (err?.code === "ENOENT") return;
37657
38379
  }
@@ -37660,10 +38382,10 @@ var InboxStore = class {
37660
38382
  const file = this.filePath(peerDeviceId);
37661
38383
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
37662
38384
  const content = messages.map((m2) => JSON.stringify(m2)).join("\n") + (messages.length > 0 ? "\n" : "");
37663
- fs19.writeFileSync(tmp, content, { mode: 384 });
37664
- fs19.renameSync(tmp, file);
38385
+ fs20.writeFileSync(tmp, content, { mode: 384 });
38386
+ fs20.renameSync(tmp, file);
37665
38387
  try {
37666
- fs19.chmodSync(file, 384);
38388
+ fs20.chmodSync(file, 384);
37667
38389
  } catch {
37668
38390
  }
37669
38391
  }
@@ -37758,7 +38480,7 @@ var InboxManager = class {
37758
38480
  };
37759
38481
 
37760
38482
  // src/state/contact-store.ts
37761
- var fs20 = __toESM(require("fs"), 1);
38483
+ var fs21 = __toESM(require("fs"), 1);
37762
38484
  var path21 = __toESM(require("path"), 1);
37763
38485
  var FILE_NAME = "contacts.json";
37764
38486
  var ContactStore = class {
@@ -37772,7 +38494,7 @@ var ContactStore = class {
37772
38494
  const file = path21.join(this.dataDir, FILE_NAME);
37773
38495
  let raw;
37774
38496
  try {
37775
- raw = fs20.readFileSync(file, "utf8");
38497
+ raw = fs21.readFileSync(file, "utf8");
37776
38498
  } catch (err) {
37777
38499
  if (err?.code !== "ENOENT") this.renameBak(file);
37778
38500
  return;
@@ -37822,13 +38544,13 @@ var ContactStore = class {
37822
38544
  null,
37823
38545
  2
37824
38546
  );
37825
- fs20.mkdirSync(this.dataDir, { recursive: true });
37826
- fs20.writeFileSync(tmp, content, { mode: 384 });
37827
- fs20.renameSync(tmp, file);
38547
+ fs21.mkdirSync(this.dataDir, { recursive: true });
38548
+ fs21.writeFileSync(tmp, content, { mode: 384 });
38549
+ fs21.renameSync(tmp, file);
37828
38550
  }
37829
38551
  renameBak(file) {
37830
38552
  try {
37831
- fs20.renameSync(file, `${file}.bak`);
38553
+ fs21.renameSync(file, `${file}.bak`);
37832
38554
  } catch {
37833
38555
  }
37834
38556
  }
@@ -37963,7 +38685,7 @@ async function autoReverseContact(args) {
37963
38685
  }
37964
38686
 
37965
38687
  // src/migrations/2026-05-20-flatten-sessions.ts
37966
- var fs21 = __toESM(require("fs"), 1);
38688
+ var fs22 = __toESM(require("fs"), 1);
37967
38689
  var path22 = __toESM(require("path"), 1);
37968
38690
  var MIGRATION_FLAG_NAME = ".migration.v1.done";
37969
38691
  function migrateFlattenSessions(opts) {
@@ -37983,7 +38705,7 @@ function migrateFlattenSessions(opts) {
37983
38705
  if (!entry.endsWith(".json")) continue;
37984
38706
  const src = path22.join(defaultDir, entry);
37985
38707
  const dst = path22.join(sessionsDir, entry);
37986
- fs21.renameSync(src, dst);
38708
+ fs22.renameSync(src, dst);
37987
38709
  movedBare += 1;
37988
38710
  }
37989
38711
  rmdirIfEmpty(defaultDir);
@@ -37995,10 +38717,10 @@ function migrateFlattenSessions(opts) {
37995
38717
  const ownerSrc = path22.join(personaDir, "owner");
37996
38718
  if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
37997
38719
  const ownerDst = path22.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
37998
- fs21.mkdirSync(ownerDst, { recursive: true });
38720
+ fs22.mkdirSync(ownerDst, { recursive: true });
37999
38721
  for (const file of readdirSafe(ownerSrc)) {
38000
38722
  if (!file.endsWith(".json")) continue;
38001
- fs21.renameSync(path22.join(ownerSrc, file), path22.join(ownerDst, file));
38723
+ fs22.renameSync(path22.join(ownerSrc, file), path22.join(ownerDst, file));
38002
38724
  movedVmOwner += 1;
38003
38725
  }
38004
38726
  rmdirIfEmpty(ownerSrc);
@@ -38006,18 +38728,18 @@ function migrateFlattenSessions(opts) {
38006
38728
  const listenerSrc = path22.join(personaDir, "listener");
38007
38729
  if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
38008
38730
  const archiveDst = path22.join(dataDir, ".legacy", `listener-${pid}`);
38009
- fs21.mkdirSync(archiveDst, { recursive: true });
38731
+ fs22.mkdirSync(archiveDst, { recursive: true });
38010
38732
  for (const file of readdirSafe(listenerSrc)) {
38011
38733
  if (!file.endsWith(".json")) continue;
38012
- fs21.renameSync(path22.join(listenerSrc, file), path22.join(archiveDst, file));
38734
+ fs22.renameSync(path22.join(listenerSrc, file), path22.join(archiveDst, file));
38013
38735
  archivedListener += 1;
38014
38736
  }
38015
38737
  rmdirIfEmpty(listenerSrc);
38016
38738
  }
38017
38739
  rmdirIfEmpty(personaDir);
38018
38740
  }
38019
- fs21.mkdirSync(sessionsDir, { recursive: true });
38020
- fs21.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
38741
+ fs22.mkdirSync(sessionsDir, { recursive: true });
38742
+ fs22.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
38021
38743
  return {
38022
38744
  skipped: false,
38023
38745
  flagWritten: true,
@@ -38028,7 +38750,7 @@ function migrateFlattenSessions(opts) {
38028
38750
  }
38029
38751
  function existsSync3(p2) {
38030
38752
  try {
38031
- fs21.statSync(p2);
38753
+ fs22.statSync(p2);
38032
38754
  return true;
38033
38755
  } catch {
38034
38756
  return false;
@@ -38036,27 +38758,27 @@ function existsSync3(p2) {
38036
38758
  }
38037
38759
  function isDir(p2) {
38038
38760
  try {
38039
- return fs21.statSync(p2).isDirectory();
38761
+ return fs22.statSync(p2).isDirectory();
38040
38762
  } catch {
38041
38763
  return false;
38042
38764
  }
38043
38765
  }
38044
38766
  function readdirSafe(p2) {
38045
38767
  try {
38046
- return fs21.readdirSync(p2);
38768
+ return fs22.readdirSync(p2);
38047
38769
  } catch {
38048
38770
  return [];
38049
38771
  }
38050
38772
  }
38051
38773
  function rmdirIfEmpty(p2) {
38052
38774
  try {
38053
- fs21.rmdirSync(p2);
38775
+ fs22.rmdirSync(p2);
38054
38776
  } catch {
38055
38777
  }
38056
38778
  }
38057
38779
 
38058
38780
  // src/transport/http-router.ts
38059
- var import_node_fs16 = __toESM(require("fs"), 1);
38781
+ var import_node_fs17 = __toESM(require("fs"), 1);
38060
38782
  var import_node_path18 = __toESM(require("path"), 1);
38061
38783
 
38062
38784
  // src/attachment/mime.ts
@@ -38236,7 +38958,7 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
38236
38958
  }
38237
38959
 
38238
38960
  // src/attachment/upload.ts
38239
- var import_node_fs15 = __toESM(require("fs"), 1);
38961
+ var import_node_fs16 = __toESM(require("fs"), 1);
38240
38962
  var import_node_path16 = __toESM(require("path"), 1);
38241
38963
  var import_node_crypto5 = __toESM(require("crypto"), 1);
38242
38964
  var import_promises = require("stream/promises");
@@ -38258,7 +38980,7 @@ async function writeUploadedAttachment(args) {
38258
38980
  assertValidFileName(args.fileName);
38259
38981
  const attachmentsRoot = import_node_path16.default.join(args.sessionDir, ".attachments");
38260
38982
  try {
38261
- import_node_fs15.default.mkdirSync(attachmentsRoot, { recursive: true });
38983
+ import_node_fs16.default.mkdirSync(attachmentsRoot, { recursive: true });
38262
38984
  } catch (err) {
38263
38985
  throw new UploadError("STORAGE_ERROR", `mkdir failed: ${err.message}`);
38264
38986
  }
@@ -38279,18 +39001,18 @@ async function writeUploadedAttachment(args) {
38279
39001
  yield buf;
38280
39002
  }
38281
39003
  },
38282
- import_node_fs15.default.createWriteStream(tmpPath, { mode: 384 })
39004
+ import_node_fs16.default.createWriteStream(tmpPath, { mode: 384 })
38283
39005
  );
38284
39006
  } catch (err) {
38285
39007
  try {
38286
- import_node_fs15.default.unlinkSync(tmpPath);
39008
+ import_node_fs16.default.unlinkSync(tmpPath);
38287
39009
  } catch {
38288
39010
  }
38289
39011
  throw new UploadError("STORAGE_ERROR", `write failed: ${err.message}`);
38290
39012
  }
38291
39013
  if (actualSize !== args.contentLength) {
38292
39014
  try {
38293
- import_node_fs15.default.unlinkSync(tmpPath);
39015
+ import_node_fs16.default.unlinkSync(tmpPath);
38294
39016
  } catch {
38295
39017
  }
38296
39018
  throw new UploadError(
@@ -38303,24 +39025,24 @@ async function writeUploadedAttachment(args) {
38303
39025
  let finalFileName;
38304
39026
  let hashDirExists = false;
38305
39027
  try {
38306
- hashDirExists = import_node_fs15.default.statSync(hashDir).isDirectory();
39028
+ hashDirExists = import_node_fs16.default.statSync(hashDir).isDirectory();
38307
39029
  } catch {
38308
39030
  }
38309
39031
  if (hashDirExists) {
38310
- const existing = import_node_fs15.default.readdirSync(hashDir).filter((n) => !n.startsWith("."));
39032
+ const existing = import_node_fs16.default.readdirSync(hashDir).filter((n) => !n.startsWith("."));
38311
39033
  finalFileName = existing[0] ?? args.fileName;
38312
39034
  try {
38313
- import_node_fs15.default.unlinkSync(tmpPath);
39035
+ import_node_fs16.default.unlinkSync(tmpPath);
38314
39036
  } catch {
38315
39037
  }
38316
39038
  } else {
38317
39039
  try {
38318
- import_node_fs15.default.mkdirSync(hashDir, { recursive: true });
39040
+ import_node_fs16.default.mkdirSync(hashDir, { recursive: true });
38319
39041
  finalFileName = args.fileName;
38320
- import_node_fs15.default.renameSync(tmpPath, import_node_path16.default.join(hashDir, finalFileName));
39042
+ import_node_fs16.default.renameSync(tmpPath, import_node_path16.default.join(hashDir, finalFileName));
38321
39043
  } catch (err) {
38322
39044
  try {
38323
- import_node_fs15.default.unlinkSync(tmpPath);
39045
+ import_node_fs16.default.unlinkSync(tmpPath);
38324
39046
  } catch {
38325
39047
  }
38326
39048
  throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
@@ -38844,7 +39566,7 @@ function withCtx(ctx, body) {
38844
39566
  function streamFile(res, absPath, logger) {
38845
39567
  let stat;
38846
39568
  try {
38847
- stat = import_node_fs16.default.statSync(absPath);
39569
+ stat = import_node_fs17.default.statSync(absPath);
38848
39570
  } catch (err) {
38849
39571
  const code = err?.code;
38850
39572
  if (code === "ENOENT") {
@@ -38867,7 +39589,7 @@ function streamFile(res, absPath, logger) {
38867
39589
  // 防止浏览器把任意 mime 当 html 渲染
38868
39590
  "X-Content-Type-Options": "nosniff"
38869
39591
  });
38870
- const stream = import_node_fs16.default.createReadStream(absPath);
39592
+ const stream = import_node_fs17.default.createReadStream(absPath);
38871
39593
  stream.on("error", (err) => {
38872
39594
  logger?.warn("streamFile read error", { absPath, err: err.message });
38873
39595
  res.destroy();
@@ -38876,7 +39598,7 @@ function streamFile(res, absPath, logger) {
38876
39598
  }
38877
39599
 
38878
39600
  // src/attachment/gc.ts
38879
- var import_node_fs17 = __toESM(require("fs"), 1);
39601
+ var import_node_fs18 = __toESM(require("fs"), 1);
38880
39602
  var import_node_path19 = __toESM(require("path"), 1);
38881
39603
  var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
38882
39604
  function runAttachmentGc(args) {
@@ -38899,7 +39621,7 @@ function runAttachmentGc(args) {
38899
39621
  const attRoot = import_node_path19.default.join(sessionDir, ".attachments");
38900
39622
  let hashDirs;
38901
39623
  try {
38902
- hashDirs = import_node_fs17.default.readdirSync(attRoot);
39624
+ hashDirs = import_node_fs18.default.readdirSync(attRoot);
38903
39625
  } catch (err) {
38904
39626
  if (err.code === "ENOENT") continue;
38905
39627
  args.logger?.warn("attachment gc: readdir failed", { attRoot, err: err.message });
@@ -38909,7 +39631,7 @@ function runAttachmentGc(args) {
38909
39631
  const hashDirAbs = import_node_path19.default.join(attRoot, hashDir);
38910
39632
  let files;
38911
39633
  try {
38912
- files = import_node_fs17.default.readdirSync(hashDirAbs);
39634
+ files = import_node_fs18.default.readdirSync(hashDirAbs);
38913
39635
  } catch {
38914
39636
  continue;
38915
39637
  }
@@ -38917,7 +39639,7 @@ function runAttachmentGc(args) {
38917
39639
  const file = import_node_path19.default.join(hashDirAbs, name);
38918
39640
  let stat;
38919
39641
  try {
38920
- stat = import_node_fs17.default.statSync(file);
39642
+ stat = import_node_fs18.default.statSync(file);
38921
39643
  } catch {
38922
39644
  continue;
38923
39645
  }
@@ -38926,25 +39648,25 @@ function runAttachmentGc(args) {
38926
39648
  if (age < ttlMs) continue;
38927
39649
  if (liveAbs.has(file)) continue;
38928
39650
  try {
38929
- import_node_fs17.default.unlinkSync(file);
39651
+ import_node_fs18.default.unlinkSync(file);
38930
39652
  } catch (err) {
38931
39653
  args.logger?.warn("attachment gc: unlink failed", { file, err: err.message });
38932
39654
  }
38933
39655
  }
38934
39656
  try {
38935
- if (import_node_fs17.default.readdirSync(hashDirAbs).length === 0) import_node_fs17.default.rmdirSync(hashDirAbs);
39657
+ if (import_node_fs18.default.readdirSync(hashDirAbs).length === 0) import_node_fs18.default.rmdirSync(hashDirAbs);
38936
39658
  } catch {
38937
39659
  }
38938
39660
  }
38939
39661
  try {
38940
- if (import_node_fs17.default.readdirSync(attRoot).length === 0) import_node_fs17.default.rmdirSync(attRoot);
39662
+ if (import_node_fs18.default.readdirSync(attRoot).length === 0) import_node_fs18.default.rmdirSync(attRoot);
38941
39663
  } catch {
38942
39664
  }
38943
39665
  }
38944
39666
  }
38945
39667
 
38946
39668
  // src/attachment/group.ts
38947
- var import_node_fs18 = __toESM(require("fs"), 1);
39669
+ var import_node_fs19 = __toESM(require("fs"), 1);
38948
39670
  var import_node_path20 = __toESM(require("path"), 1);
38949
39671
  var import_node_crypto6 = __toESM(require("crypto"), 1);
38950
39672
  init_protocol();
@@ -38970,7 +39692,7 @@ var GroupFileStore = class {
38970
39692
  readFile(scope, sessionId) {
38971
39693
  const file = this.filePath(scope, sessionId);
38972
39694
  try {
38973
- const raw = import_node_fs18.default.readFileSync(file, "utf8");
39695
+ const raw = import_node_fs19.default.readFileSync(file, "utf8");
38974
39696
  const parsed = JSON.parse(raw);
38975
39697
  if (!Array.isArray(parsed)) {
38976
39698
  this.logger?.warn("GroupFileStore.readFile: not an array; resetting session entries", {
@@ -38996,10 +39718,10 @@ var GroupFileStore = class {
38996
39718
  }
38997
39719
  writeFile(scope, sessionId, entries) {
38998
39720
  const file = this.filePath(scope, sessionId);
38999
- import_node_fs18.default.mkdirSync(import_node_path20.default.dirname(file), { recursive: true });
39721
+ import_node_fs19.default.mkdirSync(import_node_path20.default.dirname(file), { recursive: true });
39000
39722
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
39001
- import_node_fs18.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
39002
- import_node_fs18.default.renameSync(tmp, file);
39723
+ import_node_fs19.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
39724
+ import_node_fs19.default.renameSync(tmp, file);
39003
39725
  }
39004
39726
  /** 拉一份当前 session 的清单。读盘 → cache;之后调用复用 cache */
39005
39727
  list(scope, sessionId) {
@@ -39085,7 +39807,7 @@ var GroupFileStore = class {
39085
39807
  };
39086
39808
 
39087
39809
  // src/discovery/state-file.ts
39088
- var import_node_fs19 = __toESM(require("fs"), 1);
39810
+ var import_node_fs20 = __toESM(require("fs"), 1);
39089
39811
  var import_node_path21 = __toESM(require("path"), 1);
39090
39812
  function defaultStateFilePath(dataDir) {
39091
39813
  return import_node_path21.default.join(dataDir, "state.json");
@@ -39110,7 +39832,7 @@ var StateFileManager = class {
39110
39832
  }
39111
39833
  read() {
39112
39834
  try {
39113
- const raw = import_node_fs19.default.readFileSync(this.file, "utf8");
39835
+ const raw = import_node_fs20.default.readFileSync(this.file, "utf8");
39114
39836
  const parsed = JSON.parse(raw);
39115
39837
  return parsed;
39116
39838
  } catch {
@@ -39124,41 +39846,33 @@ var StateFileManager = class {
39124
39846
  return { status: "stale", existing };
39125
39847
  }
39126
39848
  write(state) {
39127
- import_node_fs19.default.mkdirSync(import_node_path21.default.dirname(this.file), { recursive: true });
39849
+ import_node_fs20.default.mkdirSync(import_node_path21.default.dirname(this.file), { recursive: true });
39128
39850
  const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
39129
- import_node_fs19.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
39130
- import_node_fs19.default.renameSync(tmp, this.file);
39851
+ import_node_fs20.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
39852
+ import_node_fs20.default.renameSync(tmp, this.file);
39131
39853
  if (process.platform !== "win32") {
39132
39854
  try {
39133
- import_node_fs19.default.chmodSync(this.file, 384);
39855
+ import_node_fs20.default.chmodSync(this.file, 384);
39134
39856
  } catch {
39135
39857
  }
39136
39858
  }
39137
39859
  }
39138
39860
  delete() {
39139
39861
  try {
39140
- import_node_fs19.default.unlinkSync(this.file);
39862
+ import_node_fs20.default.unlinkSync(this.file);
39141
39863
  } catch {
39142
39864
  }
39143
39865
  }
39144
39866
  };
39145
39867
 
39146
- // src/discovery/source-from-env.ts
39147
- function readDaemonSourceFromEnv(env = process.env) {
39148
- const v2 = env.CLAWD_DAEMON_SOURCE;
39149
- if (typeof v2 !== "string") return void 0;
39150
- const trimmed = v2.trim();
39151
- return trimmed.length > 0 ? trimmed : void 0;
39152
- }
39153
-
39154
39868
  // src/tunnel/tunnel-manager.ts
39155
- var import_node_fs23 = __toESM(require("fs"), 1);
39869
+ var import_node_fs24 = __toESM(require("fs"), 1);
39156
39870
  var import_node_path25 = __toESM(require("path"), 1);
39157
39871
  var import_node_crypto7 = __toESM(require("crypto"), 1);
39158
- var import_node_child_process5 = require("child_process");
39872
+ var import_node_child_process9 = require("child_process");
39159
39873
 
39160
39874
  // src/tunnel/tunnel-store.ts
39161
- var import_node_fs20 = __toESM(require("fs"), 1);
39875
+ var import_node_fs21 = __toESM(require("fs"), 1);
39162
39876
  var import_node_path22 = __toESM(require("path"), 1);
39163
39877
  var TunnelStore = class {
39164
39878
  constructor(filePath) {
@@ -39167,7 +39881,7 @@ var TunnelStore = class {
39167
39881
  filePath;
39168
39882
  async get() {
39169
39883
  try {
39170
- const raw = await import_node_fs20.default.promises.readFile(this.filePath, "utf8");
39884
+ const raw = await import_node_fs21.default.promises.readFile(this.filePath, "utf8");
39171
39885
  const obj = JSON.parse(raw);
39172
39886
  if (!isPersistedTunnel(obj)) return null;
39173
39887
  return obj;
@@ -39179,21 +39893,21 @@ var TunnelStore = class {
39179
39893
  }
39180
39894
  async set(v2) {
39181
39895
  const dir = import_node_path22.default.dirname(this.filePath);
39182
- await import_node_fs20.default.promises.mkdir(dir, { recursive: true });
39896
+ await import_node_fs21.default.promises.mkdir(dir, { recursive: true });
39183
39897
  const data = JSON.stringify(v2, null, 2);
39184
39898
  const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
39185
- await import_node_fs20.default.promises.writeFile(tmp, data, { mode: 384 });
39899
+ await import_node_fs21.default.promises.writeFile(tmp, data, { mode: 384 });
39186
39900
  if (process.platform !== "win32") {
39187
39901
  try {
39188
- await import_node_fs20.default.promises.chmod(tmp, 384);
39902
+ await import_node_fs21.default.promises.chmod(tmp, 384);
39189
39903
  } catch {
39190
39904
  }
39191
39905
  }
39192
- await import_node_fs20.default.promises.rename(tmp, this.filePath);
39906
+ await import_node_fs21.default.promises.rename(tmp, this.filePath);
39193
39907
  }
39194
39908
  async clear() {
39195
39909
  try {
39196
- await import_node_fs20.default.promises.unlink(this.filePath);
39910
+ await import_node_fs21.default.promises.unlink(this.filePath);
39197
39911
  } catch (err) {
39198
39912
  const code = err?.code;
39199
39913
  if (code !== "ENOENT") throw err;
@@ -39288,10 +40002,10 @@ function escape(v2) {
39288
40002
  }
39289
40003
 
39290
40004
  // src/tunnel/frpc-binary.ts
39291
- var import_node_fs21 = __toESM(require("fs"), 1);
40005
+ var import_node_fs22 = __toESM(require("fs"), 1);
39292
40006
  var import_node_os11 = __toESM(require("os"), 1);
39293
40007
  var import_node_path23 = __toESM(require("path"), 1);
39294
- var import_node_child_process3 = require("child_process");
40008
+ var import_node_child_process7 = require("child_process");
39295
40009
  var import_node_stream2 = require("stream");
39296
40010
  var import_promises3 = require("stream/promises");
39297
40011
  var FRPC_VERSION = "0.68.0";
@@ -39322,7 +40036,7 @@ function frpcDownloadUrl(version2, p2) {
39322
40036
  }
39323
40037
  async function ensureFrpcBinary(opts) {
39324
40038
  if (opts.override) {
39325
- if (!import_node_fs21.default.existsSync(opts.override)) {
40039
+ if (!import_node_fs22.default.existsSync(opts.override)) {
39326
40040
  throw new Error(`frpc binary not found at override path: ${opts.override}`);
39327
40041
  }
39328
40042
  return opts.override;
@@ -39330,10 +40044,10 @@ async function ensureFrpcBinary(opts) {
39330
40044
  const version2 = opts.version ?? FRPC_VERSION;
39331
40045
  const platform = opts.platform ?? detectPlatform();
39332
40046
  const binDir = import_node_path23.default.join(opts.dataDir, "bin");
39333
- import_node_fs21.default.mkdirSync(binDir, { recursive: true });
40047
+ import_node_fs22.default.mkdirSync(binDir, { recursive: true });
39334
40048
  cleanupStaleArtifacts(binDir);
39335
40049
  const stableBin = import_node_path23.default.join(binDir, "frpc");
39336
- if (import_node_fs21.default.existsSync(stableBin)) return stableBin;
40050
+ if (import_node_fs22.default.existsSync(stableBin)) return stableBin;
39337
40051
  const partialBin = `${stableBin}.partial`;
39338
40052
  const tarballPath = import_node_path23.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
39339
40053
  try {
@@ -39344,8 +40058,8 @@ async function ensureFrpcBinary(opts) {
39344
40058
  } else {
39345
40059
  await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
39346
40060
  }
39347
- import_node_fs21.default.chmodSync(partialBin, 493);
39348
- import_node_fs21.default.renameSync(partialBin, stableBin);
40061
+ import_node_fs22.default.chmodSync(partialBin, 493);
40062
+ import_node_fs22.default.renameSync(partialBin, stableBin);
39349
40063
  } finally {
39350
40064
  safeUnlink(tarballPath);
39351
40065
  safeUnlink(partialBin);
@@ -39355,7 +40069,7 @@ async function ensureFrpcBinary(opts) {
39355
40069
  function cleanupStaleArtifacts(binDir) {
39356
40070
  let entries;
39357
40071
  try {
39358
- entries = import_node_fs21.default.readdirSync(binDir);
40072
+ entries = import_node_fs22.default.readdirSync(binDir);
39359
40073
  } catch {
39360
40074
  return;
39361
40075
  }
@@ -39363,7 +40077,7 @@ function cleanupStaleArtifacts(binDir) {
39363
40077
  if (name.endsWith(".partial") || name.startsWith("extract-")) {
39364
40078
  const full = import_node_path23.default.join(binDir, name);
39365
40079
  try {
39366
- import_node_fs21.default.rmSync(full, { recursive: true, force: true });
40080
+ import_node_fs22.default.rmSync(full, { recursive: true, force: true });
39367
40081
  } catch {
39368
40082
  }
39369
40083
  }
@@ -39371,7 +40085,7 @@ function cleanupStaleArtifacts(binDir) {
39371
40085
  }
39372
40086
  function safeUnlink(p2) {
39373
40087
  try {
39374
- import_node_fs21.default.unlinkSync(p2);
40088
+ import_node_fs22.default.unlinkSync(p2);
39375
40089
  } catch {
39376
40090
  }
39377
40091
  }
@@ -39382,46 +40096,46 @@ async function downloadToFile(url, dest, fetchImpl) {
39382
40096
  if (!res.ok || !res.body) {
39383
40097
  throw new Error(`download failed: ${res.status} ${res.statusText}`);
39384
40098
  }
39385
- const out = import_node_fs21.default.createWriteStream(dest);
40099
+ const out = import_node_fs22.default.createWriteStream(dest);
39386
40100
  const nodeStream = import_node_stream2.Readable.fromWeb(res.body);
39387
40101
  await (0, import_promises3.pipeline)(nodeStream, out);
39388
40102
  }
39389
40103
  async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
39390
40104
  const work = import_node_path23.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
39391
- import_node_fs21.default.mkdirSync(work, { recursive: true });
40105
+ import_node_fs22.default.mkdirSync(work, { recursive: true });
39392
40106
  try {
39393
40107
  await new Promise((resolve6, reject) => {
39394
- const proc = (0, import_node_child_process3.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
40108
+ const proc = (0, import_node_child_process7.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
39395
40109
  proc.on("error", reject);
39396
40110
  proc.on("exit", (code) => code === 0 ? resolve6() : reject(new Error(`tar exited ${code}`)));
39397
40111
  });
39398
40112
  const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
39399
40113
  const src = import_node_path23.default.join(work, dirName, "frpc");
39400
- if (!import_node_fs21.default.existsSync(src)) {
40114
+ if (!import_node_fs22.default.existsSync(src)) {
39401
40115
  throw new Error(`frpc not found inside tarball at ${src}`);
39402
40116
  }
39403
- import_node_fs21.default.copyFileSync(src, destBin);
40117
+ import_node_fs22.default.copyFileSync(src, destBin);
39404
40118
  } finally {
39405
- import_node_fs21.default.rmSync(work, { recursive: true, force: true });
40119
+ import_node_fs22.default.rmSync(work, { recursive: true, force: true });
39406
40120
  }
39407
40121
  }
39408
40122
 
39409
40123
  // src/tunnel/frpc-process.ts
39410
- var import_node_fs22 = __toESM(require("fs"), 1);
40124
+ var import_node_fs23 = __toESM(require("fs"), 1);
39411
40125
  var import_node_path24 = __toESM(require("path"), 1);
39412
- var import_node_child_process4 = require("child_process");
40126
+ var import_node_child_process8 = require("child_process");
39413
40127
  function frpcPidFilePath(dataDir) {
39414
40128
  return import_node_path24.default.join(dataDir, "frpc.pid");
39415
40129
  }
39416
40130
  function writeFrpcPid(dataDir, pid) {
39417
40131
  try {
39418
- import_node_fs22.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
40132
+ import_node_fs23.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
39419
40133
  } catch {
39420
40134
  }
39421
40135
  }
39422
40136
  function clearFrpcPid(dataDir) {
39423
40137
  try {
39424
- import_node_fs22.default.unlinkSync(frpcPidFilePath(dataDir));
40138
+ import_node_fs23.default.unlinkSync(frpcPidFilePath(dataDir));
39425
40139
  } catch {
39426
40140
  }
39427
40141
  }
@@ -39437,7 +40151,7 @@ function defaultIsPidAlive(pid) {
39437
40151
  }
39438
40152
  function defaultReadPidFile(file) {
39439
40153
  try {
39440
- return import_node_fs22.default.readFileSync(file, "utf8");
40154
+ return import_node_fs23.default.readFileSync(file, "utf8");
39441
40155
  } catch {
39442
40156
  return null;
39443
40157
  }
@@ -39477,7 +40191,7 @@ async function killStaleFrpc(deps) {
39477
40191
  }
39478
40192
  if (victims.size === 0) {
39479
40193
  try {
39480
- import_node_fs22.default.unlinkSync(pidFile);
40194
+ import_node_fs23.default.unlinkSync(pidFile);
39481
40195
  } catch {
39482
40196
  }
39483
40197
  return;
@@ -39488,14 +40202,14 @@ async function killStaleFrpc(deps) {
39488
40202
  }
39489
40203
  await sleep(deps.reapWaitMs ?? 300);
39490
40204
  try {
39491
- import_node_fs22.default.unlinkSync(pidFile);
40205
+ import_node_fs23.default.unlinkSync(pidFile);
39492
40206
  } catch {
39493
40207
  }
39494
40208
  }
39495
40209
  async function defaultScanFrpcPidsByCmdline(tomlPath, logger) {
39496
40210
  if (process.platform === "win32") return [];
39497
40211
  return new Promise((resolve6) => {
39498
- const ps = (0, import_node_child_process4.spawn)("ps", ["-axo", "pid=,command="], { stdio: ["ignore", "pipe", "ignore"] });
40212
+ const ps = (0, import_node_child_process8.spawn)("ps", ["-axo", "pid=,command="], { stdio: ["ignore", "pipe", "ignore"] });
39499
40213
  let buf = "";
39500
40214
  ps.stdout.on("data", (c) => {
39501
40215
  buf += c.toString();
@@ -39663,12 +40377,12 @@ var TunnelManager = class {
39663
40377
  localPort,
39664
40378
  logLevel: "info"
39665
40379
  });
39666
- await import_node_fs23.default.promises.writeFile(tomlPath, toml, { mode: 384 });
39667
- const proc = (this.deps.spawnImpl ?? import_node_child_process5.spawn)(frpcBin, ["-c", tomlPath], {
40380
+ await import_node_fs24.default.promises.writeFile(tomlPath, toml, { mode: 384 });
40381
+ const proc = (this.deps.spawnImpl ?? import_node_child_process9.spawn)(frpcBin, ["-c", tomlPath], {
39668
40382
  stdio: ["ignore", "pipe", "pipe"]
39669
40383
  });
39670
40384
  const logFilePath = import_node_path25.default.join(this.deps.dataDir, "frpc.log");
39671
- const logStream = import_node_fs23.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
40385
+ const logStream = import_node_fs24.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
39672
40386
  logStream.on("error", () => {
39673
40387
  });
39674
40388
  const tee = (chunk) => {
@@ -39766,7 +40480,7 @@ function deriveStableDeviceKey(opts = {}) {
39766
40480
  }
39767
40481
 
39768
40482
  // src/auth-store.ts
39769
- var import_node_fs24 = __toESM(require("fs"), 1);
40483
+ var import_node_fs25 = __toESM(require("fs"), 1);
39770
40484
  var import_node_path27 = __toESM(require("path"), 1);
39771
40485
  var import_node_crypto9 = __toESM(require("crypto"), 1);
39772
40486
  var AUTH_FILE_NAME = "auth.json";
@@ -39805,7 +40519,7 @@ function defaultGenerateOwnerPrincipalId() {
39805
40519
  }
39806
40520
  function readAuthFile(file) {
39807
40521
  try {
39808
- const raw = import_node_fs24.default.readFileSync(file, "utf8");
40522
+ const raw = import_node_fs25.default.readFileSync(file, "utf8");
39809
40523
  const parsed = JSON.parse(raw);
39810
40524
  if (typeof parsed?.token !== "string" || parsed.token.length === 0) {
39811
40525
  return null;
@@ -39824,16 +40538,16 @@ function readAuthFile(file) {
39824
40538
  }
39825
40539
  }
39826
40540
  function writeAuthFile(file, content) {
39827
- import_node_fs24.default.mkdirSync(import_node_path27.default.dirname(file), { recursive: true });
39828
- import_node_fs24.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
40541
+ import_node_fs25.default.mkdirSync(import_node_path27.default.dirname(file), { recursive: true });
40542
+ import_node_fs25.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
39829
40543
  try {
39830
- import_node_fs24.default.chmodSync(file, 384);
40544
+ import_node_fs25.default.chmodSync(file, 384);
39831
40545
  } catch {
39832
40546
  }
39833
40547
  }
39834
40548
 
39835
40549
  // src/owner-profile.ts
39836
- var import_node_fs25 = __toESM(require("fs"), 1);
40550
+ var import_node_fs26 = __toESM(require("fs"), 1);
39837
40551
  var import_node_os13 = __toESM(require("os"), 1);
39838
40552
  var import_node_path28 = __toESM(require("path"), 1);
39839
40553
  var PROFILE_FILENAME = "profile.json";
@@ -39842,7 +40556,7 @@ function loadOwnerDisplayName(dataDir) {
39842
40556
  const profilePath = import_node_path28.default.join(dataDir, PROFILE_FILENAME);
39843
40557
  let raw;
39844
40558
  try {
39845
- raw = import_node_fs25.default.readFileSync(profilePath, "utf8");
40559
+ raw = import_node_fs26.default.readFileSync(profilePath, "utf8");
39846
40560
  } catch {
39847
40561
  return fallback;
39848
40562
  }
@@ -39865,7 +40579,7 @@ function loadOwnerDisplayName(dataDir) {
39865
40579
  }
39866
40580
 
39867
40581
  // src/feishu-auth/owner-identity-store.ts
39868
- var import_node_fs26 = __toESM(require("fs"), 1);
40582
+ var import_node_fs27 = __toESM(require("fs"), 1);
39869
40583
  var import_node_path29 = __toESM(require("path"), 1);
39870
40584
  var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
39871
40585
  var OwnerIdentityStore = class {
@@ -39876,7 +40590,7 @@ var OwnerIdentityStore = class {
39876
40590
  read() {
39877
40591
  let raw;
39878
40592
  try {
39879
- raw = import_node_fs26.default.readFileSync(this.file, "utf8");
40593
+ raw = import_node_fs27.default.readFileSync(this.file, "utf8");
39880
40594
  } catch {
39881
40595
  return null;
39882
40596
  }
@@ -39903,16 +40617,16 @@ var OwnerIdentityStore = class {
39903
40617
  };
39904
40618
  }
39905
40619
  write(record) {
39906
- import_node_fs26.default.mkdirSync(import_node_path29.default.dirname(this.file), { recursive: true });
39907
- import_node_fs26.default.writeFileSync(this.file, JSON.stringify(record, null, 2), { mode: 384 });
40620
+ import_node_fs27.default.mkdirSync(import_node_path29.default.dirname(this.file), { recursive: true });
40621
+ import_node_fs27.default.writeFileSync(this.file, JSON.stringify(record, null, 2), { mode: 384 });
39908
40622
  try {
39909
- import_node_fs26.default.chmodSync(this.file, 384);
40623
+ import_node_fs27.default.chmodSync(this.file, 384);
39910
40624
  } catch {
39911
40625
  }
39912
40626
  }
39913
40627
  clear() {
39914
40628
  try {
39915
- import_node_fs26.default.unlinkSync(this.file);
40629
+ import_node_fs27.default.unlinkSync(this.file);
39916
40630
  } catch (err) {
39917
40631
  const code = err?.code;
39918
40632
  if (code !== "ENOENT") throw err;
@@ -40175,7 +40889,7 @@ function verifyConnectToken(args) {
40175
40889
  }
40176
40890
 
40177
40891
  // src/feishu-auth/server-key.ts
40178
- var fs35 = __toESM(require("fs"), 1);
40892
+ var fs36 = __toESM(require("fs"), 1);
40179
40893
  var path38 = __toESM(require("path"), 1);
40180
40894
  var FILE_NAME2 = "server-signing-key.json";
40181
40895
  var ServerKeyStore = class {
@@ -40189,7 +40903,7 @@ var ServerKeyStore = class {
40189
40903
  /** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
40190
40904
  read() {
40191
40905
  try {
40192
- const raw = fs35.readFileSync(this.filePath(), "utf8");
40906
+ const raw = fs36.readFileSync(this.filePath(), "utf8");
40193
40907
  const parsed = JSON.parse(raw);
40194
40908
  if (typeof parsed.publicKeyPem === "string" && parsed.publicKeyPem.includes("PUBLIC KEY")) {
40195
40909
  return parsed.publicKeyPem;
@@ -40204,12 +40918,12 @@ var ServerKeyStore = class {
40204
40918
  publicKeyPem,
40205
40919
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
40206
40920
  };
40207
- fs35.mkdirSync(this.dataDir, { recursive: true });
40208
- fs35.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
40921
+ fs36.mkdirSync(this.dataDir, { recursive: true });
40922
+ fs36.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
40209
40923
  }
40210
40924
  clear() {
40211
40925
  try {
40212
- fs35.unlinkSync(this.filePath());
40926
+ fs36.unlinkSync(this.filePath());
40213
40927
  } catch {
40214
40928
  }
40215
40929
  }
@@ -40222,12 +40936,12 @@ init_protocol();
40222
40936
  init_protocol();
40223
40937
 
40224
40938
  // src/session/fork.ts
40225
- var import_node_fs27 = __toESM(require("fs"), 1);
40939
+ var import_node_fs28 = __toESM(require("fs"), 1);
40226
40940
  var import_node_os14 = __toESM(require("os"), 1);
40227
40941
  var import_node_path30 = __toESM(require("path"), 1);
40228
40942
  init_claude_history();
40229
40943
  function readJsonlEntries(file) {
40230
- const raw = import_node_fs27.default.readFileSync(file, "utf8");
40944
+ const raw = import_node_fs28.default.readFileSync(file, "utf8");
40231
40945
  const out = [];
40232
40946
  for (const line of raw.split("\n")) {
40233
40947
  const t = line.trim();
@@ -40243,7 +40957,7 @@ function forkSession(input) {
40243
40957
  const baseDir = input.baseDir ?? import_node_path30.default.join(import_node_os14.default.homedir(), ".claude");
40244
40958
  const projectDir = import_node_path30.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
40245
40959
  const sourceFile = import_node_path30.default.join(projectDir, `${input.toolSessionId}.jsonl`);
40246
- if (!import_node_fs27.default.existsSync(sourceFile)) {
40960
+ if (!import_node_fs28.default.existsSync(sourceFile)) {
40247
40961
  throw new Error(`fork: source transcript not found: ${sourceFile}`);
40248
40962
  }
40249
40963
  const entries = readJsonlEntries(sourceFile);
@@ -40274,8 +40988,8 @@ function forkSession(input) {
40274
40988
  forkedLines.push(JSON.stringify(forked));
40275
40989
  }
40276
40990
  const forkedFilePath = import_node_path30.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
40277
- import_node_fs27.default.mkdirSync(projectDir, { recursive: true });
40278
- import_node_fs27.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
40991
+ import_node_fs28.default.mkdirSync(projectDir, { recursive: true });
40992
+ import_node_fs28.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
40279
40993
  return { forkedToolSessionId, forkedFilePath };
40280
40994
  }
40281
40995
 
@@ -40465,6 +41179,13 @@ function buildSessionHandlers(deps) {
40465
41179
  const sessionFile = file;
40466
41180
  manager.ensureSession(sessionFile);
40467
41181
  const adapter = getAdapter2(sessionFile.tool ?? "claude");
41182
+ const caps = await adapter.capabilities();
41183
+ if (caps.features.observe === false) {
41184
+ throw new ClawdError(
41185
+ ERROR_CODES.TOOL_NOT_SUPPORTED,
41186
+ `tool ${sessionFile.tool ?? "claude"} does not support observe`
41187
+ );
41188
+ }
40468
41189
  observer.start({
40469
41190
  sessionId: args.sessionId,
40470
41191
  cwd: sessionFile.cwd,
@@ -40714,7 +41435,7 @@ function assertGuestPath(ctx, absPath, personaRoot, method, usersRoot) {
40714
41435
  }
40715
41436
  }
40716
41437
  function buildHistoryHandlers(deps) {
40717
- const { manager, history, store, personaRoot, usersRoot } = deps;
41438
+ const { manager, history, getHistoryReader, store, personaRoot, usersRoot } = deps;
40718
41439
  const projects = async (_frame, _client, ctx) => {
40719
41440
  const list2 = await history.listProjects();
40720
41441
  if (ctx?.principal.kind === "guest" && personaRoot) {
@@ -40758,7 +41479,7 @@ function buildHistoryHandlers(deps) {
40758
41479
  response: { type: "history:read", messages: [], total: 0, offset: 0 }
40759
41480
  };
40760
41481
  }
40761
- const res = await history.read({
41482
+ const res = await getHistoryReader(f.tool ?? "claude").read({
40762
41483
  cwd: f.cwd,
40763
41484
  toolSessionId: f.toolSessionId,
40764
41485
  limit: args.limit,
@@ -40837,7 +41558,7 @@ function assertGuestPath2(ctx, absPath, personaRoot, method, usersRoot) {
40837
41558
  }
40838
41559
  }
40839
41560
  function buildWorkspaceHandlers(deps) {
40840
- const { workspace, skills, agents, personaRoot, personaManager, usersRoot } = deps;
41561
+ const { workspace, skills, agents, getSkillsForTool, personaRoot, personaManager, usersRoot } = deps;
40841
41562
  const list = async (frame, _client, ctx) => {
40842
41563
  const args = WorkspaceListArgs.parse(frame);
40843
41564
  const isGuest = ctx?.principal.kind === "guest";
@@ -40859,7 +41580,7 @@ function buildWorkspaceHandlers(deps) {
40859
41580
  const args = SkillsListArgs.parse(frame);
40860
41581
  const cwdAbs = path42.resolve(args.cwd);
40861
41582
  assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
40862
- const list2 = skills.list(args);
41583
+ const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
40863
41584
  if (ctx?.principal.kind === "guest" && personaRoot) {
40864
41585
  const personaId = personaIdFromPath(cwdAbs, personaRoot);
40865
41586
  const enabled = personaId ? buildEnabledPluginNames(personaManager, personaId) : /* @__PURE__ */ new Set();
@@ -40871,6 +41592,9 @@ function buildWorkspaceHandlers(deps) {
40871
41592
  const args = AgentsListArgs.parse(frame);
40872
41593
  const cwdAbs = path42.resolve(args.cwd);
40873
41594
  assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
41595
+ if (args.tool === "codex") {
41596
+ return { response: { type: "agents:list", agents: [] } };
41597
+ }
40874
41598
  const list2 = agents.list(args);
40875
41599
  if (ctx?.principal.kind === "guest" && personaRoot) {
40876
41600
  const personaId = personaIdFromPath(cwdAbs, personaRoot);
@@ -40893,15 +41617,15 @@ init_protocol();
40893
41617
  init_protocol();
40894
41618
 
40895
41619
  // src/workspace/git.ts
40896
- var import_node_child_process6 = require("child_process");
40897
- var import_node_fs28 = __toESM(require("fs"), 1);
41620
+ var import_node_child_process10 = require("child_process");
41621
+ var import_node_fs29 = __toESM(require("fs"), 1);
40898
41622
  var import_node_path31 = __toESM(require("path"), 1);
40899
41623
  var import_node_util = require("util");
40900
- var pexec = (0, import_node_util.promisify)(import_node_child_process6.execFile);
41624
+ var pexec = (0, import_node_util.promisify)(import_node_child_process10.execFile);
40901
41625
  function normalizePath(p2) {
40902
41626
  const resolved = import_node_path31.default.resolve(p2);
40903
41627
  try {
40904
- return import_node_fs28.default.realpathSync(resolved);
41628
+ return import_node_fs29.default.realpathSync(resolved);
40905
41629
  } catch {
40906
41630
  return resolved;
40907
41631
  }
@@ -42091,22 +42815,22 @@ function pickExtId(frame) {
42091
42815
  }
42092
42816
  return extId;
42093
42817
  }
42094
- function composeState(rec, running, crashed, getPort) {
42095
- if (rec.state === "invalid") return rec;
42096
- if (manifestMode(rec.manifest) === "hosted") {
42818
+ function composeState(rec3, running, crashed, getPort) {
42819
+ if (rec3.state === "invalid") return rec3;
42820
+ if (manifestMode(rec3.manifest) === "hosted") {
42097
42821
  return {
42098
- ...rec,
42822
+ ...rec3,
42099
42823
  state: "running",
42100
- target: { kind: "hosted", url: rec.manifest.entry.url }
42824
+ target: { kind: "hosted", url: rec3.manifest.entry.url }
42101
42825
  };
42102
42826
  }
42103
- if (running.has(rec.extId)) {
42104
- const port = getPort(rec.extId);
42105
- if (port == null) return rec;
42106
- return { ...rec, state: "running", target: { kind: "local", port } };
42827
+ if (running.has(rec3.extId)) {
42828
+ const port = getPort(rec3.extId);
42829
+ if (port == null) return rec3;
42830
+ return { ...rec3, state: "running", target: { kind: "local", port } };
42107
42831
  }
42108
- if (crashed.has(rec.extId)) return { ...rec, state: "crashed" };
42109
- return rec;
42832
+ if (crashed.has(rec3.extId)) return { ...rec3, state: "crashed" };
42833
+ return rec3;
42110
42834
  }
42111
42835
  function buildExtensionHandlers(deps) {
42112
42836
  const list = async (_frame, _client, ctx) => {
@@ -42323,7 +43047,7 @@ function buildExtensionHandlers(deps) {
42323
43047
  }
42324
43048
 
42325
43049
  // src/app-builder/kill-port.ts
42326
- var import_node_child_process7 = require("child_process");
43050
+ var import_node_child_process11 = require("child_process");
42327
43051
  async function killPortOccupants(port, ownedPids, logger) {
42328
43052
  let pids;
42329
43053
  try {
@@ -42365,7 +43089,7 @@ async function killPortOccupants(port, ownedPids, logger) {
42365
43089
  }
42366
43090
  function listPidsOnPort(port) {
42367
43091
  return new Promise((resolve6, reject) => {
42368
- (0, import_node_child_process7.execFile)(
43092
+ (0, import_node_child_process11.execFile)(
42369
43093
  "lsof",
42370
43094
  ["-ti", `:${port}`],
42371
43095
  { timeout: 3e3 },
@@ -42437,8 +43161,8 @@ var PublishJobRegistry = class {
42437
43161
  };
42438
43162
 
42439
43163
  // src/app-builder/publish-job-runner.ts
42440
- var import_node_child_process8 = require("child_process");
42441
- var import_node_fs29 = require("fs");
43164
+ var import_node_child_process12 = require("child_process");
43165
+ var import_node_fs30 = require("fs");
42442
43166
  var import_node_path38 = require("path");
42443
43167
 
42444
43168
  // src/app-builder/publish-stage-parser.ts
@@ -42466,7 +43190,7 @@ function tailStderrLines(buf, n) {
42466
43190
  // src/app-builder/publish-job-runner.ts
42467
43191
  async function startPublishJob(deps, args) {
42468
43192
  const { registry: registry2, projectDir } = deps;
42469
- const spawn9 = deps.spawnImpl ?? import_node_child_process8.spawn;
43193
+ const spawn12 = deps.spawnImpl ?? import_node_child_process12.spawn;
42470
43194
  if (registry2.has(args.name)) {
42471
43195
  return { jobId: registry2.get(args.name).jobId, status: "already-publishing" };
42472
43196
  }
@@ -42474,11 +43198,11 @@ async function startPublishJob(deps, args) {
42474
43198
  const logPath = (0, import_node_path38.join)(projDir, ".publish.log");
42475
43199
  let logStream = null;
42476
43200
  try {
42477
- logStream = (0, import_node_fs29.createWriteStream)(logPath, { flags: "w" });
43201
+ logStream = (0, import_node_fs30.createWriteStream)(logPath, { flags: "w" });
42478
43202
  } catch {
42479
43203
  logStream = null;
42480
43204
  }
42481
- const child = spawn9("bash", [args.scriptPath, projDir], {
43205
+ const child = spawn12("bash", [args.scriptPath, projDir], {
42482
43206
  cwd: projDir,
42483
43207
  env: process.env,
42484
43208
  stdio: ["ignore", "pipe", "pipe"]
@@ -42732,7 +43456,7 @@ async function recoverInterruptedJobs(deps) {
42732
43456
  // src/handlers/app-builder.ts
42733
43457
  init_protocol();
42734
43458
  var import_node_path39 = require("path");
42735
- var import_node_fs30 = require("fs");
43459
+ var import_node_fs31 = require("fs");
42736
43460
  var APP_BUILDER_PERSONAS = ["persona-app-builder"];
42737
43461
  var PUBLISH_SCRIPT_REL = "extension-kit/scripts/publish.sh";
42738
43462
  var DEV_SERVER_READY_TIMEOUT_MS = 3e4;
@@ -42814,7 +43538,7 @@ function buildAppBuilderHandlers(deps) {
42814
43538
  async function listAllUsersProjects() {
42815
43539
  if (!deps.usersRoot || !deps.getStore) return [];
42816
43540
  const getStore = deps.getStore;
42817
- const userIds = await import_node_fs30.promises.readdir(deps.usersRoot).catch(() => []);
43541
+ const userIds = await import_node_fs31.promises.readdir(deps.usersRoot).catch(() => []);
42818
43542
  const perUser = await Promise.all(
42819
43543
  userIds.map((uid) => getStore(uid).list().catch(() => []))
42820
43544
  );
@@ -43354,8 +44078,8 @@ function buildMethodHandlers(deps) {
43354
44078
  }
43355
44079
 
43356
44080
  // src/app-builder/project-store.ts
43357
- var import_node_fs31 = require("fs");
43358
- var import_node_child_process9 = require("child_process");
44081
+ var import_node_fs32 = require("fs");
44082
+ var import_node_child_process13 = require("child_process");
43359
44083
  var import_node_path42 = require("path");
43360
44084
  init_protocol();
43361
44085
  var PROJECTS_DIR = "projects";
@@ -43383,7 +44107,7 @@ var ProjectStore = class {
43383
44107
  async list() {
43384
44108
  let entries;
43385
44109
  try {
43386
- entries = await import_node_fs31.promises.readdir(this.projectsRoot());
44110
+ entries = await import_node_fs32.promises.readdir(this.projectsRoot());
43387
44111
  } catch (err) {
43388
44112
  if (err.code === "ENOENT") return [];
43389
44113
  throw err;
@@ -43391,7 +44115,7 @@ var ProjectStore = class {
43391
44115
  const out = [];
43392
44116
  for (const name of entries) {
43393
44117
  try {
43394
- const raw = await import_node_fs31.promises.readFile(this.metaPath(name), "utf8");
44118
+ const raw = await import_node_fs32.promises.readFile(this.metaPath(name), "utf8");
43395
44119
  const json = JSON.parse(raw);
43396
44120
  let migrated = false;
43397
44121
  if (typeof json.devCommand !== "string" || json.devCommand.length === 0) {
@@ -43402,7 +44126,7 @@ var ProjectStore = class {
43402
44126
  if (parsed.success) {
43403
44127
  out.push(parsed.data);
43404
44128
  if (migrated) {
43405
- void import_node_fs31.promises.writeFile(this.metaPath(name), JSON.stringify(parsed.data, null, 2) + "\n", "utf8").catch(() => {
44129
+ void import_node_fs32.promises.writeFile(this.metaPath(name), JSON.stringify(parsed.data, null, 2) + "\n", "utf8").catch(() => {
43406
44130
  });
43407
44131
  }
43408
44132
  }
@@ -43446,8 +44170,8 @@ var ProjectStore = class {
43446
44170
  throw new Error(`invalid name "${name}": ${validated.error.message}`);
43447
44171
  }
43448
44172
  const dir = this.projectDir(name);
43449
- await import_node_fs31.promises.mkdir(dir, { recursive: true });
43450
- await import_node_fs31.promises.writeFile(this.metaPath(name), JSON.stringify(meta, null, 2) + "\n", "utf8");
44173
+ await import_node_fs32.promises.mkdir(dir, { recursive: true });
44174
+ await import_node_fs32.promises.writeFile(this.metaPath(name), JSON.stringify(meta, null, 2) + "\n", "utf8");
43451
44175
  return meta;
43452
44176
  }
43453
44177
  /**
@@ -43462,7 +44186,7 @@ var ProjectStore = class {
43462
44186
  const scriptPath = (0, import_node_path42.join)(personaRoot, SCAFFOLD_SCRIPT_REL);
43463
44187
  const destDir = this.projectDir(name);
43464
44188
  return await new Promise((resolve6, reject) => {
43465
- const child = (0, import_node_child_process9.spawn)("bash", [scriptPath, name, template, destDir], {
44189
+ const child = (0, import_node_child_process13.spawn)("bash", [scriptPath, name, template, destDir], {
43466
44190
  cwd: personaRoot,
43467
44191
  env: { ...process.env, PATH: process.env.PATH ?? "" },
43468
44192
  stdio: ["ignore", "pipe", "pipe"]
@@ -43492,7 +44216,7 @@ var ProjectStore = class {
43492
44216
  }
43493
44217
  async delete(name) {
43494
44218
  const dir = this.projectDir(name);
43495
- await import_node_fs31.promises.rm(dir, { recursive: true, force: true });
44219
+ await import_node_fs32.promises.rm(dir, { recursive: true, force: true });
43496
44220
  }
43497
44221
  async updatePort(name, newPort) {
43498
44222
  if (newPort < PROJECT_PORT_MIN || newPort > PROJECT_PORT_MAX) {
@@ -43508,7 +44232,7 @@ var ProjectStore = class {
43508
44232
  throw new Error(`port ${newPort} already used / \u5DF2\u88AB project "${conflict.name}" \u5360\u7528`);
43509
44233
  }
43510
44234
  const updated = { ...target, port: newPort };
43511
- await import_node_fs31.promises.writeFile(this.metaPath(name), JSON.stringify(updated, null, 2) + "\n", "utf8");
44235
+ await import_node_fs32.promises.writeFile(this.metaPath(name), JSON.stringify(updated, null, 2) + "\n", "utf8");
43512
44236
  return updated;
43513
44237
  }
43514
44238
  /**
@@ -43525,7 +44249,7 @@ var ProjectStore = class {
43525
44249
  if (!validated.success) {
43526
44250
  throw new Error(`invalid prodUrl "${url}": ${validated.error.message}`);
43527
44251
  }
43528
- await import_node_fs31.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
44252
+ await import_node_fs32.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
43529
44253
  return validated.data;
43530
44254
  }
43531
44255
  /**
@@ -43546,7 +44270,7 @@ var ProjectStore = class {
43546
44270
  if (!validated.success) {
43547
44271
  throw new Error(`invalid publishJob: ${validated.error.message}`);
43548
44272
  }
43549
- await import_node_fs31.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
44273
+ await import_node_fs32.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
43550
44274
  return validated.data;
43551
44275
  }
43552
44276
  /** 清掉 .clawd-project.json.publishJob 字段。其他字段保持原样。 */
@@ -43561,13 +44285,13 @@ var ProjectStore = class {
43561
44285
  if (!validated.success) {
43562
44286
  throw new Error(`failed to clear publishJob: ${validated.error.message}`);
43563
44287
  }
43564
- await import_node_fs31.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
44288
+ await import_node_fs32.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
43565
44289
  return validated.data;
43566
44290
  }
43567
44291
  };
43568
44292
 
43569
44293
  // src/app-builder/dev-server-supervisor.ts
43570
- var import_node_child_process10 = require("child_process");
44294
+ var import_node_child_process14 = require("child_process");
43571
44295
  var import_node_events2 = require("events");
43572
44296
  var DEFAULT_READY_PATTERN = /Local:\s+https?:\/\/|Nest application successfully started|server listening on/i;
43573
44297
  var DevServerSupervisor = class extends import_node_events2.EventEmitter {
@@ -43604,7 +44328,7 @@ var DevServerSupervisor = class extends import_node_events2.EventEmitter {
43604
44328
  tunnelHost: args.tunnelHost,
43605
44329
  devCommand: cmd
43606
44330
  });
43607
- const child = (0, import_node_child_process10.spawn)("sh", ["-c", cmd], {
44331
+ const child = (0, import_node_child_process14.spawn)("sh", ["-c", cmd], {
43608
44332
  cwd: args.cwd,
43609
44333
  env,
43610
44334
  stdio: "pipe",
@@ -43996,7 +44720,7 @@ function computeGrantForFrame(method, frame) {
43996
44720
  }
43997
44721
 
43998
44722
  // src/extension/runtime.ts
43999
- var import_node_child_process11 = require("child_process");
44723
+ var import_node_child_process15 = require("child_process");
44000
44724
  var import_node_path43 = __toESM(require("path"), 1);
44001
44725
  var import_promises10 = require("timers/promises");
44002
44726
 
@@ -44083,17 +44807,17 @@ var Runtime = class {
44083
44807
  const existing = this.handles.get(extId);
44084
44808
  if (existing) return { kind: "local", port: existing.port };
44085
44809
  const records = await loadAll(this.root);
44086
- const rec = records.find((r) => r.extId === extId);
44087
- if (!rec) throw new RuntimeError("NOT_FOUND", `extension ${extId} not installed`);
44088
- if (rec.state === "invalid")
44089
- throw new RuntimeError("INVALID_MANIFEST", rec.invalidReason);
44090
- if (manifestMode(rec.manifest) === "hosted") {
44091
- return { kind: "hosted", url: rec.manifest.entry.url };
44810
+ const rec3 = records.find((r) => r.extId === extId);
44811
+ if (!rec3) throw new RuntimeError("NOT_FOUND", `extension ${extId} not installed`);
44812
+ if (rec3.state === "invalid")
44813
+ throw new RuntimeError("INVALID_MANIFEST", rec3.invalidReason);
44814
+ if (manifestMode(rec3.manifest) === "hosted") {
44815
+ return { kind: "hosted", url: rec3.manifest.entry.url };
44092
44816
  }
44093
44817
  const port = await this.allocator.allocate().catch(() => {
44094
44818
  throw new RuntimeError("PORT_EXHAUSTED", "no free port in configured range");
44095
44819
  });
44096
- const startCommand = rec.manifest.runtime.startCommand;
44820
+ const startCommand = rec3.manifest.runtime.startCommand;
44097
44821
  const cmd = startCommand.replace(
44098
44822
  /\$CLAWOS_EXT_PORT/g,
44099
44823
  String(port)
@@ -44104,7 +44828,7 @@ var Runtime = class {
44104
44828
  CLAWOS_EXT_PORT: String(port),
44105
44829
  CLAWOS_EXT_ID: extId
44106
44830
  };
44107
- const child = (0, import_node_child_process11.spawn)("sh", ["-c", cmd], {
44831
+ const child = (0, import_node_child_process15.spawn)("sh", ["-c", cmd], {
44108
44832
  cwd: dir,
44109
44833
  env,
44110
44834
  stdio: ["ignore", "pipe", "pipe"],
@@ -44540,7 +45264,7 @@ async function startDaemon(config) {
44540
45264
  const absPath = import_node_path46.default.isAbsolute(input.relPath) ? input.relPath : import_node_path46.default.join(input.cwd, input.relPath);
44541
45265
  let size = 0;
44542
45266
  try {
44543
- size = import_node_fs32.default.statSync(absPath).size;
45267
+ size = import_node_fs33.default.statSync(absPath).size;
44544
45268
  } catch (err) {
44545
45269
  logger.warn("attachment.onFileEdit stat failed", {
44546
45270
  sessionId: input.sessionId,
@@ -44610,6 +45334,7 @@ async function startDaemon(config) {
44610
45334
  onReady: (tsid) => manager.dispatchReadyDetected(tsid)
44611
45335
  }) : new ClaudeAdapter({ logger, historyReader: new ClaudeHistoryReader() });
44612
45336
  registerAdapter("claude", claudeAdapter);
45337
+ registerAdapter("codex", new CodexAdapter({ logger, historyReader: new CodexHistoryReader() }));
44613
45338
  const personaRegistry = new PersonaRegistry(personaStore);
44614
45339
  const personaManager = new PersonaManager({
44615
45340
  store: personaStore,
@@ -44688,7 +45413,11 @@ async function startDaemon(config) {
44688
45413
  workspace,
44689
45414
  skills,
44690
45415
  agents,
45416
+ // skills:list 按 tool 路由:codex → app-server skills/list;缺省 claude → SkillsScanner(同步包成 Promise)。
45417
+ getSkillsForTool: (tool, cwd) => tool === "codex" ? listCodexSkills(cwd) : Promise.resolve(skills.list({ cwd })),
44691
45418
  history,
45419
+ // history:read 按 session.tool 路由:codex → adapter.historyReader(CodexHistoryReader);缺省 claude。
45420
+ getHistoryReader: (tool) => getAdapter(tool).historyReader ?? history,
44692
45421
  observer,
44693
45422
  getAdapter,
44694
45423
  store,
@@ -45027,8 +45756,7 @@ async function startDaemon(config) {
45027
45756
  protocolVersion: PROTOCOL_VERSION,
45028
45757
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
45029
45758
  authMode,
45030
- authToken: resolvedAuthToken ?? void 0,
45031
- source: readDaemonSourceFromEnv()
45759
+ authToken: resolvedAuthToken ?? void 0
45032
45760
  };
45033
45761
  stateMgr.write(stateSnapshot);
45034
45762
  process.stdout.write(`Ready: ${url}
@@ -45079,7 +45807,7 @@ ${bar}
45079
45807
  `);
45080
45808
  try {
45081
45809
  const connectPath = import_node_path46.default.join(config.dataDir, "connect.txt");
45082
- import_node_fs32.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
45810
+ import_node_fs33.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
45083
45811
  } catch {
45084
45812
  }
45085
45813
  } catch (err) {
@@ -45152,7 +45880,7 @@ ${bar}
45152
45880
  function migrateDropPersonsDir(dataDir) {
45153
45881
  const dir = import_node_path46.default.join(dataDir, "persons");
45154
45882
  try {
45155
- import_node_fs32.default.rmSync(dir, { recursive: true, force: true });
45883
+ import_node_fs33.default.rmSync(dir, { recursive: true, force: true });
45156
45884
  } catch {
45157
45885
  }
45158
45886
  }