@clawos-dev/clawd 0.2.136-beta.285.b451e3c → 0.2.136-beta.287.97b0d33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.cjs +314 -385
  2. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -720,8 +720,8 @@ var init_parseUtil = __esm({
720
720
  init_errors2();
721
721
  init_en();
722
722
  makeIssue = (params) => {
723
- const { data, path: path59, errorMaps, issueData } = params;
724
- const fullPath = [...path59, ...issueData.path || []];
723
+ const { data, path: path58, errorMaps, issueData } = params;
724
+ const fullPath = [...path58, ...issueData.path || []];
725
725
  const fullIssue = {
726
726
  ...issueData,
727
727
  path: fullPath
@@ -1032,11 +1032,11 @@ var init_types = __esm({
1032
1032
  init_parseUtil();
1033
1033
  init_util();
1034
1034
  ParseInputLazyPath = class {
1035
- constructor(parent, value, path59, key) {
1035
+ constructor(parent, value, path58, key) {
1036
1036
  this._cachedPath = [];
1037
1037
  this.parent = parent;
1038
1038
  this.data = value;
1039
- this._path = path59;
1039
+ this._path = path58;
1040
1040
  this._key = key;
1041
1041
  }
1042
1042
  get path() {
@@ -6218,8 +6218,8 @@ var require_req = __commonJS({
6218
6218
  if (req.originalUrl) {
6219
6219
  _req.url = req.originalUrl;
6220
6220
  } else {
6221
- const path59 = req.path;
6222
- _req.url = typeof path59 === "string" ? path59 : req.url ? req.url.path || req.url : void 0;
6221
+ const path58 = req.path;
6222
+ _req.url = typeof path58 === "string" ? path58 : req.url ? req.url.path || req.url : void 0;
6223
6223
  }
6224
6224
  if (req.query) {
6225
6225
  _req.query = req.query;
@@ -6384,14 +6384,14 @@ var require_redact = __commonJS({
6384
6384
  }
6385
6385
  return obj;
6386
6386
  }
6387
- function parsePath(path59) {
6387
+ function parsePath(path58) {
6388
6388
  const parts = [];
6389
6389
  let current = "";
6390
6390
  let inBrackets = false;
6391
6391
  let inQuotes = false;
6392
6392
  let quoteChar = "";
6393
- for (let i = 0; i < path59.length; i++) {
6394
- const char = path59[i];
6393
+ for (let i = 0; i < path58.length; i++) {
6394
+ const char = path58[i];
6395
6395
  if (!inBrackets && char === ".") {
6396
6396
  if (current) {
6397
6397
  parts.push(current);
@@ -6522,10 +6522,10 @@ var require_redact = __commonJS({
6522
6522
  return current;
6523
6523
  }
6524
6524
  function redactPaths(obj, paths, censor, remove = false) {
6525
- for (const path59 of paths) {
6526
- const parts = parsePath(path59);
6525
+ for (const path58 of paths) {
6526
+ const parts = parsePath(path58);
6527
6527
  if (parts.includes("*")) {
6528
- redactWildcardPath(obj, parts, censor, path59, remove);
6528
+ redactWildcardPath(obj, parts, censor, path58, remove);
6529
6529
  } else {
6530
6530
  if (remove) {
6531
6531
  removeKey(obj, parts);
@@ -6610,8 +6610,8 @@ var require_redact = __commonJS({
6610
6610
  }
6611
6611
  } else {
6612
6612
  if (afterWildcard.includes("*")) {
6613
- const wrappedCensor = typeof censor === "function" ? (value, path59) => {
6614
- const fullPath = [...pathArray.slice(0, pathLength), ...path59];
6613
+ const wrappedCensor = typeof censor === "function" ? (value, path58) => {
6614
+ const fullPath = [...pathArray.slice(0, pathLength), ...path58];
6615
6615
  return censor(value, fullPath);
6616
6616
  } : censor;
6617
6617
  redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
@@ -6646,8 +6646,8 @@ var require_redact = __commonJS({
6646
6646
  return null;
6647
6647
  }
6648
6648
  const pathStructure = /* @__PURE__ */ new Map();
6649
- for (const path59 of pathsToClone) {
6650
- const parts = parsePath(path59);
6649
+ for (const path58 of pathsToClone) {
6650
+ const parts = parsePath(path58);
6651
6651
  let current = pathStructure;
6652
6652
  for (let i = 0; i < parts.length; i++) {
6653
6653
  const part = parts[i];
@@ -6699,24 +6699,24 @@ var require_redact = __commonJS({
6699
6699
  }
6700
6700
  return cloneSelectively(obj, pathStructure);
6701
6701
  }
6702
- function validatePath(path59) {
6703
- if (typeof path59 !== "string") {
6702
+ function validatePath(path58) {
6703
+ if (typeof path58 !== "string") {
6704
6704
  throw new Error("Paths must be (non-empty) strings");
6705
6705
  }
6706
- if (path59 === "") {
6706
+ if (path58 === "") {
6707
6707
  throw new Error("Invalid redaction path ()");
6708
6708
  }
6709
- if (path59.includes("..")) {
6710
- throw new Error(`Invalid redaction path (${path59})`);
6709
+ if (path58.includes("..")) {
6710
+ throw new Error(`Invalid redaction path (${path58})`);
6711
6711
  }
6712
- if (path59.includes(",")) {
6713
- throw new Error(`Invalid redaction path (${path59})`);
6712
+ if (path58.includes(",")) {
6713
+ throw new Error(`Invalid redaction path (${path58})`);
6714
6714
  }
6715
6715
  let bracketCount = 0;
6716
6716
  let inQuotes = false;
6717
6717
  let quoteChar = "";
6718
- for (let i = 0; i < path59.length; i++) {
6719
- const char = path59[i];
6718
+ for (let i = 0; i < path58.length; i++) {
6719
+ const char = path58[i];
6720
6720
  if ((char === '"' || char === "'") && bracketCount > 0) {
6721
6721
  if (!inQuotes) {
6722
6722
  inQuotes = true;
@@ -6730,20 +6730,20 @@ var require_redact = __commonJS({
6730
6730
  } else if (char === "]" && !inQuotes) {
6731
6731
  bracketCount--;
6732
6732
  if (bracketCount < 0) {
6733
- throw new Error(`Invalid redaction path (${path59})`);
6733
+ throw new Error(`Invalid redaction path (${path58})`);
6734
6734
  }
6735
6735
  }
6736
6736
  }
6737
6737
  if (bracketCount !== 0) {
6738
- throw new Error(`Invalid redaction path (${path59})`);
6738
+ throw new Error(`Invalid redaction path (${path58})`);
6739
6739
  }
6740
6740
  }
6741
6741
  function validatePaths(paths) {
6742
6742
  if (!Array.isArray(paths)) {
6743
6743
  throw new TypeError("paths must be an array");
6744
6744
  }
6745
- for (const path59 of paths) {
6746
- validatePath(path59);
6745
+ for (const path58 of paths) {
6746
+ validatePath(path58);
6747
6747
  }
6748
6748
  }
6749
6749
  function slowRedact(options = {}) {
@@ -6911,8 +6911,8 @@ var require_redaction = __commonJS({
6911
6911
  if (shape[k2] === null) {
6912
6912
  o[k2] = (value) => topCensor(value, [k2]);
6913
6913
  } else {
6914
- const wrappedCensor = typeof censor === "function" ? (value, path59) => {
6915
- return censor(value, [k2, ...path59]);
6914
+ const wrappedCensor = typeof censor === "function" ? (value, path58) => {
6915
+ return censor(value, [k2, ...path58]);
6916
6916
  } : censor;
6917
6917
  o[k2] = Redact({
6918
6918
  paths: shape[k2],
@@ -7133,7 +7133,7 @@ var require_sonic_boom = __commonJS({
7133
7133
  var fs51 = require("fs");
7134
7134
  var EventEmitter3 = require("events");
7135
7135
  var inherits = require("util").inherits;
7136
- var path59 = require("path");
7136
+ var path58 = require("path");
7137
7137
  var sleep = require_atomic_sleep();
7138
7138
  var assert = require("assert");
7139
7139
  var BUSY_WRITE_TIMEOUT = 100;
@@ -7187,7 +7187,7 @@ var require_sonic_boom = __commonJS({
7187
7187
  const mode = sonic.mode;
7188
7188
  if (sonic.sync) {
7189
7189
  try {
7190
- if (sonic.mkdir) fs51.mkdirSync(path59.dirname(file), { recursive: true });
7190
+ if (sonic.mkdir) fs51.mkdirSync(path58.dirname(file), { recursive: true });
7191
7191
  const fd = fs51.openSync(file, flags, mode);
7192
7192
  fileOpened(null, fd);
7193
7193
  } catch (err) {
@@ -7195,7 +7195,7 @@ var require_sonic_boom = __commonJS({
7195
7195
  throw err;
7196
7196
  }
7197
7197
  } else if (sonic.mkdir) {
7198
- fs51.mkdir(path59.dirname(file), { recursive: true }, (err) => {
7198
+ fs51.mkdir(path58.dirname(file), { recursive: true }, (err) => {
7199
7199
  if (err) return fileOpened(err);
7200
7200
  fs51.open(file, flags, mode, fileOpened);
7201
7201
  });
@@ -10055,7 +10055,7 @@ var require_multistream = __commonJS({
10055
10055
  var require_pino = __commonJS({
10056
10056
  "../node_modules/.pnpm/pino@9.14.0/node_modules/pino/pino.js"(exports2, module2) {
10057
10057
  "use strict";
10058
- var os22 = require("os");
10058
+ var os21 = require("os");
10059
10059
  var stdSerializers = require_pino_std_serializers();
10060
10060
  var caller = require_caller();
10061
10061
  var redaction = require_redaction();
@@ -10102,7 +10102,7 @@ var require_pino = __commonJS({
10102
10102
  } = symbols;
10103
10103
  var { epochTime, nullTime } = time;
10104
10104
  var { pid } = process;
10105
- var hostname = os22.hostname();
10105
+ var hostname = os21.hostname();
10106
10106
  var defaultErrorSerializer = stdSerializers.err;
10107
10107
  var defaultOptions = {
10108
10108
  level: "info",
@@ -10826,11 +10826,11 @@ var init_lib = __esm({
10826
10826
  }
10827
10827
  }
10828
10828
  },
10829
- addToPath: function addToPath(path59, added, removed, oldPosInc, options) {
10830
- var last = path59.lastComponent;
10829
+ addToPath: function addToPath(path58, added, removed, oldPosInc, options) {
10830
+ var last = path58.lastComponent;
10831
10831
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
10832
10832
  return {
10833
- oldPos: path59.oldPos + oldPosInc,
10833
+ oldPos: path58.oldPos + oldPosInc,
10834
10834
  lastComponent: {
10835
10835
  count: last.count + 1,
10836
10836
  added,
@@ -10840,7 +10840,7 @@ var init_lib = __esm({
10840
10840
  };
10841
10841
  } else {
10842
10842
  return {
10843
- oldPos: path59.oldPos + oldPosInc,
10843
+ oldPos: path58.oldPos + oldPosInc,
10844
10844
  lastComponent: {
10845
10845
  count: 1,
10846
10846
  added,
@@ -11286,10 +11286,10 @@ function attachmentToHistoryMessage(o, ts) {
11286
11286
  const memories = raw.map((m2) => {
11287
11287
  if (!m2 || typeof m2 !== "object") return null;
11288
11288
  const rec3 = m2;
11289
- const path59 = typeof rec3.path === "string" ? rec3.path : null;
11289
+ const path58 = typeof rec3.path === "string" ? rec3.path : null;
11290
11290
  const content = typeof rec3.content === "string" ? rec3.content : null;
11291
- if (!path59 || content == null) return null;
11292
- const entry = { path: path59, content };
11291
+ if (!path58 || content == null) return null;
11292
+ const entry = { path: path58, content };
11293
11293
  if (typeof rec3.mtimeMs === "number") entry.mtimeMs = rec3.mtimeMs;
11294
11294
  return entry;
11295
11295
  }).filter((m2) => m2 !== null);
@@ -11754,12 +11754,6 @@ var init_claude_history = __esm({
11754
11754
  });
11755
11755
 
11756
11756
  // src/tools/claude.ts
11757
- function macOSDesktopCandidates(home) {
11758
- return [
11759
- import_node_path9.default.join(home, "Applications", "Claude.app", "Contents", "Resources", "app.asar.unpacked", "node_modules", "@anthropic-ai", "claude-code", "cli.js"),
11760
- "/Applications/Claude.app/Contents/Resources/app.asar.unpacked/node_modules/@anthropic-ai/claude-code/cli.js"
11761
- ];
11762
- }
11763
11757
  function probeViaWhich() {
11764
11758
  try {
11765
11759
  const out = (0, import_node_child_process2.execFileSync)("which", ["claude"], { encoding: "utf8" }).trim();
@@ -11768,19 +11762,12 @@ function probeViaWhich() {
11768
11762
  }
11769
11763
  return null;
11770
11764
  }
11771
- async function probeClaude(env = process.env, home = import_node_os5.default.homedir()) {
11765
+ async function probeClaude(env = process.env) {
11772
11766
  if (env.CLAUDE_BIN && import_node_fs9.default.existsSync(env.CLAUDE_BIN)) {
11773
11767
  return { available: true, path: env.CLAUDE_BIN };
11774
11768
  }
11775
11769
  const w2 = probeViaWhich();
11776
11770
  if (w2) return { available: true, path: w2 };
11777
- if (process.platform === "darwin") {
11778
- for (const candidate of macOSDesktopCandidates(home)) {
11779
- if (import_node_fs9.default.existsSync(candidate)) {
11780
- return { available: true, path: candidate };
11781
- }
11782
- }
11783
- }
11784
11771
  return { available: false };
11785
11772
  }
11786
11773
  function buildSpawnArgs(ctx) {
@@ -12101,10 +12088,10 @@ function parseAttachment(obj) {
12101
12088
  const memories = raw.map((m2) => {
12102
12089
  if (!m2 || typeof m2 !== "object") return null;
12103
12090
  const rec3 = m2;
12104
- const path59 = typeof rec3.path === "string" ? rec3.path : null;
12091
+ const path58 = typeof rec3.path === "string" ? rec3.path : null;
12105
12092
  const content = typeof rec3.content === "string" ? rec3.content : null;
12106
- if (!path59 || content == null) return null;
12107
- const out = { path: path59, content };
12093
+ if (!path58 || content == null) return null;
12094
+ const out = { path: path58, content };
12108
12095
  if (typeof rec3.mtimeMs === "number") out.mtimeMs = rec3.mtimeMs;
12109
12096
  return out;
12110
12097
  }).filter((m2) => m2 !== null);
@@ -12208,15 +12195,13 @@ function encodeClaudeStdin(text) {
12208
12195
  };
12209
12196
  return JSON.stringify(frame) + "\n";
12210
12197
  }
12211
- var import_node_child_process, import_node_child_process2, import_node_fs9, import_node_os5, import_node_path9, ATTACHMENT_SILENT_SUBTYPES2, unknownTypeHandler, ATTACHMENT_RE, IMAGE_EXT_MIME, CLAUDE_MODELS, CLAUDE_PERMISSION_MODES, CLAUDE_CAPABILITIES, ClaudeAdapter;
12198
+ var import_node_child_process, import_node_child_process2, import_node_fs9, ATTACHMENT_SILENT_SUBTYPES2, unknownTypeHandler, ATTACHMENT_RE, IMAGE_EXT_MIME, CLAUDE_MODELS, CLAUDE_PERMISSION_MODES, CLAUDE_CAPABILITIES, ClaudeAdapter;
12212
12199
  var init_claude = __esm({
12213
12200
  "src/tools/claude.ts"() {
12214
12201
  "use strict";
12215
12202
  import_node_child_process = require("child_process");
12216
12203
  import_node_child_process2 = require("child_process");
12217
12204
  import_node_fs9 = __toESM(require("fs"), 1);
12218
- import_node_os5 = __toESM(require("os"), 1);
12219
- import_node_path9 = __toESM(require("path"), 1);
12220
12205
  init_protocol();
12221
12206
  init_claude_history();
12222
12207
  init_tool_result_extra();
@@ -23893,8 +23878,8 @@ var require_utils = __commonJS({
23893
23878
  var result = transform[inputType][outputType](input);
23894
23879
  return result;
23895
23880
  };
23896
- exports2.resolve = function(path59) {
23897
- var parts = path59.split("/");
23881
+ exports2.resolve = function(path58) {
23882
+ var parts = path58.split("/");
23898
23883
  var result = [];
23899
23884
  for (var index = 0; index < parts.length; index++) {
23900
23885
  var part = parts[index];
@@ -29747,18 +29732,18 @@ var require_object = __commonJS({
29747
29732
  var object = new ZipObject(name, zipObjectContent, o);
29748
29733
  this.files[name] = object;
29749
29734
  };
29750
- var parentFolder = function(path59) {
29751
- if (path59.slice(-1) === "/") {
29752
- path59 = path59.substring(0, path59.length - 1);
29735
+ var parentFolder = function(path58) {
29736
+ if (path58.slice(-1) === "/") {
29737
+ path58 = path58.substring(0, path58.length - 1);
29753
29738
  }
29754
- var lastSlash = path59.lastIndexOf("/");
29755
- return lastSlash > 0 ? path59.substring(0, lastSlash) : "";
29739
+ var lastSlash = path58.lastIndexOf("/");
29740
+ return lastSlash > 0 ? path58.substring(0, lastSlash) : "";
29756
29741
  };
29757
- var forceTrailingSlash = function(path59) {
29758
- if (path59.slice(-1) !== "/") {
29759
- path59 += "/";
29742
+ var forceTrailingSlash = function(path58) {
29743
+ if (path58.slice(-1) !== "/") {
29744
+ path58 += "/";
29760
29745
  }
29761
- return path59;
29746
+ return path58;
29762
29747
  };
29763
29748
  var folderAdd = function(name, createFolders) {
29764
29749
  createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
@@ -30760,7 +30745,7 @@ var require_lib3 = __commonJS({
30760
30745
  // src/run-case/recorder.ts
30761
30746
  function startRunCaseRecorder(opts) {
30762
30747
  const now = opts.now ?? Date.now;
30763
- const dir = import_node_path47.default.dirname(opts.recordPath);
30748
+ const dir = import_node_path46.default.dirname(opts.recordPath);
30764
30749
  let stream = null;
30765
30750
  let closing = false;
30766
30751
  let closedSettled = false;
@@ -30800,12 +30785,12 @@ function startRunCaseRecorder(opts) {
30800
30785
  };
30801
30786
  return { tap, close, closed };
30802
30787
  }
30803
- var import_node_fs34, import_node_path47;
30788
+ var import_node_fs34, import_node_path46;
30804
30789
  var init_recorder = __esm({
30805
30790
  "src/run-case/recorder.ts"() {
30806
30791
  "use strict";
30807
30792
  import_node_fs34 = __toESM(require("fs"), 1);
30808
- import_node_path47 = __toESM(require("path"), 1);
30793
+ import_node_path46 = __toESM(require("path"), 1);
30809
30794
  }
30810
30795
  });
30811
30796
 
@@ -30848,7 +30833,7 @@ var init_wire = __esm({
30848
30833
  // src/run-case/controller.ts
30849
30834
  async function runController(opts) {
30850
30835
  const now = opts.now ?? Date.now;
30851
- const cwd = opts.cwd ?? (0, import_node_fs35.mkdtempSync)(import_node_path48.default.join(import_node_os20.default.tmpdir(), "clawd-runcase-"));
30836
+ const cwd = opts.cwd ?? (0, import_node_fs35.mkdtempSync)(import_node_path47.default.join(import_node_os19.default.tmpdir(), "clawd-runcase-"));
30852
30837
  const ownsCwd = opts.cwd === void 0;
30853
30838
  const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
30854
30839
  const spawnCtx = { cwd };
@@ -31015,13 +31000,13 @@ async function runController(opts) {
31015
31000
  }
31016
31001
  return exitCode ?? 0;
31017
31002
  }
31018
- var import_node_fs35, import_node_os20, import_node_path48;
31003
+ var import_node_fs35, import_node_os19, import_node_path47;
31019
31004
  var init_controller = __esm({
31020
31005
  "src/run-case/controller.ts"() {
31021
31006
  "use strict";
31022
31007
  import_node_fs35 = require("fs");
31023
- import_node_os20 = __toESM(require("os"), 1);
31024
- import_node_path48 = __toESM(require("path"), 1);
31008
+ import_node_os19 = __toESM(require("os"), 1);
31009
+ import_node_path47 = __toESM(require("path"), 1);
31025
31010
  init_claude();
31026
31011
  init_stdout_splitter();
31027
31012
  init_permission_stdio();
@@ -31256,7 +31241,7 @@ Env (advanced):
31256
31241
  `;
31257
31242
 
31258
31243
  // src/index.ts
31259
- var import_node_path46 = __toESM(require("path"), 1);
31244
+ var import_node_path45 = __toESM(require("path"), 1);
31260
31245
  var import_node_fs33 = __toESM(require("fs"), 1);
31261
31246
 
31262
31247
  // src/logger.ts
@@ -32601,7 +32586,7 @@ var SessionRunner = class {
32601
32586
  this.input({ kind: "inject-events", events });
32602
32587
  }
32603
32588
  // session:interrupt 的 SDK 通道分流:codex → AgentSession.interrupt();claude → control_request('interrupt')。
32604
- // TUI(pty) 路径在 manager.dispatchInterrupt 里先于此处理,不进这里。
32589
+ // TUI(pty) 路径在 manager.interrupt() 里先走 stop() SIGKILL,不进这里。
32605
32590
  async interrupt() {
32606
32591
  if (this.session) {
32607
32592
  this.session.interrupt();
@@ -33079,11 +33064,6 @@ var SessionManager = class {
33079
33064
  // manager.resizePty 用此映射把 UI 的 session:pty:resize 同步到 surface 内部 buffer,
33080
33065
  // 保证 snapshot serialize 时 cursor positioning 与 UI xterm 实际尺寸一致。
33081
33066
  surfacesByToolSid = /* @__PURE__ */ new Map();
33082
- // TUI 模式:sessionId → UI 最近一次上报的 xterm 尺寸。resizePty 入口无条件记录(含 pty
33083
- // 尚未 spawn / runner 尚未创建的早到 resize),registerPty / registerSurface 时回放——
33084
- // 修「mount resize 早于 lazy spawn 被丢」与「respawn 回到 120×40 后无人补发」的尺寸错配。
33085
- // 键用 sessionId 而非 toolSessionId:/clear 会 reassign tsid,sessionId 跨 respawn 稳定
33086
- lastUiSizeBySessionId = /* @__PURE__ */ new Map();
33087
33067
  // 仅 mode='tui' 需要:index.ts 装配阶段在 observer 构造后注入。
33088
33068
  // observer.onEvent 要回灌 manager.feedObserverEvents,所以 observer 必须晚于 manager
33089
33069
  // 构造;反过来 manager 又要在 mode='tui' 下 spawn session 时 attach observer。setter 解循环
@@ -33620,7 +33600,6 @@ var SessionManager = class {
33620
33600
  });
33621
33601
  this.runners.delete(args.sessionId);
33622
33602
  this.realUuidBySynth.delete(args.sessionId);
33623
- this.lastUiSizeBySessionId.delete(args.sessionId);
33624
33603
  return { response: { sessionId: args.sessionId }, broadcast };
33625
33604
  }
33626
33605
  this.deleteOwned(args.sessionId);
@@ -33678,50 +33657,12 @@ var SessionManager = class {
33678
33657
  return this.stop({ sessionId: args.sessionId });
33679
33658
  }
33680
33659
  try {
33681
- await this.dispatchInterrupt(runner);
33660
+ await runner.interrupt();
33682
33661
  } catch (err) {
33683
33662
  throw new ClawdError(ERROR_CODES.INTERNAL, err.message);
33684
33663
  }
33685
33664
  return { response: { ok: true }, broadcast: [] };
33686
33665
  }
33687
- // 同时被 interrupt / cancelQuestion 调用:按模式选 interrupt 通道。TUI 优先 pty,
33688
- // 否则 fallback 到 SDK 的 control_request(包括 mode='tui' 但 pty 未 register 的边角场景)。
33689
- async dispatchInterrupt(runner) {
33690
- const sid = runner.getState().file.sessionId;
33691
- const tsid = runner.getState().file.toolSessionId;
33692
- const pty = tsid ? this.ptyTransports.get(tsid) : void 0;
33693
- const stateBefore = runner.getState();
33694
- this.deps.logger?.info("[BUG-HUNT-INTERRUPT] dispatchInterrupt enter", {
33695
- sessionId: sid,
33696
- tsid,
33697
- ptyHit: Boolean(pty),
33698
- mode: this.deps.mode,
33699
- turnOpenBefore: stateBefore.turnOpen,
33700
- procAlive: stateBefore.procAlive,
33701
- bufferLen: stateBefore.buffer.length
33702
- });
33703
- if (pty) {
33704
- pty.write("\x1B");
33705
- this.deps.logger?.info("[BUG-HUNT-INTERRUPT] pty.write ESC done", { sessionId: sid });
33706
- runner.input({ kind: "inject-events", events: [{ kind: "turn_end" }] });
33707
- const stateAfter = runner.getState();
33708
- const lastEvent = stateAfter.buffer[stateAfter.buffer.length - 1];
33709
- this.deps.logger?.info("[BUG-HUNT-INTERRUPT] after inject turn_end", {
33710
- sessionId: sid,
33711
- turnOpenAfter: stateAfter.turnOpen,
33712
- bufferLen: stateAfter.buffer.length,
33713
- lastEventKind: lastEvent?.event?.kind,
33714
- lastEventSeq: lastEvent?.seq
33715
- });
33716
- return;
33717
- }
33718
- this.deps.logger?.warn("[BUG-HUNT-INTERRUPT] SDK fallback path (pty not registered)", {
33719
- sessionId: sid,
33720
- tsid,
33721
- mode: this.deps.mode
33722
- });
33723
- await runner.interrupt();
33724
- }
33725
33666
  // 批量版本:UI 打开 session 时一次性拿到"磁盘和快照有差异"的 user message id 集合,
33726
33667
  // 用来在消息流里精准控制 rewind 按钮的显示。session 没 toolSessionId 时返回空
33727
33668
  rewindableMessageIds(args) {
@@ -34136,7 +34077,6 @@ var SessionManager = class {
34136
34077
  });
34137
34078
  this.runners.delete(args.sessionId);
34138
34079
  this.realUuidBySynth.delete(args.sessionId);
34139
- this.lastUiSizeBySessionId.delete(args.sessionId);
34140
34080
  return { response: { sessionId: args.sessionId }, broadcast };
34141
34081
  }
34142
34082
  this.storeFor(args.scope).delete(args.sessionId);
@@ -34267,7 +34207,7 @@ var SessionManager = class {
34267
34207
  runner.input({ kind: "cancel-question", toolUseId: args.toolUseId });
34268
34208
  });
34269
34209
  if (runner.getState().procAlive) {
34270
- void this.dispatchInterrupt(runner).catch(() => {
34210
+ void runner.interrupt().catch(() => {
34271
34211
  });
34272
34212
  }
34273
34213
  return { response: { ok: true }, broadcast };
@@ -34302,14 +34242,6 @@ var SessionManager = class {
34302
34242
  /** ClaudeTuiAdapter.spawn 后调用,让 manager 持有 pty handle 供 handler input/resize 路由 */
34303
34243
  registerPty(toolSessionId, pty) {
34304
34244
  this.ptyTransports.set(toolSessionId, pty);
34305
- const sid = this.sessionIdByToolSid(toolSessionId);
34306
- const size = sid ? this.lastUiSizeBySessionId.get(sid) : void 0;
34307
- if (size) {
34308
- try {
34309
- pty.resize(size.cols, size.rows);
34310
- } catch {
34311
- }
34312
- }
34313
34245
  }
34314
34246
  /** spawn 进程 exit 时调用,清理映射防止后续 input 写到已死 pty + 释放 replay 闭包 */
34315
34247
  unregisterPty(toolSessionId) {
@@ -34399,9 +34331,6 @@ var SessionManager = class {
34399
34331
  /** ClaudeTuiAdapter spawn 时注册 surface ref;同一 tsid 重 spawn 会覆盖 */
34400
34332
  registerSurface(toolSessionId, surface) {
34401
34333
  this.surfacesByToolSid.set(toolSessionId, surface);
34402
- const sid = this.sessionIdByToolSid(toolSessionId);
34403
- const size = sid ? this.lastUiSizeBySessionId.get(sid) : void 0;
34404
- if (size) surface.resize(size.cols, size.rows);
34405
34334
  }
34406
34335
  /** spawn 进程 exit 时清理 */
34407
34336
  unregisterSurface(toolSessionId) {
@@ -34414,7 +34343,6 @@ var SessionManager = class {
34414
34343
  * 找不到 runner / toolSessionId / pty 任一缺失 → 返 false,handler 静默给 UI 报 ok=false 不抛错。
34415
34344
  */
34416
34345
  resizePty(sessionId, cols, rows) {
34417
- this.lastUiSizeBySessionId.set(sessionId, { cols, rows });
34418
34346
  const runner = this.runners.get(sessionId);
34419
34347
  if (!runner) return false;
34420
34348
  const tsid = runner.getState().file.toolSessionId;
@@ -35588,8 +35516,8 @@ function turnStartInput(text) {
35588
35516
  const items = [];
35589
35517
  let leftover = text;
35590
35518
  for (const m2 of text.matchAll(SKILL_RE)) {
35591
- const [marker, name, path59] = m2;
35592
- items.push({ type: "skill", name, path: path59 });
35519
+ const [marker, name, path58] = m2;
35520
+ items.push({ type: "skill", name, path: path58 });
35593
35521
  leftover = leftover.replace(marker, "");
35594
35522
  }
35595
35523
  for (const m2 of text.matchAll(ATTACHMENT_RE2)) {
@@ -35648,6 +35576,7 @@ function createCodexSession(ctx, sink, deps = {}) {
35648
35576
  ]);
35649
35577
  return;
35650
35578
  }
35579
+ deps.logger?.warn("codex unknown server-request auto-cancelled", { method });
35651
35580
  client.respond(id, "cancel");
35652
35581
  },
35653
35582
  onClose: () => finish(proc.exitCode)
@@ -35821,8 +35750,8 @@ var CodexAdapter = class {
35821
35750
 
35822
35751
  // src/tools/claude-tui.ts
35823
35752
  var import_node_fs11 = __toESM(require("fs"), 1);
35824
- var import_node_os6 = __toESM(require("os"), 1);
35825
- var import_node_path10 = __toESM(require("path"), 1);
35753
+ var import_node_os5 = __toESM(require("os"), 1);
35754
+ var import_node_path9 = __toESM(require("path"), 1);
35826
35755
  var import_headless = __toESM(require_xterm_headless(), 1);
35827
35756
 
35828
35757
  // ../node_modules/.pnpm/@xterm+addon-serialize@0.14.0/node_modules/@xterm/addon-serialize/lib/addon-serialize.mjs
@@ -36801,8 +36730,8 @@ function buildTuiSpawnArgs(ctx, isResume = false) {
36801
36730
  }
36802
36731
  function jsonlExistsForCtx(ctx) {
36803
36732
  if (!ctx.toolSessionId) return false;
36804
- const home = import_node_os6.default.homedir();
36805
- const file = import_node_path10.default.join(home, ".claude", "projects", cwdToHashDir(ctx.cwd), `${ctx.toolSessionId}.jsonl`);
36733
+ const home = import_node_os5.default.homedir();
36734
+ const file = import_node_path9.default.join(home, ".claude", "projects", cwdToHashDir(ctx.cwd), `${ctx.toolSessionId}.jsonl`);
36806
36735
  try {
36807
36736
  return import_node_fs11.default.statSync(file).isFile();
36808
36737
  } catch {
@@ -36999,13 +36928,13 @@ function mapSkillsListResponse(res) {
36999
36928
  const r = s ?? {};
37000
36929
  const name = str3(r.name);
37001
36930
  if (!name) continue;
37002
- const path59 = str3(r.path);
36931
+ const path58 = str3(r.path);
37003
36932
  const description = str3(r.description);
37004
36933
  const isPlugin = name.includes(":");
37005
36934
  out.push({
37006
36935
  name,
37007
36936
  source: isPlugin ? "plugin" : "project",
37008
- ...path59 ? { path: path59 } : {},
36937
+ ...path58 ? { path: path58 } : {},
37009
36938
  ...description ? { description } : {},
37010
36939
  ...isPlugin ? { plugin: name.split(":")[0] } : {}
37011
36940
  });
@@ -37045,15 +36974,15 @@ async function listCodexSkills(cwd, deps = {}) {
37045
36974
 
37046
36975
  // src/workspace/browser.ts
37047
36976
  var import_node_fs12 = __toESM(require("fs"), 1);
37048
- var import_node_os7 = __toESM(require("os"), 1);
37049
- var import_node_path11 = __toESM(require("path"), 1);
36977
+ var import_node_os6 = __toESM(require("os"), 1);
36978
+ var import_node_path10 = __toESM(require("path"), 1);
37050
36979
  init_protocol();
37051
36980
  var MAX_FILE_BYTES = 2 * 1024 * 1024;
37052
36981
  function resolveInsideCwd(cwd, subpath) {
37053
- const absCwd = import_node_path11.default.resolve(cwd);
37054
- const joined = import_node_path11.default.resolve(absCwd, subpath ?? ".");
37055
- const rel = import_node_path11.default.relative(absCwd, joined);
37056
- if (rel.startsWith("..") || import_node_path11.default.isAbsolute(rel)) {
36982
+ const absCwd = import_node_path10.default.resolve(cwd);
36983
+ const joined = import_node_path10.default.resolve(absCwd, subpath ?? ".");
36984
+ const rel = import_node_path10.default.relative(absCwd, joined);
36985
+ if (rel.startsWith("..") || import_node_path10.default.isAbsolute(rel)) {
37057
36986
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
37058
36987
  }
37059
36988
  return joined;
@@ -37071,7 +37000,7 @@ function ensureCwd(cwd) {
37071
37000
  }
37072
37001
  var WorkspaceBrowser = class {
37073
37002
  list(args) {
37074
- const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os7.default.homedir();
37003
+ const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os6.default.homedir();
37075
37004
  ensureCwd(cwd);
37076
37005
  const full = resolveInsideCwd(cwd, args.path);
37077
37006
  const dirents = import_node_fs12.default.readdirSync(full, { withFileTypes: true });
@@ -37084,7 +37013,7 @@ var WorkspaceBrowser = class {
37084
37013
  mtime: ""
37085
37014
  };
37086
37015
  try {
37087
- const st = import_node_fs12.default.statSync(import_node_path11.default.join(full, d.name));
37016
+ const st = import_node_fs12.default.statSync(import_node_path10.default.join(full, d.name));
37088
37017
  entry.mtime = new Date(st.mtimeMs).toISOString();
37089
37018
  if (d.isFile()) entry.size = st.size;
37090
37019
  } catch {
@@ -37130,8 +37059,8 @@ var WorkspaceBrowser = class {
37130
37059
 
37131
37060
  // src/skills/agents-scanner.ts
37132
37061
  var import_node_fs13 = __toESM(require("fs"), 1);
37133
- var import_node_os8 = __toESM(require("os"), 1);
37134
- var import_node_path12 = __toESM(require("path"), 1);
37062
+ var import_node_os7 = __toESM(require("os"), 1);
37063
+ var import_node_path11 = __toESM(require("path"), 1);
37135
37064
  var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
37136
37065
  function isDirLikeSync2(p2) {
37137
37066
  try {
@@ -37169,10 +37098,10 @@ function scanAgentsDir(dir, source, seen, out) {
37169
37098
  }
37170
37099
  for (const ent of entries) {
37171
37100
  if (!ent.name.endsWith(".md")) continue;
37172
- if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path12.default.join(dir, ent.name)))) {
37101
+ if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path11.default.join(dir, ent.name)))) {
37173
37102
  continue;
37174
37103
  }
37175
- const filePath = import_node_path12.default.join(dir, ent.name);
37104
+ const filePath = import_node_path11.default.join(dir, ent.name);
37176
37105
  const baseName = ent.name.replace(/\.md$/, "");
37177
37106
  if (seen.has(baseName)) continue;
37178
37107
  seen.add(baseName);
@@ -37195,7 +37124,7 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
37195
37124
  return;
37196
37125
  }
37197
37126
  for (const ent of entries) {
37198
- const childPath = import_node_path12.default.join(dir, ent.name);
37127
+ const childPath = import_node_path11.default.join(dir, ent.name);
37199
37128
  if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
37200
37129
  walk2(childPath, [...namespaces, ent.name]);
37201
37130
  continue;
@@ -37220,9 +37149,9 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
37220
37149
  walk2(root, []);
37221
37150
  }
37222
37151
  function readInstalledPlugins2(home) {
37223
- const pluginsDir = import_node_path12.default.join(home, ".claude", "plugins");
37224
- const v2 = import_node_path12.default.join(pluginsDir, "installed_plugins_v2.json");
37225
- const v1 = import_node_path12.default.join(pluginsDir, "installed_plugins.json");
37152
+ const pluginsDir = import_node_path11.default.join(home, ".claude", "plugins");
37153
+ const v2 = import_node_path11.default.join(pluginsDir, "installed_plugins_v2.json");
37154
+ const v1 = import_node_path11.default.join(pluginsDir, "installed_plugins.json");
37226
37155
  let raw = null;
37227
37156
  for (const candidate of [v2, v1]) {
37228
37157
  try {
@@ -37251,19 +37180,19 @@ function readInstalledPlugins2(home) {
37251
37180
  return out;
37252
37181
  }
37253
37182
  function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
37254
- let cur = import_node_path12.default.resolve(startCwd);
37255
- const fsRoot = import_node_path12.default.parse(cur).root;
37183
+ let cur = import_node_path11.default.resolve(startCwd);
37184
+ const fsRoot = import_node_path11.default.parse(cur).root;
37256
37185
  while (true) {
37257
- scanAgentsDir(import_node_path12.default.join(cur, ".claude", "agents"), "project", seen, out);
37186
+ scanAgentsDir(import_node_path11.default.join(cur, ".claude", "agents"), "project", seen, out);
37258
37187
  let hasGit = false;
37259
37188
  try {
37260
- hasGit = import_node_fs13.default.existsSync(import_node_path12.default.join(cur, ".git"));
37189
+ hasGit = import_node_fs13.default.existsSync(import_node_path11.default.join(cur, ".git"));
37261
37190
  } catch {
37262
37191
  }
37263
37192
  if (hasGit) return;
37264
37193
  if (cur === home) return;
37265
37194
  if (cur === fsRoot) return;
37266
- const parent = import_node_path12.default.dirname(cur);
37195
+ const parent = import_node_path11.default.dirname(cur);
37267
37196
  if (parent === cur) return;
37268
37197
  cur = parent;
37269
37198
  }
@@ -37273,7 +37202,7 @@ var AgentsScanner = class {
37273
37202
  extraPluginRoots;
37274
37203
  policyDir;
37275
37204
  constructor(opts = {}) {
37276
- this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os8.default.homedir();
37205
+ this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os7.default.homedir();
37277
37206
  this.extraPluginRoots = opts.extraPluginRoots ?? [];
37278
37207
  if (opts.policyDir !== void 0) {
37279
37208
  this.policyDir = opts.policyDir;
@@ -37298,7 +37227,7 @@ var AgentsScanner = class {
37298
37227
  }
37299
37228
  const fsBlock = [];
37300
37229
  scanAgentsDir(
37301
- import_node_path12.default.join(this.home, ".claude", "agents"),
37230
+ import_node_path11.default.join(this.home, ".claude", "agents"),
37302
37231
  "global",
37303
37232
  seen,
37304
37233
  fsBlock
@@ -37312,7 +37241,7 @@ var AgentsScanner = class {
37312
37241
  ...this.extraPluginRoots
37313
37242
  ];
37314
37243
  for (const { name, root } of plugins) {
37315
- const agentsRoot = import_node_path12.default.join(root, "agents");
37244
+ const agentsRoot = import_node_path11.default.join(root, "agents");
37316
37245
  scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
37317
37246
  }
37318
37247
  return [...builtinBlock, ...fsBlock];
@@ -37321,27 +37250,27 @@ var AgentsScanner = class {
37321
37250
 
37322
37251
  // src/observer/session-observer.ts
37323
37252
  var import_node_fs15 = __toESM(require("fs"), 1);
37324
- var import_node_os10 = __toESM(require("os"), 1);
37325
- var import_node_path14 = __toESM(require("path"), 1);
37253
+ var import_node_os9 = __toESM(require("os"), 1);
37254
+ var import_node_path13 = __toESM(require("path"), 1);
37326
37255
  init_claude_history();
37327
37256
 
37328
37257
  // src/observer/subagent-meta-observer.ts
37329
37258
  var import_node_fs14 = __toESM(require("fs"), 1);
37330
- var import_node_os9 = __toESM(require("os"), 1);
37331
- var import_node_path13 = __toESM(require("path"), 1);
37259
+ var import_node_os8 = __toESM(require("os"), 1);
37260
+ var import_node_path12 = __toESM(require("path"), 1);
37332
37261
  init_claude_history();
37333
37262
  var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
37334
37263
  var SubagentMetaObserver = class {
37335
37264
  constructor(opts) {
37336
37265
  this.opts = opts;
37337
- this.home = opts.home ?? import_node_os9.default.homedir();
37266
+ this.home = opts.home ?? import_node_os8.default.homedir();
37338
37267
  }
37339
37268
  opts;
37340
37269
  home;
37341
37270
  watches = /* @__PURE__ */ new Map();
37342
37271
  // public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
37343
37272
  resolveSubagentDir(cwd, toolSessionId) {
37344
- return import_node_path13.default.join(
37273
+ return import_node_path12.default.join(
37345
37274
  this.home,
37346
37275
  ".claude",
37347
37276
  "projects",
@@ -37397,7 +37326,7 @@ var SubagentMetaObserver = class {
37397
37326
  if (!m2) return;
37398
37327
  const agentId = m2[1];
37399
37328
  if (w2.emitted.has(agentId)) return;
37400
- const file = import_node_path13.default.join(w2.dirPath, name);
37329
+ const file = import_node_path12.default.join(w2.dirPath, name);
37401
37330
  let raw;
37402
37331
  try {
37403
37332
  raw = import_node_fs14.default.readFileSync(file, "utf8");
@@ -37445,7 +37374,7 @@ var SubagentMetaObserver = class {
37445
37374
  var SessionObserver = class {
37446
37375
  constructor(opts) {
37447
37376
  this.opts = opts;
37448
- this.home = opts.home ?? import_node_os10.default.homedir();
37377
+ this.home = opts.home ?? import_node_os9.default.homedir();
37449
37378
  this.metaObserver = opts.enableSubagentMetaObserver ? new SubagentMetaObserver({ home: this.home, onEvent: opts.onEvent }) : null;
37450
37379
  }
37451
37380
  opts;
@@ -37457,7 +37386,7 @@ var SessionObserver = class {
37457
37386
  metaObserver;
37458
37387
  resolveJsonlPath(cwd, toolSessionId, override) {
37459
37388
  if (override) return override;
37460
- return import_node_path14.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
37389
+ return import_node_path13.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
37461
37390
  }
37462
37391
  start(args) {
37463
37392
  this.stop(args.sessionId);
@@ -37478,10 +37407,10 @@ var SessionObserver = class {
37478
37407
  prevIsRejectSentinel: false
37479
37408
  };
37480
37409
  try {
37481
- import_node_fs15.default.mkdirSync(import_node_path14.default.dirname(filePath), { recursive: true });
37410
+ import_node_fs15.default.mkdirSync(import_node_path13.default.dirname(filePath), { recursive: true });
37482
37411
  } catch {
37483
37412
  }
37484
- w2.watcher = import_node_fs15.default.watch(import_node_path14.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
37413
+ w2.watcher = import_node_fs15.default.watch(import_node_path13.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
37485
37414
  if (!changedName || !filePath.endsWith(changedName)) return;
37486
37415
  this.poll(w2);
37487
37416
  });
@@ -38288,7 +38217,7 @@ async function authenticate(token, deps) {
38288
38217
 
38289
38218
  // src/permission/capability-store.ts
38290
38219
  var fs18 = __toESM(require("fs"), 1);
38291
- var path19 = __toESM(require("path"), 1);
38220
+ var path18 = __toESM(require("path"), 1);
38292
38221
  var CAPABILITIES_FILE_NAME = "capabilities.json";
38293
38222
  var FILE_VERSION = 1;
38294
38223
  var CapabilityStore = class {
@@ -38318,7 +38247,7 @@ var CapabilityStore = class {
38318
38247
  this.flush();
38319
38248
  }
38320
38249
  filePath() {
38321
- return path19.join(this.dataDir, CAPABILITIES_FILE_NAME);
38250
+ return path18.join(this.dataDir, CAPABILITIES_FILE_NAME);
38322
38251
  }
38323
38252
  readFromDisk() {
38324
38253
  const file = this.filePath();
@@ -38465,7 +38394,7 @@ function cleanupGuestSessionsForCapability(cap, factory) {
38465
38394
 
38466
38395
  // src/inbox/inbox-store.ts
38467
38396
  var fs20 = __toESM(require("fs"), 1);
38468
- var path20 = __toESM(require("path"), 1);
38397
+ var path19 = __toESM(require("path"), 1);
38469
38398
  var INBOX_SUBDIR = "inbox";
38470
38399
  var InboxStore = class {
38471
38400
  constructor(dataDir) {
@@ -38563,10 +38492,10 @@ var InboxStore = class {
38563
38492
  }
38564
38493
  }
38565
38494
  dirPath() {
38566
- return path20.join(this.dataDir, INBOX_SUBDIR);
38495
+ return path19.join(this.dataDir, INBOX_SUBDIR);
38567
38496
  }
38568
38497
  filePath(peerDeviceId) {
38569
- return path20.join(this.dirPath(), `${peerDeviceId}.jsonl`);
38498
+ return path19.join(this.dirPath(), `${peerDeviceId}.jsonl`);
38570
38499
  }
38571
38500
  };
38572
38501
  function parseAllLines(raw) {
@@ -38654,7 +38583,7 @@ var InboxManager = class {
38654
38583
 
38655
38584
  // src/state/contact-store.ts
38656
38585
  var fs21 = __toESM(require("fs"), 1);
38657
- var path21 = __toESM(require("path"), 1);
38586
+ var path20 = __toESM(require("path"), 1);
38658
38587
  var FILE_NAME = "contacts.json";
38659
38588
  var ContactStore = class {
38660
38589
  constructor(dataDir) {
@@ -38664,7 +38593,7 @@ var ContactStore = class {
38664
38593
  contacts = /* @__PURE__ */ new Map();
38665
38594
  load() {
38666
38595
  this.contacts.clear();
38667
- const file = path21.join(this.dataDir, FILE_NAME);
38596
+ const file = path20.join(this.dataDir, FILE_NAME);
38668
38597
  let raw;
38669
38598
  try {
38670
38599
  raw = fs21.readFileSync(file, "utf8");
@@ -38710,7 +38639,7 @@ var ContactStore = class {
38710
38639
  return existed;
38711
38640
  }
38712
38641
  flush() {
38713
- const file = path21.join(this.dataDir, FILE_NAME);
38642
+ const file = path20.join(this.dataDir, FILE_NAME);
38714
38643
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
38715
38644
  const content = JSON.stringify(
38716
38645
  { contacts: Array.from(this.contacts.values()) },
@@ -38874,52 +38803,52 @@ async function autoReverseContact(args) {
38874
38803
 
38875
38804
  // src/migrations/2026-05-20-flatten-sessions.ts
38876
38805
  var fs22 = __toESM(require("fs"), 1);
38877
- var path22 = __toESM(require("path"), 1);
38806
+ var path21 = __toESM(require("path"), 1);
38878
38807
  var MIGRATION_FLAG_NAME = ".migration.v1.done";
38879
38808
  function migrateFlattenSessions(opts) {
38880
38809
  const dataDir = opts.dataDir;
38881
38810
  const now = opts.now ?? Date.now;
38882
- const sessionsDir = path22.join(dataDir, "sessions");
38883
- const flagPath = path22.join(sessionsDir, MIGRATION_FLAG_NAME);
38811
+ const sessionsDir = path21.join(dataDir, "sessions");
38812
+ const flagPath = path21.join(sessionsDir, MIGRATION_FLAG_NAME);
38884
38813
  if (existsSync3(flagPath)) {
38885
38814
  return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
38886
38815
  }
38887
38816
  let movedBare = 0;
38888
38817
  let movedVmOwner = 0;
38889
38818
  let archivedListener = 0;
38890
- const defaultDir = path22.join(sessionsDir, "default");
38819
+ const defaultDir = path21.join(sessionsDir, "default");
38891
38820
  if (existsSync3(defaultDir)) {
38892
38821
  for (const entry of readdirSafe(defaultDir)) {
38893
38822
  if (!entry.endsWith(".json")) continue;
38894
- const src = path22.join(defaultDir, entry);
38895
- const dst = path22.join(sessionsDir, entry);
38823
+ const src = path21.join(defaultDir, entry);
38824
+ const dst = path21.join(sessionsDir, entry);
38896
38825
  fs22.renameSync(src, dst);
38897
38826
  movedBare += 1;
38898
38827
  }
38899
38828
  rmdirIfEmpty(defaultDir);
38900
38829
  }
38901
38830
  for (const pid of readdirSafe(sessionsDir)) {
38902
- const personaDir = path22.join(sessionsDir, pid);
38831
+ const personaDir = path21.join(sessionsDir, pid);
38903
38832
  if (!isDir(personaDir)) continue;
38904
38833
  if (pid === "default") continue;
38905
- const ownerSrc = path22.join(personaDir, "owner");
38834
+ const ownerSrc = path21.join(personaDir, "owner");
38906
38835
  if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
38907
- const ownerDst = path22.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
38836
+ const ownerDst = path21.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
38908
38837
  fs22.mkdirSync(ownerDst, { recursive: true });
38909
38838
  for (const file of readdirSafe(ownerSrc)) {
38910
38839
  if (!file.endsWith(".json")) continue;
38911
- fs22.renameSync(path22.join(ownerSrc, file), path22.join(ownerDst, file));
38840
+ fs22.renameSync(path21.join(ownerSrc, file), path21.join(ownerDst, file));
38912
38841
  movedVmOwner += 1;
38913
38842
  }
38914
38843
  rmdirIfEmpty(ownerSrc);
38915
38844
  }
38916
- const listenerSrc = path22.join(personaDir, "listener");
38845
+ const listenerSrc = path21.join(personaDir, "listener");
38917
38846
  if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
38918
- const archiveDst = path22.join(dataDir, ".legacy", `listener-${pid}`);
38847
+ const archiveDst = path21.join(dataDir, ".legacy", `listener-${pid}`);
38919
38848
  fs22.mkdirSync(archiveDst, { recursive: true });
38920
38849
  for (const file of readdirSafe(listenerSrc)) {
38921
38850
  if (!file.endsWith(".json")) continue;
38922
- fs22.renameSync(path22.join(listenerSrc, file), path22.join(archiveDst, file));
38851
+ fs22.renameSync(path21.join(listenerSrc, file), path21.join(archiveDst, file));
38923
38852
  archivedListener += 1;
38924
38853
  }
38925
38854
  rmdirIfEmpty(listenerSrc);
@@ -38967,10 +38896,10 @@ function rmdirIfEmpty(p2) {
38967
38896
 
38968
38897
  // src/transport/http-router.ts
38969
38898
  var import_node_fs17 = __toESM(require("fs"), 1);
38970
- var import_node_path18 = __toESM(require("path"), 1);
38899
+ var import_node_path17 = __toESM(require("path"), 1);
38971
38900
 
38972
38901
  // src/attachment/mime.ts
38973
- var import_node_path15 = __toESM(require("path"), 1);
38902
+ var import_node_path14 = __toESM(require("path"), 1);
38974
38903
  var TEXT_PLAIN = "text/plain; charset=utf-8";
38975
38904
  var EXT_TO_NATIVE_MIME = {
38976
38905
  // 图片
@@ -39077,7 +39006,7 @@ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
39077
39006
  ".mk"
39078
39007
  ]);
39079
39008
  function lookupMime(filePathOrName) {
39080
- const ext = import_node_path15.default.extname(filePathOrName).toLowerCase();
39009
+ const ext = import_node_path14.default.extname(filePathOrName).toLowerCase();
39081
39010
  if (EXT_TO_NATIVE_MIME[ext]) return EXT_TO_NATIVE_MIME[ext];
39082
39011
  if (TEXT_EXTENSIONS.has(ext)) return TEXT_PLAIN;
39083
39012
  return "application/octet-stream";
@@ -39147,7 +39076,7 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
39147
39076
 
39148
39077
  // src/attachment/upload.ts
39149
39078
  var import_node_fs16 = __toESM(require("fs"), 1);
39150
- var import_node_path16 = __toESM(require("path"), 1);
39079
+ var import_node_path15 = __toESM(require("path"), 1);
39151
39080
  var import_node_crypto5 = __toESM(require("crypto"), 1);
39152
39081
  var import_promises = require("stream/promises");
39153
39082
  var UploadError = class extends Error {
@@ -39159,14 +39088,14 @@ var UploadError = class extends Error {
39159
39088
  code;
39160
39089
  };
39161
39090
  function assertValidFileName(fileName) {
39162
- if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path16.default.basename(fileName)) {
39091
+ if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path15.default.basename(fileName)) {
39163
39092
  throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
39164
39093
  }
39165
39094
  }
39166
39095
  var HASH_PREFIX_LEN = 16;
39167
39096
  async function writeUploadedAttachment(args) {
39168
39097
  assertValidFileName(args.fileName);
39169
- const attachmentsRoot = import_node_path16.default.join(args.sessionDir, ".attachments");
39098
+ const attachmentsRoot = import_node_path15.default.join(args.sessionDir, ".attachments");
39170
39099
  try {
39171
39100
  import_node_fs16.default.mkdirSync(attachmentsRoot, { recursive: true });
39172
39101
  } catch (err) {
@@ -39174,7 +39103,7 @@ async function writeUploadedAttachment(args) {
39174
39103
  }
39175
39104
  const hasher = import_node_crypto5.default.createHash("sha256");
39176
39105
  let actualSize = 0;
39177
- const tmpPath = import_node_path16.default.join(
39106
+ const tmpPath = import_node_path15.default.join(
39178
39107
  attachmentsRoot,
39179
39108
  `.upload-${process.pid}-${Date.now()}-${import_node_crypto5.default.randomBytes(4).toString("hex")}`
39180
39109
  );
@@ -39209,7 +39138,7 @@ async function writeUploadedAttachment(args) {
39209
39138
  );
39210
39139
  }
39211
39140
  const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
39212
- const hashDir = import_node_path16.default.join(attachmentsRoot, attachmentId);
39141
+ const hashDir = import_node_path15.default.join(attachmentsRoot, attachmentId);
39213
39142
  let finalFileName;
39214
39143
  let hashDirExists = false;
39215
39144
  try {
@@ -39227,7 +39156,7 @@ async function writeUploadedAttachment(args) {
39227
39156
  try {
39228
39157
  import_node_fs16.default.mkdirSync(hashDir, { recursive: true });
39229
39158
  finalFileName = args.fileName;
39230
- import_node_fs16.default.renameSync(tmpPath, import_node_path16.default.join(hashDir, finalFileName));
39159
+ import_node_fs16.default.renameSync(tmpPath, import_node_path15.default.join(hashDir, finalFileName));
39231
39160
  } catch (err) {
39232
39161
  try {
39233
39162
  import_node_fs16.default.unlinkSync(tmpPath);
@@ -39236,8 +39165,8 @@ async function writeUploadedAttachment(args) {
39236
39165
  throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
39237
39166
  }
39238
39167
  }
39239
- const absPath = import_node_path16.default.join(hashDir, finalFileName);
39240
- const relPath = import_node_path16.default.relative(args.sessionDir, absPath);
39168
+ const absPath = import_node_path15.default.join(hashDir, finalFileName);
39169
+ const relPath = import_node_path15.default.relative(args.sessionDir, absPath);
39241
39170
  args.groupFileStore.upsert(args.scope, args.sessionId, {
39242
39171
  relPath: absPath,
39243
39172
  // 存绝对路径,与现有 agent 入清单的形态一致(attachment.ts:144 双形态兼容)
@@ -39251,8 +39180,8 @@ async function writeUploadedAttachment(args) {
39251
39180
 
39252
39181
  // src/extension/import.ts
39253
39182
  var import_promises2 = __toESM(require("fs/promises"), 1);
39254
- var import_node_path17 = __toESM(require("path"), 1);
39255
- var import_node_os11 = __toESM(require("os"), 1);
39183
+ var import_node_path16 = __toESM(require("path"), 1);
39184
+ var import_node_os10 = __toESM(require("os"), 1);
39256
39185
  var import_jszip = __toESM(require_lib3(), 1);
39257
39186
  var ImportError = class extends Error {
39258
39187
  constructor(code, message) {
@@ -39269,7 +39198,7 @@ async function importZip(buf, root) {
39269
39198
  throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
39270
39199
  }
39271
39200
  for (const name of Object.keys(zip.files)) {
39272
- if (name.includes("..") || name.startsWith("/") || import_node_path17.default.isAbsolute(name)) {
39201
+ if (name.includes("..") || name.startsWith("/") || import_node_path16.default.isAbsolute(name)) {
39273
39202
  throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
39274
39203
  }
39275
39204
  }
@@ -39302,7 +39231,7 @@ async function importZip(buf, root) {
39302
39231
  );
39303
39232
  }
39304
39233
  }
39305
- const destDir = import_node_path17.default.join(root, manifest.id);
39234
+ const destDir = import_node_path16.default.join(root, manifest.id);
39306
39235
  let destExists = false;
39307
39236
  try {
39308
39237
  await import_promises2.default.access(destDir);
@@ -39312,15 +39241,15 @@ async function importZip(buf, root) {
39312
39241
  if (destExists) {
39313
39242
  throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
39314
39243
  }
39315
- const stage = await import_promises2.default.mkdtemp(import_node_path17.default.join(import_node_os11.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
39244
+ const stage = await import_promises2.default.mkdtemp(import_node_path16.default.join(import_node_os10.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
39316
39245
  try {
39317
39246
  for (const [name, entry] of Object.entries(zip.files)) {
39318
- const dest = import_node_path17.default.join(stage, name);
39247
+ const dest = import_node_path16.default.join(stage, name);
39319
39248
  if (entry.dir) {
39320
39249
  await import_promises2.default.mkdir(dest, { recursive: true });
39321
39250
  continue;
39322
39251
  }
39323
- await import_promises2.default.mkdir(import_node_path17.default.dirname(dest), { recursive: true });
39252
+ await import_promises2.default.mkdir(import_node_path16.default.dirname(dest), { recursive: true });
39324
39253
  const content = await entry.async("nodebuffer");
39325
39254
  await import_promises2.default.writeFile(dest, content);
39326
39255
  }
@@ -39434,7 +39363,7 @@ function isValidUploadFileName(fileName) {
39434
39363
  if (fileName === "." || fileName === "..") return false;
39435
39364
  if (fileName.startsWith(".")) return false;
39436
39365
  if (fileName.includes("/") || fileName.includes("\\")) return false;
39437
- return fileName === import_node_path18.default.basename(fileName);
39366
+ return fileName === import_node_path17.default.basename(fileName);
39438
39367
  }
39439
39368
  function createHttpRouter(deps) {
39440
39369
  return async (req, res) => {
@@ -39663,7 +39592,7 @@ function createHttpRouter(deps) {
39663
39592
  return true;
39664
39593
  }
39665
39594
  let absPath;
39666
- if (import_node_path18.default.isAbsolute(pathParam)) {
39595
+ if (import_node_path17.default.isAbsolute(pathParam)) {
39667
39596
  absPath = pathParam;
39668
39597
  } else if (deps.sessionStore) {
39669
39598
  const file = deps.sessionStore.read(sid);
@@ -39671,7 +39600,7 @@ function createHttpRouter(deps) {
39671
39600
  sendJson(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
39672
39601
  return true;
39673
39602
  }
39674
- absPath = import_node_path18.default.join(file.cwd, pathParam);
39603
+ absPath = import_node_path17.default.join(file.cwd, pathParam);
39675
39604
  } else {
39676
39605
  sendJson(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
39677
39606
  return true;
@@ -39769,7 +39698,7 @@ function streamFile(res, absPath, logger) {
39769
39698
  return;
39770
39699
  }
39771
39700
  const mime = lookupMime(absPath);
39772
- const basename = import_node_path18.default.basename(absPath);
39701
+ const basename = import_node_path17.default.basename(absPath);
39773
39702
  res.writeHead(200, {
39774
39703
  "Content-Type": mime,
39775
39704
  "Content-Length": String(stat.size),
@@ -39787,7 +39716,7 @@ function streamFile(res, absPath, logger) {
39787
39716
 
39788
39717
  // src/attachment/gc.ts
39789
39718
  var import_node_fs18 = __toESM(require("fs"), 1);
39790
- var import_node_path19 = __toESM(require("path"), 1);
39719
+ var import_node_path18 = __toESM(require("path"), 1);
39791
39720
  var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
39792
39721
  function runAttachmentGc(args) {
39793
39722
  const now = (args.now ?? Date.now)();
@@ -39796,17 +39725,17 @@ function runAttachmentGc(args) {
39796
39725
  for (const { scope, sessionId } of args.sessionScopes) {
39797
39726
  for (const entry of args.groupFileStore.list(scope, sessionId)) {
39798
39727
  if (entry.stale) continue;
39799
- if (import_node_path19.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
39728
+ if (import_node_path18.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
39800
39729
  }
39801
39730
  }
39802
39731
  for (const { scope, sessionId } of args.sessionScopes) {
39803
- const sessionDir = args.getSessionCwd?.(sessionId) ?? import_node_path19.default.join(
39732
+ const sessionDir = args.getSessionCwd?.(sessionId) ?? import_node_path18.default.join(
39804
39733
  args.dataDir,
39805
39734
  "sessions",
39806
39735
  ...scopeSubPath(scope).map(safeFileName),
39807
39736
  safeFileName(sessionId)
39808
39737
  );
39809
- const attRoot = import_node_path19.default.join(sessionDir, ".attachments");
39738
+ const attRoot = import_node_path18.default.join(sessionDir, ".attachments");
39810
39739
  let hashDirs;
39811
39740
  try {
39812
39741
  hashDirs = import_node_fs18.default.readdirSync(attRoot);
@@ -39816,7 +39745,7 @@ function runAttachmentGc(args) {
39816
39745
  continue;
39817
39746
  }
39818
39747
  for (const hashDir of hashDirs) {
39819
- const hashDirAbs = import_node_path19.default.join(attRoot, hashDir);
39748
+ const hashDirAbs = import_node_path18.default.join(attRoot, hashDir);
39820
39749
  let files;
39821
39750
  try {
39822
39751
  files = import_node_fs18.default.readdirSync(hashDirAbs);
@@ -39824,7 +39753,7 @@ function runAttachmentGc(args) {
39824
39753
  continue;
39825
39754
  }
39826
39755
  for (const name of files) {
39827
- const file = import_node_path19.default.join(hashDirAbs, name);
39756
+ const file = import_node_path18.default.join(hashDirAbs, name);
39828
39757
  let stat;
39829
39758
  try {
39830
39759
  stat = import_node_fs18.default.statSync(file);
@@ -39855,7 +39784,7 @@ function runAttachmentGc(args) {
39855
39784
 
39856
39785
  // src/attachment/group.ts
39857
39786
  var import_node_fs19 = __toESM(require("fs"), 1);
39858
- var import_node_path20 = __toESM(require("path"), 1);
39787
+ var import_node_path19 = __toESM(require("path"), 1);
39859
39788
  var import_node_crypto6 = __toESM(require("crypto"), 1);
39860
39789
  init_protocol();
39861
39790
  var GroupFileStore = class {
@@ -39867,11 +39796,11 @@ var GroupFileStore = class {
39867
39796
  this.logger = opts.logger;
39868
39797
  }
39869
39798
  rootForScope(scope) {
39870
- return import_node_path20.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
39799
+ return import_node_path19.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
39871
39800
  }
39872
39801
  /** 与 SessionStore.filePath 平级,扩展名 .group-files.json */
39873
39802
  filePath(scope, sessionId) {
39874
- return import_node_path20.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
39803
+ return import_node_path19.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
39875
39804
  }
39876
39805
  cacheKey(scope, sessionId) {
39877
39806
  return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
@@ -39906,7 +39835,7 @@ var GroupFileStore = class {
39906
39835
  }
39907
39836
  writeFile(scope, sessionId, entries) {
39908
39837
  const file = this.filePath(scope, sessionId);
39909
- import_node_fs19.default.mkdirSync(import_node_path20.default.dirname(file), { recursive: true });
39838
+ import_node_fs19.default.mkdirSync(import_node_path19.default.dirname(file), { recursive: true });
39910
39839
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
39911
39840
  import_node_fs19.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
39912
39841
  import_node_fs19.default.renameSync(tmp, file);
@@ -39996,9 +39925,9 @@ var GroupFileStore = class {
39996
39925
 
39997
39926
  // src/discovery/state-file.ts
39998
39927
  var import_node_fs20 = __toESM(require("fs"), 1);
39999
- var import_node_path21 = __toESM(require("path"), 1);
39928
+ var import_node_path20 = __toESM(require("path"), 1);
40000
39929
  function defaultStateFilePath(dataDir) {
40001
- return import_node_path21.default.join(dataDir, "state.json");
39930
+ return import_node_path20.default.join(dataDir, "state.json");
40002
39931
  }
40003
39932
  function isPidAlive(pid) {
40004
39933
  if (!Number.isFinite(pid) || pid <= 0) return false;
@@ -40034,7 +39963,7 @@ var StateFileManager = class {
40034
39963
  return { status: "stale", existing };
40035
39964
  }
40036
39965
  write(state) {
40037
- import_node_fs20.default.mkdirSync(import_node_path21.default.dirname(this.file), { recursive: true });
39966
+ import_node_fs20.default.mkdirSync(import_node_path20.default.dirname(this.file), { recursive: true });
40038
39967
  const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
40039
39968
  import_node_fs20.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
40040
39969
  import_node_fs20.default.renameSync(tmp, this.file);
@@ -40063,13 +39992,13 @@ function readDaemonSourceFromEnv(env = process.env) {
40063
39992
 
40064
39993
  // src/tunnel/tunnel-manager.ts
40065
39994
  var import_node_fs24 = __toESM(require("fs"), 1);
40066
- var import_node_path25 = __toESM(require("path"), 1);
39995
+ var import_node_path24 = __toESM(require("path"), 1);
40067
39996
  var import_node_crypto7 = __toESM(require("crypto"), 1);
40068
39997
  var import_node_child_process9 = require("child_process");
40069
39998
 
40070
39999
  // src/tunnel/tunnel-store.ts
40071
40000
  var import_node_fs21 = __toESM(require("fs"), 1);
40072
- var import_node_path22 = __toESM(require("path"), 1);
40001
+ var import_node_path21 = __toESM(require("path"), 1);
40073
40002
  var TunnelStore = class {
40074
40003
  constructor(filePath) {
40075
40004
  this.filePath = filePath;
@@ -40088,7 +40017,7 @@ var TunnelStore = class {
40088
40017
  }
40089
40018
  }
40090
40019
  async set(v2) {
40091
- const dir = import_node_path22.default.dirname(this.filePath);
40020
+ const dir = import_node_path21.default.dirname(this.filePath);
40092
40021
  await import_node_fs21.default.promises.mkdir(dir, { recursive: true });
40093
40022
  const data = JSON.stringify(v2, null, 2);
40094
40023
  const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
@@ -40199,8 +40128,8 @@ function escape(v2) {
40199
40128
 
40200
40129
  // src/tunnel/frpc-binary.ts
40201
40130
  var import_node_fs22 = __toESM(require("fs"), 1);
40202
- var import_node_os12 = __toESM(require("os"), 1);
40203
- var import_node_path23 = __toESM(require("path"), 1);
40131
+ var import_node_os11 = __toESM(require("os"), 1);
40132
+ var import_node_path22 = __toESM(require("path"), 1);
40204
40133
  var import_node_child_process7 = require("child_process");
40205
40134
  var import_node_stream2 = require("stream");
40206
40135
  var import_promises3 = require("stream/promises");
@@ -40239,13 +40168,13 @@ async function ensureFrpcBinary(opts) {
40239
40168
  }
40240
40169
  const version2 = opts.version ?? FRPC_VERSION;
40241
40170
  const platform = opts.platform ?? detectPlatform();
40242
- const binDir = import_node_path23.default.join(opts.dataDir, "bin");
40171
+ const binDir = import_node_path22.default.join(opts.dataDir, "bin");
40243
40172
  import_node_fs22.default.mkdirSync(binDir, { recursive: true });
40244
40173
  cleanupStaleArtifacts(binDir);
40245
- const stableBin = import_node_path23.default.join(binDir, "frpc");
40174
+ const stableBin = import_node_path22.default.join(binDir, "frpc");
40246
40175
  if (import_node_fs22.default.existsSync(stableBin)) return stableBin;
40247
40176
  const partialBin = `${stableBin}.partial`;
40248
- const tarballPath = import_node_path23.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
40177
+ const tarballPath = import_node_path22.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
40249
40178
  try {
40250
40179
  const url = frpcDownloadUrl(version2, platform);
40251
40180
  await downloadToFile(url, tarballPath, opts.fetchImpl);
@@ -40271,7 +40200,7 @@ function cleanupStaleArtifacts(binDir) {
40271
40200
  }
40272
40201
  for (const name of entries) {
40273
40202
  if (name.endsWith(".partial") || name.startsWith("extract-")) {
40274
- const full = import_node_path23.default.join(binDir, name);
40203
+ const full = import_node_path22.default.join(binDir, name);
40275
40204
  try {
40276
40205
  import_node_fs22.default.rmSync(full, { recursive: true, force: true });
40277
40206
  } catch {
@@ -40297,7 +40226,7 @@ async function downloadToFile(url, dest, fetchImpl) {
40297
40226
  await (0, import_promises3.pipeline)(nodeStream, out);
40298
40227
  }
40299
40228
  async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
40300
- const work = import_node_path23.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
40229
+ const work = import_node_path22.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
40301
40230
  import_node_fs22.default.mkdirSync(work, { recursive: true });
40302
40231
  try {
40303
40232
  await new Promise((resolve6, reject) => {
@@ -40306,7 +40235,7 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
40306
40235
  proc.on("exit", (code) => code === 0 ? resolve6() : reject(new Error(`tar exited ${code}`)));
40307
40236
  });
40308
40237
  const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
40309
- const src = import_node_path23.default.join(work, dirName, "frpc");
40238
+ const src = import_node_path22.default.join(work, dirName, "frpc");
40310
40239
  if (!import_node_fs22.default.existsSync(src)) {
40311
40240
  throw new Error(`frpc not found inside tarball at ${src}`);
40312
40241
  }
@@ -40318,10 +40247,10 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
40318
40247
 
40319
40248
  // src/tunnel/frpc-process.ts
40320
40249
  var import_node_fs23 = __toESM(require("fs"), 1);
40321
- var import_node_path24 = __toESM(require("path"), 1);
40250
+ var import_node_path23 = __toESM(require("path"), 1);
40322
40251
  var import_node_child_process8 = require("child_process");
40323
40252
  function frpcPidFilePath(dataDir) {
40324
- return import_node_path24.default.join(dataDir, "frpc.pid");
40253
+ return import_node_path23.default.join(dataDir, "frpc.pid");
40325
40254
  }
40326
40255
  function writeFrpcPid(dataDir, pid) {
40327
40256
  try {
@@ -40363,7 +40292,7 @@ function defaultSleep(ms) {
40363
40292
  }
40364
40293
  async function killStaleFrpc(deps) {
40365
40294
  const pidFile = frpcPidFilePath(deps.dataDir);
40366
- const tomlPath = import_node_path24.default.join(deps.dataDir, "frpc.toml");
40295
+ const tomlPath = import_node_path23.default.join(deps.dataDir, "frpc.toml");
40367
40296
  const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
40368
40297
  const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
40369
40298
  const killPid = deps.killPidImpl ?? defaultKillPid;
@@ -40435,7 +40364,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
40435
40364
  var TunnelManager = class {
40436
40365
  constructor(deps) {
40437
40366
  this.deps = deps;
40438
- this.store = deps.store ?? new TunnelStore(import_node_path25.default.join(deps.dataDir, "tunnel.json"));
40367
+ this.store = deps.store ?? new TunnelStore(import_node_path24.default.join(deps.dataDir, "tunnel.json"));
40439
40368
  this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
40440
40369
  this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
40441
40370
  }
@@ -40562,7 +40491,7 @@ var TunnelManager = class {
40562
40491
  dataDir: this.deps.dataDir,
40563
40492
  override: this.deps.frpcBinaryOverride ?? void 0
40564
40493
  });
40565
- const tomlPath = import_node_path25.default.join(this.deps.dataDir, "frpc.toml");
40494
+ const tomlPath = import_node_path24.default.join(this.deps.dataDir, "frpc.toml");
40566
40495
  const proxyName = `clawd-${t.subdomain}-${localPort}-${import_node_crypto7.default.randomBytes(3).toString("hex")}`;
40567
40496
  const toml = buildFrpcToml({
40568
40497
  serverAddr: t.frpsHost,
@@ -40577,7 +40506,7 @@ var TunnelManager = class {
40577
40506
  const proc = (this.deps.spawnImpl ?? import_node_child_process9.spawn)(frpcBin, ["-c", tomlPath], {
40578
40507
  stdio: ["ignore", "pipe", "pipe"]
40579
40508
  });
40580
- const logFilePath = import_node_path25.default.join(this.deps.dataDir, "frpc.log");
40509
+ const logFilePath = import_node_path24.default.join(this.deps.dataDir, "frpc.log");
40581
40510
  const logStream = import_node_fs24.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
40582
40511
  logStream.on("error", () => {
40583
40512
  });
@@ -40660,16 +40589,16 @@ async function waitForFrpcReady(proc, timeoutMs) {
40660
40589
  }
40661
40590
 
40662
40591
  // src/tunnel/device-key.ts
40663
- var import_node_os13 = __toESM(require("os"), 1);
40664
- var import_node_path26 = __toESM(require("path"), 1);
40592
+ var import_node_os12 = __toESM(require("os"), 1);
40593
+ var import_node_path25 = __toESM(require("path"), 1);
40665
40594
  var import_node_crypto8 = __toESM(require("crypto"), 1);
40666
40595
  var DERIVE_SALT = "clawd-tunnel-device-v1";
40667
40596
  function deriveStableDeviceKey(opts = {}) {
40668
- const hostname = opts.hostname ?? import_node_os13.default.hostname();
40669
- const uid = opts.uid ?? (typeof import_node_os13.default.userInfo === "function" ? import_node_os13.default.userInfo().uid : 0);
40670
- const home = opts.home ?? import_node_os13.default.homedir();
40671
- const defaultDataDir = import_node_path26.default.resolve(import_node_path26.default.join(home, ".clawd"));
40672
- const normalizedDataDir = opts.dataDir ? import_node_path26.default.resolve(opts.dataDir) : null;
40597
+ const hostname = opts.hostname ?? import_node_os12.default.hostname();
40598
+ const uid = opts.uid ?? (typeof import_node_os12.default.userInfo === "function" ? import_node_os12.default.userInfo().uid : 0);
40599
+ const home = opts.home ?? import_node_os12.default.homedir();
40600
+ const defaultDataDir = import_node_path25.default.resolve(import_node_path25.default.join(home, ".clawd"));
40601
+ const normalizedDataDir = opts.dataDir ? import_node_path25.default.resolve(opts.dataDir) : null;
40673
40602
  const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
40674
40603
  const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
40675
40604
  return import_node_crypto8.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
@@ -40677,11 +40606,11 @@ function deriveStableDeviceKey(opts = {}) {
40677
40606
 
40678
40607
  // src/auth-store.ts
40679
40608
  var import_node_fs25 = __toESM(require("fs"), 1);
40680
- var import_node_path27 = __toESM(require("path"), 1);
40609
+ var import_node_path26 = __toESM(require("path"), 1);
40681
40610
  var import_node_crypto9 = __toESM(require("crypto"), 1);
40682
40611
  var AUTH_FILE_NAME = "auth.json";
40683
40612
  function authFilePath(dataDir) {
40684
- return import_node_path27.default.join(dataDir, AUTH_FILE_NAME);
40613
+ return import_node_path26.default.join(dataDir, AUTH_FILE_NAME);
40685
40614
  }
40686
40615
  function loadOrCreateAuthFile(opts) {
40687
40616
  const file = authFilePath(opts.dataDir);
@@ -40734,7 +40663,7 @@ function readAuthFile(file) {
40734
40663
  }
40735
40664
  }
40736
40665
  function writeAuthFile(file, content) {
40737
- import_node_fs25.default.mkdirSync(import_node_path27.default.dirname(file), { recursive: true });
40666
+ import_node_fs25.default.mkdirSync(import_node_path26.default.dirname(file), { recursive: true });
40738
40667
  import_node_fs25.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
40739
40668
  try {
40740
40669
  import_node_fs25.default.chmodSync(file, 384);
@@ -40744,12 +40673,12 @@ function writeAuthFile(file, content) {
40744
40673
 
40745
40674
  // src/owner-profile.ts
40746
40675
  var import_node_fs26 = __toESM(require("fs"), 1);
40747
- var import_node_os14 = __toESM(require("os"), 1);
40748
- var import_node_path28 = __toESM(require("path"), 1);
40676
+ var import_node_os13 = __toESM(require("os"), 1);
40677
+ var import_node_path27 = __toESM(require("path"), 1);
40749
40678
  var PROFILE_FILENAME = "profile.json";
40750
40679
  function loadOwnerDisplayName(dataDir) {
40751
- const fallback = import_node_os14.default.userInfo().username;
40752
- const profilePath = import_node_path28.default.join(dataDir, PROFILE_FILENAME);
40680
+ const fallback = import_node_os13.default.userInfo().username;
40681
+ const profilePath = import_node_path27.default.join(dataDir, PROFILE_FILENAME);
40753
40682
  let raw;
40754
40683
  try {
40755
40684
  raw = import_node_fs26.default.readFileSync(profilePath, "utf8");
@@ -40776,12 +40705,12 @@ function loadOwnerDisplayName(dataDir) {
40776
40705
 
40777
40706
  // src/feishu-auth/owner-identity-store.ts
40778
40707
  var import_node_fs27 = __toESM(require("fs"), 1);
40779
- var import_node_path29 = __toESM(require("path"), 1);
40708
+ var import_node_path28 = __toESM(require("path"), 1);
40780
40709
  var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
40781
40710
  var OwnerIdentityStore = class {
40782
40711
  file;
40783
40712
  constructor(dataDir) {
40784
- this.file = import_node_path29.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
40713
+ this.file = import_node_path28.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
40785
40714
  }
40786
40715
  read() {
40787
40716
  let raw;
@@ -40813,7 +40742,7 @@ var OwnerIdentityStore = class {
40813
40742
  };
40814
40743
  }
40815
40744
  write(record) {
40816
- import_node_fs27.default.mkdirSync(import_node_path29.default.dirname(this.file), { recursive: true });
40745
+ import_node_fs27.default.mkdirSync(import_node_path28.default.dirname(this.file), { recursive: true });
40817
40746
  import_node_fs27.default.writeFileSync(this.file, JSON.stringify(record, null, 2), { mode: 384 });
40818
40747
  try {
40819
40748
  import_node_fs27.default.chmodSync(this.file, 384);
@@ -40941,9 +40870,9 @@ var CentralClientError = class extends Error {
40941
40870
  code;
40942
40871
  cause;
40943
40872
  };
40944
- async function centralRequest(opts, path59, init) {
40873
+ async function centralRequest(opts, path58, init) {
40945
40874
  const f = opts.fetchImpl ?? globalThis.fetch;
40946
- const url = `${opts.api.replace(/\/+$/, "")}${path59}`;
40875
+ const url = `${opts.api.replace(/\/+$/, "")}${path58}`;
40947
40876
  const ctrl = new AbortController();
40948
40877
  const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
40949
40878
  let res;
@@ -41086,7 +41015,7 @@ function verifyConnectToken(args) {
41086
41015
 
41087
41016
  // src/feishu-auth/server-key.ts
41088
41017
  var fs36 = __toESM(require("fs"), 1);
41089
- var path38 = __toESM(require("path"), 1);
41018
+ var path37 = __toESM(require("path"), 1);
41090
41019
  var FILE_NAME2 = "server-signing-key.json";
41091
41020
  var ServerKeyStore = class {
41092
41021
  constructor(dataDir) {
@@ -41094,7 +41023,7 @@ var ServerKeyStore = class {
41094
41023
  }
41095
41024
  dataDir;
41096
41025
  filePath() {
41097
- return path38.join(this.dataDir, FILE_NAME2);
41026
+ return path37.join(this.dataDir, FILE_NAME2);
41098
41027
  }
41099
41028
  /** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
41100
41029
  read() {
@@ -41133,8 +41062,8 @@ init_protocol();
41133
41062
 
41134
41063
  // src/session/fork.ts
41135
41064
  var import_node_fs28 = __toESM(require("fs"), 1);
41136
- var import_node_os15 = __toESM(require("os"), 1);
41137
- var import_node_path30 = __toESM(require("path"), 1);
41065
+ var import_node_os14 = __toESM(require("os"), 1);
41066
+ var import_node_path29 = __toESM(require("path"), 1);
41138
41067
  init_claude_history();
41139
41068
  function readJsonlEntries(file) {
41140
41069
  const raw = import_node_fs28.default.readFileSync(file, "utf8");
@@ -41150,9 +41079,9 @@ function readJsonlEntries(file) {
41150
41079
  return out;
41151
41080
  }
41152
41081
  function forkSession(input) {
41153
- const baseDir = input.baseDir ?? import_node_path30.default.join(import_node_os15.default.homedir(), ".claude");
41154
- const projectDir = import_node_path30.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
41155
- const sourceFile = import_node_path30.default.join(projectDir, `${input.toolSessionId}.jsonl`);
41082
+ const baseDir = input.baseDir ?? import_node_path29.default.join(import_node_os14.default.homedir(), ".claude");
41083
+ const projectDir = import_node_path29.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
41084
+ const sourceFile = import_node_path29.default.join(projectDir, `${input.toolSessionId}.jsonl`);
41156
41085
  if (!import_node_fs28.default.existsSync(sourceFile)) {
41157
41086
  throw new Error(`fork: source transcript not found: ${sourceFile}`);
41158
41087
  }
@@ -41183,7 +41112,7 @@ function forkSession(input) {
41183
41112
  }
41184
41113
  forkedLines.push(JSON.stringify(forked));
41185
41114
  }
41186
- const forkedFilePath = import_node_path30.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
41115
+ const forkedFilePath = import_node_path29.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
41187
41116
  import_node_fs28.default.mkdirSync(projectDir, { recursive: true });
41188
41117
  import_node_fs28.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
41189
41118
  return { forkedToolSessionId, forkedFilePath };
@@ -41561,7 +41490,7 @@ function buildPermissionHandlers(deps) {
41561
41490
  }
41562
41491
 
41563
41492
  // src/handlers/history.ts
41564
- var path41 = __toESM(require("path"), 1);
41493
+ var path40 = __toESM(require("path"), 1);
41565
41494
  init_protocol();
41566
41495
 
41567
41496
  // src/session/recent-dirs.ts
@@ -41579,7 +41508,7 @@ function listRecentDirs(store, limit = 50) {
41579
41508
  }
41580
41509
 
41581
41510
  // src/permission/persona-paths.ts
41582
- var path40 = __toESM(require("path"), 1);
41511
+ var path39 = __toESM(require("path"), 1);
41583
41512
  function getAllowedPersonaIds(grants, action) {
41584
41513
  const ids = /* @__PURE__ */ new Set();
41585
41514
  for (const g2 of grants) {
@@ -41592,31 +41521,31 @@ function getAllowedPersonaIds(grants, action) {
41592
41521
  return ids;
41593
41522
  }
41594
41523
  function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
41595
- const target = path40.resolve(absPath);
41524
+ const target = path39.resolve(absPath);
41596
41525
  if (userWorkDir) {
41597
- const u = path40.resolve(userWorkDir);
41598
- const usep = u.endsWith(path40.sep) ? "" : path40.sep;
41526
+ const u = path39.resolve(userWorkDir);
41527
+ const usep = u.endsWith(path39.sep) ? "" : path39.sep;
41599
41528
  if (target === u || target.startsWith(u + usep)) return true;
41600
41529
  }
41601
- const root = path40.resolve(personaRoot);
41602
- const sep2 = root.endsWith(path40.sep) ? "" : path40.sep;
41530
+ const root = path39.resolve(personaRoot);
41531
+ const sep2 = root.endsWith(path39.sep) ? "" : path39.sep;
41603
41532
  if (!target.startsWith(root + sep2)) return false;
41604
- const rel = path40.relative(root, target);
41533
+ const rel = path39.relative(root, target);
41605
41534
  if (!rel || rel.startsWith("..")) return false;
41606
- const personaId = rel.split(path40.sep)[0];
41535
+ const personaId = rel.split(path39.sep)[0];
41607
41536
  if (!personaId) return false;
41608
41537
  const allowed = getAllowedPersonaIds(grants, action);
41609
41538
  if (allowed === "*") return true;
41610
41539
  return allowed.has(personaId);
41611
41540
  }
41612
41541
  function personaIdFromPath(absPath, personaRoot) {
41613
- const root = path40.resolve(personaRoot);
41614
- const target = path40.resolve(absPath);
41615
- const sep2 = root.endsWith(path40.sep) ? "" : path40.sep;
41542
+ const root = path39.resolve(personaRoot);
41543
+ const target = path39.resolve(absPath);
41544
+ const sep2 = root.endsWith(path39.sep) ? "" : path39.sep;
41616
41545
  if (!target.startsWith(root + sep2)) return null;
41617
- const rel = path40.relative(root, target);
41546
+ const rel = path39.relative(root, target);
41618
41547
  if (!rel || rel.startsWith("..")) return null;
41619
- const id = rel.split(path40.sep)[0];
41548
+ const id = rel.split(path39.sep)[0];
41620
41549
  return id || null;
41621
41550
  }
41622
41551
 
@@ -41643,7 +41572,7 @@ function buildHistoryHandlers(deps) {
41643
41572
  if (!pid) return false;
41644
41573
  return isGuestPathAllowed(
41645
41574
  ctx.grants,
41646
- path41.join(personaRoot, pid),
41575
+ path40.join(personaRoot, pid),
41647
41576
  personaRoot,
41648
41577
  "read",
41649
41578
  userWorkDir
@@ -41655,7 +41584,7 @@ function buildHistoryHandlers(deps) {
41655
41584
  };
41656
41585
  const list = async (frame, _client, ctx) => {
41657
41586
  const args = HistoryListArgs.parse(frame);
41658
- assertGuestPath(ctx, path41.resolve(args.projectPath), personaRoot, "history:list");
41587
+ assertGuestPath(ctx, path40.resolve(args.projectPath), personaRoot, "history:list");
41659
41588
  const sessions = await history.listSessions(args);
41660
41589
  return { response: { type: "history:list", sessions } };
41661
41590
  };
@@ -41687,13 +41616,13 @@ function buildHistoryHandlers(deps) {
41687
41616
  };
41688
41617
  const subagents = async (frame, _client, ctx) => {
41689
41618
  const args = HistorySubagentsArgs.parse(frame);
41690
- assertGuestPath(ctx, path41.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
41619
+ assertGuestPath(ctx, path40.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
41691
41620
  const subs = await history.listSubagents(args);
41692
41621
  return { response: { type: "history:subagents", subagents: subs } };
41693
41622
  };
41694
41623
  const subagentRead = async (frame, _client, ctx) => {
41695
41624
  const args = HistorySubagentReadArgs.parse(frame);
41696
- assertGuestPath(ctx, path41.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
41625
+ assertGuestPath(ctx, path40.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
41697
41626
  const res = await history.readSubagent(args);
41698
41627
  return { response: { type: "history:subagent-read", ...res } };
41699
41628
  };
@@ -41702,7 +41631,7 @@ function buildHistoryHandlers(deps) {
41702
41631
  if (ctx?.principal.kind === "guest" && personaRoot) {
41703
41632
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
41704
41633
  const filtered = dirs.filter(
41705
- (d) => isGuestPathAllowed(ctx.grants, path41.resolve(d.cwd), personaRoot, "read", userWorkDir)
41634
+ (d) => isGuestPathAllowed(ctx.grants, path40.resolve(d.cwd), personaRoot, "read", userWorkDir)
41706
41635
  );
41707
41636
  return { response: { type: "history:recentDirs", dirs: filtered } };
41708
41637
  }
@@ -41719,8 +41648,8 @@ function buildHistoryHandlers(deps) {
41719
41648
  }
41720
41649
 
41721
41650
  // src/handlers/workspace.ts
41722
- var path42 = __toESM(require("path"), 1);
41723
- var os16 = __toESM(require("os"), 1);
41651
+ var path41 = __toESM(require("path"), 1);
41652
+ var os15 = __toESM(require("os"), 1);
41724
41653
  init_protocol();
41725
41654
  init_protocol();
41726
41655
  function buildEnabledPluginNames(personaManager, personaId) {
@@ -41760,23 +41689,23 @@ function buildWorkspaceHandlers(deps) {
41760
41689
  const list = async (frame, _client, ctx) => {
41761
41690
  const args = WorkspaceListArgs.parse(frame);
41762
41691
  const isGuest = ctx?.principal.kind === "guest";
41763
- const fallbackCwd = isGuest && personaRoot ? personaRoot : os16.homedir();
41764
- const resolvedCwd = path42.resolve(args.cwd ?? fallbackCwd);
41765
- const target = args.path ? path42.resolve(resolvedCwd, args.path) : resolvedCwd;
41692
+ const fallbackCwd = isGuest && personaRoot ? personaRoot : os15.homedir();
41693
+ const resolvedCwd = path41.resolve(args.cwd ?? fallbackCwd);
41694
+ const target = args.path ? path41.resolve(resolvedCwd, args.path) : resolvedCwd;
41766
41695
  assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
41767
41696
  const res = workspace.list({ ...args, cwd: resolvedCwd });
41768
41697
  return { response: { type: "workspace:list", ...res } };
41769
41698
  };
41770
41699
  const read = async (frame, _client, ctx) => {
41771
41700
  const args = WorkspaceReadArgs.parse(frame);
41772
- const target = path42.isAbsolute(args.path) ? path42.resolve(args.path) : path42.resolve(args.cwd, args.path);
41701
+ const target = path41.isAbsolute(args.path) ? path41.resolve(args.path) : path41.resolve(args.cwd, args.path);
41773
41702
  assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
41774
41703
  const res = workspace.read(args);
41775
41704
  return { response: { type: "workspace:read", ...res } };
41776
41705
  };
41777
41706
  const skillsList = async (frame, _client, ctx) => {
41778
41707
  const args = SkillsListArgs.parse(frame);
41779
- const cwdAbs = path42.resolve(args.cwd);
41708
+ const cwdAbs = path41.resolve(args.cwd);
41780
41709
  assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
41781
41710
  const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
41782
41711
  if (ctx?.principal.kind === "guest" && personaRoot) {
@@ -41788,7 +41717,7 @@ function buildWorkspaceHandlers(deps) {
41788
41717
  };
41789
41718
  const agentsList = async (frame, _client, ctx) => {
41790
41719
  const args = AgentsListArgs.parse(frame);
41791
- const cwdAbs = path42.resolve(args.cwd);
41720
+ const cwdAbs = path41.resolve(args.cwd);
41792
41721
  assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
41793
41722
  if (args.tool === "codex") {
41794
41723
  return { response: { type: "agents:list", agents: [] } };
@@ -41810,18 +41739,18 @@ function buildWorkspaceHandlers(deps) {
41810
41739
  }
41811
41740
 
41812
41741
  // src/handlers/git.ts
41813
- var path44 = __toESM(require("path"), 1);
41742
+ var path43 = __toESM(require("path"), 1);
41814
41743
  init_protocol();
41815
41744
  init_protocol();
41816
41745
 
41817
41746
  // src/workspace/git.ts
41818
41747
  var import_node_child_process10 = require("child_process");
41819
41748
  var import_node_fs29 = __toESM(require("fs"), 1);
41820
- var import_node_path31 = __toESM(require("path"), 1);
41749
+ var import_node_path30 = __toESM(require("path"), 1);
41821
41750
  var import_node_util = require("util");
41822
41751
  var pexec = (0, import_node_util.promisify)(import_node_child_process10.execFile);
41823
41752
  function normalizePath(p2) {
41824
- const resolved = import_node_path31.default.resolve(p2);
41753
+ const resolved = import_node_path30.default.resolve(p2);
41825
41754
  try {
41826
41755
  return import_node_fs29.default.realpathSync(resolved);
41827
41756
  } catch {
@@ -41897,7 +41826,7 @@ async function listGitBranches(cwd) {
41897
41826
  function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
41898
41827
  if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
41899
41828
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
41900
- if (!isGuestPathAllowed(ctx.grants, path44.resolve(cwd), personaRoot, "read", userWorkDir)) {
41829
+ if (!isGuestPathAllowed(ctx.grants, path43.resolve(cwd), personaRoot, "read", userWorkDir)) {
41901
41830
  throw new ClawdError(
41902
41831
  ERROR_CODES.UNAUTHORIZED,
41903
41832
  `guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
@@ -42285,7 +42214,7 @@ function buildDeviceHandlers(deps) {
42285
42214
  }
42286
42215
 
42287
42216
  // src/handlers/meta.ts
42288
- var import_node_os16 = __toESM(require("os"), 1);
42217
+ var import_node_os15 = __toESM(require("os"), 1);
42289
42218
  init_protocol();
42290
42219
 
42291
42220
  // src/version.ts
@@ -42316,7 +42245,7 @@ function buildReadyFrame(deps, client) {
42316
42245
  return {
42317
42246
  version,
42318
42247
  protocolVersion: PROTOCOL_VERSION,
42319
- hostname: import_node_os16.default.hostname(),
42248
+ hostname: import_node_os15.default.hostname(),
42320
42249
  os: process.platform,
42321
42250
  tools,
42322
42251
  runningSessions: info.runningSessions,
@@ -42411,7 +42340,7 @@ function buildPersonaHandlers(deps) {
42411
42340
  }
42412
42341
 
42413
42342
  // src/handlers/attachment.ts
42414
- var import_node_path32 = __toESM(require("path"), 1);
42343
+ var import_node_path31 = __toESM(require("path"), 1);
42415
42344
  init_protocol();
42416
42345
  init_protocol();
42417
42346
  var DEFAULT_TTL_SECONDS = 24 * 3600;
@@ -42466,12 +42395,12 @@ function buildAttachmentHandlers(deps) {
42466
42395
  `session ${args.sessionId} scope unresolved`
42467
42396
  );
42468
42397
  }
42469
- const cwdAbs = import_node_path32.default.resolve(sessionFile.cwd);
42470
- const candidateAbs = import_node_path32.default.isAbsolute(args.relPath) ? import_node_path32.default.resolve(args.relPath) : import_node_path32.default.resolve(cwdAbs, args.relPath);
42398
+ const cwdAbs = import_node_path31.default.resolve(sessionFile.cwd);
42399
+ const candidateAbs = import_node_path31.default.isAbsolute(args.relPath) ? import_node_path31.default.resolve(args.relPath) : import_node_path31.default.resolve(cwdAbs, args.relPath);
42471
42400
  assertGuestAttachmentPath(ctx, candidateAbs, deps.personaRoot, "attachment.signUrl", deps.usersRoot);
42472
42401
  const entries = deps.groupFileStore.list(scope, args.sessionId);
42473
42402
  const entry = entries.find((e) => {
42474
- const storedAbs = import_node_path32.default.isAbsolute(e.relPath) ? import_node_path32.default.resolve(e.relPath) : import_node_path32.default.resolve(cwdAbs, e.relPath);
42403
+ const storedAbs = import_node_path31.default.isAbsolute(e.relPath) ? import_node_path31.default.resolve(e.relPath) : import_node_path31.default.resolve(cwdAbs, e.relPath);
42475
42404
  return storedAbs === candidateAbs && !e.stale;
42476
42405
  });
42477
42406
  if (!entry) {
@@ -42495,7 +42424,7 @@ function buildAttachmentHandlers(deps) {
42495
42424
  if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
42496
42425
  const f = deps.sessionStore.read(sessionId);
42497
42426
  if (!f) return;
42498
- assertGuestAttachmentPath(ctx, import_node_path32.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
42427
+ assertGuestAttachmentPath(ctx, import_node_path31.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
42499
42428
  }
42500
42429
  const groupAdd = async (frame, _client, ctx) => {
42501
42430
  if (!deps.groupFileStore || !deps.getSessionScope) {
@@ -42567,19 +42496,19 @@ function buildAttachmentHandlers(deps) {
42567
42496
 
42568
42497
  // src/handlers/extension.ts
42569
42498
  var import_promises7 = __toESM(require("fs/promises"), 1);
42570
- var import_node_path37 = __toESM(require("path"), 1);
42499
+ var import_node_path36 = __toESM(require("path"), 1);
42571
42500
  init_protocol();
42572
42501
 
42573
42502
  // src/extension/bundle-zip.ts
42574
42503
  var import_promises4 = __toESM(require("fs/promises"), 1);
42575
- var import_node_path33 = __toESM(require("path"), 1);
42504
+ var import_node_path32 = __toESM(require("path"), 1);
42576
42505
  var import_node_crypto11 = __toESM(require("crypto"), 1);
42577
42506
  var import_jszip2 = __toESM(require_lib3(), 1);
42578
42507
  async function bundleExtensionDir(dir) {
42579
42508
  const entries = await listFilesSorted(dir);
42580
42509
  const zip = new import_jszip2.default();
42581
42510
  for (const rel of entries) {
42582
- const abs = import_node_path33.default.join(dir, rel);
42511
+ const abs = import_node_path32.default.join(dir, rel);
42583
42512
  const content = await import_promises4.default.readFile(abs);
42584
42513
  zip.file(rel, content, { date: FIXED_DATE });
42585
42514
  }
@@ -42600,7 +42529,7 @@ async function listFilesSorted(rootDir) {
42600
42529
  return out;
42601
42530
  }
42602
42531
  async function walk(absRoot, relPrefix, out) {
42603
- const dirAbs = import_node_path33.default.join(absRoot, relPrefix);
42532
+ const dirAbs = import_node_path32.default.join(absRoot, relPrefix);
42604
42533
  const entries = await import_promises4.default.readdir(dirAbs, { withFileTypes: true });
42605
42534
  for (const e of entries) {
42606
42535
  if (IGNORE_BASENAMES.has(e.name)) continue;
@@ -42654,25 +42583,25 @@ function computePublishCheck(args) {
42654
42583
 
42655
42584
  // src/extension/install-flow.ts
42656
42585
  var import_promises5 = __toESM(require("fs/promises"), 1);
42657
- var import_node_path35 = __toESM(require("path"), 1);
42658
- var import_node_os18 = __toESM(require("os"), 1);
42586
+ var import_node_path34 = __toESM(require("path"), 1);
42587
+ var import_node_os17 = __toESM(require("os"), 1);
42659
42588
  var import_node_crypto12 = __toESM(require("crypto"), 1);
42660
42589
  var import_jszip3 = __toESM(require_lib3(), 1);
42661
42590
 
42662
42591
  // src/extension/paths.ts
42663
- var import_node_os17 = __toESM(require("os"), 1);
42664
- var import_node_path34 = __toESM(require("path"), 1);
42592
+ var import_node_os16 = __toESM(require("os"), 1);
42593
+ var import_node_path33 = __toESM(require("path"), 1);
42665
42594
  function clawdHomeRoot(override) {
42666
- return override ?? process.env.CLAWD_HOME ?? import_node_path34.default.join(import_node_os17.default.homedir(), ".clawd");
42595
+ return override ?? process.env.CLAWD_HOME ?? import_node_path33.default.join(import_node_os16.default.homedir(), ".clawd");
42667
42596
  }
42668
42597
  function extensionsRoot(override) {
42669
- return import_node_path34.default.join(clawdHomeRoot(override), "extensions");
42598
+ return import_node_path33.default.join(clawdHomeRoot(override), "extensions");
42670
42599
  }
42671
42600
  function publishedChannelsFile(override) {
42672
- return import_node_path34.default.join(clawdHomeRoot(override), "extensions-published.json");
42601
+ return import_node_path33.default.join(clawdHomeRoot(override), "extensions-published.json");
42673
42602
  }
42674
42603
  function bundleCacheRoot(override) {
42675
- return import_node_path34.default.join(clawdHomeRoot(override), "extension-bundles");
42604
+ return import_node_path33.default.join(clawdHomeRoot(override), "extension-bundles");
42676
42605
  }
42677
42606
 
42678
42607
  // src/extension/install-flow.ts
@@ -42699,7 +42628,7 @@ async function installFromChannel(args, deps) {
42699
42628
  throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
42700
42629
  }
42701
42630
  for (const name of Object.keys(zip.files)) {
42702
- if (name.includes("..") || name.startsWith("/") || import_node_path35.default.isAbsolute(name)) {
42631
+ if (name.includes("..") || name.startsWith("/") || import_node_path34.default.isAbsolute(name)) {
42703
42632
  throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
42704
42633
  }
42705
42634
  }
@@ -42731,7 +42660,7 @@ async function installFromChannel(args, deps) {
42731
42660
  );
42732
42661
  }
42733
42662
  const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
42734
- const destDir = import_node_path35.default.join(deps.extensionsRoot, localExtId);
42663
+ const destDir = import_node_path34.default.join(deps.extensionsRoot, localExtId);
42735
42664
  let destExists = false;
42736
42665
  try {
42737
42666
  await import_promises5.default.access(destDir);
@@ -42745,16 +42674,16 @@ async function installFromChannel(args, deps) {
42745
42674
  );
42746
42675
  }
42747
42676
  const stage = await import_promises5.default.mkdtemp(
42748
- import_node_path35.default.join(import_node_os18.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
42677
+ import_node_path34.default.join(import_node_os17.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
42749
42678
  );
42750
42679
  try {
42751
42680
  for (const [name, entry] of Object.entries(zip.files)) {
42752
- const dest = import_node_path35.default.join(stage, name);
42681
+ const dest = import_node_path34.default.join(stage, name);
42753
42682
  if (entry.dir) {
42754
42683
  await import_promises5.default.mkdir(dest, { recursive: true });
42755
42684
  continue;
42756
42685
  }
42757
- await import_promises5.default.mkdir(import_node_path35.default.dirname(dest), { recursive: true });
42686
+ await import_promises5.default.mkdir(import_node_path34.default.dirname(dest), { recursive: true });
42758
42687
  if (name === "manifest.json") {
42759
42688
  const rewritten = { ...parsed.data, id: localExtId };
42760
42689
  await import_promises5.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -42775,8 +42704,8 @@ async function installFromChannel(args, deps) {
42775
42704
 
42776
42705
  // src/extension/update-flow.ts
42777
42706
  var import_promises6 = __toESM(require("fs/promises"), 1);
42778
- var import_node_path36 = __toESM(require("path"), 1);
42779
- var import_node_os19 = __toESM(require("os"), 1);
42707
+ var import_node_path35 = __toESM(require("path"), 1);
42708
+ var import_node_os18 = __toESM(require("os"), 1);
42780
42709
  var import_node_crypto13 = __toESM(require("crypto"), 1);
42781
42710
  var import_jszip4 = __toESM(require_lib3(), 1);
42782
42711
  var UpdateError = class extends Error {
@@ -42792,11 +42721,11 @@ async function updateFromChannel(args, deps) {
42792
42721
  channelRef.extId,
42793
42722
  channelRef.ownerPrincipalId
42794
42723
  );
42795
- const liveDir = import_node_path36.default.join(deps.extensionsRoot, localExtId);
42724
+ const liveDir = import_node_path35.default.join(deps.extensionsRoot, localExtId);
42796
42725
  const prevDir = `${liveDir}.prev`;
42797
42726
  let existingVersion;
42798
42727
  try {
42799
- const raw = await import_promises6.default.readFile(import_node_path36.default.join(liveDir, "manifest.json"), "utf8");
42728
+ const raw = await import_promises6.default.readFile(import_node_path35.default.join(liveDir, "manifest.json"), "utf8");
42800
42729
  const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
42801
42730
  if (!parsed2.success) {
42802
42731
  throw new UpdateError(
@@ -42829,7 +42758,7 @@ async function updateFromChannel(args, deps) {
42829
42758
  throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
42830
42759
  }
42831
42760
  for (const name of Object.keys(zip.files)) {
42832
- if (name.includes("..") || name.startsWith("/") || import_node_path36.default.isAbsolute(name)) {
42761
+ if (name.includes("..") || name.startsWith("/") || import_node_path35.default.isAbsolute(name)) {
42833
42762
  throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
42834
42763
  }
42835
42764
  }
@@ -42864,16 +42793,16 @@ async function updateFromChannel(args, deps) {
42864
42793
  await import_promises6.default.rm(prevDir, { recursive: true, force: true });
42865
42794
  await import_promises6.default.rename(liveDir, prevDir);
42866
42795
  const stage = await import_promises6.default.mkdtemp(
42867
- import_node_path36.default.join(import_node_os19.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
42796
+ import_node_path35.default.join(import_node_os18.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
42868
42797
  );
42869
42798
  try {
42870
42799
  for (const [name, entry] of Object.entries(zip.files)) {
42871
- const dest = import_node_path36.default.join(stage, name);
42800
+ const dest = import_node_path35.default.join(stage, name);
42872
42801
  if (entry.dir) {
42873
42802
  await import_promises6.default.mkdir(dest, { recursive: true });
42874
42803
  continue;
42875
42804
  }
42876
- await import_promises6.default.mkdir(import_node_path36.default.dirname(dest), { recursive: true });
42805
+ await import_promises6.default.mkdir(import_node_path35.default.dirname(dest), { recursive: true });
42877
42806
  if (name === "manifest.json") {
42878
42807
  const rewritten = { ...parsed.data, id: localExtId };
42879
42808
  await import_promises6.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -42966,7 +42895,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
42966
42895
  );
42967
42896
  }
42968
42897
  }
42969
- const manifestPath = import_node_path37.default.join(root, extId, "manifest.json");
42898
+ const manifestPath = import_node_path36.default.join(root, extId, "manifest.json");
42970
42899
  const manifest = await readManifest(root, extId);
42971
42900
  const next = { ...manifest, version: newVersion };
42972
42901
  const tmp = `${manifestPath}.tmp`;
@@ -42974,7 +42903,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
42974
42903
  await import_promises7.default.rename(tmp, manifestPath);
42975
42904
  }
42976
42905
  async function readManifest(root, extId) {
42977
- const file = import_node_path37.default.join(root, extId, "manifest.json");
42906
+ const file = import_node_path36.default.join(root, extId, "manifest.json");
42978
42907
  let raw;
42979
42908
  try {
42980
42909
  raw = await import_promises7.default.readFile(file, "utf8");
@@ -43065,7 +42994,7 @@ function buildExtensionHandlers(deps) {
43065
42994
  };
43066
42995
  async function buildSnapshotMeta(extId) {
43067
42996
  const manifest = await readManifest(deps.root, extId);
43068
- const { sha256, buffer } = await bundleExtensionDir(import_node_path37.default.join(deps.root, extId));
42997
+ const { sha256, buffer } = await bundleExtensionDir(import_node_path36.default.join(deps.root, extId));
43069
42998
  return { manifest, contentHash: sha256, buffer };
43070
42999
  }
43071
43000
  const publish = async (frame, _client, ctx) => {
@@ -43362,7 +43291,7 @@ var PublishJobRegistry = class {
43362
43291
  // src/app-builder/publish-job-runner.ts
43363
43292
  var import_node_child_process12 = require("child_process");
43364
43293
  var import_node_fs30 = require("fs");
43365
- var import_node_path38 = require("path");
43294
+ var import_node_path37 = require("path");
43366
43295
 
43367
43296
  // src/app-builder/publish-stage-parser.ts
43368
43297
  var STAGE_RE = /^\s*::stage::(build|deploy|verify)\s*$/;
@@ -43394,7 +43323,7 @@ async function startPublishJob(deps, args) {
43394
43323
  return { jobId: registry2.get(args.name).jobId, status: "already-publishing" };
43395
43324
  }
43396
43325
  const projDir = projectDir(args.name);
43397
- const logPath = (0, import_node_path38.join)(projDir, ".publish.log");
43326
+ const logPath = (0, import_node_path37.join)(projDir, ".publish.log");
43398
43327
  let logStream = null;
43399
43328
  try {
43400
43329
  logStream = (0, import_node_fs30.createWriteStream)(logPath, { flags: "w" });
@@ -43654,7 +43583,7 @@ async function recoverInterruptedJobs(deps) {
43654
43583
 
43655
43584
  // src/handlers/app-builder.ts
43656
43585
  init_protocol();
43657
- var import_node_path39 = require("path");
43586
+ var import_node_path38 = require("path");
43658
43587
  var import_node_fs31 = require("fs");
43659
43588
  var APP_BUILDER_PERSONAS = ["persona-app-builder"];
43660
43589
  var PUBLISH_SCRIPT_REL = "extension-kit/scripts/publish.sh";
@@ -44031,7 +43960,7 @@ function buildAppBuilderHandlers(deps) {
44031
43960
  });
44032
43961
  await userStore.clearPublishJob(args.name);
44033
43962
  }
44034
- const scriptPath = (0, import_node_path39.join)(deps.personaRoot, PUBLISH_SCRIPT_REL);
43963
+ const scriptPath = (0, import_node_path38.join)(deps.personaRoot, PUBLISH_SCRIPT_REL);
44035
43964
  deps.logger?.info("app-builder.publish.start", {
44036
43965
  name: args.name,
44037
43966
  sessionId: boundSession.sessionId,
@@ -44125,7 +44054,7 @@ function buildAppBuilderHandlers(deps) {
44125
44054
 
44126
44055
  // src/extension/registry.ts
44127
44056
  var import_promises8 = __toESM(require("fs/promises"), 1);
44128
- var import_node_path40 = __toESM(require("path"), 1);
44057
+ var import_node_path39 = __toESM(require("path"), 1);
44129
44058
  async function loadAll(root) {
44130
44059
  let entries;
44131
44060
  try {
@@ -44138,13 +44067,13 @@ async function loadAll(root) {
44138
44067
  for (const ent of entries) {
44139
44068
  if (!ent.isDirectory()) continue;
44140
44069
  if (ent.name.startsWith(".")) continue;
44141
- records.push(await loadOne(import_node_path40.default.join(root, ent.name), ent.name));
44070
+ records.push(await loadOne(import_node_path39.default.join(root, ent.name), ent.name));
44142
44071
  }
44143
44072
  records.sort((a, b2) => a.extId < b2.extId ? -1 : a.extId > b2.extId ? 1 : 0);
44144
44073
  return records;
44145
44074
  }
44146
44075
  async function loadOne(dir, dirName) {
44147
- const manifestPath = import_node_path40.default.join(dir, "manifest.json");
44076
+ const manifestPath = import_node_path39.default.join(dir, "manifest.json");
44148
44077
  let raw;
44149
44078
  try {
44150
44079
  raw = await import_promises8.default.readFile(manifestPath, "utf8");
@@ -44189,7 +44118,7 @@ async function loadOne(dir, dirName) {
44189
44118
 
44190
44119
  // src/extension/uninstall.ts
44191
44120
  var import_promises9 = __toESM(require("fs/promises"), 1);
44192
- var import_node_path41 = __toESM(require("path"), 1);
44121
+ var import_node_path40 = __toESM(require("path"), 1);
44193
44122
  var UninstallError = class extends Error {
44194
44123
  constructor(code, message) {
44195
44124
  super(message);
@@ -44198,7 +44127,7 @@ var UninstallError = class extends Error {
44198
44127
  code;
44199
44128
  };
44200
44129
  async function uninstall(deps) {
44201
- const dir = import_node_path41.default.join(deps.root, deps.extId);
44130
+ const dir = import_node_path40.default.join(deps.root, deps.extId);
44202
44131
  try {
44203
44132
  await import_promises9.default.access(dir);
44204
44133
  } catch {
@@ -44279,7 +44208,7 @@ function buildMethodHandlers(deps) {
44279
44208
  // src/app-builder/project-store.ts
44280
44209
  var import_node_fs32 = require("fs");
44281
44210
  var import_node_child_process13 = require("child_process");
44282
- var import_node_path42 = require("path");
44211
+ var import_node_path41 = require("path");
44283
44212
  init_protocol();
44284
44213
  var PROJECTS_DIR = "projects";
44285
44214
  var META_FILE = ".clawd-project.json";
@@ -44294,14 +44223,14 @@ var ProjectStore = class {
44294
44223
  root;
44295
44224
  /** projects/<name>/.clawd-project.json 路径 */
44296
44225
  metaPath(name) {
44297
- return (0, import_node_path42.join)(this.projectsRoot(), name, META_FILE);
44226
+ return (0, import_node_path41.join)(this.projectsRoot(), name, META_FILE);
44298
44227
  }
44299
44228
  /** projects/<name>/ 目录路径(cwd 用) */
44300
44229
  projectDir(name) {
44301
- return (0, import_node_path42.join)(this.projectsRoot(), name);
44230
+ return (0, import_node_path41.join)(this.projectsRoot(), name);
44302
44231
  }
44303
44232
  projectsRoot() {
44304
- return (0, import_node_path42.join)(this.root, PROJECTS_DIR);
44233
+ return (0, import_node_path41.join)(this.root, PROJECTS_DIR);
44305
44234
  }
44306
44235
  async list() {
44307
44236
  let entries;
@@ -44382,7 +44311,7 @@ var ProjectStore = class {
44382
44311
  * 代码再参考"。assistant 进 project 时目录已是完整模板,直接 pnpm install 即可。
44383
44312
  */
44384
44313
  async scaffold(name, template = DEFAULT_TEMPLATE, personaRoot = this.root) {
44385
- const scriptPath = (0, import_node_path42.join)(personaRoot, SCAFFOLD_SCRIPT_REL);
44314
+ const scriptPath = (0, import_node_path41.join)(personaRoot, SCAFFOLD_SCRIPT_REL);
44386
44315
  const destDir = this.projectDir(name);
44387
44316
  return await new Promise((resolve6, reject) => {
44388
44317
  const child = (0, import_node_child_process13.spawn)("bash", [scriptPath, name, template, destDir], {
@@ -44920,7 +44849,7 @@ function computeGrantForFrame(method, frame) {
44920
44849
 
44921
44850
  // src/extension/runtime.ts
44922
44851
  var import_node_child_process15 = require("child_process");
44923
- var import_node_path43 = __toESM(require("path"), 1);
44852
+ var import_node_path42 = __toESM(require("path"), 1);
44924
44853
  var import_promises10 = require("timers/promises");
44925
44854
 
44926
44855
  // src/extension/port-allocator.ts
@@ -45021,7 +44950,7 @@ var Runtime = class {
45021
44950
  /\$CLAWOS_EXT_PORT/g,
45022
44951
  String(port)
45023
44952
  );
45024
- const dir = import_node_path43.default.join(this.root, extId);
44953
+ const dir = import_node_path42.default.join(this.root, extId);
45025
44954
  const env = {
45026
44955
  ...process.env,
45027
44956
  CLAWOS_EXT_PORT: String(port),
@@ -45133,7 +45062,7 @@ ${handle.stderrTail}`
45133
45062
 
45134
45063
  // src/extension/published-channels.ts
45135
45064
  var import_promises11 = __toESM(require("fs/promises"), 1);
45136
- var import_node_path44 = __toESM(require("path"), 1);
45065
+ var import_node_path43 = __toESM(require("path"), 1);
45137
45066
  init_zod();
45138
45067
  var PublishedChannelsError = class extends Error {
45139
45068
  constructor(code, message) {
@@ -45232,7 +45161,7 @@ var PublishedChannelStore = class {
45232
45161
  )
45233
45162
  };
45234
45163
  const tmp = `${this.filePath}.tmp`;
45235
- await import_promises11.default.mkdir(import_node_path44.default.dirname(this.filePath), { recursive: true });
45164
+ await import_promises11.default.mkdir(import_node_path43.default.dirname(this.filePath), { recursive: true });
45236
45165
  await import_promises11.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
45237
45166
  await import_promises11.default.rename(tmp, this.filePath);
45238
45167
  }
@@ -45240,7 +45169,7 @@ var PublishedChannelStore = class {
45240
45169
 
45241
45170
  // src/extension/bundle-cache.ts
45242
45171
  var import_promises12 = __toESM(require("fs/promises"), 1);
45243
- var import_node_path45 = __toESM(require("path"), 1);
45172
+ var import_node_path44 = __toESM(require("path"), 1);
45244
45173
  var BundleCache = class {
45245
45174
  constructor(rootDir) {
45246
45175
  this.rootDir = rootDir;
@@ -45249,14 +45178,14 @@ var BundleCache = class {
45249
45178
  /** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
45250
45179
  async write(snapshotHash, buffer) {
45251
45180
  await import_promises12.default.mkdir(this.rootDir, { recursive: true });
45252
- const file = import_node_path45.default.join(this.rootDir, `${snapshotHash}.zip`);
45181
+ const file = import_node_path44.default.join(this.rootDir, `${snapshotHash}.zip`);
45253
45182
  const tmp = `${file}.tmp`;
45254
45183
  await import_promises12.default.writeFile(tmp, buffer, { mode: 384 });
45255
45184
  await import_promises12.default.rename(tmp, file);
45256
45185
  }
45257
45186
  /** Returns the bundle bytes, or null when the file doesn't exist. */
45258
45187
  async read(snapshotHash) {
45259
- const file = import_node_path45.default.join(this.rootDir, `${snapshotHash}.zip`);
45188
+ const file = import_node_path44.default.join(this.rootDir, `${snapshotHash}.zip`);
45260
45189
  try {
45261
45190
  return await import_promises12.default.readFile(file);
45262
45191
  } catch (e) {
@@ -45266,7 +45195,7 @@ var BundleCache = class {
45266
45195
  }
45267
45196
  /** Idempotent — missing file is not an error. */
45268
45197
  async delete(snapshotHash) {
45269
- const file = import_node_path45.default.join(this.rootDir, `${snapshotHash}.zip`);
45198
+ const file = import_node_path44.default.join(this.rootDir, `${snapshotHash}.zip`);
45270
45199
  await import_promises12.default.rm(file, { force: true });
45271
45200
  }
45272
45201
  };
@@ -45275,7 +45204,7 @@ var BundleCache = class {
45275
45204
  async function startDaemon(config) {
45276
45205
  const logger = createLogger({
45277
45206
  level: config.logLevel,
45278
- file: import_node_path46.default.join(config.dataDir, "clawd.log")
45207
+ file: import_node_path45.default.join(config.dataDir, "clawd.log")
45279
45208
  });
45280
45209
  logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
45281
45210
  const stateMgr = new StateFileManager({ dataDir: config.dataDir });
@@ -45411,8 +45340,8 @@ async function startDaemon(config) {
45411
45340
  const agents = new AgentsScanner();
45412
45341
  const history = new ClaudeHistoryReader();
45413
45342
  let transport = null;
45414
- const personaStore = new PersonaStore(import_node_path46.default.join(config.dataDir, "personas"));
45415
- const usersRoot = import_node_path46.default.join(config.dataDir, "users");
45343
+ const personaStore = new PersonaStore(import_node_path45.default.join(config.dataDir, "personas"));
45344
+ const usersRoot = import_node_path45.default.join(config.dataDir, "users");
45416
45345
  const defaultsRoot = findDefaultsRoot();
45417
45346
  if (defaultsRoot) {
45418
45347
  seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
@@ -45432,7 +45361,7 @@ async function startDaemon(config) {
45432
45361
  getAdapter,
45433
45362
  historyReader: history,
45434
45363
  dataDir: config.dataDir,
45435
- personaRoot: import_node_path46.default.join(config.dataDir, "personas"),
45364
+ personaRoot: import_node_path45.default.join(config.dataDir, "personas"),
45436
45365
  usersRoot,
45437
45366
  personaStore,
45438
45367
  ownerDisplayName,
@@ -45462,7 +45391,7 @@ async function startDaemon(config) {
45462
45391
  // 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
45463
45392
  attachmentGroup: {
45464
45393
  onFileEdit: (input) => {
45465
- const absPath = import_node_path46.default.isAbsolute(input.relPath) ? input.relPath : import_node_path46.default.join(input.cwd, input.relPath);
45394
+ const absPath = import_node_path45.default.isAbsolute(input.relPath) ? input.relPath : import_node_path45.default.join(input.cwd, input.relPath);
45466
45395
  let size = 0;
45467
45396
  try {
45468
45397
  size = import_node_fs33.default.statSync(absPath).size;
@@ -45651,11 +45580,11 @@ async function startDaemon(config) {
45651
45580
  // 'persona/<pid>/owner',default 走 'default'。
45652
45581
  getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
45653
45582
  // guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
45654
- personaRoot: import_node_path46.default.join(config.dataDir, "personas"),
45583
+ personaRoot: import_node_path45.default.join(config.dataDir, "personas"),
45655
45584
  usersRoot
45656
45585
  },
45657
45586
  // workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
45658
- personaRoot: import_node_path46.default.join(config.dataDir, "personas"),
45587
+ personaRoot: import_node_path45.default.join(config.dataDir, "personas"),
45659
45588
  // v2 多人 persona 隔离:handler 派生 guest user-dir 放行
45660
45589
  usersRoot,
45661
45590
  // capability:list / delete handler 依赖
@@ -45744,7 +45673,7 @@ async function startDaemon(config) {
45744
45673
  // 发布上线脚手架化 (spec 2026-06-03 §5.2):
45745
45674
  // appBuilderPersonaRoot 用于拼 publish.sh 绝对路径(persona-app-builder 安装在
45746
45675
  // dataDir/personas/persona-app-builder 之下,extension-kit/scripts/publish.sh 是相对路径)。
45747
- appBuilderPersonaRoot: import_node_path46.default.join(config.dataDir, "personas", "persona-app-builder"),
45676
+ appBuilderPersonaRoot: import_node_path45.default.join(config.dataDir, "personas", "persona-app-builder"),
45748
45677
  // 发布上线脚手架化 (spec 2026-06-03 §5.2.2):
45749
45678
  // 复用 SessionManagerDeps.broadcastFrame 同款 dispatch 逻辑 —— runner 调 manager.send
45750
45679
  // 取回 broadcast 帧后逐帧 push 到 transport,跟 manager 自身的 deps 一致。
@@ -45993,8 +45922,8 @@ async function startDaemon(config) {
45993
45922
  const lines = [
45994
45923
  `Tunnel: ${r.url}`,
45995
45924
  ...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
45996
- `Frpc config: ${import_node_path46.default.join(config.dataDir, "frpc.toml")}`,
45997
- `Frpc log: ${import_node_path46.default.join(config.dataDir, "frpc.log")}`
45925
+ `Frpc config: ${import_node_path45.default.join(config.dataDir, "frpc.toml")}`,
45926
+ `Frpc log: ${import_node_path45.default.join(config.dataDir, "frpc.log")}`
45998
45927
  ];
45999
45928
  const width = Math.max(...lines.map((l) => l.length));
46000
45929
  const bar = "\u2550".repeat(width + 4);
@@ -46007,7 +45936,7 @@ ${bar}
46007
45936
 
46008
45937
  `);
46009
45938
  try {
46010
- const connectPath = import_node_path46.default.join(config.dataDir, "connect.txt");
45939
+ const connectPath = import_node_path45.default.join(config.dataDir, "connect.txt");
46011
45940
  import_node_fs33.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
46012
45941
  } catch {
46013
45942
  }
@@ -46079,7 +46008,7 @@ ${bar}
46079
46008
  };
46080
46009
  }
46081
46010
  function migrateDropPersonsDir(dataDir) {
46082
- const dir = import_node_path46.default.join(dataDir, "persons");
46011
+ const dir = import_node_path45.default.join(dataDir, "persons");
46083
46012
  try {
46084
46013
  import_node_fs33.default.rmSync(dir, { recursive: true, force: true });
46085
46014
  } catch {