@clawos-dev/clawd 0.2.603 → 0.2.604

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 +485 -483
  2. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -62563,6 +62563,81 @@ var SubscriptionChannelStore = class {
62563
62563
  }
62564
62564
  };
62565
62565
 
62566
+ // src/tools/subscription-channels-apply.ts
62567
+ var import_node_fs36 = __toESM(require("fs"), 1);
62568
+ var import_node_os13 = __toESM(require("os"), 1);
62569
+ var import_node_path41 = __toESM(require("path"), 1);
62570
+ var TABLE_HEADER = /^\s*\[\[?\s*([A-Za-z0-9_.-]+)\s*\]\]?\s*(?:#.*)?$/;
62571
+ var KEY_LINE = /^\s*([A-Za-z0-9_.-]+)\s*=/;
62572
+ function stripCodexProvider(text) {
62573
+ const out = [];
62574
+ let inProviderSection = false;
62575
+ for (const line of text.split("\n")) {
62576
+ const headerMatch = TABLE_HEADER.exec(line);
62577
+ if (headerMatch) {
62578
+ const section = headerMatch[1].trim();
62579
+ inProviderSection = section === "model_providers" || section.startsWith("model_providers.");
62580
+ if (inProviderSection) continue;
62581
+ out.push(line);
62582
+ continue;
62583
+ }
62584
+ if (inProviderSection) continue;
62585
+ const keyMatch = KEY_LINE.exec(line);
62586
+ if (keyMatch) {
62587
+ const key = keyMatch[1].trim();
62588
+ if (key === "model_provider" || key.startsWith("model_providers.")) {
62589
+ continue;
62590
+ }
62591
+ }
62592
+ out.push(line);
62593
+ }
62594
+ return out.join("\n").trim();
62595
+ }
62596
+ function applyCodexSubscriptionChannel(opts) {
62597
+ const codexHome = opts.codexHome || process.env.CODEX_HOME || import_node_path41.default.join(import_node_os13.default.homedir(), ".codex");
62598
+ import_node_fs36.default.mkdirSync(codexHome, { recursive: true });
62599
+ const configFile = import_node_path41.default.join(codexHome, "config.toml");
62600
+ const original = import_node_fs36.default.existsSync(configFile) ? import_node_fs36.default.readFileSync(configFile, "utf8") : "";
62601
+ const rest = stripCodexProvider(original);
62602
+ let content;
62603
+ if (opts.channel) {
62604
+ const ch = opts.channel;
62605
+ content = [
62606
+ 'model_provider = "cliproxyapi"',
62607
+ ...rest ? ["", rest] : [],
62608
+ "",
62609
+ "[model_providers.cliproxyapi]",
62610
+ 'name = "cliproxyapi"',
62611
+ `base_url = ${JSON.stringify(ch.baseUrl)}`,
62612
+ 'wire_api = "responses"',
62613
+ `auth = { command = "echo", args = [${JSON.stringify(ch.apiKey)}] }`,
62614
+ ""
62615
+ ].join("\n");
62616
+ } else {
62617
+ content = [
62618
+ 'model_provider = "openai"',
62619
+ ...rest ? ["", rest] : [],
62620
+ ""
62621
+ ].join("\n");
62622
+ }
62623
+ const tmpFile = `${configFile}.tmp.${Date.now()}`;
62624
+ import_node_fs36.default.writeFileSync(tmpFile, content, { mode: 384 });
62625
+ import_node_fs36.default.renameSync(tmpFile, configFile);
62626
+ }
62627
+ function applyPiSubscriptionChannel(opts) {
62628
+ const agentDir = opts.agentDir || process.env.PI_CODING_AGENT_DIR || import_node_path41.default.join(import_node_os13.default.homedir(), ".pi", "agent");
62629
+ if (!import_node_fs36.default.existsSync(agentDir)) return false;
62630
+ const configFile = import_node_path41.default.join(agentDir, "cliproxyapi.json");
62631
+ if (opts.channel) {
62632
+ const data = { baseUrl: opts.channel.baseUrl, apiKey: opts.channel.apiKey };
62633
+ const tmp = `${configFile}.tmp.${Date.now()}`;
62634
+ import_node_fs36.default.writeFileSync(tmp, JSON.stringify(data, null, 2) + "\n", { mode: 384 });
62635
+ import_node_fs36.default.renameSync(tmp, configFile);
62636
+ return true;
62637
+ }
62638
+ return false;
62639
+ }
62640
+
62566
62641
  // src/deploy/local-probe.ts
62567
62642
  function pickVersion(s2) {
62568
62643
  return /(\d+)\.(\d+)(?:\.(\d+))?/.exec(s2)?.[0];
@@ -62611,10 +62686,10 @@ async function probeLocalVersion(exec, pkg) {
62611
62686
 
62612
62687
  // src/tools/shell-path.ts
62613
62688
  var import_node_child_process10 = require("child_process");
62614
- var import_node_os13 = __toESM(require("os"), 1);
62689
+ var import_node_os14 = __toESM(require("os"), 1);
62615
62690
  function refreshPathFromLoginShell() {
62616
62691
  if (process.platform === "win32") return;
62617
- const shell = process.env.SHELL ?? import_node_os13.default.userInfo().shell ?? "/bin/zsh";
62692
+ const shell = process.env.SHELL ?? import_node_os14.default.userInfo().shell ?? "/bin/zsh";
62618
62693
  try {
62619
62694
  const out = (0, import_node_child_process10.execFileSync)(shell, ["-ilc", 'command echo -n "$PATH"'], {
62620
62695
  encoding: "utf8",
@@ -63160,15 +63235,15 @@ async function refreshTunnelUrlOnStartup(deps) {
63160
63235
  }
63161
63236
 
63162
63237
  // src/lark-bot-connector/binding-store.ts
63163
- var import_node_fs36 = __toESM(require("fs"), 1);
63164
- var import_node_path41 = __toESM(require("path"), 1);
63238
+ var import_node_fs37 = __toESM(require("fs"), 1);
63239
+ var import_node_path42 = __toESM(require("path"), 1);
63165
63240
  function createLarkBotBindingStore(personaRoot) {
63166
- const filePath = (personaId2) => import_node_path41.default.join(personaRoot, safeFileName(personaId2), ".clawd", "lark-bot.json");
63241
+ const filePath = (personaId2) => import_node_path42.default.join(personaRoot, safeFileName(personaId2), ".clawd", "lark-bot.json");
63167
63242
  const read = (personaId2) => {
63168
63243
  const file = filePath(personaId2);
63169
- if (!import_node_fs36.default.existsSync(file)) return null;
63244
+ if (!import_node_fs37.default.existsSync(file)) return null;
63170
63245
  try {
63171
- const raw = JSON.parse(import_node_fs36.default.readFileSync(file, "utf8"));
63246
+ const raw = JSON.parse(import_node_fs37.default.readFileSync(file, "utf8"));
63172
63247
  if (typeof raw?.appId !== "string" || raw.appId.length === 0) return null;
63173
63248
  return raw;
63174
63249
  } catch {
@@ -63177,16 +63252,16 @@ function createLarkBotBindingStore(personaRoot) {
63177
63252
  };
63178
63253
  const write = (personaId2, meta) => {
63179
63254
  const file = filePath(personaId2);
63180
- import_node_fs36.default.mkdirSync(import_node_path41.default.dirname(file), { recursive: true });
63255
+ import_node_fs37.default.mkdirSync(import_node_path42.default.dirname(file), { recursive: true });
63181
63256
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
63182
- import_node_fs36.default.writeFileSync(tmp, JSON.stringify(meta, null, 2), { mode: 384 });
63183
- import_node_fs36.default.renameSync(tmp, file);
63257
+ import_node_fs37.default.writeFileSync(tmp, JSON.stringify(meta, null, 2), { mode: 384 });
63258
+ import_node_fs37.default.renameSync(tmp, file);
63184
63259
  };
63185
63260
  return {
63186
63261
  read,
63187
63262
  write,
63188
63263
  remove(personaId2) {
63189
- import_node_fs36.default.rmSync(filePath(personaId2), { force: true });
63264
+ import_node_fs37.default.rmSync(filePath(personaId2), { force: true });
63190
63265
  },
63191
63266
  addRemovedChat(personaId2, chatId) {
63192
63267
  const meta = read(personaId2);
@@ -63338,8 +63413,8 @@ function createLarkBotCloudClient(opts) {
63338
63413
  }
63339
63414
 
63340
63415
  // src/lark-bot-connector/chat-router.ts
63341
- var import_node_fs37 = __toESM(require("fs"), 1);
63342
- var import_node_path42 = __toESM(require("path"), 1);
63416
+ var import_node_fs38 = __toESM(require("fs"), 1);
63417
+ var import_node_path43 = __toESM(require("path"), 1);
63343
63418
  init_protocol();
63344
63419
  var ERROR_REPLY_TEXT = "\u5904\u7406\u51FA\u9519\u4E86\uFF0C\u8BF7\u91CD\u8BD5";
63345
63420
  var LOCAL_TURN_RETRIES = 2;
@@ -63417,9 +63492,9 @@ function createLarkChatRouter(deps) {
63417
63492
  continue;
63418
63493
  }
63419
63494
  const dir = deps.mediaRootFor(env.chatId);
63420
- import_node_fs37.default.mkdirSync(dir, { recursive: true });
63421
- const p3 = import_node_path42.default.join(dir, `${safeMediaName(ownerMessageId)}-${i2}.${ext}`);
63422
- import_node_fs37.default.writeFileSync(p3, r2.data);
63495
+ import_node_fs38.default.mkdirSync(dir, { recursive: true });
63496
+ const p3 = import_node_path43.default.join(dir, `${safeMediaName(ownerMessageId)}-${i2}.${ext}`);
63497
+ import_node_fs38.default.writeFileSync(p3, r2.data);
63423
63498
  lines.push(`[\u56FE\u7247: ${p3}]\uFF08\u7528 Read \u5DE5\u5177\u67E5\u770B\uFF09`);
63424
63499
  } catch (err) {
63425
63500
  deps.logger?.warn(`larkBot image fetch failed ${key}: ${err.message}`);
@@ -63440,9 +63515,9 @@ function createLarkChatRouter(deps) {
63440
63515
  continue;
63441
63516
  }
63442
63517
  const dir = deps.mediaRootFor(env.chatId);
63443
- import_node_fs37.default.mkdirSync(dir, { recursive: true });
63444
- const p3 = import_node_path42.default.join(dir, `${safeMediaName(ownerMessageId)}-${i2}-${safeAttachmentName(f2.name)}`);
63445
- import_node_fs37.default.writeFileSync(p3, r2.data);
63518
+ import_node_fs38.default.mkdirSync(dir, { recursive: true });
63519
+ const p3 = import_node_path43.default.join(dir, `${safeMediaName(ownerMessageId)}-${i2}-${safeAttachmentName(f2.name)}`);
63520
+ import_node_fs38.default.writeFileSync(p3, r2.data);
63446
63521
  lines.push(`[\u6587\u4EF6: ${p3}]\uFF08\u7528 Read \u5DE5\u5177\u67E5\u770B\uFF09`);
63447
63522
  } catch (err) {
63448
63523
  deps.logger?.warn(`larkBot file fetch failed ${f2.key}: ${err.message}`);
@@ -64813,7 +64888,7 @@ function openHttpLineStream(opts) {
64813
64888
  init_protocol();
64814
64889
 
64815
64890
  // src/tools/codex-cloud-session.ts
64816
- var import_node_fs38 = __toESM(require("fs"), 1);
64891
+ var import_node_fs39 = __toESM(require("fs"), 1);
64817
64892
 
64818
64893
  // src/tools/cloud-portable-input.ts
64819
64894
  async function portableCloudInput(text, resolvers) {
@@ -64842,7 +64917,7 @@ function cloudImageInput(deps) {
64842
64917
  const mime = lookupMime(p3);
64843
64918
  if (!mime.startsWith("image/")) return null;
64844
64919
  try {
64845
- const bytes = (deps.readFile ?? import_node_fs38.default.readFileSync)(p3);
64920
+ const bytes = (deps.readFile ?? import_node_fs39.default.readFileSync)(p3);
64846
64921
  return { type: "image", url: `data:${mime};base64,${bytes.toString("base64")}` };
64847
64922
  } catch (e) {
64848
64923
  deps.logger?.warn("cloud image attachment unreadable", { path: p3, message: e.message });
@@ -65000,7 +65075,7 @@ init_protocol();
65000
65075
 
65001
65076
  // src/tools/pi.ts
65002
65077
  var import_node_child_process12 = require("child_process");
65003
- var import_node_fs40 = __toESM(require("fs"), 1);
65078
+ var import_node_fs41 = __toESM(require("fs"), 1);
65004
65079
  init_protocol();
65005
65080
 
65006
65081
  // src/tools/pi-rpc-client.ts
@@ -65101,8 +65176,8 @@ var PiRpcClient = class {
65101
65176
  // src/tools/pi-session.ts
65102
65177
  var import_node_child_process11 = require("child_process");
65103
65178
  var import_node_crypto12 = require("crypto");
65104
- var import_node_fs39 = __toESM(require("fs"), 1);
65105
- var import_node_path43 = __toESM(require("path"), 1);
65179
+ var import_node_fs40 = __toESM(require("fs"), 1);
65180
+ var import_node_path44 = __toESM(require("path"), 1);
65106
65181
 
65107
65182
  // src/tools/pi-events.ts
65108
65183
  init_protocol();
@@ -65374,8 +65449,8 @@ ${dirs.map((d2) => `- ${d2}`).join("\n")}`;
65374
65449
  function createPiSession(ctx, sink, deps = {}) {
65375
65450
  const cmd = process.env.PI_BIN ?? "pi";
65376
65451
  const sessionId = ctx.toolSessionId ?? (0, import_node_crypto12.randomUUID)();
65377
- const skillsDir = import_node_path43.default.join(ctx.cwd, ".claude", "skills");
65378
- const exists = deps.skillsDirExists ?? ((d2) => import_node_fs39.default.existsSync(d2));
65452
+ const skillsDir = import_node_path44.default.join(ctx.cwd, ".claude", "skills");
65453
+ const exists = deps.skillsDirExists ?? ((d2) => import_node_fs40.default.existsSync(d2));
65379
65454
  const args = buildPiArgs(ctx, {
65380
65455
  sessionId,
65381
65456
  skillsDir: exists(skillsDir) ? skillsDir : void 0,
@@ -65437,10 +65512,10 @@ var PI_DEFAULT_MODEL_ENTRY = {
65437
65512
  };
65438
65513
  var PI_FULL_ACCESS = { id: "never", label: "Full Access", description: "pi \u65E0\u5BA1\u6279\uFF1A\u4ECE\u4E0D\u8BE2\u95EE\uFF0C\u81EA\u4E3B\u6267\u884C" };
65439
65514
  async function probePi(env = process.env) {
65440
- if (env.PI_BIN && import_node_fs40.default.existsSync(env.PI_BIN)) return { available: true, path: env.PI_BIN };
65515
+ if (env.PI_BIN && import_node_fs41.default.existsSync(env.PI_BIN)) return { available: true, path: env.PI_BIN };
65441
65516
  try {
65442
65517
  const out = (0, import_node_child_process12.execFileSync)("which", ["pi"], { encoding: "utf8" }).trim();
65443
- if (out && import_node_fs40.default.existsSync(out)) return { available: true, path: out };
65518
+ if (out && import_node_fs41.default.existsSync(out)) return { available: true, path: out };
65444
65519
  } catch {
65445
65520
  }
65446
65521
  return { available: false };
@@ -65757,7 +65832,7 @@ var CloudPiAdapter = class {
65757
65832
  init_protocol();
65758
65833
 
65759
65834
  // src/tools/codex-skills.ts
65760
- var import_node_path44 = __toESM(require("path"), 1);
65835
+ var import_node_path45 = __toESM(require("path"), 1);
65761
65836
  function str4(v3) {
65762
65837
  return typeof v3 === "string" ? v3 : void 0;
65763
65838
  }
@@ -65794,7 +65869,7 @@ async function listCodexSkills(cwd, deps = {}) {
65794
65869
  // 先写 extraRoots 再写 list(stdio 按写入顺序处理,fire-and-forget 不 await 回包;
65795
65870
  // codex-session.ts ready 序列同款,两处保持一致)。失败不阻塞 list。
65796
65871
  beforeRequest: (client) => {
65797
- void client.request("skills/extraRoots/set", { extraRoots: [import_node_path44.default.join(cwd, ".claude", "skills")] }).catch(() => void 0);
65872
+ void client.request("skills/extraRoots/set", { extraRoots: [import_node_path45.default.join(cwd, ".claude", "skills")] }).catch(() => void 0);
65798
65873
  }
65799
65874
  });
65800
65875
  return mapSkillsListResponse(res);
@@ -65868,23 +65943,23 @@ function rec4(v3) {
65868
65943
  }
65869
65944
 
65870
65945
  // src/workspace/browser.ts
65871
- var import_node_fs41 = __toESM(require("fs"), 1);
65872
- var import_node_os14 = __toESM(require("os"), 1);
65873
- var import_node_path45 = __toESM(require("path"), 1);
65946
+ var import_node_fs42 = __toESM(require("fs"), 1);
65947
+ var import_node_os15 = __toESM(require("os"), 1);
65948
+ var import_node_path46 = __toESM(require("path"), 1);
65874
65949
  init_protocol();
65875
65950
  var MAX_FILE_BYTES2 = 2 * 1024 * 1024;
65876
65951
  function resolveInsideCwd(cwd, subpath) {
65877
- const absCwd = import_node_path45.default.resolve(cwd);
65878
- const joined = import_node_path45.default.resolve(absCwd, subpath ?? ".");
65879
- const rel = import_node_path45.default.relative(absCwd, joined);
65880
- if (rel.startsWith("..") || import_node_path45.default.isAbsolute(rel)) {
65952
+ const absCwd = import_node_path46.default.resolve(cwd);
65953
+ const joined = import_node_path46.default.resolve(absCwd, subpath ?? ".");
65954
+ const rel = import_node_path46.default.relative(absCwd, joined);
65955
+ if (rel.startsWith("..") || import_node_path46.default.isAbsolute(rel)) {
65881
65956
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
65882
65957
  }
65883
65958
  return joined;
65884
65959
  }
65885
65960
  function ensureCwd(cwd) {
65886
65961
  try {
65887
- const stat = import_node_fs41.default.statSync(cwd);
65962
+ const stat = import_node_fs42.default.statSync(cwd);
65888
65963
  if (!stat.isDirectory()) {
65889
65964
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${cwd}`);
65890
65965
  }
@@ -65895,10 +65970,10 @@ function ensureCwd(cwd) {
65895
65970
  }
65896
65971
  var WorkspaceBrowser = class {
65897
65972
  list(args) {
65898
- const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os14.default.homedir();
65973
+ const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os15.default.homedir();
65899
65974
  ensureCwd(cwd);
65900
65975
  const full = resolveInsideCwd(cwd, args.path);
65901
- const dirents = import_node_fs41.default.readdirSync(full, { withFileTypes: true });
65976
+ const dirents = import_node_fs42.default.readdirSync(full, { withFileTypes: true });
65902
65977
  const entries = [];
65903
65978
  for (const d2 of dirents) {
65904
65979
  if (!args.showHidden && d2.name.startsWith(".")) continue;
@@ -65908,7 +65983,7 @@ var WorkspaceBrowser = class {
65908
65983
  mtime: ""
65909
65984
  };
65910
65985
  try {
65911
- const st2 = import_node_fs41.default.statSync(import_node_path45.default.join(full, d2.name));
65986
+ const st2 = import_node_fs42.default.statSync(import_node_path46.default.join(full, d2.name));
65912
65987
  entry.mtime = new Date(st2.mtimeMs).toISOString();
65913
65988
  if (d2.isFile()) entry.size = st2.size;
65914
65989
  } catch {
@@ -65924,14 +65999,14 @@ var WorkspaceBrowser = class {
65924
65999
  read(args) {
65925
66000
  ensureCwd(args.cwd);
65926
66001
  const full = resolveInsideCwd(args.cwd, args.path);
65927
- const st2 = import_node_fs41.default.statSync(full);
66002
+ const st2 = import_node_fs42.default.statSync(full);
65928
66003
  if (!st2.isFile()) {
65929
66004
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `not a file: ${args.path}`);
65930
66005
  }
65931
66006
  if (st2.size > MAX_FILE_BYTES2) {
65932
66007
  throw new ClawdError(ERROR_CODES.FILE_TOO_LARGE, `file > ${MAX_FILE_BYTES2} bytes`);
65933
66008
  }
65934
- const buf = import_node_fs41.default.readFileSync(full);
66009
+ const buf = import_node_fs42.default.readFileSync(full);
65935
66010
  const isBinary = buf.includes(0);
65936
66011
  if (isBinary) {
65937
66012
  return {
@@ -65953,20 +66028,20 @@ var WorkspaceBrowser = class {
65953
66028
  };
65954
66029
 
65955
66030
  // src/skills/agents-scanner.ts
65956
- var import_node_fs42 = __toESM(require("fs"), 1);
65957
- var import_node_os15 = __toESM(require("os"), 1);
65958
- var import_node_path46 = __toESM(require("path"), 1);
66031
+ var import_node_fs43 = __toESM(require("fs"), 1);
66032
+ var import_node_os16 = __toESM(require("os"), 1);
66033
+ var import_node_path47 = __toESM(require("path"), 1);
65959
66034
  var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
65960
66035
  function isDirLikeSync2(p3) {
65961
66036
  try {
65962
- return import_node_fs42.default.statSync(p3).isDirectory();
66037
+ return import_node_fs43.default.statSync(p3).isDirectory();
65963
66038
  } catch {
65964
66039
  return false;
65965
66040
  }
65966
66041
  }
65967
66042
  function fileExistsSync(p3) {
65968
66043
  try {
65969
- return import_node_fs42.default.statSync(p3).isFile();
66044
+ return import_node_fs43.default.statSync(p3).isFile();
65970
66045
  } catch {
65971
66046
  return false;
65972
66047
  }
@@ -65974,7 +66049,7 @@ function fileExistsSync(p3) {
65974
66049
  function parseAgentFile(filePath) {
65975
66050
  let content;
65976
66051
  try {
65977
- content = import_node_fs42.default.readFileSync(filePath, "utf8");
66052
+ content = import_node_fs43.default.readFileSync(filePath, "utf8");
65978
66053
  } catch {
65979
66054
  return {};
65980
66055
  }
@@ -65987,16 +66062,16 @@ function parseAgentFile(filePath) {
65987
66062
  function scanAgentsDir(dir, source, seen, out) {
65988
66063
  let entries;
65989
66064
  try {
65990
- entries = import_node_fs42.default.readdirSync(dir, { withFileTypes: true });
66065
+ entries = import_node_fs43.default.readdirSync(dir, { withFileTypes: true });
65991
66066
  } catch {
65992
66067
  return;
65993
66068
  }
65994
66069
  for (const ent of entries) {
65995
66070
  if (!ent.name.endsWith(".md")) continue;
65996
- if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path46.default.join(dir, ent.name)))) {
66071
+ if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path47.default.join(dir, ent.name)))) {
65997
66072
  continue;
65998
66073
  }
65999
- const filePath = import_node_path46.default.join(dir, ent.name);
66074
+ const filePath = import_node_path47.default.join(dir, ent.name);
66000
66075
  const baseName = ent.name.replace(/\.md$/, "");
66001
66076
  if (seen.has(baseName)) continue;
66002
66077
  seen.add(baseName);
@@ -66014,12 +66089,12 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
66014
66089
  function walk2(dir, namespaces) {
66015
66090
  let entries;
66016
66091
  try {
66017
- entries = import_node_fs42.default.readdirSync(dir, { withFileTypes: true });
66092
+ entries = import_node_fs43.default.readdirSync(dir, { withFileTypes: true });
66018
66093
  } catch {
66019
66094
  return;
66020
66095
  }
66021
66096
  for (const ent of entries) {
66022
- const childPath = import_node_path46.default.join(dir, ent.name);
66097
+ const childPath = import_node_path47.default.join(dir, ent.name);
66023
66098
  if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
66024
66099
  walk2(childPath, [...namespaces, ent.name]);
66025
66100
  continue;
@@ -66044,13 +66119,13 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
66044
66119
  walk2(root, []);
66045
66120
  }
66046
66121
  function readInstalledPlugins2(home) {
66047
- const pluginsDir = import_node_path46.default.join(home, ".claude", "plugins");
66048
- const v22 = import_node_path46.default.join(pluginsDir, "installed_plugins_v2.json");
66049
- const v1 = import_node_path46.default.join(pluginsDir, "installed_plugins.json");
66122
+ const pluginsDir = import_node_path47.default.join(home, ".claude", "plugins");
66123
+ const v22 = import_node_path47.default.join(pluginsDir, "installed_plugins_v2.json");
66124
+ const v1 = import_node_path47.default.join(pluginsDir, "installed_plugins.json");
66050
66125
  let raw = null;
66051
66126
  for (const candidate of [v22, v1]) {
66052
66127
  try {
66053
- raw = import_node_fs42.default.readFileSync(candidate, "utf8");
66128
+ raw = import_node_fs43.default.readFileSync(candidate, "utf8");
66054
66129
  break;
66055
66130
  } catch {
66056
66131
  }
@@ -66075,19 +66150,19 @@ function readInstalledPlugins2(home) {
66075
66150
  return out;
66076
66151
  }
66077
66152
  function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
66078
- let cur = import_node_path46.default.resolve(startCwd);
66079
- const fsRoot = import_node_path46.default.parse(cur).root;
66153
+ let cur = import_node_path47.default.resolve(startCwd);
66154
+ const fsRoot = import_node_path47.default.parse(cur).root;
66080
66155
  while (true) {
66081
- scanAgentsDir(import_node_path46.default.join(cur, ".claude", "agents"), "project", seen, out);
66156
+ scanAgentsDir(import_node_path47.default.join(cur, ".claude", "agents"), "project", seen, out);
66082
66157
  let hasGit = false;
66083
66158
  try {
66084
- hasGit = import_node_fs42.default.existsSync(import_node_path46.default.join(cur, ".git"));
66159
+ hasGit = import_node_fs43.default.existsSync(import_node_path47.default.join(cur, ".git"));
66085
66160
  } catch {
66086
66161
  }
66087
66162
  if (hasGit) return;
66088
66163
  if (cur === home) return;
66089
66164
  if (cur === fsRoot) return;
66090
- const parent = import_node_path46.default.dirname(cur);
66165
+ const parent = import_node_path47.default.dirname(cur);
66091
66166
  if (parent === cur) return;
66092
66167
  cur = parent;
66093
66168
  }
@@ -66097,7 +66172,7 @@ var AgentsScanner = class {
66097
66172
  extraPluginRoots;
66098
66173
  policyDir;
66099
66174
  constructor(opts = {}) {
66100
- this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os15.default.homedir();
66175
+ this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os16.default.homedir();
66101
66176
  this.extraPluginRoots = opts.extraPluginRoots ?? [];
66102
66177
  if (opts.policyDir !== void 0) {
66103
66178
  this.policyDir = opts.policyDir;
@@ -66122,7 +66197,7 @@ var AgentsScanner = class {
66122
66197
  }
66123
66198
  const fsBlock = [];
66124
66199
  scanAgentsDir(
66125
- import_node_path46.default.join(this.home, ".claude", "agents"),
66200
+ import_node_path47.default.join(this.home, ".claude", "agents"),
66126
66201
  "global",
66127
66202
  seen,
66128
66203
  fsBlock
@@ -66136,7 +66211,7 @@ var AgentsScanner = class {
66136
66211
  ...this.extraPluginRoots
66137
66212
  ];
66138
66213
  for (const { name, root } of plugins) {
66139
- const agentsRoot = import_node_path46.default.join(root, "agents");
66214
+ const agentsRoot = import_node_path47.default.join(root, "agents");
66140
66215
  scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
66141
66216
  }
66142
66217
  return [...builtinBlock, ...fsBlock];
@@ -66144,28 +66219,28 @@ var AgentsScanner = class {
66144
66219
  };
66145
66220
 
66146
66221
  // src/observer/session-observer.ts
66147
- var import_node_fs44 = __toESM(require("fs"), 1);
66148
- var import_node_os17 = __toESM(require("os"), 1);
66149
- var import_node_path48 = __toESM(require("path"), 1);
66222
+ var import_node_fs45 = __toESM(require("fs"), 1);
66223
+ var import_node_os18 = __toESM(require("os"), 1);
66224
+ var import_node_path49 = __toESM(require("path"), 1);
66150
66225
  init_claude_history();
66151
66226
 
66152
66227
  // src/observer/subagent-meta-observer.ts
66153
- var import_node_fs43 = __toESM(require("fs"), 1);
66154
- var import_node_os16 = __toESM(require("os"), 1);
66155
- var import_node_path47 = __toESM(require("path"), 1);
66228
+ var import_node_fs44 = __toESM(require("fs"), 1);
66229
+ var import_node_os17 = __toESM(require("os"), 1);
66230
+ var import_node_path48 = __toESM(require("path"), 1);
66156
66231
  init_claude_history();
66157
66232
  var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
66158
66233
  var SubagentMetaObserver = class {
66159
66234
  constructor(opts) {
66160
66235
  this.opts = opts;
66161
- this.home = opts.home ?? import_node_os16.default.homedir();
66236
+ this.home = opts.home ?? import_node_os17.default.homedir();
66162
66237
  }
66163
66238
  opts;
66164
66239
  home;
66165
66240
  watches = /* @__PURE__ */ new Map();
66166
66241
  // public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
66167
66242
  resolveSubagentDir(cwd, toolSessionId) {
66168
- return import_node_path47.default.join(
66243
+ return import_node_path48.default.join(
66169
66244
  this.home,
66170
66245
  ".claude",
66171
66246
  "projects",
@@ -66195,7 +66270,7 @@ var SubagentMetaObserver = class {
66195
66270
  attachWatcher(w3) {
66196
66271
  if (w3.watcher) return;
66197
66272
  try {
66198
- w3.watcher = import_node_fs43.default.watch(w3.dirPath, { persistent: false }, (_evt, name) => {
66273
+ w3.watcher = import_node_fs44.default.watch(w3.dirPath, { persistent: false }, (_evt, name) => {
66199
66274
  if (!name) return;
66200
66275
  const m3 = META_RE.exec(String(name));
66201
66276
  if (!m3) return;
@@ -66207,7 +66282,7 @@ var SubagentMetaObserver = class {
66207
66282
  scan(w3) {
66208
66283
  let entries;
66209
66284
  try {
66210
- entries = import_node_fs43.default.readdirSync(w3.dirPath);
66285
+ entries = import_node_fs44.default.readdirSync(w3.dirPath);
66211
66286
  } catch {
66212
66287
  return;
66213
66288
  }
@@ -66221,10 +66296,10 @@ var SubagentMetaObserver = class {
66221
66296
  if (!m3) return;
66222
66297
  const agentId = m3[1];
66223
66298
  if (w3.emitted.has(agentId)) return;
66224
- const file = import_node_path47.default.join(w3.dirPath, name);
66299
+ const file = import_node_path48.default.join(w3.dirPath, name);
66225
66300
  let raw;
66226
66301
  try {
66227
- raw = import_node_fs43.default.readFileSync(file, "utf8");
66302
+ raw = import_node_fs44.default.readFileSync(file, "utf8");
66228
66303
  } catch {
66229
66304
  return;
66230
66305
  }
@@ -66269,7 +66344,7 @@ var SubagentMetaObserver = class {
66269
66344
  var SessionObserver = class {
66270
66345
  constructor(opts) {
66271
66346
  this.opts = opts;
66272
- this.home = opts.home ?? import_node_os17.default.homedir();
66347
+ this.home = opts.home ?? import_node_os18.default.homedir();
66273
66348
  this.metaObserver = opts.enableSubagentMetaObserver ? new SubagentMetaObserver({ home: this.home, onEvent: opts.onEvent }) : null;
66274
66349
  }
66275
66350
  opts;
@@ -66281,14 +66356,14 @@ var SessionObserver = class {
66281
66356
  metaObserver;
66282
66357
  resolveJsonlPath(cwd, toolSessionId, override) {
66283
66358
  if (override) return override;
66284
- return import_node_path48.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
66359
+ return import_node_path49.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
66285
66360
  }
66286
66361
  start(args) {
66287
66362
  this.stop(args.sessionId);
66288
66363
  const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
66289
66364
  let size = 0;
66290
66365
  try {
66291
- size = import_node_fs44.default.statSync(filePath).size;
66366
+ size = import_node_fs45.default.statSync(filePath).size;
66292
66367
  } catch {
66293
66368
  }
66294
66369
  const w3 = {
@@ -66301,16 +66376,16 @@ var SessionObserver = class {
66301
66376
  adapter: args.adapter,
66302
66377
  prevIsRejectSentinel: false,
66303
66378
  toolSessionId: args.toolSessionId,
66304
- sawFile: import_node_fs44.default.existsSync(filePath),
66379
+ sawFile: import_node_fs45.default.existsSync(filePath),
66305
66380
  lastRelocateScanMs: 0,
66306
66381
  pendingCwdDerive: false,
66307
66382
  lastDeriveMs: 0
66308
66383
  };
66309
66384
  try {
66310
- import_node_fs44.default.mkdirSync(import_node_path48.default.dirname(filePath), { recursive: true });
66385
+ import_node_fs45.default.mkdirSync(import_node_path49.default.dirname(filePath), { recursive: true });
66311
66386
  } catch {
66312
66387
  }
66313
- w3.watcher = import_node_fs44.default.watch(import_node_path48.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
66388
+ w3.watcher = import_node_fs45.default.watch(import_node_path49.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
66314
66389
  if (!changedName || !w3.filePath.endsWith(changedName)) return;
66315
66390
  this.poll(w3);
66316
66391
  });
@@ -66333,7 +66408,7 @@ var SessionObserver = class {
66333
66408
  // 异常静默吞,不阻塞 watcher 启动
66334
66409
  hydrateMetaTail(w3, maxLines = 200) {
66335
66410
  try {
66336
- const raw = import_node_fs44.default.readFileSync(w3.filePath, "utf8");
66411
+ const raw = import_node_fs45.default.readFileSync(w3.filePath, "utf8");
66337
66412
  if (!raw) return;
66338
66413
  const allLines = raw.split("\n").filter((l2) => l2.trim().length > 0);
66339
66414
  if (allLines.length === 0) return;
@@ -66357,7 +66432,7 @@ var SessionObserver = class {
66357
66432
  poll(w3) {
66358
66433
  let size = 0;
66359
66434
  try {
66360
- size = import_node_fs44.default.statSync(w3.filePath).size;
66435
+ size = import_node_fs45.default.statSync(w3.filePath).size;
66361
66436
  } catch {
66362
66437
  if (w3.sawFile) this.maybeRelocate(w3);
66363
66438
  return;
@@ -66368,11 +66443,11 @@ var SessionObserver = class {
66368
66443
  w3.buf = "";
66369
66444
  }
66370
66445
  if (size === w3.lastSize) return;
66371
- const fd = import_node_fs44.default.openSync(w3.filePath, "r");
66446
+ const fd = import_node_fs45.default.openSync(w3.filePath, "r");
66372
66447
  try {
66373
66448
  const len = size - w3.lastSize;
66374
66449
  const buf = Buffer.alloc(len);
66375
- import_node_fs44.default.readSync(fd, buf, 0, len, w3.lastSize);
66450
+ import_node_fs45.default.readSync(fd, buf, 0, len, w3.lastSize);
66376
66451
  w3.lastSize = size;
66377
66452
  w3.buf += buf.toString("utf8");
66378
66453
  let newlineIndex;
@@ -66395,7 +66470,7 @@ var SessionObserver = class {
66395
66470
  }
66396
66471
  }
66397
66472
  } finally {
66398
- import_node_fs44.default.closeSync(fd);
66473
+ import_node_fs45.default.closeSync(fd);
66399
66474
  }
66400
66475
  if (w3.pendingCwdDerive) this.maybeDeriveCwd(w3);
66401
66476
  }
@@ -66407,7 +66482,7 @@ var SessionObserver = class {
66407
66482
  const now = Date.now();
66408
66483
  if (now - w3.lastRelocateScanMs < 1e3) return;
66409
66484
  w3.lastRelocateScanMs = now;
66410
- const projectsRoot = import_node_path48.default.join(this.home, ".claude", "projects");
66485
+ const projectsRoot = import_node_path49.default.join(this.home, ".claude", "projects");
66411
66486
  const found = findTranscriptByToolSessionId(projectsRoot, w3.toolSessionId);
66412
66487
  if (!found || found === w3.filePath) return;
66413
66488
  try {
@@ -66416,7 +66491,7 @@ var SessionObserver = class {
66416
66491
  }
66417
66492
  w3.filePath = found;
66418
66493
  try {
66419
- w3.watcher = import_node_fs44.default.watch(import_node_path48.default.dirname(found), { persistent: false }, (_event, changedName) => {
66494
+ w3.watcher = import_node_fs45.default.watch(import_node_path49.default.dirname(found), { persistent: false }, (_event, changedName) => {
66420
66495
  if (!changedName || !w3.filePath.endsWith(changedName)) return;
66421
66496
  this.poll(w3);
66422
66497
  });
@@ -66538,9 +66613,9 @@ function listRegistered() {
66538
66613
  // src/tools/title-generator.ts
66539
66614
  var import_node_child_process13 = require("child_process");
66540
66615
  init_protocol();
66541
- var import_node_fs45 = __toESM(require("fs"), 1);
66542
- var import_node_os18 = __toESM(require("os"), 1);
66543
- var import_node_path49 = __toESM(require("path"), 1);
66616
+ var import_node_fs46 = __toESM(require("fs"), 1);
66617
+ var import_node_os19 = __toESM(require("os"), 1);
66618
+ var import_node_path50 = __toESM(require("path"), 1);
66544
66619
  var TITLE_GEN_DIR_PREFIX = "clawd-title-";
66545
66620
  var TITLE_INPUT_MAX_CHARS = 400;
66546
66621
  var DEFAULT_TITLE_GEN_TIMEOUT_MS = 45e3;
@@ -66631,21 +66706,21 @@ async function generateSessionTitle(file, firstMessage, deps = {}) {
66631
66706
  }
66632
66707
  let workDir;
66633
66708
  try {
66634
- workDir = import_node_fs45.default.mkdtempSync(import_node_path49.default.join(import_node_os18.default.tmpdir(), TITLE_GEN_DIR_PREFIX));
66709
+ workDir = import_node_fs46.default.mkdtempSync(import_node_path50.default.join(import_node_os19.default.tmpdir(), TITLE_GEN_DIR_PREFIX));
66635
66710
  } catch {
66636
66711
  return null;
66637
66712
  }
66638
66713
  const cleanupWorkDir = () => {
66639
66714
  try {
66640
- import_node_fs45.default.rmSync(workDir, { recursive: true, force: true });
66715
+ import_node_fs46.default.rmSync(workDir, { recursive: true, force: true });
66641
66716
  } catch {
66642
66717
  }
66643
66718
  };
66644
- const outFile = import_node_path49.default.join(workDir, `codex-title-${process.pid}-${++outFileSeq}-${Date.now()}.txt`);
66645
- const schemaFile = import_node_path49.default.join(workDir, "title-schema.json");
66719
+ const outFile = import_node_path50.default.join(workDir, `codex-title-${process.pid}-${++outFileSeq}-${Date.now()}.txt`);
66720
+ const schemaFile = import_node_path50.default.join(workDir, "title-schema.json");
66646
66721
  if (tool === "codex") {
66647
66722
  try {
66648
- import_node_fs45.default.writeFileSync(schemaFile, CODEX_TITLE_SCHEMA);
66723
+ import_node_fs46.default.writeFileSync(schemaFile, CODEX_TITLE_SCHEMA);
66649
66724
  } catch {
66650
66725
  cleanupWorkDir();
66651
66726
  return null;
@@ -66700,7 +66775,7 @@ async function generateSessionTitle(file, firstMessage, deps = {}) {
66700
66775
  if (tool === "claude" || tool === "pi") return finish(parseTitleJson(stdout));
66701
66776
  let fileText = "";
66702
66777
  try {
66703
- fileText = import_node_fs45.default.readFileSync(outFile, "utf8");
66778
+ fileText = import_node_fs46.default.readFileSync(outFile, "utf8");
66704
66779
  } catch {
66705
66780
  return finish(null);
66706
66781
  }
@@ -67396,8 +67471,8 @@ async function authenticate(token, deps) {
67396
67471
  }
67397
67472
 
67398
67473
  // src/legacy-cleanup.ts
67399
- var fs56 = __toESM(require("fs/promises"), 1);
67400
- var path57 = __toESM(require("path"), 1);
67474
+ var fs57 = __toESM(require("fs/promises"), 1);
67475
+ var path58 = __toESM(require("path"), 1);
67401
67476
  var LEGACY_FILES = [
67402
67477
  "personal-capability.json",
67403
67478
  "received-capabilities.json",
@@ -67406,9 +67481,9 @@ var LEGACY_FILES = [
67406
67481
  async function cleanupLegacyCapabilityFiles(dataDir, logger) {
67407
67482
  const removed = [];
67408
67483
  for (const name of LEGACY_FILES) {
67409
- const p3 = path57.join(dataDir, name);
67484
+ const p3 = path58.join(dataDir, name);
67410
67485
  try {
67411
- await fs56.unlink(p3);
67486
+ await fs57.unlink(p3);
67412
67487
  removed.push(name);
67413
67488
  logger.debug("legacy capability file removed", { file: name });
67414
67489
  } catch (err) {
@@ -67420,13 +67495,13 @@ async function cleanupLegacyCapabilityFiles(dataDir, logger) {
67420
67495
  }
67421
67496
 
67422
67497
  // src/inbox/inbox-store.ts
67423
- var fs57 = __toESM(require("fs"), 1);
67424
- var path58 = __toESM(require("path"), 1);
67498
+ var fs58 = __toESM(require("fs"), 1);
67499
+ var path59 = __toESM(require("path"), 1);
67425
67500
  var INBOX_SUBDIR = "inbox";
67426
67501
  var InboxStore = class {
67427
67502
  constructor(dataDir) {
67428
67503
  this.dataDir = dataDir;
67429
- fs57.mkdirSync(this.dirPath(), { recursive: true });
67504
+ fs58.mkdirSync(this.dirPath(), { recursive: true });
67430
67505
  }
67431
67506
  dataDir;
67432
67507
  /**
@@ -67438,7 +67513,7 @@ var InboxStore = class {
67438
67513
  const file = this.filePath(peerDeviceId);
67439
67514
  let raw;
67440
67515
  try {
67441
- raw = fs57.readFileSync(file, "utf8");
67516
+ raw = fs58.readFileSync(file, "utf8");
67442
67517
  } catch (err) {
67443
67518
  if (err?.code === "ENOENT") return [];
67444
67519
  return [];
@@ -67454,7 +67529,7 @@ var InboxStore = class {
67454
67529
  const dir = this.dirPath();
67455
67530
  let entries;
67456
67531
  try {
67457
- entries = fs57.readdirSync(dir);
67532
+ entries = fs58.readdirSync(dir);
67458
67533
  } catch (err) {
67459
67534
  if (err?.code === "ENOENT") return [];
67460
67535
  return [];
@@ -67470,9 +67545,9 @@ var InboxStore = class {
67470
67545
  if (existing.some((m3) => m3.id === message.id)) return;
67471
67546
  const file = this.filePath(message.peerDeviceId);
67472
67547
  const line = JSON.stringify(message) + "\n";
67473
- fs57.appendFileSync(file, line, { mode: 384 });
67548
+ fs58.appendFileSync(file, line, { mode: 384 });
67474
67549
  try {
67475
- fs57.chmodSync(file, 384);
67550
+ fs58.chmodSync(file, 384);
67476
67551
  } catch {
67477
67552
  }
67478
67553
  }
@@ -67502,7 +67577,7 @@ var InboxStore = class {
67502
67577
  removeByPeerDeviceId(peerDeviceId) {
67503
67578
  const file = this.filePath(peerDeviceId);
67504
67579
  try {
67505
- fs57.unlinkSync(file);
67580
+ fs58.unlinkSync(file);
67506
67581
  } catch (err) {
67507
67582
  if (err?.code === "ENOENT") return;
67508
67583
  }
@@ -67511,18 +67586,18 @@ var InboxStore = class {
67511
67586
  const file = this.filePath(peerDeviceId);
67512
67587
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
67513
67588
  const content = messages.map((m3) => JSON.stringify(m3)).join("\n") + (messages.length > 0 ? "\n" : "");
67514
- fs57.writeFileSync(tmp, content, { mode: 384 });
67515
- fs57.renameSync(tmp, file);
67589
+ fs58.writeFileSync(tmp, content, { mode: 384 });
67590
+ fs58.renameSync(tmp, file);
67516
67591
  try {
67517
- fs57.chmodSync(file, 384);
67592
+ fs58.chmodSync(file, 384);
67518
67593
  } catch {
67519
67594
  }
67520
67595
  }
67521
67596
  dirPath() {
67522
- return path58.join(this.dataDir, INBOX_SUBDIR);
67597
+ return path59.join(this.dataDir, INBOX_SUBDIR);
67523
67598
  }
67524
67599
  filePath(peerDeviceId) {
67525
- return path58.join(this.dirPath(), `${peerDeviceId}.jsonl`);
67600
+ return path59.join(this.dirPath(), `${peerDeviceId}.jsonl`);
67526
67601
  }
67527
67602
  };
67528
67603
  function parseAllLines(raw) {
@@ -67610,8 +67685,8 @@ var InboxManager = class {
67610
67685
  };
67611
67686
 
67612
67687
  // src/state/contact-store.ts
67613
- var fs58 = __toESM(require("fs"), 1);
67614
- var path59 = __toESM(require("path"), 1);
67688
+ var fs59 = __toESM(require("fs"), 1);
67689
+ var path60 = __toESM(require("path"), 1);
67615
67690
  var FILE_NAME = "contacts.json";
67616
67691
  var ContactStore = class {
67617
67692
  constructor(dataDir) {
@@ -67621,10 +67696,10 @@ var ContactStore = class {
67621
67696
  contacts = /* @__PURE__ */ new Map();
67622
67697
  load() {
67623
67698
  this.contacts.clear();
67624
- const file = path59.join(this.dataDir, FILE_NAME);
67699
+ const file = path60.join(this.dataDir, FILE_NAME);
67625
67700
  let raw;
67626
67701
  try {
67627
- raw = fs58.readFileSync(file, "utf8");
67702
+ raw = fs59.readFileSync(file, "utf8");
67628
67703
  } catch (err) {
67629
67704
  if (err?.code !== "ENOENT") this.renameBak(file);
67630
67705
  return;
@@ -67705,20 +67780,20 @@ var ContactStore = class {
67705
67780
  return true;
67706
67781
  }
67707
67782
  flush() {
67708
- const file = path59.join(this.dataDir, FILE_NAME);
67783
+ const file = path60.join(this.dataDir, FILE_NAME);
67709
67784
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
67710
67785
  const content = JSON.stringify(
67711
67786
  { contacts: Array.from(this.contacts.values()) },
67712
67787
  null,
67713
67788
  2
67714
67789
  );
67715
- fs58.mkdirSync(this.dataDir, { recursive: true });
67716
- fs58.writeFileSync(tmp, content, { mode: 384 });
67717
- fs58.renameSync(tmp, file);
67790
+ fs59.mkdirSync(this.dataDir, { recursive: true });
67791
+ fs59.writeFileSync(tmp, content, { mode: 384 });
67792
+ fs59.renameSync(tmp, file);
67718
67793
  }
67719
67794
  renameBak(file) {
67720
67795
  try {
67721
- fs58.renameSync(file, `${file}.bak`);
67796
+ fs59.renameSync(file, `${file}.bak`);
67722
67797
  } catch {
67723
67798
  }
67724
67799
  }
@@ -67826,61 +67901,61 @@ async function connectRemote(args) {
67826
67901
  }
67827
67902
 
67828
67903
  // src/migrations/2026-05-20-flatten-sessions.ts
67829
- var fs59 = __toESM(require("fs"), 1);
67830
- var path60 = __toESM(require("path"), 1);
67904
+ var fs60 = __toESM(require("fs"), 1);
67905
+ var path61 = __toESM(require("path"), 1);
67831
67906
  var MIGRATION_FLAG_NAME = ".migration.v1.done";
67832
67907
  function migrateFlattenSessions(opts) {
67833
67908
  const dataDir = opts.dataDir;
67834
67909
  const now = opts.now ?? Date.now;
67835
- const sessionsDir = path60.join(dataDir, "sessions");
67836
- const flagPath = path60.join(sessionsDir, MIGRATION_FLAG_NAME);
67910
+ const sessionsDir = path61.join(dataDir, "sessions");
67911
+ const flagPath = path61.join(sessionsDir, MIGRATION_FLAG_NAME);
67837
67912
  if (existsSync3(flagPath)) {
67838
67913
  return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
67839
67914
  }
67840
67915
  let movedBare = 0;
67841
67916
  let movedVmOwner = 0;
67842
67917
  let archivedListener = 0;
67843
- const defaultDir = path60.join(sessionsDir, "default");
67918
+ const defaultDir = path61.join(sessionsDir, "default");
67844
67919
  if (existsSync3(defaultDir)) {
67845
67920
  for (const entry of readdirSafe(defaultDir)) {
67846
67921
  if (!entry.endsWith(".json")) continue;
67847
- const src = path60.join(defaultDir, entry);
67848
- const dst = path60.join(sessionsDir, entry);
67849
- fs59.renameSync(src, dst);
67922
+ const src = path61.join(defaultDir, entry);
67923
+ const dst = path61.join(sessionsDir, entry);
67924
+ fs60.renameSync(src, dst);
67850
67925
  movedBare += 1;
67851
67926
  }
67852
67927
  rmdirIfEmpty(defaultDir);
67853
67928
  }
67854
67929
  for (const pid of readdirSafe(sessionsDir)) {
67855
- const personaDir = path60.join(sessionsDir, pid);
67930
+ const personaDir = path61.join(sessionsDir, pid);
67856
67931
  if (!isDir(personaDir)) continue;
67857
67932
  if (pid === "default") continue;
67858
- const ownerSrc = path60.join(personaDir, "owner");
67933
+ const ownerSrc = path61.join(personaDir, "owner");
67859
67934
  if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
67860
- const ownerDst = path60.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
67861
- fs59.mkdirSync(ownerDst, { recursive: true });
67935
+ const ownerDst = path61.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
67936
+ fs60.mkdirSync(ownerDst, { recursive: true });
67862
67937
  for (const file of readdirSafe(ownerSrc)) {
67863
67938
  if (!file.endsWith(".json")) continue;
67864
- fs59.renameSync(path60.join(ownerSrc, file), path60.join(ownerDst, file));
67939
+ fs60.renameSync(path61.join(ownerSrc, file), path61.join(ownerDst, file));
67865
67940
  movedVmOwner += 1;
67866
67941
  }
67867
67942
  rmdirIfEmpty(ownerSrc);
67868
67943
  }
67869
- const listenerSrc = path60.join(personaDir, "listener");
67944
+ const listenerSrc = path61.join(personaDir, "listener");
67870
67945
  if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
67871
- const archiveDst = path60.join(dataDir, ".legacy", `listener-${pid}`);
67872
- fs59.mkdirSync(archiveDst, { recursive: true });
67946
+ const archiveDst = path61.join(dataDir, ".legacy", `listener-${pid}`);
67947
+ fs60.mkdirSync(archiveDst, { recursive: true });
67873
67948
  for (const file of readdirSafe(listenerSrc)) {
67874
67949
  if (!file.endsWith(".json")) continue;
67875
- fs59.renameSync(path60.join(listenerSrc, file), path60.join(archiveDst, file));
67950
+ fs60.renameSync(path61.join(listenerSrc, file), path61.join(archiveDst, file));
67876
67951
  archivedListener += 1;
67877
67952
  }
67878
67953
  rmdirIfEmpty(listenerSrc);
67879
67954
  }
67880
67955
  rmdirIfEmpty(personaDir);
67881
67956
  }
67882
- fs59.mkdirSync(sessionsDir, { recursive: true });
67883
- fs59.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
67957
+ fs60.mkdirSync(sessionsDir, { recursive: true });
67958
+ fs60.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
67884
67959
  return {
67885
67960
  skipped: false,
67886
67961
  flagWritten: true,
@@ -67891,7 +67966,7 @@ function migrateFlattenSessions(opts) {
67891
67966
  }
67892
67967
  function existsSync3(p3) {
67893
67968
  try {
67894
- fs59.statSync(p3);
67969
+ fs60.statSync(p3);
67895
67970
  return true;
67896
67971
  } catch {
67897
67972
  return false;
@@ -67899,62 +67974,62 @@ function existsSync3(p3) {
67899
67974
  }
67900
67975
  function isDir(p3) {
67901
67976
  try {
67902
- return fs59.statSync(p3).isDirectory();
67977
+ return fs60.statSync(p3).isDirectory();
67903
67978
  } catch {
67904
67979
  return false;
67905
67980
  }
67906
67981
  }
67907
67982
  function readdirSafe(p3) {
67908
67983
  try {
67909
- return fs59.readdirSync(p3);
67984
+ return fs60.readdirSync(p3);
67910
67985
  } catch {
67911
67986
  return [];
67912
67987
  }
67913
67988
  }
67914
67989
  function rmdirIfEmpty(p3) {
67915
67990
  try {
67916
- fs59.rmdirSync(p3);
67991
+ fs60.rmdirSync(p3);
67917
67992
  } catch {
67918
67993
  }
67919
67994
  }
67920
67995
 
67921
67996
  // src/migrations/2026-08-18-drop-seeded-projects.ts
67922
- var fs60 = __toESM(require("fs"), 1);
67923
- var path61 = __toESM(require("path"), 1);
67997
+ var fs61 = __toESM(require("fs"), 1);
67998
+ var path62 = __toESM(require("path"), 1);
67924
67999
  var DROP_SEEDED_PROJECTS_FLAG = ".projects-seed-dropped.v1.done";
67925
68000
  function dropSeededProjects(opts) {
67926
- fs60.mkdirSync(opts.dataDir, { recursive: true });
67927
- const flag = path61.join(opts.dataDir, DROP_SEEDED_PROJECTS_FLAG);
67928
- if (fs60.existsSync(flag)) return { skipped: true, dropped: 0, backup: null };
67929
- const file = path61.join(opts.dataDir, "projects.json");
68001
+ fs61.mkdirSync(opts.dataDir, { recursive: true });
68002
+ const flag = path62.join(opts.dataDir, DROP_SEEDED_PROJECTS_FLAG);
68003
+ if (fs61.existsSync(flag)) return { skipped: true, dropped: 0, backup: null };
68004
+ const file = path62.join(opts.dataDir, "projects.json");
67930
68005
  let raw = null;
67931
68006
  let dropped = 0;
67932
68007
  try {
67933
- raw = fs60.readFileSync(file, "utf8");
68008
+ raw = fs61.readFileSync(file, "utf8");
67934
68009
  dropped = JSON.parse(raw).projects?.length ?? 0;
67935
68010
  } catch {
67936
68011
  }
67937
68012
  let backup = null;
67938
68013
  if (raw != null && dropped > 0) {
67939
- const dir = path61.join(opts.dataDir, "backups");
67940
- fs60.mkdirSync(dir, { recursive: true });
67941
- backup = path61.join(dir, `projects.seed-dropped.${(opts.now ?? Date.now)()}.json`);
67942
- fs60.writeFileSync(backup, raw);
68014
+ const dir = path62.join(opts.dataDir, "backups");
68015
+ fs61.mkdirSync(dir, { recursive: true });
68016
+ backup = path62.join(dir, `projects.seed-dropped.${(opts.now ?? Date.now)()}.json`);
68017
+ fs61.writeFileSync(backup, raw);
67943
68018
  }
67944
68019
  if (raw != null || dropped > 0) {
67945
- fs60.writeFileSync(file, JSON.stringify({ projects: [] }, null, 2));
68020
+ fs61.writeFileSync(file, JSON.stringify({ projects: [] }, null, 2));
67946
68021
  }
67947
- fs60.writeFileSync(flag, (/* @__PURE__ */ new Date()).toISOString());
68022
+ fs61.writeFileSync(flag, (/* @__PURE__ */ new Date()).toISOString());
67948
68023
  return { skipped: false, dropped, backup };
67949
68024
  }
67950
68025
 
67951
68026
  // src/transport/http-router.ts
67952
- var import_node_fs47 = __toESM(require("fs"), 1);
67953
- var import_node_path52 = __toESM(require("path"), 1);
68027
+ var import_node_fs48 = __toESM(require("fs"), 1);
68028
+ var import_node_path53 = __toESM(require("path"), 1);
67954
68029
 
67955
68030
  // src/attachment/upload.ts
67956
- var import_node_fs46 = __toESM(require("fs"), 1);
67957
- var import_node_path50 = __toESM(require("path"), 1);
68031
+ var import_node_fs47 = __toESM(require("fs"), 1);
68032
+ var import_node_path51 = __toESM(require("path"), 1);
67958
68033
  var import_node_crypto15 = __toESM(require("crypto"), 1);
67959
68034
  var import_promises8 = require("stream/promises");
67960
68035
  var UploadError = class extends Error {
@@ -67966,22 +68041,22 @@ var UploadError = class extends Error {
67966
68041
  code;
67967
68042
  };
67968
68043
  function assertValidFileName(fileName) {
67969
- if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path50.default.basename(fileName)) {
68044
+ if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path51.default.basename(fileName)) {
67970
68045
  throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
67971
68046
  }
67972
68047
  }
67973
68048
  var HASH_PREFIX_LEN = 16;
67974
68049
  async function writeUploadedAttachment(args) {
67975
68050
  assertValidFileName(args.fileName);
67976
- const attachmentsRoot = import_node_path50.default.join(args.baseDir, ".attachments");
68051
+ const attachmentsRoot = import_node_path51.default.join(args.baseDir, ".attachments");
67977
68052
  try {
67978
- import_node_fs46.default.mkdirSync(attachmentsRoot, { recursive: true });
68053
+ import_node_fs47.default.mkdirSync(attachmentsRoot, { recursive: true });
67979
68054
  } catch (err) {
67980
68055
  throw new UploadError("STORAGE_ERROR", `mkdir failed: ${err.message}`);
67981
68056
  }
67982
68057
  const hasher = import_node_crypto15.default.createHash("sha256");
67983
68058
  let actualSize = 0;
67984
- const tmpPath = import_node_path50.default.join(
68059
+ const tmpPath = import_node_path51.default.join(
67985
68060
  attachmentsRoot,
67986
68061
  `.upload-${process.pid}-${Date.now()}-${import_node_crypto15.default.randomBytes(4).toString("hex")}`
67987
68062
  );
@@ -67996,18 +68071,18 @@ async function writeUploadedAttachment(args) {
67996
68071
  yield buf;
67997
68072
  }
67998
68073
  },
67999
- import_node_fs46.default.createWriteStream(tmpPath, { mode: 384 })
68074
+ import_node_fs47.default.createWriteStream(tmpPath, { mode: 384 })
68000
68075
  );
68001
68076
  } catch (err) {
68002
68077
  try {
68003
- import_node_fs46.default.unlinkSync(tmpPath);
68078
+ import_node_fs47.default.unlinkSync(tmpPath);
68004
68079
  } catch {
68005
68080
  }
68006
68081
  throw new UploadError("STORAGE_ERROR", `write failed: ${err.message}`);
68007
68082
  }
68008
68083
  if (actualSize !== args.contentLength) {
68009
68084
  try {
68010
- import_node_fs46.default.unlinkSync(tmpPath);
68085
+ import_node_fs47.default.unlinkSync(tmpPath);
68011
68086
  } catch {
68012
68087
  }
68013
68088
  throw new UploadError(
@@ -68016,34 +68091,34 @@ async function writeUploadedAttachment(args) {
68016
68091
  );
68017
68092
  }
68018
68093
  const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
68019
- const hashDir = import_node_path50.default.join(attachmentsRoot, attachmentId);
68094
+ const hashDir = import_node_path51.default.join(attachmentsRoot, attachmentId);
68020
68095
  let finalFileName;
68021
68096
  let hashDirExists = false;
68022
68097
  try {
68023
- hashDirExists = import_node_fs46.default.statSync(hashDir).isDirectory();
68098
+ hashDirExists = import_node_fs47.default.statSync(hashDir).isDirectory();
68024
68099
  } catch {
68025
68100
  }
68026
68101
  if (hashDirExists) {
68027
- const existing = import_node_fs46.default.readdirSync(hashDir).filter((n2) => !n2.startsWith("."));
68102
+ const existing = import_node_fs47.default.readdirSync(hashDir).filter((n2) => !n2.startsWith("."));
68028
68103
  finalFileName = existing[0] ?? args.fileName;
68029
68104
  try {
68030
- import_node_fs46.default.unlinkSync(tmpPath);
68105
+ import_node_fs47.default.unlinkSync(tmpPath);
68031
68106
  } catch {
68032
68107
  }
68033
68108
  } else {
68034
68109
  try {
68035
- import_node_fs46.default.mkdirSync(hashDir, { recursive: true });
68110
+ import_node_fs47.default.mkdirSync(hashDir, { recursive: true });
68036
68111
  finalFileName = args.fileName;
68037
- import_node_fs46.default.renameSync(tmpPath, import_node_path50.default.join(hashDir, finalFileName));
68112
+ import_node_fs47.default.renameSync(tmpPath, import_node_path51.default.join(hashDir, finalFileName));
68038
68113
  } catch (err) {
68039
68114
  try {
68040
- import_node_fs46.default.unlinkSync(tmpPath);
68115
+ import_node_fs47.default.unlinkSync(tmpPath);
68041
68116
  } catch {
68042
68117
  }
68043
68118
  throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
68044
68119
  }
68045
68120
  }
68046
- const absPath = import_node_path50.default.join(hashDir, finalFileName);
68121
+ const absPath = import_node_path51.default.join(hashDir, finalFileName);
68047
68122
  const relPath = absPath;
68048
68123
  args.groupFileStore.upsert(args.scope, args.sessionId, {
68049
68124
  relPath: absPath,
@@ -68058,8 +68133,8 @@ async function writeUploadedAttachment(args) {
68058
68133
 
68059
68134
  // src/extension/import.ts
68060
68135
  var import_promises9 = __toESM(require("fs/promises"), 1);
68061
- var import_node_path51 = __toESM(require("path"), 1);
68062
- var import_node_os19 = __toESM(require("os"), 1);
68136
+ var import_node_path52 = __toESM(require("path"), 1);
68137
+ var import_node_os20 = __toESM(require("os"), 1);
68063
68138
  var import_jszip = __toESM(require_lib3(), 1);
68064
68139
  var ImportError = class extends Error {
68065
68140
  constructor(code, message) {
@@ -68076,7 +68151,7 @@ async function importZip(buf, root) {
68076
68151
  throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
68077
68152
  }
68078
68153
  for (const name of Object.keys(zip.files)) {
68079
- if (name.includes("..") || name.startsWith("/") || import_node_path51.default.isAbsolute(name)) {
68154
+ if (name.includes("..") || name.startsWith("/") || import_node_path52.default.isAbsolute(name)) {
68080
68155
  throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
68081
68156
  }
68082
68157
  }
@@ -68109,7 +68184,7 @@ async function importZip(buf, root) {
68109
68184
  );
68110
68185
  }
68111
68186
  }
68112
- const destDir = import_node_path51.default.join(root, manifest.id);
68187
+ const destDir = import_node_path52.default.join(root, manifest.id);
68113
68188
  let destExists = false;
68114
68189
  try {
68115
68190
  await import_promises9.default.access(destDir);
@@ -68119,15 +68194,15 @@ async function importZip(buf, root) {
68119
68194
  if (destExists) {
68120
68195
  throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
68121
68196
  }
68122
- const stage = await import_promises9.default.mkdtemp(import_node_path51.default.join(import_node_os19.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
68197
+ const stage = await import_promises9.default.mkdtemp(import_node_path52.default.join(import_node_os20.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
68123
68198
  try {
68124
68199
  for (const [name, entry] of Object.entries(zip.files)) {
68125
- const dest = import_node_path51.default.join(stage, name);
68200
+ const dest = import_node_path52.default.join(stage, name);
68126
68201
  if (entry.dir) {
68127
68202
  await import_promises9.default.mkdir(dest, { recursive: true });
68128
68203
  continue;
68129
68204
  }
68130
- await import_promises9.default.mkdir(import_node_path51.default.dirname(dest), { recursive: true });
68205
+ await import_promises9.default.mkdir(import_node_path52.default.dirname(dest), { recursive: true });
68131
68206
  const content = await entry.async("nodebuffer");
68132
68207
  await import_promises9.default.writeFile(dest, content);
68133
68208
  }
@@ -68181,7 +68256,7 @@ var SHARE_UI_ASSET_MIME = {
68181
68256
  ".wasm": "application/wasm"
68182
68257
  };
68183
68258
  function shareUiAssetMime(filePath) {
68184
- const ext = import_node_path52.default.extname(filePath).toLowerCase();
68259
+ const ext = import_node_path53.default.extname(filePath).toLowerCase();
68185
68260
  return SHARE_UI_ASSET_MIME[ext] ?? lookupMime(filePath);
68186
68261
  }
68187
68262
  var AUTHED_RPC_ROUTE_PREFIX = "/rpc/";
@@ -68280,7 +68355,7 @@ function isValidUploadFileName(fileName) {
68280
68355
  if (fileName === "." || fileName === "..") return false;
68281
68356
  if (fileName.startsWith(".")) return false;
68282
68357
  if (fileName.includes("/") || fileName.includes("\\")) return false;
68283
- return fileName === import_node_path52.default.basename(fileName);
68358
+ return fileName === import_node_path53.default.basename(fileName);
68284
68359
  }
68285
68360
  function createHttpRouter(deps) {
68286
68361
  return async (req, res) => {
@@ -68364,7 +68439,7 @@ function createHttpRouter(deps) {
68364
68439
  }
68365
68440
  let buf;
68366
68441
  try {
68367
- buf = await import_node_fs47.default.promises.readFile(abs);
68442
+ buf = await import_node_fs48.default.promises.readFile(abs);
68368
68443
  } catch {
68369
68444
  sendJson2(res, 404, { code: "NOT_FOUND", message: "asset not found" });
68370
68445
  return true;
@@ -68510,7 +68585,7 @@ function createHttpRouter(deps) {
68510
68585
  sendHtml(res, statusByCode[r2.code], loader.renderErrorHtml(r2.code, msgByCode[r2.code]));
68511
68586
  return true;
68512
68587
  }
68513
- sendHtml(res, 200, loader.renderViewerHtml(import_node_path52.default.basename(r2.absPath)));
68588
+ sendHtml(res, 200, loader.renderViewerHtml(import_node_path53.default.basename(r2.absPath)));
68514
68589
  return true;
68515
68590
  }
68516
68591
  const ctx = deps.authResolver.resolveFromHeader(
@@ -68631,7 +68706,7 @@ function createHttpRouter(deps) {
68631
68706
  return true;
68632
68707
  }
68633
68708
  let absPath;
68634
- if (import_node_path52.default.isAbsolute(pathParam)) {
68709
+ if (import_node_path53.default.isAbsolute(pathParam)) {
68635
68710
  absPath = pathParam;
68636
68711
  } else if (deps.sessionStore) {
68637
68712
  const file = deps.sessionStore.read(sid);
@@ -68639,7 +68714,7 @@ function createHttpRouter(deps) {
68639
68714
  sendJson2(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
68640
68715
  return true;
68641
68716
  }
68642
- absPath = import_node_path52.default.join(file.cwd, pathParam);
68717
+ absPath = import_node_path53.default.join(file.cwd, pathParam);
68643
68718
  } else {
68644
68719
  sendJson2(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
68645
68720
  return true;
@@ -68723,7 +68798,7 @@ function withCtx(ctx, body) {
68723
68798
  function streamFile(res, absPath, logger) {
68724
68799
  let stat;
68725
68800
  try {
68726
- stat = import_node_fs47.default.statSync(absPath);
68801
+ stat = import_node_fs48.default.statSync(absPath);
68727
68802
  } catch (err) {
68728
68803
  const code = err?.code;
68729
68804
  if (code === "ENOENT") {
@@ -68738,7 +68813,7 @@ function streamFile(res, absPath, logger) {
68738
68813
  return;
68739
68814
  }
68740
68815
  const mime = lookupMime(absPath);
68741
- const basename2 = import_node_path52.default.basename(absPath);
68816
+ const basename2 = import_node_path53.default.basename(absPath);
68742
68817
  res.writeHead(200, {
68743
68818
  "Content-Type": mime,
68744
68819
  "Content-Length": String(stat.size),
@@ -68746,7 +68821,7 @@ function streamFile(res, absPath, logger) {
68746
68821
  // 防止浏览器把任意 mime 当 html 渲染
68747
68822
  "X-Content-Type-Options": "nosniff"
68748
68823
  });
68749
- const stream = import_node_fs47.default.createReadStream(absPath);
68824
+ const stream = import_node_fs48.default.createReadStream(absPath);
68750
68825
  stream.on("error", (err) => {
68751
68826
  logger?.warn("streamFile read error", { absPath, err: err.message });
68752
68827
  res.destroy();
@@ -68755,8 +68830,8 @@ function streamFile(res, absPath, logger) {
68755
68830
  }
68756
68831
 
68757
68832
  // src/attachment/gc.ts
68758
- var import_node_fs48 = __toESM(require("fs"), 1);
68759
- var import_node_path53 = __toESM(require("path"), 1);
68833
+ var import_node_fs49 = __toESM(require("fs"), 1);
68834
+ var import_node_path54 = __toESM(require("path"), 1);
68760
68835
  var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
68761
68836
  function runAttachmentGc(args) {
68762
68837
  const now = (args.now ?? Date.now)();
@@ -68765,12 +68840,12 @@ function runAttachmentGc(args) {
68765
68840
  for (const { scope, sessionId } of args.sessionScopes) {
68766
68841
  for (const entry of args.groupFileStore.list(scope, sessionId)) {
68767
68842
  if (entry.stale) continue;
68768
- if (import_node_path53.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
68843
+ if (import_node_path54.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
68769
68844
  }
68770
68845
  }
68771
68846
  const visited = /* @__PURE__ */ new Set();
68772
68847
  for (const { scope, sessionId } of args.sessionScopes) {
68773
- const legacyDir = args.getSessionCwd?.(sessionId) ?? import_node_path53.default.join(
68848
+ const legacyDir = args.getSessionCwd?.(sessionId) ?? import_node_path54.default.join(
68774
68849
  args.dataDir,
68775
68850
  "sessions",
68776
68851
  ...scopeSubPath(scope).map(safeFileName),
@@ -68783,28 +68858,28 @@ function runAttachmentGc(args) {
68783
68858
  return true;
68784
68859
  });
68785
68860
  for (const rootDir of roots) {
68786
- const attRoot = import_node_path53.default.join(rootDir, ".attachments");
68861
+ const attRoot = import_node_path54.default.join(rootDir, ".attachments");
68787
68862
  let hashDirs;
68788
68863
  try {
68789
- hashDirs = import_node_fs48.default.readdirSync(attRoot);
68864
+ hashDirs = import_node_fs49.default.readdirSync(attRoot);
68790
68865
  } catch (err) {
68791
68866
  if (err.code === "ENOENT") continue;
68792
68867
  args.logger?.warn("attachment gc: readdir failed", { attRoot, err: err.message });
68793
68868
  continue;
68794
68869
  }
68795
68870
  for (const hashDir of hashDirs) {
68796
- const hashDirAbs = import_node_path53.default.join(attRoot, hashDir);
68871
+ const hashDirAbs = import_node_path54.default.join(attRoot, hashDir);
68797
68872
  let files;
68798
68873
  try {
68799
- files = import_node_fs48.default.readdirSync(hashDirAbs);
68874
+ files = import_node_fs49.default.readdirSync(hashDirAbs);
68800
68875
  } catch {
68801
68876
  continue;
68802
68877
  }
68803
68878
  for (const name of files) {
68804
- const file = import_node_path53.default.join(hashDirAbs, name);
68879
+ const file = import_node_path54.default.join(hashDirAbs, name);
68805
68880
  let stat;
68806
68881
  try {
68807
- stat = import_node_fs48.default.statSync(file);
68882
+ stat = import_node_fs49.default.statSync(file);
68808
68883
  } catch {
68809
68884
  continue;
68810
68885
  }
@@ -68813,18 +68888,18 @@ function runAttachmentGc(args) {
68813
68888
  if (age < ttlMs) continue;
68814
68889
  if (liveAbs.has(file)) continue;
68815
68890
  try {
68816
- import_node_fs48.default.unlinkSync(file);
68891
+ import_node_fs49.default.unlinkSync(file);
68817
68892
  } catch (err) {
68818
68893
  args.logger?.warn("attachment gc: unlink failed", { file, err: err.message });
68819
68894
  }
68820
68895
  }
68821
68896
  try {
68822
- if (import_node_fs48.default.readdirSync(hashDirAbs).length === 0) import_node_fs48.default.rmdirSync(hashDirAbs);
68897
+ if (import_node_fs49.default.readdirSync(hashDirAbs).length === 0) import_node_fs49.default.rmdirSync(hashDirAbs);
68823
68898
  } catch {
68824
68899
  }
68825
68900
  }
68826
68901
  try {
68827
- if (import_node_fs48.default.readdirSync(attRoot).length === 0) import_node_fs48.default.rmdirSync(attRoot);
68902
+ if (import_node_fs49.default.readdirSync(attRoot).length === 0) import_node_fs49.default.rmdirSync(attRoot);
68828
68903
  } catch {
68829
68904
  }
68830
68905
  }
@@ -68832,8 +68907,8 @@ function runAttachmentGc(args) {
68832
68907
  }
68833
68908
 
68834
68909
  // src/attachment/group.ts
68835
- var import_node_fs49 = __toESM(require("fs"), 1);
68836
- var import_node_path54 = __toESM(require("path"), 1);
68910
+ var import_node_fs50 = __toESM(require("fs"), 1);
68911
+ var import_node_path55 = __toESM(require("path"), 1);
68837
68912
  var import_node_crypto16 = __toESM(require("crypto"), 1);
68838
68913
  init_protocol();
68839
68914
  var GroupFileStore = class {
@@ -68845,11 +68920,11 @@ var GroupFileStore = class {
68845
68920
  this.logger = opts.logger;
68846
68921
  }
68847
68922
  rootForScope(scope) {
68848
- return import_node_path54.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
68923
+ return import_node_path55.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
68849
68924
  }
68850
68925
  /** 与 SessionStore.filePath 平级,扩展名 .group-files.json */
68851
68926
  filePath(scope, sessionId) {
68852
- return import_node_path54.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
68927
+ return import_node_path55.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
68853
68928
  }
68854
68929
  cacheKey(scope, sessionId) {
68855
68930
  return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
@@ -68858,7 +68933,7 @@ var GroupFileStore = class {
68858
68933
  readFile(scope, sessionId) {
68859
68934
  const file = this.filePath(scope, sessionId);
68860
68935
  try {
68861
- const raw = import_node_fs49.default.readFileSync(file, "utf8");
68936
+ const raw = import_node_fs50.default.readFileSync(file, "utf8");
68862
68937
  const parsed = JSON.parse(raw);
68863
68938
  if (!Array.isArray(parsed)) {
68864
68939
  this.logger?.warn("GroupFileStore.readFile: not an array; resetting session entries", {
@@ -68884,10 +68959,10 @@ var GroupFileStore = class {
68884
68959
  }
68885
68960
  writeFile(scope, sessionId, entries) {
68886
68961
  const file = this.filePath(scope, sessionId);
68887
- import_node_fs49.default.mkdirSync(import_node_path54.default.dirname(file), { recursive: true });
68962
+ import_node_fs50.default.mkdirSync(import_node_path55.default.dirname(file), { recursive: true });
68888
68963
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
68889
- import_node_fs49.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
68890
- import_node_fs49.default.renameSync(tmp, file);
68964
+ import_node_fs50.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
68965
+ import_node_fs50.default.renameSync(tmp, file);
68891
68966
  }
68892
68967
  /** 拉一份当前 session 的清单。读盘 → cache;之后调用复用 cache */
68893
68968
  list(scope, sessionId) {
@@ -68979,7 +69054,7 @@ var GroupFileStore = class {
68979
69054
  */
68980
69055
  deleteSession(scope, sessionId) {
68981
69056
  try {
68982
- import_node_fs49.default.unlinkSync(this.filePath(scope, sessionId));
69057
+ import_node_fs50.default.unlinkSync(this.filePath(scope, sessionId));
68983
69058
  } catch (err) {
68984
69059
  if (err?.code !== "ENOENT") throw err;
68985
69060
  }
@@ -68992,7 +69067,7 @@ var GroupFileStore = class {
68992
69067
  * 不在 persona 目录里(见文件头的路径约定)。没树的 persona 是 noop。
68993
69068
  */
68994
69069
  deletePersona(personaId2) {
68995
- import_node_fs49.default.rmSync(import_node_path54.default.join(this.dataDir, "sessions", safeFileName(personaId2)), { recursive: true, force: true });
69070
+ import_node_fs50.default.rmSync(import_node_path55.default.join(this.dataDir, "sessions", safeFileName(personaId2)), { recursive: true, force: true });
68996
69071
  const prefix = `persona:${personaId2}:`;
68997
69072
  for (const key of this.cache.keys()) {
68998
69073
  if (key.startsWith(prefix)) this.cache.delete(key);
@@ -69001,10 +69076,10 @@ var GroupFileStore = class {
69001
69076
  };
69002
69077
 
69003
69078
  // src/discovery/state-file.ts
69004
- var import_node_fs50 = __toESM(require("fs"), 1);
69005
- var import_node_path55 = __toESM(require("path"), 1);
69079
+ var import_node_fs51 = __toESM(require("fs"), 1);
69080
+ var import_node_path56 = __toESM(require("path"), 1);
69006
69081
  function defaultStateFilePath(dataDir) {
69007
- return import_node_path55.default.join(dataDir, "state.json");
69082
+ return import_node_path56.default.join(dataDir, "state.json");
69008
69083
  }
69009
69084
  function isPidAlive(pid) {
69010
69085
  if (!Number.isFinite(pid) || pid <= 0) return false;
@@ -69026,7 +69101,7 @@ var StateFileManager = class {
69026
69101
  }
69027
69102
  read() {
69028
69103
  try {
69029
- const raw = import_node_fs50.default.readFileSync(this.file, "utf8");
69104
+ const raw = import_node_fs51.default.readFileSync(this.file, "utf8");
69030
69105
  const parsed = JSON.parse(raw);
69031
69106
  return parsed;
69032
69107
  } catch {
@@ -69040,20 +69115,20 @@ var StateFileManager = class {
69040
69115
  return { status: "stale", existing };
69041
69116
  }
69042
69117
  write(state) {
69043
- import_node_fs50.default.mkdirSync(import_node_path55.default.dirname(this.file), { recursive: true });
69118
+ import_node_fs51.default.mkdirSync(import_node_path56.default.dirname(this.file), { recursive: true });
69044
69119
  const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
69045
- import_node_fs50.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
69046
- import_node_fs50.default.renameSync(tmp, this.file);
69120
+ import_node_fs51.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
69121
+ import_node_fs51.default.renameSync(tmp, this.file);
69047
69122
  if (process.platform !== "win32") {
69048
69123
  try {
69049
- import_node_fs50.default.chmodSync(this.file, 384);
69124
+ import_node_fs51.default.chmodSync(this.file, 384);
69050
69125
  } catch {
69051
69126
  }
69052
69127
  }
69053
69128
  }
69054
69129
  delete() {
69055
69130
  try {
69056
- import_node_fs50.default.unlinkSync(this.file);
69131
+ import_node_fs51.default.unlinkSync(this.file);
69057
69132
  } catch {
69058
69133
  }
69059
69134
  }
@@ -69067,14 +69142,14 @@ function readSpawnedByDesktopFromEnv(env = process.env) {
69067
69142
  }
69068
69143
 
69069
69144
  // src/tunnel/tunnel-manager.ts
69070
- var import_node_fs54 = __toESM(require("fs"), 1);
69071
- var import_node_path59 = __toESM(require("path"), 1);
69145
+ var import_node_fs55 = __toESM(require("fs"), 1);
69146
+ var import_node_path60 = __toESM(require("path"), 1);
69072
69147
  var import_node_crypto17 = __toESM(require("crypto"), 1);
69073
69148
  var import_node_child_process16 = require("child_process");
69074
69149
 
69075
69150
  // src/tunnel/tunnel-store.ts
69076
- var import_node_fs51 = __toESM(require("fs"), 1);
69077
- var import_node_path56 = __toESM(require("path"), 1);
69151
+ var import_node_fs52 = __toESM(require("fs"), 1);
69152
+ var import_node_path57 = __toESM(require("path"), 1);
69078
69153
  var TunnelStore = class {
69079
69154
  constructor(filePath) {
69080
69155
  this.filePath = filePath;
@@ -69082,7 +69157,7 @@ var TunnelStore = class {
69082
69157
  filePath;
69083
69158
  async get() {
69084
69159
  try {
69085
- const raw = await import_node_fs51.default.promises.readFile(this.filePath, "utf8");
69160
+ const raw = await import_node_fs52.default.promises.readFile(this.filePath, "utf8");
69086
69161
  const obj = JSON.parse(raw);
69087
69162
  if (!isPersistedTunnel(obj)) return null;
69088
69163
  return obj;
@@ -69093,22 +69168,22 @@ var TunnelStore = class {
69093
69168
  }
69094
69169
  }
69095
69170
  async set(v3) {
69096
- const dir = import_node_path56.default.dirname(this.filePath);
69097
- await import_node_fs51.default.promises.mkdir(dir, { recursive: true });
69171
+ const dir = import_node_path57.default.dirname(this.filePath);
69172
+ await import_node_fs52.default.promises.mkdir(dir, { recursive: true });
69098
69173
  const data = JSON.stringify(v3, null, 2);
69099
69174
  const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
69100
- await import_node_fs51.default.promises.writeFile(tmp, data, { mode: 384 });
69175
+ await import_node_fs52.default.promises.writeFile(tmp, data, { mode: 384 });
69101
69176
  if (process.platform !== "win32") {
69102
69177
  try {
69103
- await import_node_fs51.default.promises.chmod(tmp, 384);
69178
+ await import_node_fs52.default.promises.chmod(tmp, 384);
69104
69179
  } catch {
69105
69180
  }
69106
69181
  }
69107
- await import_node_fs51.default.promises.rename(tmp, this.filePath);
69182
+ await import_node_fs52.default.promises.rename(tmp, this.filePath);
69108
69183
  }
69109
69184
  async clear() {
69110
69185
  try {
69111
- await import_node_fs51.default.promises.unlink(this.filePath);
69186
+ await import_node_fs52.default.promises.unlink(this.filePath);
69112
69187
  } catch (err) {
69113
69188
  const code = err?.code;
69114
69189
  if (code !== "ENOENT") throw err;
@@ -69203,9 +69278,9 @@ function escape2(v3) {
69203
69278
  }
69204
69279
 
69205
69280
  // src/tunnel/frpc-binary.ts
69206
- var import_node_fs52 = __toESM(require("fs"), 1);
69207
- var import_node_os20 = __toESM(require("os"), 1);
69208
- var import_node_path57 = __toESM(require("path"), 1);
69281
+ var import_node_fs53 = __toESM(require("fs"), 1);
69282
+ var import_node_os21 = __toESM(require("os"), 1);
69283
+ var import_node_path58 = __toESM(require("path"), 1);
69209
69284
  var import_node_child_process14 = require("child_process");
69210
69285
  var import_node_stream4 = require("stream");
69211
69286
  var import_promises10 = require("stream/promises");
@@ -69237,20 +69312,20 @@ function frpcDownloadUrl(version2, p3) {
69237
69312
  }
69238
69313
  async function ensureFrpcBinary(opts) {
69239
69314
  if (opts.override) {
69240
- if (!import_node_fs52.default.existsSync(opts.override)) {
69315
+ if (!import_node_fs53.default.existsSync(opts.override)) {
69241
69316
  throw new Error(`frpc binary not found at override path: ${opts.override}`);
69242
69317
  }
69243
69318
  return opts.override;
69244
69319
  }
69245
69320
  const version2 = opts.version ?? FRPC_VERSION;
69246
69321
  const platform = opts.platform ?? detectPlatform();
69247
- const binDir = import_node_path57.default.join(opts.dataDir, "bin");
69248
- import_node_fs52.default.mkdirSync(binDir, { recursive: true });
69322
+ const binDir = import_node_path58.default.join(opts.dataDir, "bin");
69323
+ import_node_fs53.default.mkdirSync(binDir, { recursive: true });
69249
69324
  cleanupStaleArtifacts(binDir);
69250
- const stableBin = import_node_path57.default.join(binDir, "frpc");
69251
- if (import_node_fs52.default.existsSync(stableBin)) return stableBin;
69325
+ const stableBin = import_node_path58.default.join(binDir, "frpc");
69326
+ if (import_node_fs53.default.existsSync(stableBin)) return stableBin;
69252
69327
  const partialBin = `${stableBin}.partial`;
69253
- const tarballPath = import_node_path57.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
69328
+ const tarballPath = import_node_path58.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
69254
69329
  try {
69255
69330
  const url = frpcDownloadUrl(version2, platform);
69256
69331
  await downloadToFile(url, tarballPath, opts.fetchImpl);
@@ -69259,8 +69334,8 @@ async function ensureFrpcBinary(opts) {
69259
69334
  } else {
69260
69335
  await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
69261
69336
  }
69262
- import_node_fs52.default.chmodSync(partialBin, 493);
69263
- import_node_fs52.default.renameSync(partialBin, stableBin);
69337
+ import_node_fs53.default.chmodSync(partialBin, 493);
69338
+ import_node_fs53.default.renameSync(partialBin, stableBin);
69264
69339
  } finally {
69265
69340
  safeUnlink(tarballPath);
69266
69341
  safeUnlink(partialBin);
@@ -69270,15 +69345,15 @@ async function ensureFrpcBinary(opts) {
69270
69345
  function cleanupStaleArtifacts(binDir) {
69271
69346
  let entries;
69272
69347
  try {
69273
- entries = import_node_fs52.default.readdirSync(binDir);
69348
+ entries = import_node_fs53.default.readdirSync(binDir);
69274
69349
  } catch {
69275
69350
  return;
69276
69351
  }
69277
69352
  for (const name of entries) {
69278
69353
  if (name.endsWith(".partial") || name.startsWith("extract-")) {
69279
- const full = import_node_path57.default.join(binDir, name);
69354
+ const full = import_node_path58.default.join(binDir, name);
69280
69355
  try {
69281
- import_node_fs52.default.rmSync(full, { recursive: true, force: true });
69356
+ import_node_fs53.default.rmSync(full, { recursive: true, force: true });
69282
69357
  } catch {
69283
69358
  }
69284
69359
  }
@@ -69286,7 +69361,7 @@ function cleanupStaleArtifacts(binDir) {
69286
69361
  }
69287
69362
  function safeUnlink(p3) {
69288
69363
  try {
69289
- import_node_fs52.default.unlinkSync(p3);
69364
+ import_node_fs53.default.unlinkSync(p3);
69290
69365
  } catch {
69291
69366
  }
69292
69367
  }
@@ -69297,13 +69372,13 @@ async function downloadToFile(url, dest, fetchImpl) {
69297
69372
  if (!res.ok || !res.body) {
69298
69373
  throw new Error(`download failed: ${res.status} ${res.statusText}`);
69299
69374
  }
69300
- const out = import_node_fs52.default.createWriteStream(dest);
69375
+ const out = import_node_fs53.default.createWriteStream(dest);
69301
69376
  const nodeStream = import_node_stream4.Readable.fromWeb(res.body);
69302
69377
  await (0, import_promises10.pipeline)(nodeStream, out);
69303
69378
  }
69304
69379
  async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
69305
- const work = import_node_path57.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
69306
- import_node_fs52.default.mkdirSync(work, { recursive: true });
69380
+ const work = import_node_path58.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
69381
+ import_node_fs53.default.mkdirSync(work, { recursive: true });
69307
69382
  try {
69308
69383
  await new Promise((resolve9, reject) => {
69309
69384
  const proc = (0, import_node_child_process14.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
@@ -69311,32 +69386,32 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
69311
69386
  proc.on("exit", (code) => code === 0 ? resolve9() : reject(new Error(`tar exited ${code}`)));
69312
69387
  });
69313
69388
  const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
69314
- const src = import_node_path57.default.join(work, dirName, "frpc");
69315
- if (!import_node_fs52.default.existsSync(src)) {
69389
+ const src = import_node_path58.default.join(work, dirName, "frpc");
69390
+ if (!import_node_fs53.default.existsSync(src)) {
69316
69391
  throw new Error(`frpc not found inside tarball at ${src}`);
69317
69392
  }
69318
- import_node_fs52.default.copyFileSync(src, destBin);
69393
+ import_node_fs53.default.copyFileSync(src, destBin);
69319
69394
  } finally {
69320
- import_node_fs52.default.rmSync(work, { recursive: true, force: true });
69395
+ import_node_fs53.default.rmSync(work, { recursive: true, force: true });
69321
69396
  }
69322
69397
  }
69323
69398
 
69324
69399
  // src/tunnel/frpc-process.ts
69325
- var import_node_fs53 = __toESM(require("fs"), 1);
69326
- var import_node_path58 = __toESM(require("path"), 1);
69400
+ var import_node_fs54 = __toESM(require("fs"), 1);
69401
+ var import_node_path59 = __toESM(require("path"), 1);
69327
69402
  var import_node_child_process15 = require("child_process");
69328
69403
  function frpcPidFilePath(dataDir) {
69329
- return import_node_path58.default.join(dataDir, "frpc.pid");
69404
+ return import_node_path59.default.join(dataDir, "frpc.pid");
69330
69405
  }
69331
69406
  function writeFrpcPid(dataDir, pid) {
69332
69407
  try {
69333
- import_node_fs53.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
69408
+ import_node_fs54.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
69334
69409
  } catch {
69335
69410
  }
69336
69411
  }
69337
69412
  function clearFrpcPid(dataDir) {
69338
69413
  try {
69339
- import_node_fs53.default.unlinkSync(frpcPidFilePath(dataDir));
69414
+ import_node_fs54.default.unlinkSync(frpcPidFilePath(dataDir));
69340
69415
  } catch {
69341
69416
  }
69342
69417
  }
@@ -69352,7 +69427,7 @@ function defaultIsPidAlive(pid) {
69352
69427
  }
69353
69428
  function defaultReadPidFile(file) {
69354
69429
  try {
69355
- return import_node_fs53.default.readFileSync(file, "utf8");
69430
+ return import_node_fs54.default.readFileSync(file, "utf8");
69356
69431
  } catch {
69357
69432
  return null;
69358
69433
  }
@@ -69368,7 +69443,7 @@ function defaultSleep2(ms) {
69368
69443
  }
69369
69444
  async function killStaleFrpc(deps) {
69370
69445
  const pidFile = frpcPidFilePath(deps.dataDir);
69371
- const tomlPath = import_node_path58.default.join(deps.dataDir, "frpc.toml");
69446
+ const tomlPath = import_node_path59.default.join(deps.dataDir, "frpc.toml");
69372
69447
  const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
69373
69448
  const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
69374
69449
  const killPid = deps.killPidImpl ?? defaultKillPid;
@@ -69392,7 +69467,7 @@ async function killStaleFrpc(deps) {
69392
69467
  }
69393
69468
  if (victims.size === 0) {
69394
69469
  try {
69395
- import_node_fs53.default.unlinkSync(pidFile);
69470
+ import_node_fs54.default.unlinkSync(pidFile);
69396
69471
  } catch {
69397
69472
  }
69398
69473
  return;
@@ -69403,7 +69478,7 @@ async function killStaleFrpc(deps) {
69403
69478
  }
69404
69479
  await sleep2(deps.reapWaitMs ?? 300);
69405
69480
  try {
69406
- import_node_fs53.default.unlinkSync(pidFile);
69481
+ import_node_fs54.default.unlinkSync(pidFile);
69407
69482
  } catch {
69408
69483
  }
69409
69484
  }
@@ -69440,7 +69515,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
69440
69515
  var TunnelManager = class {
69441
69516
  constructor(deps) {
69442
69517
  this.deps = deps;
69443
- this.store = deps.store ?? new TunnelStore(import_node_path59.default.join(deps.dataDir, "tunnel.json"));
69518
+ this.store = deps.store ?? new TunnelStore(import_node_path60.default.join(deps.dataDir, "tunnel.json"));
69444
69519
  this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
69445
69520
  this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
69446
69521
  }
@@ -69567,7 +69642,7 @@ var TunnelManager = class {
69567
69642
  dataDir: this.deps.dataDir,
69568
69643
  override: this.deps.frpcBinaryOverride ?? void 0
69569
69644
  });
69570
- const tomlPath = import_node_path59.default.join(this.deps.dataDir, "frpc.toml");
69645
+ const tomlPath = import_node_path60.default.join(this.deps.dataDir, "frpc.toml");
69571
69646
  const proxyName = `clawd-${t2.subdomain}-${localPort}-${import_node_crypto17.default.randomBytes(3).toString("hex")}`;
69572
69647
  const toml = buildFrpcToml({
69573
69648
  serverAddr: t2.frpsHost,
@@ -69578,14 +69653,14 @@ var TunnelManager = class {
69578
69653
  localPort,
69579
69654
  logLevel: "info"
69580
69655
  });
69581
- await import_node_fs54.default.promises.writeFile(tomlPath, toml, { mode: 384 });
69656
+ await import_node_fs55.default.promises.writeFile(tomlPath, toml, { mode: 384 });
69582
69657
  const proc = (this.deps.spawnImpl ?? import_node_child_process16.spawn)(frpcBin, ["-c", tomlPath], {
69583
69658
  stdio: ["ignore", "pipe", "pipe"]
69584
69659
  });
69585
- const logDir = import_node_path59.default.join(this.deps.dataDir, "log");
69586
- import_node_fs54.default.mkdirSync(logDir, { recursive: true });
69587
- const logFilePath = import_node_path59.default.join(logDir, "frpc.log");
69588
- const logStream = import_node_fs54.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
69660
+ const logDir = import_node_path60.default.join(this.deps.dataDir, "log");
69661
+ import_node_fs55.default.mkdirSync(logDir, { recursive: true });
69662
+ const logFilePath = import_node_path60.default.join(logDir, "frpc.log");
69663
+ const logStream = import_node_fs55.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
69589
69664
  logStream.on("error", () => {
69590
69665
  });
69591
69666
  const tee = (chunk) => {
@@ -69667,28 +69742,28 @@ async function waitForFrpcReady(proc, timeoutMs) {
69667
69742
  }
69668
69743
 
69669
69744
  // src/tunnel/device-key.ts
69670
- var import_node_os21 = __toESM(require("os"), 1);
69671
- var import_node_path60 = __toESM(require("path"), 1);
69745
+ var import_node_os22 = __toESM(require("os"), 1);
69746
+ var import_node_path61 = __toESM(require("path"), 1);
69672
69747
  var import_node_crypto18 = __toESM(require("crypto"), 1);
69673
69748
  var DERIVE_SALT = "clawd-tunnel-device-v1";
69674
69749
  function deriveStableDeviceKey(opts = {}) {
69675
- const hostname = opts.hostname ?? import_node_os21.default.hostname();
69676
- const uid = opts.uid ?? (typeof import_node_os21.default.userInfo === "function" ? import_node_os21.default.userInfo().uid : 0);
69677
- const home = opts.home ?? import_node_os21.default.homedir();
69678
- const defaultDataDir = import_node_path60.default.resolve(import_node_path60.default.join(home, ".clawd"));
69679
- const normalizedDataDir = opts.dataDir ? import_node_path60.default.resolve(opts.dataDir) : null;
69750
+ const hostname = opts.hostname ?? import_node_os22.default.hostname();
69751
+ const uid = opts.uid ?? (typeof import_node_os22.default.userInfo === "function" ? import_node_os22.default.userInfo().uid : 0);
69752
+ const home = opts.home ?? import_node_os22.default.homedir();
69753
+ const defaultDataDir = import_node_path61.default.resolve(import_node_path61.default.join(home, ".clawd"));
69754
+ const normalizedDataDir = opts.dataDir ? import_node_path61.default.resolve(opts.dataDir) : null;
69680
69755
  const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
69681
69756
  const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
69682
69757
  return import_node_crypto18.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
69683
69758
  }
69684
69759
 
69685
69760
  // src/auth-store.ts
69686
- var import_node_fs55 = __toESM(require("fs"), 1);
69687
- var import_node_path61 = __toESM(require("path"), 1);
69761
+ var import_node_fs56 = __toESM(require("fs"), 1);
69762
+ var import_node_path62 = __toESM(require("path"), 1);
69688
69763
  var import_node_crypto19 = __toESM(require("crypto"), 1);
69689
69764
  var AUTH_FILE_NAME = "auth.json";
69690
69765
  function authFilePath(dataDir) {
69691
- return import_node_path61.default.join(dataDir, AUTH_FILE_NAME);
69766
+ return import_node_path62.default.join(dataDir, AUTH_FILE_NAME);
69692
69767
  }
69693
69768
  function loadOrCreateAuthFile(opts) {
69694
69769
  const file = authFilePath(opts.dataDir);
@@ -69729,7 +69804,7 @@ function defaultGenerateOwnerPrincipalId() {
69729
69804
  }
69730
69805
  function readAuthFile(file) {
69731
69806
  try {
69732
- const raw = import_node_fs55.default.readFileSync(file, "utf8");
69807
+ const raw = import_node_fs56.default.readFileSync(file, "utf8");
69733
69808
  const parsed = JSON.parse(raw);
69734
69809
  if (typeof parsed?.token !== "string" || parsed.token.length === 0) {
69735
69810
  return null;
@@ -69750,26 +69825,26 @@ function readAuthFile(file) {
69750
69825
  }
69751
69826
  }
69752
69827
  function writeAuthFile(file, content) {
69753
- import_node_fs55.default.mkdirSync(import_node_path61.default.dirname(file), { recursive: true });
69754
- import_node_fs55.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
69828
+ import_node_fs56.default.mkdirSync(import_node_path62.default.dirname(file), { recursive: true });
69829
+ import_node_fs56.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
69755
69830
  try {
69756
- import_node_fs55.default.chmodSync(file, 384);
69831
+ import_node_fs56.default.chmodSync(file, 384);
69757
69832
  } catch {
69758
69833
  }
69759
69834
  }
69760
69835
 
69761
69836
  // src/owner-profile.ts
69762
- var import_node_fs56 = __toESM(require("fs"), 1);
69763
- var import_node_os22 = __toESM(require("os"), 1);
69764
- var import_node_path62 = __toESM(require("path"), 1);
69837
+ var import_node_fs57 = __toESM(require("fs"), 1);
69838
+ var import_node_os23 = __toESM(require("os"), 1);
69839
+ var import_node_path63 = __toESM(require("path"), 1);
69765
69840
  var PROFILE_FILENAME = "profile.json";
69766
69841
  function profilePath(dataDir) {
69767
- return import_node_path62.default.join(dataDir, PROFILE_FILENAME);
69842
+ return import_node_path63.default.join(dataDir, PROFILE_FILENAME);
69768
69843
  }
69769
69844
  function loadOwnerProfile(dataDir) {
69770
69845
  let raw;
69771
69846
  try {
69772
- raw = import_node_fs56.default.readFileSync(profilePath(dataDir), "utf8");
69847
+ raw = import_node_fs57.default.readFileSync(profilePath(dataDir), "utf8");
69773
69848
  } catch {
69774
69849
  return {};
69775
69850
  }
@@ -69785,11 +69860,11 @@ function loadOwnerProfile(dataDir) {
69785
69860
  }
69786
69861
  function patchOwnerProfile(dataDir, patch) {
69787
69862
  const merged = { ...loadOwnerProfile(dataDir), ...patch };
69788
- import_node_fs56.default.writeFileSync(profilePath(dataDir), JSON.stringify(merged, null, 2), { encoding: "utf8", mode: 384 });
69863
+ import_node_fs57.default.writeFileSync(profilePath(dataDir), JSON.stringify(merged, null, 2), { encoding: "utf8", mode: 384 });
69789
69864
  return merged;
69790
69865
  }
69791
69866
  function loadOwnerDisplayName(dataDir) {
69792
- const fallback = import_node_os22.default.userInfo().username;
69867
+ const fallback = import_node_os23.default.userInfo().username;
69793
69868
  const displayName = loadOwnerProfile(dataDir).displayName;
69794
69869
  if (typeof displayName !== "string" || displayName.length === 0) {
69795
69870
  if (displayName !== void 0) {
@@ -69801,18 +69876,18 @@ function loadOwnerDisplayName(dataDir) {
69801
69876
  }
69802
69877
 
69803
69878
  // src/feishu-auth/owner-identity-store.ts
69804
- var import_node_fs57 = __toESM(require("fs"), 1);
69805
- var import_node_path63 = __toESM(require("path"), 1);
69879
+ var import_node_fs58 = __toESM(require("fs"), 1);
69880
+ var import_node_path64 = __toESM(require("path"), 1);
69806
69881
  var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
69807
69882
  var OwnerIdentityStore = class {
69808
69883
  file;
69809
69884
  constructor(dataDir) {
69810
- this.file = import_node_path63.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
69885
+ this.file = import_node_path64.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
69811
69886
  }
69812
69887
  read() {
69813
69888
  let raw;
69814
69889
  try {
69815
- raw = import_node_fs57.default.readFileSync(this.file, "utf8");
69890
+ raw = import_node_fs58.default.readFileSync(this.file, "utf8");
69816
69891
  } catch {
69817
69892
  return null;
69818
69893
  }
@@ -69839,16 +69914,16 @@ var OwnerIdentityStore = class {
69839
69914
  };
69840
69915
  }
69841
69916
  write(record4) {
69842
- import_node_fs57.default.mkdirSync(import_node_path63.default.dirname(this.file), { recursive: true });
69843
- import_node_fs57.default.writeFileSync(this.file, JSON.stringify(record4, null, 2), { mode: 384 });
69917
+ import_node_fs58.default.mkdirSync(import_node_path64.default.dirname(this.file), { recursive: true });
69918
+ import_node_fs58.default.writeFileSync(this.file, JSON.stringify(record4, null, 2), { mode: 384 });
69844
69919
  try {
69845
- import_node_fs57.default.chmodSync(this.file, 384);
69920
+ import_node_fs58.default.chmodSync(this.file, 384);
69846
69921
  } catch {
69847
69922
  }
69848
69923
  }
69849
69924
  clear() {
69850
69925
  try {
69851
- import_node_fs57.default.unlinkSync(this.file);
69926
+ import_node_fs58.default.unlinkSync(this.file);
69852
69927
  } catch (err) {
69853
69928
  const code = err?.code;
69854
69929
  if (code !== "ENOENT") throw err;
@@ -70344,8 +70419,8 @@ function verifyConnectToken(args) {
70344
70419
  }
70345
70420
 
70346
70421
  // src/feishu-auth/server-key.ts
70347
- var fs74 = __toESM(require("fs"), 1);
70348
- var path76 = __toESM(require("path"), 1);
70422
+ var fs75 = __toESM(require("fs"), 1);
70423
+ var path77 = __toESM(require("path"), 1);
70349
70424
  var FILE_NAME2 = "server-signing-key.json";
70350
70425
  var ServerKeyStore = class {
70351
70426
  constructor(dataDir) {
@@ -70353,12 +70428,12 @@ var ServerKeyStore = class {
70353
70428
  }
70354
70429
  dataDir;
70355
70430
  filePath() {
70356
- return path76.join(this.dataDir, FILE_NAME2);
70431
+ return path77.join(this.dataDir, FILE_NAME2);
70357
70432
  }
70358
70433
  /** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
70359
70434
  read() {
70360
70435
  try {
70361
- const raw = fs74.readFileSync(this.filePath(), "utf8");
70436
+ const raw = fs75.readFileSync(this.filePath(), "utf8");
70362
70437
  const parsed = JSON.parse(raw);
70363
70438
  if (typeof parsed.publicKeyPem === "string" && parsed.publicKeyPem.includes("PUBLIC KEY")) {
70364
70439
  return parsed.publicKeyPem;
@@ -70373,12 +70448,12 @@ var ServerKeyStore = class {
70373
70448
  publicKeyPem,
70374
70449
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
70375
70450
  };
70376
- fs74.mkdirSync(this.dataDir, { recursive: true });
70377
- fs74.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
70451
+ fs75.mkdirSync(this.dataDir, { recursive: true });
70452
+ fs75.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
70378
70453
  }
70379
70454
  clear() {
70380
70455
  try {
70381
- fs74.unlinkSync(this.filePath());
70456
+ fs75.unlinkSync(this.filePath());
70382
70457
  } catch {
70383
70458
  }
70384
70459
  }
@@ -70394,13 +70469,13 @@ var import_node_path80 = __toESM(require("path"), 1);
70394
70469
  init_protocol();
70395
70470
 
70396
70471
  // src/session/fork.ts
70397
- var import_node_fs58 = __toESM(require("fs"), 1);
70398
- var import_node_os23 = __toESM(require("os"), 1);
70399
- var import_node_path64 = __toESM(require("path"), 1);
70472
+ var import_node_fs59 = __toESM(require("fs"), 1);
70473
+ var import_node_os24 = __toESM(require("os"), 1);
70474
+ var import_node_path65 = __toESM(require("path"), 1);
70400
70475
  var import_node_crypto21 = require("crypto");
70401
70476
  init_claude_history();
70402
70477
  function readJsonlEntries(file) {
70403
- const raw = import_node_fs58.default.readFileSync(file, "utf8");
70478
+ const raw = import_node_fs59.default.readFileSync(file, "utf8");
70404
70479
  const out = [];
70405
70480
  for (const line of raw.split("\n")) {
70406
70481
  const t2 = line.trim();
@@ -70413,19 +70488,19 @@ function readJsonlEntries(file) {
70413
70488
  return out;
70414
70489
  }
70415
70490
  function forkSession(input) {
70416
- const baseDir = input.baseDir ?? import_node_path64.default.join(import_node_os23.default.homedir(), ".claude");
70417
- let projectDir = import_node_path64.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
70418
- let sourceFile = import_node_path64.default.join(projectDir, `${input.toolSessionId}.jsonl`);
70419
- if (!import_node_fs58.default.existsSync(sourceFile)) {
70491
+ const baseDir = input.baseDir ?? import_node_path65.default.join(import_node_os24.default.homedir(), ".claude");
70492
+ let projectDir = import_node_path65.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
70493
+ let sourceFile = import_node_path65.default.join(projectDir, `${input.toolSessionId}.jsonl`);
70494
+ if (!import_node_fs59.default.existsSync(sourceFile)) {
70420
70495
  const found = findTranscriptByToolSessionId(
70421
- import_node_path64.default.join(baseDir, "projects"),
70496
+ import_node_path65.default.join(baseDir, "projects"),
70422
70497
  input.toolSessionId
70423
70498
  );
70424
70499
  if (!found) {
70425
70500
  throw new Error(`fork: source transcript not found: ${sourceFile}`);
70426
70501
  }
70427
70502
  sourceFile = found;
70428
- projectDir = import_node_path64.default.dirname(found);
70503
+ projectDir = import_node_path65.default.dirname(found);
70429
70504
  }
70430
70505
  const entries = readJsonlEntries(sourceFile);
70431
70506
  const mainEntries = entries.filter((e) => e.isSidechain !== true);
@@ -70454,17 +70529,17 @@ function forkSession(input) {
70454
70529
  }
70455
70530
  forkedLines.push(JSON.stringify(forked));
70456
70531
  }
70457
- const outDir = input.targetCwd ? import_node_path64.default.join(baseDir, "projects", cwdToHashDir(input.targetCwd)) : projectDir;
70458
- const forkedFilePath = import_node_path64.default.join(outDir, `${forkedToolSessionId}.jsonl`);
70459
- import_node_fs58.default.mkdirSync(outDir, { recursive: true });
70460
- import_node_fs58.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
70532
+ const outDir = input.targetCwd ? import_node_path65.default.join(baseDir, "projects", cwdToHashDir(input.targetCwd)) : projectDir;
70533
+ const forkedFilePath = import_node_path65.default.join(outDir, `${forkedToolSessionId}.jsonl`);
70534
+ import_node_fs59.default.mkdirSync(outDir, { recursive: true });
70535
+ import_node_fs59.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
70461
70536
  return { forkedToolSessionId, forkedFilePath };
70462
70537
  }
70463
70538
 
70464
70539
  // src/tools/codex-fork.ts
70465
70540
  var import_node_child_process17 = require("child_process");
70466
- var import_node_fs59 = __toESM(require("fs"), 1);
70467
- var import_node_path65 = __toESM(require("path"), 1);
70541
+ var import_node_fs60 = __toESM(require("fs"), 1);
70542
+ var import_node_path66 = __toESM(require("path"), 1);
70468
70543
  function openCodexAppServer(home, cwd) {
70469
70544
  const proc = (0, import_node_child_process17.spawn)(process.env.CODEX_BIN ?? "codex", ["app-server", "--listen", "stdio://"], {
70470
70545
  cwd,
@@ -70484,7 +70559,7 @@ function openCodexAppServer(home, cwd) {
70484
70559
  async function forkCodexThread(input, deps = {}) {
70485
70560
  const source = locateCodexThread(input.roots, input.sourceThreadId);
70486
70561
  if (!source) throw new Error(`codex fork: source thread not found: ${input.sourceThreadId}`);
70487
- const rollout = parseCodexRollout(import_node_fs59.default.readFileSync(source.file, "utf8"));
70562
+ const rollout = parseCodexRollout(import_node_fs60.default.readFileSync(source.file, "utf8"));
70488
70563
  if (rollout.meta?.threadId.toLowerCase() !== input.sourceThreadId.toLowerCase()) {
70489
70564
  throw new Error(`codex fork: source thread metadata does not match ${input.sourceThreadId}`);
70490
70565
  }
@@ -70514,7 +70589,7 @@ async function forkCodexThread(input, deps = {}) {
70514
70589
  if (typeof forkedToolSessionId !== "string" || !forkedToolSessionId) {
70515
70590
  throw new Error("codex fork: app-server returned no thread id");
70516
70591
  }
70517
- const forked = locateCodexThread([import_node_path65.default.join(source.home, "sessions")], forkedToolSessionId);
70592
+ const forked = locateCodexThread([import_node_path66.default.join(source.home, "sessions")], forkedToolSessionId);
70518
70593
  if (!forked) throw new Error(`codex fork: rollout not found for forked thread ${forkedToolSessionId}`);
70519
70594
  return { forkedToolSessionId, forkedFilePath: forked.file };
70520
70595
  })()]);
@@ -70525,19 +70600,19 @@ async function forkCodexThread(input, deps = {}) {
70525
70600
  }
70526
70601
 
70527
70602
  // src/session/external-scan.ts
70528
- var import_node_fs60 = __toESM(require("fs"), 1);
70603
+ var import_node_fs61 = __toESM(require("fs"), 1);
70529
70604
  var import_promises11 = __toESM(require("fs/promises"), 1);
70530
- var import_node_os24 = __toESM(require("os"), 1);
70531
- var import_node_path66 = __toESM(require("path"), 1);
70605
+ var import_node_os25 = __toESM(require("os"), 1);
70606
+ var import_node_path67 = __toESM(require("path"), 1);
70532
70607
  var import_node_module = require("module");
70533
70608
  var import_node_child_process18 = require("child_process");
70534
70609
  var import_meta7 = {};
70535
70610
  function defaultRoots() {
70536
- const home = import_node_os24.default.homedir();
70611
+ const home = import_node_os25.default.homedir();
70537
70612
  return {
70538
- claudeProjectsDir: import_node_path66.default.join(home, ".claude", "projects"),
70539
- codexDir: import_node_path66.default.join(home, ".codex"),
70540
- clawdDir: import_node_path66.default.join(home, ".clawd")
70613
+ claudeProjectsDir: import_node_path67.default.join(home, ".claude", "projects"),
70614
+ codexDir: import_node_path67.default.join(home, ".codex"),
70615
+ clawdDir: import_node_path67.default.join(home, ".clawd")
70541
70616
  };
70542
70617
  }
70543
70618
  function width(s2) {
@@ -70588,7 +70663,7 @@ function userText(msg) {
70588
70663
  }
70589
70664
  function isDir2(p3) {
70590
70665
  try {
70591
- return import_node_fs60.default.statSync(p3).isDirectory();
70666
+ return import_node_fs61.default.statSync(p3).isDirectory();
70592
70667
  } catch {
70593
70668
  return false;
70594
70669
  }
@@ -70597,7 +70672,7 @@ async function scanClaude(roots) {
70597
70672
  const out = [];
70598
70673
  let dirs;
70599
70674
  try {
70600
- dirs = import_node_fs60.default.readdirSync(roots.claudeProjectsDir, { withFileTypes: true });
70675
+ dirs = import_node_fs61.default.readdirSync(roots.claudeProjectsDir, { withFileTypes: true });
70601
70676
  } catch {
70602
70677
  return out;
70603
70678
  }
@@ -70605,16 +70680,16 @@ async function scanClaude(roots) {
70605
70680
  if (!d2.isDirectory()) continue;
70606
70681
  let files;
70607
70682
  try {
70608
- files = import_node_fs60.default.readdirSync(import_node_path66.default.join(roots.claudeProjectsDir, d2.name));
70683
+ files = import_node_fs61.default.readdirSync(import_node_path67.default.join(roots.claudeProjectsDir, d2.name));
70609
70684
  } catch {
70610
70685
  continue;
70611
70686
  }
70612
70687
  for (const name of files) {
70613
70688
  if (!name.endsWith(".jsonl")) continue;
70614
- const file = import_node_path66.default.join(roots.claudeProjectsDir, d2.name, name);
70689
+ const file = import_node_path67.default.join(roots.claudeProjectsDir, d2.name, name);
70615
70690
  let st2;
70616
70691
  try {
70617
- st2 = import_node_fs60.default.statSync(file);
70692
+ st2 = import_node_fs61.default.statSync(file);
70618
70693
  } catch {
70619
70694
  continue;
70620
70695
  }
@@ -70667,7 +70742,7 @@ async function scanClaude(roots) {
70667
70742
  return out;
70668
70743
  }
70669
70744
  async function countCodexTurns(rolloutPath) {
70670
- if (!rolloutPath || !import_node_fs60.default.existsSync(rolloutPath)) return { turns: 0, first: "" };
70745
+ if (!rolloutPath || !import_node_fs61.default.existsSync(rolloutPath)) return { turns: 0, first: "" };
70671
70746
  let turns = 0;
70672
70747
  let first = "";
70673
70748
  for await (const rec6 of jsonLines(rolloutPath)) {
@@ -70741,7 +70816,7 @@ async function codexFromRows(rows) {
70741
70816
  async function scanCodex(roots) {
70742
70817
  let dbs = [];
70743
70818
  try {
70744
- dbs = import_node_fs60.default.readdirSync(roots.codexDir).filter((n2) => /^state_.*\.sqlite$/.test(n2)).sort().map((n2) => import_node_path66.default.join(roots.codexDir, n2));
70819
+ dbs = import_node_fs61.default.readdirSync(roots.codexDir).filter((n2) => /^state_.*\.sqlite$/.test(n2)).sort().map((n2) => import_node_path67.default.join(roots.codexDir, n2));
70745
70820
  } catch {
70746
70821
  }
70747
70822
  if (!dbs.length) return [];
@@ -70750,14 +70825,14 @@ async function scanCodex(roots) {
70750
70825
  }
70751
70826
  async function scanExternalSessions(rootsIn) {
70752
70827
  const roots = { ...defaultRoots(), ...rootsIn };
70753
- const personaRoot = import_node_path66.default.join(roots.clawdDir, "personas");
70828
+ const personaRoot = import_node_path67.default.join(roots.clawdDir, "personas");
70754
70829
  const all = [...await scanClaude(roots), ...await scanCodex(roots)];
70755
70830
  const out = [];
70756
70831
  for (const c2 of all) {
70757
70832
  if (c2.skip) continue;
70758
70833
  if (c2.turns < 1) continue;
70759
70834
  if (!c2.cwd || !isDir2(c2.cwd)) continue;
70760
- if (c2.cwd === roots.clawdDir || c2.cwd === personaRoot || c2.cwd.startsWith(personaRoot + import_node_path66.default.sep) || c2.cwd.startsWith(roots.clawdDir + import_node_path66.default.sep)) {
70835
+ if (c2.cwd === roots.clawdDir || c2.cwd === personaRoot || c2.cwd.startsWith(personaRoot + import_node_path67.default.sep) || c2.cwd.startsWith(roots.clawdDir + import_node_path67.default.sep)) {
70761
70836
  continue;
70762
70837
  }
70763
70838
  out.push({
@@ -70774,13 +70849,13 @@ async function scanExternalSessions(rootsIn) {
70774
70849
  }
70775
70850
 
70776
70851
  // src/session/import-ledger.ts
70777
- var import_node_fs61 = __toESM(require("fs"), 1);
70778
- var import_node_path67 = __toESM(require("path"), 1);
70852
+ var import_node_fs62 = __toESM(require("fs"), 1);
70853
+ var import_node_path68 = __toESM(require("path"), 1);
70779
70854
  var LEDGER_FILENAME = "session-import-ledger.json";
70780
70855
  function readImportLedger(dataDir) {
70781
70856
  try {
70782
70857
  const parsed = JSON.parse(
70783
- import_node_fs61.default.readFileSync(import_node_path67.default.join(dataDir, LEDGER_FILENAME), "utf8")
70858
+ import_node_fs62.default.readFileSync(import_node_path68.default.join(dataDir, LEDGER_FILENAME), "utf8")
70784
70859
  );
70785
70860
  return Array.isArray(parsed) ? parsed : [];
70786
70861
  } catch {
@@ -70788,15 +70863,15 @@ function readImportLedger(dataDir) {
70788
70863
  }
70789
70864
  }
70790
70865
  function appendImportLedger(dataDir, entry) {
70791
- const file = import_node_path67.default.join(dataDir, LEDGER_FILENAME);
70866
+ const file = import_node_path68.default.join(dataDir, LEDGER_FILENAME);
70792
70867
  const entries = readImportLedger(dataDir);
70793
70868
  entries.push(entry);
70794
- import_node_fs61.default.writeFileSync(file, JSON.stringify(entries, null, 2), { encoding: "utf8", mode: 384 });
70869
+ import_node_fs62.default.writeFileSync(file, JSON.stringify(entries, null, 2), { encoding: "utf8", mode: 384 });
70795
70870
  }
70796
70871
 
70797
70872
  // src/handlers/session.ts
70798
70873
  init_protocol();
70799
- var import_node_path68 = __toESM(require("path"), 1);
70874
+ var import_node_path69 = __toESM(require("path"), 1);
70800
70875
  function canReadSearchHit(ctx, file) {
70801
70876
  if (!ctx || ctx.principal.kind === "owner") return true;
70802
70877
  return canAccessPersona(ctx.grants, file.ownerPersonaId, "read") && file.creatorPrincipalId === ctx.principal.id;
@@ -71077,7 +71152,7 @@ ${attribution}` } : args;
71077
71152
  `principal guest:${ctx.principal.id} cannot fork tool session ${args.toolSessionId}`
71078
71153
  );
71079
71154
  }
71080
- if (source?.tool === "codex" && args.targetCwd && import_node_path68.default.resolve(args.targetCwd) !== import_node_path68.default.resolve(source.cwd)) {
71155
+ if (source?.tool === "codex" && args.targetCwd && import_node_path69.default.resolve(args.targetCwd) !== import_node_path69.default.resolve(source.cwd)) {
71081
71156
  throw new ClawdError(ERROR_CODES.FORBIDDEN, "fork: guest targetCwd must match source cwd");
71082
71157
  }
71083
71158
  }
@@ -71354,7 +71429,7 @@ function buildPermissionHandlers(deps) {
71354
71429
  }
71355
71430
 
71356
71431
  // src/handlers/history.ts
71357
- var path83 = __toESM(require("path"), 1);
71432
+ var path84 = __toESM(require("path"), 1);
71358
71433
  init_protocol();
71359
71434
 
71360
71435
  // src/session/recent-dirs.ts
@@ -71372,7 +71447,7 @@ function listRecentDirs(store, limit = 50) {
71372
71447
  }
71373
71448
 
71374
71449
  // src/permission/persona-paths.ts
71375
- var path82 = __toESM(require("path"), 1);
71450
+ var path83 = __toESM(require("path"), 1);
71376
71451
  function getAllowedPersonaIds(grants, action) {
71377
71452
  const ids = /* @__PURE__ */ new Set();
71378
71453
  for (const g3 of grants) {
@@ -71385,42 +71460,42 @@ function getAllowedPersonaIds(grants, action) {
71385
71460
  return ids;
71386
71461
  }
71387
71462
  function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
71388
- const target = path82.resolve(absPath);
71463
+ const target = path83.resolve(absPath);
71389
71464
  if (userWorkDir) {
71390
- const u2 = path82.resolve(userWorkDir);
71391
- const usep = u2.endsWith(path82.sep) ? "" : path82.sep;
71465
+ const u2 = path83.resolve(userWorkDir);
71466
+ const usep = u2.endsWith(path83.sep) ? "" : path83.sep;
71392
71467
  if (target === u2 || target.startsWith(u2 + usep)) return true;
71393
71468
  }
71394
- const root = path82.resolve(personaRoot);
71395
- const sep4 = root.endsWith(path82.sep) ? "" : path82.sep;
71469
+ const root = path83.resolve(personaRoot);
71470
+ const sep4 = root.endsWith(path83.sep) ? "" : path83.sep;
71396
71471
  if (!target.startsWith(root + sep4)) return false;
71397
- const rel = path82.relative(root, target);
71472
+ const rel = path83.relative(root, target);
71398
71473
  if (!rel || rel.startsWith("..")) return false;
71399
- const personaId2 = rel.split(path82.sep)[0];
71474
+ const personaId2 = rel.split(path83.sep)[0];
71400
71475
  if (!personaId2) return false;
71401
71476
  const allowed = getAllowedPersonaIds(grants, action);
71402
71477
  if (allowed === "*") return true;
71403
71478
  return allowed.has(personaId2);
71404
71479
  }
71405
71480
  function personaIdFromPath(absPath, personaRoot) {
71406
- const root = path82.resolve(personaRoot);
71407
- const target = path82.resolve(absPath);
71408
- const sep4 = root.endsWith(path82.sep) ? "" : path82.sep;
71481
+ const root = path83.resolve(personaRoot);
71482
+ const target = path83.resolve(absPath);
71483
+ const sep4 = root.endsWith(path83.sep) ? "" : path83.sep;
71409
71484
  if (!target.startsWith(root + sep4)) return null;
71410
- const rel = path82.relative(root, target);
71485
+ const rel = path83.relative(root, target);
71411
71486
  if (!rel || rel.startsWith("..")) return null;
71412
- const id = rel.split(path82.sep)[0];
71487
+ const id = rel.split(path83.sep)[0];
71413
71488
  return id || null;
71414
71489
  }
71415
71490
  function isPathWithin(dir, absPath) {
71416
- const d2 = path82.resolve(dir);
71417
- const t2 = path82.resolve(absPath);
71418
- const sep4 = d2.endsWith(path82.sep) ? "" : path82.sep;
71491
+ const d2 = path83.resolve(dir);
71492
+ const t2 = path83.resolve(absPath);
71493
+ const sep4 = d2.endsWith(path83.sep) ? "" : path83.sep;
71419
71494
  return t2 === d2 || t2.startsWith(d2 + sep4);
71420
71495
  }
71421
71496
  function isPathInGuestBoundary(personaRoot, personaId2, userWorkDir, absPath) {
71422
71497
  if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
71423
- return personaIdFromPath(path82.resolve(absPath), personaRoot) === personaId2;
71498
+ return personaIdFromPath(path83.resolve(absPath), personaRoot) === personaId2;
71424
71499
  }
71425
71500
 
71426
71501
  // src/handlers/history.ts
@@ -71474,7 +71549,7 @@ function buildHistoryHandlers(deps) {
71474
71549
  if (!pid) return false;
71475
71550
  return isGuestPathAllowed(
71476
71551
  ctx.grants,
71477
- path83.join(personaRoot, pid),
71552
+ path84.join(personaRoot, pid),
71478
71553
  personaRoot,
71479
71554
  "read",
71480
71555
  userWorkDir
@@ -71486,7 +71561,7 @@ function buildHistoryHandlers(deps) {
71486
71561
  };
71487
71562
  const list = async (frame, _client, ctx) => {
71488
71563
  const args = HistoryListArgs.parse(frame);
71489
- assertGuestPath(ctx, path83.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
71564
+ assertGuestPath(ctx, path84.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
71490
71565
  const sessions = await history.listSessions(args);
71491
71566
  return { response: { type: "history:list", sessions } };
71492
71567
  };
@@ -71534,14 +71609,14 @@ function buildHistoryHandlers(deps) {
71534
71609
  };
71535
71610
  const subagents = async (frame, _client, ctx) => {
71536
71611
  const args = HistorySubagentsArgs.parse(frame);
71537
- assertGuestPath(ctx, path83.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
71612
+ assertGuestPath(ctx, path84.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
71538
71613
  assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagents");
71539
71614
  const subs = await historyReaderForToolSession(args.toolSessionId).listSubagents(args);
71540
71615
  return { response: { type: "history:subagents", subagents: subs } };
71541
71616
  };
71542
71617
  const subagentRead = async (frame, _client, ctx) => {
71543
71618
  const args = HistorySubagentReadArgs.parse(frame);
71544
- assertGuestPath(ctx, path83.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
71619
+ assertGuestPath(ctx, path84.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
71545
71620
  assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagent-read");
71546
71621
  const res = await historyReaderForToolSession(args.toolSessionId).readSubagent(args);
71547
71622
  return { response: { type: "history:subagent-read", ...res } };
@@ -71551,7 +71626,7 @@ function buildHistoryHandlers(deps) {
71551
71626
  if (ctx?.principal.kind === "guest" && personaRoot) {
71552
71627
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
71553
71628
  const filtered = dirs.filter(
71554
- (d2) => isGuestPathAllowed(ctx.grants, path83.resolve(d2.cwd), personaRoot, "read", userWorkDir)
71629
+ (d2) => isGuestPathAllowed(ctx.grants, path84.resolve(d2.cwd), personaRoot, "read", userWorkDir)
71555
71630
  );
71556
71631
  return { response: { type: "history:recentDirs", dirs: filtered } };
71557
71632
  }
@@ -71568,17 +71643,17 @@ function buildHistoryHandlers(deps) {
71568
71643
  }
71569
71644
 
71570
71645
  // src/handlers/projects.ts
71571
- var fs79 = __toESM(require("fs"), 1);
71572
- var os26 = __toESM(require("os"), 1);
71573
- var path84 = __toESM(require("path"), 1);
71646
+ var fs80 = __toESM(require("fs"), 1);
71647
+ var os27 = __toESM(require("os"), 1);
71648
+ var path85 = __toESM(require("path"), 1);
71574
71649
  var import_node_child_process19 = require("child_process");
71575
71650
  init_protocol();
71576
- var DEFAULT_PROJECTS_ROOT = path84.join(os26.homedir(), "Documents", "ChatGPT");
71651
+ var DEFAULT_PROJECTS_ROOT = path85.join(os27.homedir(), "Documents", "ChatGPT");
71577
71652
  function allocateDir(root, name) {
71578
- let candidate = path84.join(root, name);
71653
+ let candidate = path85.join(root, name);
71579
71654
  let n2 = 2;
71580
- while (fs79.existsSync(candidate)) {
71581
- candidate = path84.join(root, `${name} ${n2}`);
71655
+ while (fs80.existsSync(candidate)) {
71656
+ candidate = path85.join(root, `${name} ${n2}`);
71582
71657
  n2 += 1;
71583
71658
  }
71584
71659
  return candidate;
@@ -71606,7 +71681,7 @@ function buildProjectHandlers(deps) {
71606
71681
  throw new ClawdError(ERROR_CODES.INVALID_CWD, "project:reveal \u4EC5\u652F\u6301 macOS");
71607
71682
  }
71608
71683
  try {
71609
- if (!fs79.statSync(args.path).isDirectory()) throw new Error("not dir");
71684
+ if (!fs80.statSync(args.path).isDirectory()) throw new Error("not dir");
71610
71685
  } catch {
71611
71686
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
71612
71687
  }
@@ -71622,7 +71697,7 @@ function buildProjectHandlers(deps) {
71622
71697
  let target;
71623
71698
  if (args.path) {
71624
71699
  try {
71625
- if (!fs79.statSync(args.path).isDirectory()) throw new Error("not dir");
71700
+ if (!fs80.statSync(args.path).isDirectory()) throw new Error("not dir");
71626
71701
  } catch {
71627
71702
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
71628
71703
  }
@@ -71630,15 +71705,15 @@ function buildProjectHandlers(deps) {
71630
71705
  } else {
71631
71706
  const name = args.name;
71632
71707
  try {
71633
- fs79.mkdirSync(root, { recursive: true });
71708
+ fs80.mkdirSync(root, { recursive: true });
71634
71709
  target = allocateDir(root, name);
71635
- fs79.mkdirSync(target);
71710
+ fs80.mkdirSync(target);
71636
71711
  } catch (err) {
71637
71712
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `\u521B\u5EFA\u9879\u76EE\u76EE\u5F55\u5931\u8D25: ${String(err)}`);
71638
71713
  }
71639
71714
  const git2 = (0, import_node_child_process19.spawnSync)("git", ["init"], { cwd: target, stdio: "ignore" });
71640
71715
  if (git2.status !== 0) {
71641
- fs79.rmSync(target, { recursive: true, force: true });
71716
+ fs80.rmSync(target, { recursive: true, force: true });
71642
71717
  throw new ClawdError(
71643
71718
  ERROR_CODES.INVALID_CWD,
71644
71719
  `git init \u5931\u8D25\uFF08${git2.error ? String(git2.error) : `exit ${git2.status}`}\uFF09: ${target}`
@@ -71663,9 +71738,9 @@ function buildProjectHandlers(deps) {
71663
71738
  }
71664
71739
 
71665
71740
  // src/handlers/workspace.ts
71666
- var path85 = __toESM(require("path"), 1);
71741
+ var path86 = __toESM(require("path"), 1);
71667
71742
  init_protocol();
71668
- var os27 = __toESM(require("os"), 1);
71743
+ var os28 = __toESM(require("os"), 1);
71669
71744
  init_protocol();
71670
71745
  init_protocol();
71671
71746
  function buildEnabledPluginNames(personaManager, personaId2) {
@@ -71705,23 +71780,23 @@ function buildWorkspaceHandlers(deps) {
71705
71780
  const list = async (frame, _client, ctx) => {
71706
71781
  const args = WorkspaceListArgs.parse(frame);
71707
71782
  const isGuest = ctx?.principal.kind === "guest";
71708
- const fallbackCwd = isGuest && personaRoot ? personaRoot : os27.homedir();
71709
- const resolvedCwd = path85.resolve(args.cwd ?? fallbackCwd);
71710
- const target = args.path ? path85.resolve(resolvedCwd, args.path) : resolvedCwd;
71783
+ const fallbackCwd = isGuest && personaRoot ? personaRoot : os28.homedir();
71784
+ const resolvedCwd = path86.resolve(args.cwd ?? fallbackCwd);
71785
+ const target = args.path ? path86.resolve(resolvedCwd, args.path) : resolvedCwd;
71711
71786
  assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
71712
71787
  const res = workspace.list({ ...args, cwd: resolvedCwd });
71713
71788
  return { response: { type: "workspace:list", ...res } };
71714
71789
  };
71715
71790
  const read = async (frame, _client, ctx) => {
71716
71791
  const args = WorkspaceReadArgs.parse(frame);
71717
- const target = path85.isAbsolute(args.path) ? path85.resolve(args.path) : path85.resolve(args.cwd, args.path);
71792
+ const target = path86.isAbsolute(args.path) ? path86.resolve(args.path) : path86.resolve(args.cwd, args.path);
71718
71793
  assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
71719
71794
  const res = workspace.read(args);
71720
71795
  return { response: { type: "workspace:read", ...res } };
71721
71796
  };
71722
71797
  const skillsList = async (frame, _client, ctx) => {
71723
71798
  const args = SkillsListArgs.parse(frame);
71724
- const cwdAbs = path85.resolve(args.cwd);
71799
+ const cwdAbs = path86.resolve(args.cwd);
71725
71800
  assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
71726
71801
  const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
71727
71802
  if (ctx?.principal.kind === "guest" && personaRoot) {
@@ -71733,7 +71808,7 @@ function buildWorkspaceHandlers(deps) {
71733
71808
  };
71734
71809
  const agentsList = async (frame, _client, ctx) => {
71735
71810
  const args = AgentsListArgs.parse(frame);
71736
- const cwdAbs = path85.resolve(args.cwd);
71811
+ const cwdAbs = path86.resolve(args.cwd);
71737
71812
  assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
71738
71813
  if (isCodexFamily(args.tool) || isPiFamily(args.tool)) {
71739
71814
  return { response: { type: "agents:list", agents: [] } };
@@ -71755,20 +71830,20 @@ function buildWorkspaceHandlers(deps) {
71755
71830
  }
71756
71831
 
71757
71832
  // src/handlers/git.ts
71758
- var path87 = __toESM(require("path"), 1);
71833
+ var path88 = __toESM(require("path"), 1);
71759
71834
  init_protocol();
71760
71835
  init_protocol();
71761
71836
 
71762
71837
  // src/workspace/git.ts
71763
71838
  var import_node_child_process20 = require("child_process");
71764
- var import_node_fs62 = __toESM(require("fs"), 1);
71765
- var import_node_path69 = __toESM(require("path"), 1);
71839
+ var import_node_fs63 = __toESM(require("fs"), 1);
71840
+ var import_node_path70 = __toESM(require("path"), 1);
71766
71841
  var import_node_util2 = require("util");
71767
71842
  var pexec = (0, import_node_util2.promisify)(import_node_child_process20.execFile);
71768
71843
  function normalizePath(p3) {
71769
- const resolved = import_node_path69.default.resolve(p3);
71844
+ const resolved = import_node_path70.default.resolve(p3);
71770
71845
  try {
71771
- return import_node_fs62.default.realpathSync(resolved);
71846
+ return import_node_fs63.default.realpathSync(resolved);
71772
71847
  } catch {
71773
71848
  return resolved;
71774
71849
  }
@@ -71842,7 +71917,7 @@ async function listGitBranches(cwd) {
71842
71917
  function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
71843
71918
  if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
71844
71919
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
71845
- if (!isGuestPathAllowed(ctx.grants, path87.resolve(cwd), personaRoot, "read", userWorkDir)) {
71920
+ if (!isGuestPathAllowed(ctx.grants, path88.resolve(cwd), personaRoot, "read", userWorkDir)) {
71846
71921
  throw new ClawdError(
71847
71922
  ERROR_CODES.UNAUTHORIZED,
71848
71923
  `guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
@@ -72099,12 +72174,12 @@ async function queryCodexAccount(deps = {}) {
72099
72174
  }
72100
72175
 
72101
72176
  // src/tools/pi-account.ts
72102
- var import_node_fs63 = __toESM(require("fs"), 1);
72103
- var import_node_path70 = __toESM(require("path"), 1);
72177
+ var import_node_fs64 = __toESM(require("fs"), 1);
72178
+ var import_node_path71 = __toESM(require("path"), 1);
72104
72179
  function readPiCredentials(agentDir) {
72105
72180
  let raw;
72106
72181
  try {
72107
- raw = JSON.parse(import_node_fs63.default.readFileSync(import_node_path70.default.join(agentDir, "auth.json"), "utf8"));
72182
+ raw = JSON.parse(import_node_fs64.default.readFileSync(import_node_path71.default.join(agentDir, "auth.json"), "utf8"));
72108
72183
  } catch {
72109
72184
  return {};
72110
72185
  }
@@ -72187,81 +72262,6 @@ function buildEngineHandlers(deps, overrides = {}) {
72187
72262
  return { "engine:status": status, "engine:connectPool": connectPool };
72188
72263
  }
72189
72264
 
72190
- // src/tools/subscription-channels-apply.ts
72191
- var import_node_fs64 = __toESM(require("fs"), 1);
72192
- var import_node_os25 = __toESM(require("os"), 1);
72193
- var import_node_path71 = __toESM(require("path"), 1);
72194
- var TABLE_HEADER = /^\s*\[\[?\s*([A-Za-z0-9_.-]+)\s*\]\]?\s*(?:#.*)?$/;
72195
- var KEY_LINE = /^\s*([A-Za-z0-9_.-]+)\s*=/;
72196
- function stripCodexProvider(text) {
72197
- const out = [];
72198
- let inProviderSection = false;
72199
- for (const line of text.split("\n")) {
72200
- const headerMatch = TABLE_HEADER.exec(line);
72201
- if (headerMatch) {
72202
- const section = headerMatch[1].trim();
72203
- inProviderSection = section === "model_providers" || section.startsWith("model_providers.");
72204
- if (inProviderSection) continue;
72205
- out.push(line);
72206
- continue;
72207
- }
72208
- if (inProviderSection) continue;
72209
- const keyMatch = KEY_LINE.exec(line);
72210
- if (keyMatch) {
72211
- const key = keyMatch[1].trim();
72212
- if (key === "model_provider" || key.startsWith("model_providers.")) {
72213
- continue;
72214
- }
72215
- }
72216
- out.push(line);
72217
- }
72218
- return out.join("\n").trim();
72219
- }
72220
- function applyCodexSubscriptionChannel(opts) {
72221
- const codexHome = opts.codexHome || process.env.CODEX_HOME || import_node_path71.default.join(import_node_os25.default.homedir(), ".codex");
72222
- import_node_fs64.default.mkdirSync(codexHome, { recursive: true });
72223
- const configFile = import_node_path71.default.join(codexHome, "config.toml");
72224
- const original = import_node_fs64.default.existsSync(configFile) ? import_node_fs64.default.readFileSync(configFile, "utf8") : "";
72225
- const rest = stripCodexProvider(original);
72226
- let content;
72227
- if (opts.channel) {
72228
- const ch = opts.channel;
72229
- content = [
72230
- 'model_provider = "cliproxyapi"',
72231
- ...rest ? ["", rest] : [],
72232
- "",
72233
- "[model_providers.cliproxyapi]",
72234
- 'name = "cliproxyapi"',
72235
- `base_url = ${JSON.stringify(ch.baseUrl)}`,
72236
- 'wire_api = "responses"',
72237
- `auth = { command = "echo", args = [${JSON.stringify(ch.apiKey)}] }`,
72238
- ""
72239
- ].join("\n");
72240
- } else {
72241
- content = [
72242
- 'model_provider = "openai"',
72243
- ...rest ? ["", rest] : [],
72244
- ""
72245
- ].join("\n");
72246
- }
72247
- const tmpFile = `${configFile}.tmp.${Date.now()}`;
72248
- import_node_fs64.default.writeFileSync(tmpFile, content, { mode: 384 });
72249
- import_node_fs64.default.renameSync(tmpFile, configFile);
72250
- }
72251
- function applyPiSubscriptionChannel(opts) {
72252
- const agentDir = opts.agentDir || process.env.PI_CODING_AGENT_DIR || import_node_path71.default.join(import_node_os25.default.homedir(), ".pi", "agent");
72253
- if (!import_node_fs64.default.existsSync(agentDir)) return false;
72254
- const configFile = import_node_path71.default.join(agentDir, "cliproxyapi.json");
72255
- if (opts.channel) {
72256
- const data = { baseUrl: opts.channel.baseUrl, apiKey: opts.channel.apiKey };
72257
- const tmp = `${configFile}.tmp.${Date.now()}`;
72258
- import_node_fs64.default.writeFileSync(tmp, JSON.stringify(data, null, 2) + "\n", { mode: 384 });
72259
- import_node_fs64.default.renameSync(tmp, configFile);
72260
- return true;
72261
- }
72262
- return false;
72263
- }
72264
-
72265
72265
  // src/handlers/channels.ts
72266
72266
  function buildChannelsHandlers(deps) {
72267
72267
  const get = async () => {
@@ -73264,7 +73264,7 @@ function computeMethodAccess(args) {
73264
73264
  }
73265
73265
 
73266
73266
  // src/version.ts
73267
- var version = "0.2.603".length > 0 ? "0.2.603" : "dev";
73267
+ var version = "0.2.604".length > 0 ? "0.2.604" : "dev";
73268
73268
 
73269
73269
  // src/cli-probe/probe.ts
73270
73270
  var fs83 = __toESM(require("fs"), 1);
@@ -75892,6 +75892,8 @@ async function startDaemon(config) {
75892
75892
  let transport = null;
75893
75893
  const personaStore = new PersonaStore(import_node_path84.default.join(config.dataDir, "personas"));
75894
75894
  const subscriptionChannelStore = new SubscriptionChannelStore({ dataDir: config.dataDir });
75895
+ const activeSubscriptionChannel = subscriptionChannelStore.getActive();
75896
+ if (activeSubscriptionChannel) applyPiSubscriptionChannel({ channel: activeSubscriptionChannel });
75895
75897
  const usersRoot = import_node_path84.default.join(config.dataDir, "users");
75896
75898
  const defaultsRoot = findDefaultsRoot(logger);
75897
75899
  if (defaultsRoot) {