@clawos-dev/clawd 0.2.719 → 0.2.721

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs CHANGED
@@ -8258,7 +8258,7 @@ var init_schemas = __esm({
8258
8258
  id: external_exports.string().min(1),
8259
8259
  label: external_exports.string().min(1),
8260
8260
  description: external_exports.string().optional(),
8261
- contextWindowSize: external_exports.number().int().positive(),
8261
+ contextWindowSize: external_exports.number().int().positive().optional(),
8262
8262
  default: external_exports.boolean().optional(),
8263
8263
  // Per-model efforts override the global effort options; absence uses the tool's global config field.
8264
8264
  efforts: external_exports.array(SelectOptionSchema).optional(),
@@ -16138,7 +16138,7 @@ function asRecord2(v3) {
16138
16138
  }
16139
16139
  function readAuthKey(codexHome) {
16140
16140
  try {
16141
- const raw = JSON.parse(import_node_fs22.default.readFileSync(import_node_path22.default.join(codexHome, "auth.json"), "utf8"));
16141
+ const raw = JSON.parse(import_node_fs11.default.readFileSync(import_node_path10.default.join(codexHome, "auth.json"), "utf8"));
16142
16142
  const key = asRecord2(raw)?.OPENAI_API_KEY;
16143
16143
  return typeof key === "string" && key ? key : void 0;
16144
16144
  } catch {
@@ -16173,7 +16173,7 @@ async function resolveProviderEndpoint(rawConfig, deps = {}) {
16173
16173
  const baseUrl = entry.base_url;
16174
16174
  if (typeof baseUrl !== "string" || !baseUrl) return null;
16175
16175
  const env = deps.env ?? process.env;
16176
- const codexHome = deps.codexHome ?? env.CODEX_HOME ?? import_node_path22.default.join(import_node_os10.default.homedir(), ".codex");
16176
+ const codexHome = deps.codexHome ?? env.CODEX_HOME ?? import_node_path10.default.join(import_node_os7.default.homedir(), ".codex");
16177
16177
  const envKey = typeof entry.env_key === "string" && entry.env_key ? entry.env_key : null;
16178
16178
  const inlineToken = typeof entry.experimental_bearer_token === "string" && entry.experimental_bearer_token ? entry.experimental_bearer_token : void 0;
16179
16179
  const auth = asRecord2(entry.auth);
@@ -16221,14 +16221,14 @@ async function fetchProviderModels(endpoint, deps = {}) {
16221
16221
  clearTimeout(timer);
16222
16222
  }
16223
16223
  }
16224
- var import_node_child_process2, import_node_fs22, import_node_os10, import_node_path22, import_node_util, PROVIDER_FETCH_TIMEOUT_MS, defaultExecFile, AUTH_COMMAND_TIMEOUT_MS;
16224
+ var import_node_child_process2, import_node_fs11, import_node_os7, import_node_path10, import_node_util, PROVIDER_FETCH_TIMEOUT_MS, defaultExecFile, AUTH_COMMAND_TIMEOUT_MS;
16225
16225
  var init_codex_provider_models = __esm({
16226
16226
  "src/tools/codex-provider-models.ts"() {
16227
16227
  "use strict";
16228
16228
  import_node_child_process2 = require("child_process");
16229
- import_node_fs22 = __toESM(require("fs"), 1);
16230
- import_node_os10 = __toESM(require("os"), 1);
16231
- import_node_path22 = __toESM(require("path"), 1);
16229
+ import_node_fs11 = __toESM(require("fs"), 1);
16230
+ import_node_os7 = __toESM(require("os"), 1);
16231
+ import_node_path10 = __toESM(require("path"), 1);
16232
16232
  import_node_util = require("util");
16233
16233
  PROVIDER_FETCH_TIMEOUT_MS = 1e4;
16234
16234
  defaultExecFile = (0, import_node_util.promisify)(import_node_child_process2.execFile);
@@ -16491,17 +16491,17 @@ function stripCodexProvider(text) {
16491
16491
  return out.join("\n").trim();
16492
16492
  }
16493
16493
  function writeFileAtomic(file, data) {
16494
- const target = import_node_fs23.default.existsSync(file) && import_node_fs23.default.lstatSync(file).isSymbolicLink() ? import_node_fs23.default.realpathSync(file) : file;
16494
+ const target = import_node_fs12.default.existsSync(file) && import_node_fs12.default.lstatSync(file).isSymbolicLink() ? import_node_fs12.default.realpathSync(file) : file;
16495
16495
  const tmp = `${target}.tmp.${process.pid}.${Date.now()}`;
16496
- import_node_fs23.default.writeFileSync(tmp, data, { mode: 384 });
16497
- import_node_fs23.default.renameSync(tmp, target);
16496
+ import_node_fs12.default.writeFileSync(tmp, data, { mode: 384 });
16497
+ import_node_fs12.default.renameSync(tmp, target);
16498
16498
  }
16499
16499
  function snapshotFile(file) {
16500
- const original = import_node_fs23.default.existsSync(file) ? import_node_fs23.default.readFileSync(file) : null;
16500
+ const original = import_node_fs12.default.existsSync(file) ? import_node_fs12.default.readFileSync(file) : null;
16501
16501
  return () => {
16502
- const current = import_node_fs23.default.existsSync(file) ? import_node_fs23.default.readFileSync(file) : null;
16502
+ const current = import_node_fs12.default.existsSync(file) ? import_node_fs12.default.readFileSync(file) : null;
16503
16503
  if (original === null) {
16504
- if (current !== null) import_node_fs23.default.rmSync(file, { force: true });
16504
+ if (current !== null) import_node_fs12.default.rmSync(file, { force: true });
16505
16505
  return;
16506
16506
  }
16507
16507
  if (current !== null && current.equals(original)) return;
@@ -16510,9 +16510,9 @@ function snapshotFile(file) {
16510
16510
  }
16511
16511
  function applyCodexSubscriptionChannel(opts) {
16512
16512
  const codexHome = resolveCodexHome2(opts.codexHome);
16513
- import_node_fs23.default.mkdirSync(codexHome, { recursive: true });
16514
- const configFile = import_node_path23.default.join(codexHome, "config.toml");
16515
- const original = import_node_fs23.default.existsSync(configFile) ? import_node_fs23.default.readFileSync(configFile, "utf8") : "";
16513
+ import_node_fs12.default.mkdirSync(codexHome, { recursive: true });
16514
+ const configFile = import_node_path11.default.join(codexHome, "config.toml");
16515
+ const original = import_node_fs12.default.existsSync(configFile) ? import_node_fs12.default.readFileSync(configFile, "utf8") : "";
16516
16516
  const rest = stripCodexProvider(original);
16517
16517
  let content;
16518
16518
  if (opts.channel) {
@@ -16539,8 +16539,8 @@ function applyCodexSubscriptionChannel(opts) {
16539
16539
  }
16540
16540
  function applyPiSubscriptionChannel(opts) {
16541
16541
  const agentDir = resolvePiAgentDir(opts.agentDir);
16542
- if (!import_node_fs23.default.existsSync(agentDir)) return false;
16543
- const configFile = import_node_path23.default.join(agentDir, PI_SUBSCRIPTION_FILE);
16542
+ if (!import_node_fs12.default.existsSync(agentDir)) return false;
16543
+ const configFile = import_node_path11.default.join(agentDir, PI_SUBSCRIPTION_FILE);
16544
16544
  if (opts.channel) {
16545
16545
  const data = { baseUrl: opts.channel.baseUrl, apiKey: opts.channel.apiKey };
16546
16546
  writeFileAtomic(configFile, JSON.stringify(data, null, 2) + "\n");
@@ -16559,16 +16559,16 @@ function claudeSubscriptionEnv(channel) {
16559
16559
  };
16560
16560
  }
16561
16561
  function readSettings(file) {
16562
- if (!import_node_fs23.default.existsSync(file)) return {};
16563
- const value = JSON.parse(import_node_fs23.default.readFileSync(file, "utf8"));
16562
+ if (!import_node_fs12.default.existsSync(file)) return {};
16563
+ const value = JSON.parse(import_node_fs12.default.readFileSync(file, "utf8"));
16564
16564
  if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("Claude settings must be a JSON object");
16565
16565
  return value;
16566
16566
  }
16567
16567
  function applyClaudeSubscriptionChannel(opts) {
16568
16568
  const dir = resolveClaudeConfigDir(opts.configDir);
16569
- const file = import_node_path23.default.join(dir, "settings.json");
16570
- const backupFile = import_node_path23.default.join(dir, CLAUDE_SUBSCRIPTION_BACKUP);
16571
- if (!opts.channel && !import_node_fs23.default.existsSync(backupFile)) return;
16569
+ const file = import_node_path11.default.join(dir, "settings.json");
16570
+ const backupFile = import_node_path11.default.join(dir, CLAUDE_SUBSCRIPTION_BACKUP);
16571
+ if (!opts.channel && !import_node_fs12.default.existsSync(backupFile)) return;
16572
16572
  const settings = readSettings(file);
16573
16573
  if (settings.env !== void 0 && (!settings.env || typeof settings.env !== "object" || Array.isArray(settings.env))) {
16574
16574
  throw new Error("Claude settings.env must be a JSON object");
@@ -16576,10 +16576,10 @@ function applyClaudeSubscriptionChannel(opts) {
16576
16576
  const env = { ...settings.env };
16577
16577
  if (opts.channel) {
16578
16578
  const connection = claudeSubscriptionEnv(opts.channel);
16579
- import_node_fs23.default.mkdirSync(dir, { recursive: true });
16580
- if (!import_node_fs23.default.existsSync(backupFile)) {
16579
+ import_node_fs12.default.mkdirSync(dir, { recursive: true });
16580
+ if (!import_node_fs12.default.existsSync(backupFile)) {
16581
16581
  writeFileAtomic(backupFile, JSON.stringify({
16582
- hadSettings: import_node_fs23.default.existsSync(file),
16582
+ hadSettings: import_node_fs12.default.existsSync(file),
16583
16583
  hadEnv: settings.env !== void 0,
16584
16584
  env: Object.fromEntries(Object.keys(connection).filter((key) => key in env).map((key) => [key, env[key]]))
16585
16585
  }) + "\n");
@@ -16596,24 +16596,24 @@ function applyClaudeSubscriptionChannel(opts) {
16596
16596
  Object.assign(env, backup.env);
16597
16597
  if (Object.keys(env).length || backup.hadEnv) settings.env = env;
16598
16598
  else delete settings.env;
16599
- if (!backup.hadSettings && !Object.keys(settings).length) import_node_fs23.default.rmSync(file, { force: true });
16599
+ if (!backup.hadSettings && !Object.keys(settings).length) import_node_fs12.default.rmSync(file, { force: true });
16600
16600
  else writeFileAtomic(file, JSON.stringify(settings, null, 2) + "\n");
16601
- import_node_fs23.default.unlinkSync(backupFile);
16601
+ import_node_fs12.default.unlinkSync(backupFile);
16602
16602
  }
16603
- var import_node_fs23, import_node_os11, import_node_path23, PROVIDER_ID, isOwnProvider, resolveCodexHome2, resolvePiAgentDir, PI_SUBSCRIPTION_FILE, resolveClaudeConfigDir, CLAUDE_SUBSCRIPTION_BACKUP, CLAUDE_CONNECTION_KEYS;
16603
+ var import_node_fs12, import_node_os8, import_node_path11, PROVIDER_ID, isOwnProvider, resolveCodexHome2, resolvePiAgentDir, PI_SUBSCRIPTION_FILE, resolveClaudeConfigDir, CLAUDE_SUBSCRIPTION_BACKUP, CLAUDE_CONNECTION_KEYS;
16604
16604
  var init_subscription_channels_apply = __esm({
16605
16605
  "src/tools/subscription-channels-apply.ts"() {
16606
16606
  "use strict";
16607
- import_node_fs23 = __toESM(require("fs"), 1);
16608
- import_node_os11 = __toESM(require("os"), 1);
16609
- import_node_path23 = __toESM(require("path"), 1);
16607
+ import_node_fs12 = __toESM(require("fs"), 1);
16608
+ import_node_os8 = __toESM(require("os"), 1);
16609
+ import_node_path11 = __toESM(require("path"), 1);
16610
16610
  init_codex_config_toml();
16611
16611
  PROVIDER_ID = "cliproxyapi";
16612
16612
  isOwnProvider = (path113) => path113[0] === "model_providers" && path113[1] === PROVIDER_ID;
16613
- resolveCodexHome2 = (codexHome) => codexHome || process.env.CODEX_HOME || import_node_path23.default.join(import_node_os11.default.homedir(), ".codex");
16614
- resolvePiAgentDir = (agentDir) => agentDir || process.env.PI_CODING_AGENT_DIR || import_node_path23.default.join(import_node_os11.default.homedir(), ".pi", "agent");
16613
+ resolveCodexHome2 = (codexHome) => codexHome || process.env.CODEX_HOME || import_node_path11.default.join(import_node_os8.default.homedir(), ".codex");
16614
+ resolvePiAgentDir = (agentDir) => agentDir || process.env.PI_CODING_AGENT_DIR || import_node_path11.default.join(import_node_os8.default.homedir(), ".pi", "agent");
16615
16615
  PI_SUBSCRIPTION_FILE = "cliproxyapi.json";
16616
- resolveClaudeConfigDir = (configDir) => configDir || process.env.CLAUDE_CONFIG_DIR || import_node_path23.default.join(import_node_os11.default.homedir(), ".claude");
16616
+ resolveClaudeConfigDir = (configDir) => configDir || process.env.CLAUDE_CONFIG_DIR || import_node_path11.default.join(import_node_os8.default.homedir(), ".claude");
16617
16617
  CLAUDE_SUBSCRIPTION_BACKUP = "clawd-subscription-backup.json";
16618
16618
  CLAUDE_CONNECTION_KEYS = ["ANTHROPIC_BASE_URL", "ANTHROPIC_AUTH_TOKEN", "ANTHROPIC_API_KEY", "CLAUDE_CODE_USE_BEDROCK", "CLAUDE_CODE_USE_VERTEX", "CLAUDE_CODE_USE_FOUNDRY"];
16619
16619
  }
@@ -16623,13 +16623,13 @@ var init_subscription_channels_apply = __esm({
16623
16623
  function probeViaWhich() {
16624
16624
  try {
16625
16625
  const out = (0, import_node_child_process4.execFileSync)("which", ["claude"], { encoding: "utf8" }).trim();
16626
- if (out && import_node_fs24.default.existsSync(out)) return out;
16626
+ if (out && import_node_fs13.default.existsSync(out)) return out;
16627
16627
  } catch {
16628
16628
  }
16629
16629
  return null;
16630
16630
  }
16631
16631
  async function probeClaude(env = process.env) {
16632
- if (env.CLAUDE_BIN && import_node_fs24.default.existsSync(env.CLAUDE_BIN)) {
16632
+ if (env.CLAUDE_BIN && import_node_fs13.default.existsSync(env.CLAUDE_BIN)) {
16633
16633
  return { available: true, path: env.CLAUDE_BIN };
16634
16634
  }
16635
16635
  const w3 = probeViaWhich();
@@ -17095,27 +17095,13 @@ function encodeClaudeStdin(text) {
17095
17095
  };
17096
17096
  return JSON.stringify(frame) + "\n";
17097
17097
  }
17098
- function resolveClaudeContextWindow(modelId) {
17099
- if (!modelId) return void 0;
17100
- const models = CLAUDE_CAPABILITIES.models;
17101
- const exact = models.find((m3) => m3.id === modelId);
17102
- if (exact) return exact.contextWindowSize;
17103
- const lower = modelId.toLowerCase();
17104
- const contains = models.find((m3) => m3.id && lower.includes(m3.id.toLowerCase()));
17105
- if (contains) {
17106
- if (contains.id === "opus" && /opus-4-[67]/i.test(modelId)) return 1e6;
17107
- return contains.contextWindowSize;
17108
- }
17109
- if (/\[1m\]/i.test(modelId)) return 1e6;
17110
- return void 0;
17111
- }
17112
- var import_node_child_process3, import_node_child_process4, import_node_fs24, ATTACHMENT_SILENT_SUBTYPES2, unknownTypeHandler, ATTACHMENT_RE, IMAGE_EXT_MIME, CLAUDE_MODEL_IDS, CLAUDE_MODELS, _assertModelIdsAligned, CLAUDE_PERMISSION_MODES, CLAUDE_CAPABILITIES, ClaudeAdapter;
17098
+ var import_node_child_process3, import_node_child_process4, import_node_fs13, ATTACHMENT_SILENT_SUBTYPES2, unknownTypeHandler, ATTACHMENT_RE, IMAGE_EXT_MIME, CLAUDE_MODEL_IDS, CLAUDE_MODELS, _assertModelIdsAligned, CLAUDE_PERMISSION_MODES, CLAUDE_CAPABILITIES, ClaudeAdapter;
17113
17099
  var init_claude = __esm({
17114
17100
  "src/tools/claude.ts"() {
17115
17101
  "use strict";
17116
17102
  import_node_child_process3 = require("child_process");
17117
17103
  import_node_child_process4 = require("child_process");
17118
- import_node_fs24 = __toESM(require("fs"), 1);
17104
+ import_node_fs13 = __toESM(require("fs"), 1);
17119
17105
  init_protocol();
17120
17106
  init_codex_provider_models();
17121
17107
  init_subscription_channels_apply();
@@ -17139,10 +17125,10 @@ var init_claude = __esm({
17139
17125
  };
17140
17126
  CLAUDE_MODEL_IDS = ["opus", "fable", "sonnet", "haiku"];
17141
17127
  CLAUDE_MODELS = [
17142
- { id: "opus", label: "Opus", description: "Most capable", contextWindowSize: 1e6, default: true },
17143
- { id: "fable", label: "Fable", contextWindowSize: 1e6 },
17144
- { id: "sonnet", label: "Sonnet", description: "Fast, balanced", contextWindowSize: 1e6 },
17145
- { id: "haiku", label: "Haiku", description: "Fastest, lightest", contextWindowSize: 1e6 }
17128
+ { id: "opus", label: "Opus", description: "Most capable", default: true },
17129
+ { id: "fable", label: "Fable" },
17130
+ { id: "sonnet", label: "Sonnet", description: "Fast, balanced" },
17131
+ { id: "haiku", label: "Haiku", description: "Fastest, lightest" }
17146
17132
  ];
17147
17133
  _assertModelIdsAligned = CLAUDE_MODELS.map((m3) => m3.id);
17148
17134
  CLAUDE_PERMISSION_MODES = [
@@ -17239,7 +17225,7 @@ var init_claude = __esm({
17239
17225
  if (known.has(model.id)) continue;
17240
17226
  known.add(model.id);
17241
17227
  const native = CLAUDE_MODELS.find((entry) => entry.id === model.id);
17242
- merged.push(native ?? { id: model.id, label: model.id, contextWindowSize: resolveClaudeContextWindow(model.id) ?? 2e5 });
17228
+ merged.push(native ?? { id: model.id, label: model.id });
17243
17229
  }
17244
17230
  merged.sort((a2, b3) => a2.id.localeCompare(b3.id));
17245
17231
  return {
@@ -17253,14 +17239,14 @@ var init_claude = __esm({
17253
17239
  const channel = this.getSubscriptionChannel?.();
17254
17240
  if (!channel) return buildSpawnEnv(ctx.env);
17255
17241
  const env = { ...ctx.env, ...claudeSubscriptionEnv(channel) };
17256
- if (ctx.model && !CLAUDE_MODEL_IDS.includes(ctx.model)) {
17242
+ if (ctx.model && !CLAUDE_MODEL_IDS.includes(ctx.model.replace(/\[1m\]$/, ""))) {
17257
17243
  for (const alias of CLAUDE_MODEL_IDS) env["ANTHROPIC_DEFAULT_" + alias.toUpperCase() + "_MODEL"] = ctx.model;
17258
17244
  env.CLAUDE_CODE_SUBAGENT_MODEL = ctx.model;
17259
17245
  }
17260
17246
  return buildSpawnEnv(env);
17261
17247
  }
17262
- resolveContextWindow(modelId) {
17263
- return resolveClaudeContextWindow(modelId);
17248
+ resolveContextWindow(_modelId) {
17249
+ return void 0;
17264
17250
  }
17265
17251
  spawn(ctx) {
17266
17252
  const args = buildSpawnArgs(ctx);
@@ -46853,7 +46839,7 @@ function requireEnvironmentIdentity(stores, environment) {
46853
46839
  var import_node_path90 = __toESM(require("path"), 1);
46854
46840
  var import_node_fs69 = __toESM(require("fs"), 1);
46855
46841
  var import_node_os33 = __toESM(require("os"), 1);
46856
- var import_node_crypto33 = require("crypto");
46842
+ var import_node_crypto34 = require("crypto");
46857
46843
  var import_node_url6 = require("url");
46858
46844
 
46859
46845
  // src/logger.ts
@@ -47509,10 +47495,10 @@ var SessionStoreFactory = class {
47509
47495
  };
47510
47496
 
47511
47497
  // src/session/manager.ts
47512
- var import_node_fs13 = __toESM(require("fs"), 1);
47513
- var import_node_path14 = __toESM(require("path"), 1);
47514
- var import_node_os8 = __toESM(require("os"), 1);
47515
- var import_node_crypto5 = require("crypto");
47498
+ var import_node_fs16 = __toESM(require("fs"), 1);
47499
+ var import_node_path16 = __toESM(require("path"), 1);
47500
+ var import_node_os10 = __toESM(require("os"), 1);
47501
+ var import_node_crypto6 = require("crypto");
47516
47502
  init_protocol();
47517
47503
 
47518
47504
  // src/tools/guest-settings.ts
@@ -47770,9 +47756,9 @@ function extractLarkReplyText(events) {
47770
47756
  }
47771
47757
 
47772
47758
  // src/session/runner.ts
47773
- var import_node_os7 = __toESM(require("os"), 1);
47774
- var import_node_path13 = __toESM(require("path"), 1);
47775
- var import_node_crypto4 = require("crypto");
47759
+ var import_node_os9 = __toESM(require("os"), 1);
47760
+ var import_node_path15 = __toESM(require("path"), 1);
47761
+ var import_node_crypto5 = require("crypto");
47776
47762
 
47777
47763
  // src/session/reducer.ts
47778
47764
  init_protocol();
@@ -49058,19 +49044,54 @@ init_permission_stdio();
49058
49044
  init_protocol();
49059
49045
  init_claude_history();
49060
49046
 
49047
+ // src/tools/claude-session-driver.ts
49048
+ var import_node_crypto4 = require("crypto");
49049
+ init_claude();
49050
+
49051
+ // src/tools/first-byte.ts
49052
+ var VISIBLE = /* @__PURE__ */ new Set(["thinking", "tool_call", "text"]);
49053
+ function createFirstByteClock(now = Date.now) {
49054
+ let at3 = null;
49055
+ return {
49056
+ reset() {
49057
+ at3 = null;
49058
+ },
49059
+ see(events) {
49060
+ if (at3 === null && events.some((e) => VISIBLE.has(e.kind))) at3 = now();
49061
+ },
49062
+ afterFirstByteMs() {
49063
+ return at3 === null ? void 0 : Math.max(0, Math.round(now() - at3));
49064
+ }
49065
+ };
49066
+ }
49067
+
49068
+ // src/tools/claude-session-driver.ts
49069
+ function claudeContextUsagePatch(raw) {
49070
+ if (!raw || typeof raw !== "object") return null;
49071
+ const usage = raw;
49072
+ const total = usage.totalTokens;
49073
+ const window2 = usage.rawMaxTokens;
49074
+ if (typeof total !== "number" || !Number.isSafeInteger(total) || total < 0 || typeof window2 !== "number" || !Number.isSafeInteger(window2) || window2 <= 0) return null;
49075
+ return {
49076
+ ...typeof usage.model === "string" && usage.model ? { resolvedModel: usage.model } : {},
49077
+ contextUsage: { inputTokens: total, outputTokens: 0 },
49078
+ contextWindowSize: window2
49079
+ };
49080
+ }
49081
+
49061
49082
  // src/tools/spawn-error.ts
49062
- var import_node_path10 = __toESM(require("path"), 1);
49083
+ var import_node_path12 = __toESM(require("path"), 1);
49063
49084
  function describeSpawnError(err, fallbackBin, cwd, pathEnv = process.env.PATH) {
49064
49085
  const message = err instanceof Error ? err.message : String(err);
49065
49086
  const e = err;
49066
49087
  if (e?.code !== "ENOENT") return message;
49067
49088
  const bin = typeof e.path === "string" && e.path ? e.path : fallbackBin;
49068
- return `\u8D77\u4E0D\u4E86 ${bin}\uFF1APATH \u91CC\u6CA1\u6709\u5B83\uFF0C\u6216\u5DE5\u4F5C\u76EE\u5F55\u4E0D\u5B58\u5728\u3002\u5DE5\u4F5C\u76EE\u5F55\uFF1A${cwd || "(\u672A\u77E5)"}\uFF5Cclawd \u770B\u5230\u7684 PATH\uFF1A${pathEnv || "(\u7A7A)"}` + (import_node_path10.default.basename(bin) === "codex" || fallbackBin === process.env.CODEX_BIN ? `\u3002${CODEX_INSTALL_HELP}` : "");
49089
+ return `\u8D77\u4E0D\u4E86 ${bin}\uFF1APATH \u91CC\u6CA1\u6709\u5B83\uFF0C\u6216\u5DE5\u4F5C\u76EE\u5F55\u4E0D\u5B58\u5728\u3002\u5DE5\u4F5C\u76EE\u5F55\uFF1A${cwd || "(\u672A\u77E5)"}\uFF5Cclawd \u770B\u5230\u7684 PATH\uFF1A${pathEnv || "(\u7A7A)"}` + (import_node_path12.default.basename(bin) === "codex" || fallbackBin === process.env.CODEX_BIN ? `\u3002${CODEX_INSTALL_HELP}` : "");
49069
49090
  }
49070
49091
 
49071
49092
  // src/persona/mcp-secret-render.ts
49072
- var import_node_fs11 = __toESM(require("fs"), 1);
49073
- var import_node_path11 = __toESM(require("path"), 1);
49093
+ var import_node_fs14 = __toESM(require("fs"), 1);
49094
+ var import_node_path13 = __toESM(require("path"), 1);
49074
49095
  var PLACEHOLDER = /\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g;
49075
49096
  var PERSONA_SECRET_MCP_ID_PREFIX = "persona-secrets:";
49076
49097
  var PERSONA_DIR_PLACEHOLDER = "${CLAWD_PERSONA_DIR}";
@@ -49081,10 +49102,10 @@ function renderPersonaDir(v3, personaDir) {
49081
49102
  return v3.split(PERSONA_DIR_PLACEHOLDER).join(personaDir);
49082
49103
  }
49083
49104
  function renderPersonaMcpSecrets(args) {
49084
- const src = import_node_path11.default.join(args.personaDir, ".mcp.json");
49105
+ const src = import_node_path13.default.join(args.personaDir, ".mcp.json");
49085
49106
  let parsed;
49086
49107
  try {
49087
- parsed = JSON.parse(import_node_fs11.default.readFileSync(src, "utf8"));
49108
+ parsed = JSON.parse(import_node_fs14.default.readFileSync(src, "utf8"));
49088
49109
  } catch (e) {
49089
49110
  const code = e.code;
49090
49111
  if (code !== "ENOENT") {
@@ -49137,15 +49158,15 @@ function renderPersonaMcpSecrets(args) {
49137
49158
  vars: [...missing].sort()
49138
49159
  });
49139
49160
  }
49140
- const outPath = import_node_path11.default.join(args.outDir, `${safeFileName(args.personaId)}.mcp.json`);
49141
- import_node_fs11.default.mkdirSync(args.outDir, { recursive: true, mode: 448 });
49161
+ const outPath = import_node_path13.default.join(args.outDir, `${safeFileName(args.personaId)}.mcp.json`);
49162
+ import_node_fs14.default.mkdirSync(args.outDir, { recursive: true, mode: 448 });
49142
49163
  const content = {
49143
49164
  _comment: "daemon \u6BCF\u6B21 spawn \u73B0\u6E32\uFF1B\u6765\u6E90\u662F persona \u76EE\u5F55\u7684 .mcp.json\uFF08\u53EA\u6709\u58F0\u660E\uFF09+ \u51ED\u636E\u8868\uFF08\u53EA\u6709\u503C\uFF09+ persona \u76EE\u5F55\u8DEF\u5F84\uFF08args \u91CC\u7684 ${CLAWD_PERSONA_DIR}\uFF09\u3002\u540C\u540D server \u538B\u8FC7 persona \u76EE\u5F55\u90A3\u4EFD\uFF0C\u503C\u56E0\u6B64\u4E0D\u843D persona \u76EE\u5F55\u3001\u4E0D\u8FDB agent \u4E3B\u8FDB\u7A0B env\u3002\u624B\u6539\u65E0\u6548\u3002",
49144
49165
  mcpServers: rendered
49145
49166
  };
49146
49167
  const tmp = `${outPath}.tmp-${process.pid}-${Date.now()}`;
49147
- import_node_fs11.default.writeFileSync(tmp, JSON.stringify(content, null, 2), { encoding: "utf8", mode: 384 });
49148
- import_node_fs11.default.renameSync(tmp, outPath);
49168
+ import_node_fs14.default.writeFileSync(tmp, JSON.stringify(content, null, 2), { encoding: "utf8", mode: 384 });
49169
+ import_node_fs14.default.renameSync(tmp, outPath);
49149
49170
  return {
49150
49171
  id: `${PERSONA_SECRET_MCP_ID_PREFIX}${args.personaId}`,
49151
49172
  path: outPath
@@ -49159,8 +49180,8 @@ function attachPersonaSecretMcp(ctx, resolve9) {
49159
49180
  }
49160
49181
 
49161
49182
  // src/ipc-recorder.ts
49162
- var import_node_fs12 = __toESM(require("fs"), 1);
49163
- var import_node_path12 = __toESM(require("path"), 1);
49183
+ var import_node_fs15 = __toESM(require("fs"), 1);
49184
+ var import_node_path14 = __toESM(require("path"), 1);
49164
49185
  function tsForFilename(ms) {
49165
49186
  return new Date(ms).toISOString().replace(/[:.]/g, "-");
49166
49187
  }
@@ -49171,8 +49192,8 @@ function startRecorder(opts) {
49171
49192
  return null;
49172
49193
  }
49173
49194
  const now = opts.now ?? Date.now;
49174
- const dir = import_node_path12.default.join(opts.dataDir, "ipc-recordings", opts.sessionId);
49175
- const filePath = import_node_path12.default.join(dir, `${tsForFilename(now())}.jsonl`);
49195
+ const dir = import_node_path14.default.join(opts.dataDir, "ipc-recordings", opts.sessionId);
49196
+ const filePath = import_node_path14.default.join(dir, `${tsForFilename(now())}.jsonl`);
49176
49197
  let stream = null;
49177
49198
  let closedResolve;
49178
49199
  const closed = new Promise((resolve9) => {
@@ -49181,8 +49202,8 @@ function startRecorder(opts) {
49181
49202
  let exited = false;
49182
49203
  const ensureStream = () => {
49183
49204
  if (stream) return stream;
49184
- import_node_fs12.default.mkdirSync(dir, { recursive: true });
49185
- stream = import_node_fs12.default.createWriteStream(filePath, { flags: "a" });
49205
+ import_node_fs15.default.mkdirSync(dir, { recursive: true });
49206
+ stream = import_node_fs15.default.createWriteStream(filePath, { flags: "a" });
49186
49207
  stream.on("close", () => closedResolve());
49187
49208
  return stream;
49188
49209
  };
@@ -49280,7 +49301,7 @@ var SessionRunner = class {
49280
49301
  bufferCap: this.hooks.bufferCap ?? 500,
49281
49302
  now: this.hooks.now ?? Date.now,
49282
49303
  resolveContextWindow: this.hooks.resolveContextWindow,
49283
- genUuid: this.hooks.genUuid ?? import_node_crypto4.randomUUID,
49304
+ genUuid: this.hooks.genUuid ?? import_node_crypto5.randomUUID,
49284
49305
  ownerDisplayName: this.hooks.ownerDisplayName,
49285
49306
  ownerDeviceId: this.hooks.ownerDeviceId,
49286
49307
  ownerFeishuUnionId: this.hooks.ownerFeishuUnionId,
@@ -49424,15 +49445,8 @@ var SessionRunner = class {
49424
49445
  if (!proc || !this.state.procAlive || this.state.turnOpen || this.hooks.adapter.id !== "claude" || this.hooks.mode === "tui") return;
49425
49446
  const refresh = this.sendControlRequest("get_context_usage", { detail: "summary" }).then((raw) => {
49426
49447
  if (this.proc !== proc || this.contextRefresh !== refresh || this.state.turnOpen || !raw || typeof raw !== "object") return;
49427
- const usage = raw;
49428
- const total = usage.totalTokens;
49429
- const window2 = usage.rawMaxTokens;
49430
- if (typeof total !== "number" || !Number.isSafeInteger(total) || total < 0 || typeof window2 !== "number" || !Number.isSafeInteger(window2) || window2 <= 0) return;
49431
- this.feedObserverEvents([{ kind: "meta_update", patch: {
49432
- ...typeof usage.model === "string" && usage.model ? { resolvedModel: usage.model } : {},
49433
- contextUsage: { inputTokens: total, outputTokens: 0 },
49434
- contextWindowSize: window2
49435
- } }]);
49448
+ const patch = claudeContextUsagePatch(raw);
49449
+ if (patch) this.feedObserverEvents([{ kind: "meta_update", patch }]);
49436
49450
  }).catch((err) => {
49437
49451
  this.hooks.logger?.debug("claude context summary unavailable", { message: String(err) });
49438
49452
  });
@@ -49444,7 +49458,7 @@ var SessionRunner = class {
49444
49458
  if (!proc || !this.state.procAlive) {
49445
49459
  return Promise.reject(new Error("session not running"));
49446
49460
  }
49447
- const requestId = (this.hooks.genUuid ?? import_node_crypto4.randomUUID)();
49461
+ const requestId = (this.hooks.genUuid ?? import_node_crypto5.randomUUID)();
49448
49462
  const frame = {
49449
49463
  type: "control_request",
49450
49464
  request_id: requestId,
@@ -49649,7 +49663,7 @@ var SessionRunner = class {
49649
49663
  isSubagentActive() {
49650
49664
  const toolSessionId = this.state.file.toolSessionId;
49651
49665
  if (!toolSessionId) return false;
49652
- const projectsRoot = import_node_path13.default.join(this.hooks.home ?? import_node_os7.default.homedir(), ".claude", "projects");
49666
+ const projectsRoot = import_node_path15.default.join(this.hooks.home ?? import_node_os9.default.homedir(), ".claude", "projects");
49653
49667
  const mtime = newestSubagentMtimeMs(projectsRoot, this.state.file.cwd, toolSessionId);
49654
49668
  if (mtime === null) return false;
49655
49669
  const now = (this.hooks.now ?? Date.now)();
@@ -49682,7 +49696,7 @@ var SessionRunner = class {
49682
49696
  const session = this.hooks.adapter.createSession(ctx, {
49683
49697
  pushEvents: (events) => {
49684
49698
  if (!isCurrent() || events.length === 0) return;
49685
- const uuid = (this.hooks.genUuid ?? import_node_crypto4.randomUUID)();
49699
+ const uuid = (this.hooks.genUuid ?? import_node_crypto5.randomUUID)();
49686
49700
  this.input({ kind: "inject-events", events: events.map((e) => e.uuid ? e : { ...e, uuid }) });
49687
49701
  },
49688
49702
  onExit: (code) => {
@@ -49838,7 +49852,7 @@ function nowIso2(deps) {
49838
49852
  return new Date((deps.now ?? Date.now)()).toISOString();
49839
49853
  }
49840
49854
  function newSessionId() {
49841
- return (0, import_node_crypto5.randomUUID)().replace(/-/g, "").slice(0, 16);
49855
+ return (0, import_node_crypto6.randomUUID)().replace(/-/g, "").slice(0, 16);
49842
49856
  }
49843
49857
  function buildDispatchTaskPack(args) {
49844
49858
  return formatDispatchTaskEnvelope({
@@ -49876,7 +49890,7 @@ function derivePersonaSpawnCwd(file, personaRoot, cloud) {
49876
49890
  `derivePersonaSpawnCwd: personaRoot missing for owner session ${file.sessionId} (ownerPersonaId=${personaId2})`
49877
49891
  );
49878
49892
  }
49879
- return import_node_path14.default.join(personaRoot, safeFileName(personaId2));
49893
+ return import_node_path16.default.join(personaRoot, safeFileName(personaId2));
49880
49894
  }
49881
49895
  function makeInitialState(file, subSessionMeta) {
49882
49896
  return {
@@ -49981,7 +49995,7 @@ var SessionManager = class {
49981
49995
  assertLocalCwd(cwd, tool) {
49982
49996
  if (this.deps.getAdapter(tool).remote) return;
49983
49997
  try {
49984
- if (!import_node_fs13.default.statSync(cwd).isDirectory()) throw new Error("not dir");
49998
+ if (!import_node_fs16.default.statSync(cwd).isDirectory()) throw new Error("not dir");
49985
49999
  } catch {
49986
50000
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${cwd}`);
49987
50001
  }
@@ -50029,10 +50043,10 @@ var SessionManager = class {
50029
50043
  // 枚举 persona:有 factory 时扫 personas/,兼容模式扫 sessions/(排除 default)。
50030
50044
  listPersonaIdsOnDisk() {
50031
50045
  if (!this.deps.dataDir) return [];
50032
- const root = this.deps.storeFactory ? import_node_path14.default.join(this.deps.dataDir, "personas") : import_node_path14.default.join(this.deps.dataDir, "sessions");
50046
+ const root = this.deps.storeFactory ? import_node_path16.default.join(this.deps.dataDir, "personas") : import_node_path16.default.join(this.deps.dataDir, "sessions");
50033
50047
  let entries;
50034
50048
  try {
50035
- entries = import_node_fs13.default.readdirSync(root, { withFileTypes: true });
50049
+ entries = import_node_fs16.default.readdirSync(root, { withFileTypes: true });
50036
50050
  } catch (err) {
50037
50051
  const code = err?.code;
50038
50052
  if (code === "ENOENT") return [];
@@ -50043,7 +50057,7 @@ var SessionManager = class {
50043
50057
  // 仅 factory 布局枚举 persona 的 guests/<capId>/。
50044
50058
  listGuestCapIdsForPersona(personaId2) {
50045
50059
  if (!this.deps.dataDir || !this.deps.storeFactory) return [];
50046
- const root = import_node_path14.default.join(
50060
+ const root = import_node_path16.default.join(
50047
50061
  this.deps.dataDir,
50048
50062
  "personas",
50049
50063
  personaId2,
@@ -50053,7 +50067,7 @@ var SessionManager = class {
50053
50067
  );
50054
50068
  let entries;
50055
50069
  try {
50056
- entries = import_node_fs13.default.readdirSync(root, { withFileTypes: true });
50070
+ entries = import_node_fs16.default.readdirSync(root, { withFileTypes: true });
50057
50071
  } catch (err) {
50058
50072
  const code = err?.code;
50059
50073
  if (code === "ENOENT") return [];
@@ -50145,7 +50159,7 @@ var SessionManager = class {
50145
50159
  { ownerIdleKillDelayMs: this.deps.ownerIdleKillDelayMs }
50146
50160
  );
50147
50161
  if (subSessionMeta?.userWorkDir) {
50148
- import_node_fs13.default.mkdirSync(subSessionMeta.userWorkDir, { recursive: true });
50162
+ import_node_fs16.default.mkdirSync(subSessionMeta.userWorkDir, { recursive: true });
50149
50163
  }
50150
50164
  if (scope.kind === "persona" && scope.mode === "guest") {
50151
50165
  if ((file.tool ?? "claude") === PI_TOOL_ID) {
@@ -50161,7 +50175,7 @@ var SessionManager = class {
50161
50175
  if ((file.tool ?? "claude") === "claude") {
50162
50176
  const base = this.deps.personaStore?.readSandboxSettings(scope.personaId) ?? null;
50163
50177
  const sandboxSettings = composeGuestSandbox(base, subSessionMeta.userWorkDir, file.cwd);
50164
- const ownerCreds = readOwnerCredentials(import_node_os8.default.homedir(), this.deps.logger);
50178
+ const ownerCreds = readOwnerCredentials(import_node_os10.default.homedir(), this.deps.logger);
50165
50179
  const merged = mergeOwnerCredentials(sandboxSettings, ownerCreds);
50166
50180
  if (ownerCreds) {
50167
50181
  this.deps.logger?.info("owner credentials injected into guest spawn", {
@@ -50172,8 +50186,8 @@ var SessionManager = class {
50172
50186
  }
50173
50187
  subSessionMeta.extraSettings = JSON.stringify(merged);
50174
50188
  }
50175
- const home = import_node_os8.default.homedir();
50176
- const expand = (p3) => p3 === "~" ? home : p3.startsWith("~/") ? import_node_path14.default.join(home, p3.slice(2)) : p3;
50189
+ const home = import_node_os10.default.homedir();
50190
+ const expand = (p3) => p3 === "~" ? home : p3.startsWith("~/") ? import_node_path16.default.join(home, p3.slice(2)) : p3;
50177
50191
  const codexCfg = this.deps.personaStore?.readCodexSandboxSettings(scope.personaId) ?? null;
50178
50192
  subSessionMeta.codexSandbox = {
50179
50193
  writableRoots: [
@@ -50219,7 +50233,7 @@ var SessionManager = class {
50219
50233
  mode: this.deps.mode
50220
50234
  });
50221
50235
  if (this.deps.mode === "tui" && (file.tool ?? "claude") === "claude" && !file.toolSessionId) {
50222
- const newTsid = (0, import_node_crypto5.randomUUID)();
50236
+ const newTsid = (0, import_node_crypto6.randomUUID)();
50223
50237
  this.deps.logger?.debug("tui mode: backfilling missing toolSessionId", {
50224
50238
  sessionId: file.sessionId,
50225
50239
  newToolSessionId: newTsid
@@ -50352,7 +50366,7 @@ var SessionManager = class {
50352
50366
  this.assertLocalCwd(cwd, tool);
50353
50367
  const engineOverridden = tool !== (personaDefaults?.tool ?? "claude");
50354
50368
  const iso = nowIso2(this.deps);
50355
- const toolSessionId = this.deps.mode === "tui" && tool === "claude" ? (0, import_node_crypto5.randomUUID)() : void 0;
50369
+ const toolSessionId = this.deps.mode === "tui" && tool === "claude" ? (0, import_node_crypto6.randomUUID)() : void 0;
50356
50370
  const file = {
50357
50371
  sessionId: args.cloudFork?.sessionId ?? newSessionId(),
50358
50372
  cwd,
@@ -51071,7 +51085,7 @@ var SessionManager = class {
51071
51085
  );
51072
51086
  this.titleGenPending.get(args.sessionId)?.abort();
51073
51087
  this.titleGenPending.delete(args.sessionId);
51074
- const nextToolSessionId = this.deps.mode === "tui" && (existingFile.tool ?? "claude") === "claude" ? (0, import_node_crypto5.randomUUID)() : void 0;
51088
+ const nextToolSessionId = this.deps.mode === "tui" && (existingFile.tool ?? "claude") === "claude" ? (0, import_node_crypto6.randomUUID)() : void 0;
51075
51089
  this.clearPendingTurnEnd(args.sessionId);
51076
51090
  const runner = this.runners.get(args.sessionId);
51077
51091
  if (runner) {
@@ -51354,7 +51368,7 @@ var SessionManager = class {
51354
51368
  this.titleGenPending.get(args.sessionId)?.abort();
51355
51369
  this.titleGenPending.delete(args.sessionId);
51356
51370
  const runner = this.ensureRunnerForScope(file, args.scope);
51357
- const nextToolSessionId = this.deps.mode === "tui" && (file.tool ?? "claude") === "claude" ? (0, import_node_crypto5.randomUUID)() : void 0;
51371
+ const nextToolSessionId = this.deps.mode === "tui" && (file.tool ?? "claude") === "claude" ? (0, import_node_crypto6.randomUUID)() : void 0;
51358
51372
  const { broadcast } = this.withCollector(() => {
51359
51373
  runner.input({
51360
51374
  kind: "command",
@@ -52079,24 +52093,24 @@ var SessionManager = class {
52079
52093
  };
52080
52094
 
52081
52095
  // src/projects/store.ts
52082
- var fs15 = __toESM(require("fs"), 1);
52083
- var os9 = __toESM(require("os"), 1);
52084
- var path19 = __toESM(require("path"), 1);
52096
+ var fs18 = __toESM(require("fs"), 1);
52097
+ var os11 = __toESM(require("os"), 1);
52098
+ var path21 = __toESM(require("path"), 1);
52085
52099
  init_protocol();
52086
52100
 
52087
52101
  // src/projects/codex-registry.ts
52088
- var fs14 = __toESM(require("fs"), 1);
52089
- var os8 = __toESM(require("os"), 1);
52090
- var path18 = __toESM(require("path"), 1);
52102
+ var fs17 = __toESM(require("fs"), 1);
52103
+ var os10 = __toESM(require("os"), 1);
52104
+ var path20 = __toESM(require("path"), 1);
52091
52105
  function normalizeProjectPath(p3) {
52092
- const home = os8.homedir();
52093
- const expanded = p3 === "~" ? home : p3.startsWith("~/") ? path18.join(home, p3.slice(2)) : p3;
52094
- return path18.resolve(expanded);
52106
+ const home = os10.homedir();
52107
+ const expanded = p3 === "~" ? home : p3.startsWith("~/") ? path20.join(home, p3.slice(2)) : p3;
52108
+ return path20.resolve(expanded);
52095
52109
  }
52096
52110
  function readCodexProjects(opts) {
52097
52111
  let raw;
52098
52112
  try {
52099
- raw = fs14.readFileSync(opts.stateFile, "utf8");
52113
+ raw = fs17.readFileSync(opts.stateFile, "utf8");
52100
52114
  } catch {
52101
52115
  return [];
52102
52116
  }
@@ -52134,7 +52148,7 @@ var ProjectsStore = class {
52134
52148
  load() {
52135
52149
  let raw;
52136
52150
  try {
52137
- raw = fs15.readFileSync(this.opts.file, "utf8");
52151
+ raw = fs18.readFileSync(this.opts.file, "utf8");
52138
52152
  } catch {
52139
52153
  return;
52140
52154
  }
@@ -52149,8 +52163,8 @@ var ProjectsStore = class {
52149
52163
  }
52150
52164
  }
52151
52165
  save() {
52152
- fs15.mkdirSync(path19.dirname(this.opts.file), { recursive: true });
52153
- fs15.writeFileSync(
52166
+ fs18.mkdirSync(path21.dirname(this.opts.file), { recursive: true });
52167
+ fs18.writeFileSync(
52154
52168
  this.opts.file,
52155
52169
  JSON.stringify({ projects: this.entries, annotations: this.annotations }, null, 2)
52156
52170
  );
@@ -52160,10 +52174,10 @@ var ProjectsStore = class {
52160
52174
  }
52161
52175
  isProjectablePath(p3) {
52162
52176
  const abs = this.normalize(p3);
52163
- const rel = path19.relative(path19.resolve(this.opts.clawdDir), abs);
52164
- const insideClawd = !(rel.startsWith("..") || path19.isAbsolute(rel));
52177
+ const rel = path21.relative(path21.resolve(this.opts.clawdDir), abs);
52178
+ const insideClawd = !(rel.startsWith("..") || path21.isAbsolute(rel));
52165
52179
  if (insideClawd) return false;
52166
- if (abs === path19.resolve(os9.homedir()) || abs === path19.parse(abs).root) return false;
52180
+ if (abs === path21.resolve(os11.homedir()) || abs === path21.parse(abs).root) return false;
52167
52181
  return true;
52168
52182
  }
52169
52183
  list() {
@@ -52229,7 +52243,7 @@ var ProjectsStore = class {
52229
52243
  if (existing) return existing;
52230
52244
  const entry = {
52231
52245
  path: abs,
52232
- name: name ?? path19.basename(abs),
52246
+ name: name ?? path21.basename(abs),
52233
52247
  createdAt: (this.opts.now ?? (() => (/* @__PURE__ */ new Date()).toISOString()))()
52234
52248
  };
52235
52249
  this.entries.push(entry);
@@ -52238,43 +52252,43 @@ var ProjectsStore = class {
52238
52252
  };
52239
52253
 
52240
52254
  // src/persona/store.ts
52241
- var fs16 = __toESM(require("fs"), 1);
52242
- var path20 = __toESM(require("path"), 1);
52255
+ var fs19 = __toESM(require("fs"), 1);
52256
+ var path22 = __toESM(require("path"), 1);
52243
52257
  init_protocol();
52244
52258
  var PersonaStore = class {
52245
52259
  constructor(root) {
52246
52260
  this.root = root;
52247
- fs16.mkdirSync(root, { recursive: true });
52261
+ fs19.mkdirSync(root, { recursive: true });
52248
52262
  }
52249
52263
  root;
52250
52264
  personaDir(personaId2) {
52251
- return path20.join(this.root, safeFileName(personaId2));
52265
+ return path22.join(this.root, safeFileName(personaId2));
52252
52266
  }
52253
52267
  metaPath(personaId2) {
52254
- return path20.join(this.personaDir(personaId2), ".clawd", "persona.json");
52268
+ return path22.join(this.personaDir(personaId2), ".clawd", "persona.json");
52255
52269
  }
52256
52270
  claudeMdPath(personaId2) {
52257
- return path20.join(this.personaDir(personaId2), "CLAUDE.md");
52271
+ return path22.join(this.personaDir(personaId2), "CLAUDE.md");
52258
52272
  }
52259
52273
  // codex 原生读 cwd 的 AGENTS.md。人格双写镜像:claude 读 CLAUDE.md、codex 读 AGENTS.md,
52260
52274
  // 两份内容恒一致,persona 切 tool 零迁移。
52261
52275
  agentsMdPath(personaId2) {
52262
- return path20.join(this.personaDir(personaId2), "AGENTS.md");
52276
+ return path22.join(this.personaDir(personaId2), "AGENTS.md");
52263
52277
  }
52264
52278
  /**
52265
52279
  * guest sandbox base 放 .clawd/,避免 CC project settings 自动加载。
52266
52280
  * manager 读取后叠加强制底座和 userWorkDir,以 inline settings 注入会话。
52267
52281
  */
52268
52282
  sandboxSettingsPath(personaId2) {
52269
- return path20.join(this.personaDir(personaId2), ".clawd", "sandbox-settings.json");
52283
+ return path22.join(this.personaDir(personaId2), ".clawd", "sandbox-settings.json");
52270
52284
  }
52271
52285
  /** 用户人格补充层:OTA 不覆盖,只经 extraSystemPrompt 注入,避免重复加载人格。 */
52272
52286
  personalityLocalPath(personaId2) {
52273
- return path20.join(this.personaDir(personaId2), ".clawd", "personality.local.md");
52287
+ return path22.join(this.personaDir(personaId2), ".clawd", "personality.local.md");
52274
52288
  }
52275
52289
  write(persona, personality) {
52276
52290
  const dir = this.personaDir(persona.personaId);
52277
- fs16.mkdirSync(path20.join(dir, ".clawd"), { recursive: true });
52291
+ fs19.mkdirSync(path22.join(dir, ".clawd"), { recursive: true });
52278
52292
  this.atomicWrite(this.claudeMdPath(persona.personaId), personality);
52279
52293
  this.atomicWrite(this.agentsMdPath(persona.personaId), personality);
52280
52294
  this.writeSandboxSettings(persona.personaId, buildGuestSettingsV1());
@@ -52287,26 +52301,26 @@ var PersonaStore = class {
52287
52301
  /** 读人格补充层正文;文件不存在返回 null(= 该 persona 没有补充,走内置人格)。 */
52288
52302
  readPersonalityLocal(personaId2) {
52289
52303
  const p3 = this.personalityLocalPath(personaId2);
52290
- if (!fs16.existsSync(p3)) return null;
52291
- return fs16.readFileSync(p3, "utf8");
52304
+ if (!fs19.existsSync(p3)) return null;
52305
+ return fs19.readFileSync(p3, "utf8");
52292
52306
  }
52293
52307
  /** 纯空白表示清空,删除文件;缺目录时创建 .clawd/。 */
52294
52308
  writePersonalityLocal(personaId2, body) {
52295
52309
  const p3 = this.personalityLocalPath(personaId2);
52296
52310
  if (!body.trim()) {
52297
- fs16.rmSync(p3, { force: true });
52311
+ fs19.rmSync(p3, { force: true });
52298
52312
  return;
52299
52313
  }
52300
- fs16.mkdirSync(path20.dirname(p3), { recursive: true });
52314
+ fs19.mkdirSync(path22.dirname(p3), { recursive: true });
52301
52315
  this.atomicWrite(p3, body);
52302
52316
  }
52303
52317
  /** 补缺失的 AGENTS.md 镜像;已有文件(含用户编辑)不覆盖,无 CLAUDE.md 则不生成。 */
52304
52318
  ensureAgentsMirror(personaId2) {
52305
52319
  const claudeMd = this.claudeMdPath(personaId2);
52306
52320
  const agentsMd = this.agentsMdPath(personaId2);
52307
- if (!fs16.existsSync(claudeMd)) return false;
52308
- if (fs16.existsSync(agentsMd)) return false;
52309
- this.atomicWrite(agentsMd, fs16.readFileSync(claudeMd, "utf8"));
52321
+ if (!fs19.existsSync(claudeMd)) return false;
52322
+ if (fs19.existsSync(agentsMd)) return false;
52323
+ this.atomicWrite(agentsMd, fs19.readFileSync(claudeMd, "utf8"));
52310
52324
  return true;
52311
52325
  }
52312
52326
  /**
@@ -52349,22 +52363,22 @@ var PersonaStore = class {
52349
52363
  };
52350
52364
  }
52351
52365
  codexSandboxSettingsPath(personaId2) {
52352
- return path20.join(this.personaDir(personaId2), ".clawd", "codex-sandbox.json");
52366
+ return path22.join(this.personaDir(personaId2), ".clawd", "codex-sandbox.json");
52353
52367
  }
52354
52368
  /** 读 codex-sandbox.json;不存在/损坏 → null。 */
52355
52369
  readCodexSandboxSettings(personaId2) {
52356
52370
  const p3 = this.codexSandboxSettingsPath(personaId2);
52357
- if (!fs16.existsSync(p3)) return null;
52371
+ if (!fs19.existsSync(p3)) return null;
52358
52372
  try {
52359
- return CodexSandboxSettingsSchema.parse(JSON.parse(fs16.readFileSync(p3, "utf8")));
52373
+ return CodexSandboxSettingsSchema.parse(JSON.parse(fs19.readFileSync(p3, "utf8")));
52360
52374
  } catch {
52361
52375
  return null;
52362
52376
  }
52363
52377
  }
52364
52378
  /** 覆盖写 codex-sandbox.json(seed/migrate 用)。 */
52365
52379
  writeCodexSandboxSettings(personaId2, settings) {
52366
- const dir = path20.join(this.personaDir(personaId2), ".clawd");
52367
- fs16.mkdirSync(dir, { recursive: true });
52380
+ const dir = path22.join(this.personaDir(personaId2), ".clawd");
52381
+ fs19.mkdirSync(dir, { recursive: true });
52368
52382
  this.atomicWrite(this.codexSandboxSettingsPath(personaId2), JSON.stringify(settings, null, 2));
52369
52383
  }
52370
52384
  writeMeta(persona) {
@@ -52372,8 +52386,8 @@ var PersonaStore = class {
52372
52386
  }
52373
52387
  read(personaId2) {
52374
52388
  const p3 = this.metaPath(personaId2);
52375
- if (!fs16.existsSync(p3)) return null;
52376
- const raw = JSON.parse(fs16.readFileSync(p3, "utf8"));
52389
+ if (!fs19.existsSync(p3)) return null;
52390
+ const raw = JSON.parse(fs19.readFileSync(p3, "utf8"));
52377
52391
  if (raw && typeof raw === "object" && "tokenMap" in raw) {
52378
52392
  delete raw.tokenMap;
52379
52393
  this.atomicWrite(p3, JSON.stringify(raw, null, 2));
@@ -52381,43 +52395,43 @@ var PersonaStore = class {
52381
52395
  return PersonaFileSchema.parse(raw);
52382
52396
  }
52383
52397
  has(personaId2) {
52384
- return fs16.existsSync(this.metaPath(personaId2));
52398
+ return fs19.existsSync(this.metaPath(personaId2));
52385
52399
  }
52386
52400
  readPersonality(personaId2) {
52387
52401
  const claudeMd = this.claudeMdPath(personaId2);
52388
- if (fs16.existsSync(claudeMd)) return fs16.readFileSync(claudeMd, "utf8");
52402
+ if (fs19.existsSync(claudeMd)) return fs19.readFileSync(claudeMd, "utf8");
52389
52403
  const agentsMd = this.agentsMdPath(personaId2);
52390
- if (fs16.existsSync(agentsMd)) return fs16.readFileSync(agentsMd, "utf8");
52404
+ if (fs19.existsSync(agentsMd)) return fs19.readFileSync(agentsMd, "utf8");
52391
52405
  return null;
52392
52406
  }
52393
52407
  /** 缺失或读/解析失败返回 null;owner 手编的内容不强校验形状。 */
52394
52408
  readSandboxSettings(personaId2) {
52395
52409
  const p3 = this.sandboxSettingsPath(personaId2);
52396
- if (!fs16.existsSync(p3)) return null;
52410
+ if (!fs19.existsSync(p3)) return null;
52397
52411
  try {
52398
- return JSON.parse(fs16.readFileSync(p3, "utf8"));
52412
+ return JSON.parse(fs19.readFileSync(p3, "utf8"));
52399
52413
  } catch {
52400
52414
  return null;
52401
52415
  }
52402
52416
  }
52403
52417
  /** Persona 私有 skills 目录路径:<personaDir>/.claude/skills */
52404
52418
  skillsDir(personaId2) {
52405
- return path20.join(this.personaDir(personaId2), ".claude", "skills");
52419
+ return path22.join(this.personaDir(personaId2), ".claude", "skills");
52406
52420
  }
52407
52421
  /**
52408
52422
  * Claude Code 项目级 settings 路径:`<personaDir>/.claude/settings.json`。
52409
52423
  * 这里只读 `enabledPlugins` 字段,由 owner 通过 CC `/plugin` 之类命令维护,daemon 不写。
52410
52424
  */
52411
52425
  claudeSettingsPath(personaId2) {
52412
- return path20.join(this.personaDir(personaId2), ".claude", "settings.json");
52426
+ return path22.join(this.personaDir(personaId2), ".claude", "settings.json");
52413
52427
  }
52414
52428
  /** 取 enabledPlugins 中非空且 value === true 的 id;文件缺失、读/解析失败或字段非对象均返回 []。 */
52415
52429
  readEnabledPlugins(personaId2) {
52416
52430
  const p3 = this.claudeSettingsPath(personaId2);
52417
- if (!fs16.existsSync(p3)) return [];
52431
+ if (!fs19.existsSync(p3)) return [];
52418
52432
  let raw;
52419
52433
  try {
52420
- raw = JSON.parse(fs16.readFileSync(p3, "utf8"));
52434
+ raw = JSON.parse(fs19.readFileSync(p3, "utf8"));
52421
52435
  } catch {
52422
52436
  return [];
52423
52437
  }
@@ -52431,22 +52445,22 @@ var PersonaStore = class {
52431
52445
  return out;
52432
52446
  }
52433
52447
  list() {
52434
- if (!fs16.existsSync(this.root)) return [];
52435
- return fs16.readdirSync(this.root).filter((name) => {
52436
- return fs16.existsSync(path20.join(this.root, name, ".clawd", "persona.json"));
52448
+ if (!fs19.existsSync(this.root)) return [];
52449
+ return fs19.readdirSync(this.root).filter((name) => {
52450
+ return fs19.existsSync(path22.join(this.root, name, ".clawd", "persona.json"));
52437
52451
  });
52438
52452
  }
52439
52453
  remove(personaId2) {
52440
52454
  const dir = this.personaDir(personaId2);
52441
- if (fs16.existsSync(dir)) fs16.rmSync(dir, { recursive: true, force: true });
52455
+ if (fs19.existsSync(dir)) fs19.rmSync(dir, { recursive: true, force: true });
52442
52456
  }
52443
52457
  personaDirPath(personaId2) {
52444
52458
  return this.personaDir(personaId2);
52445
52459
  }
52446
52460
  atomicWrite(file, content) {
52447
52461
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
52448
- fs16.writeFileSync(tmp, content, { mode: 384 });
52449
- fs16.renameSync(tmp, file);
52462
+ fs19.writeFileSync(tmp, content, { mode: 384 });
52463
+ fs19.renameSync(tmp, file);
52450
52464
  }
52451
52465
  };
52452
52466
 
@@ -52496,8 +52510,8 @@ var PersonaRegistry = class {
52496
52510
  };
52497
52511
 
52498
52512
  // src/persona/seed.ts
52499
- var fs17 = __toESM(require("fs"), 1);
52500
- var path21 = __toESM(require("path"), 1);
52513
+ var fs20 = __toESM(require("fs"), 1);
52514
+ var path23 = __toESM(require("path"), 1);
52501
52515
  var import_node_url = require("url");
52502
52516
  init_protocol();
52503
52517
  var import_meta = {};
@@ -52664,24 +52678,24 @@ function bundleSiblingFromArgv(argv1, sibling) {
52664
52678
  if (!argv1) return null;
52665
52679
  let real = argv1;
52666
52680
  try {
52667
- real = fs17.realpathSync(argv1);
52681
+ real = fs20.realpathSync(argv1);
52668
52682
  } catch {
52669
52683
  }
52670
- return path21.resolve(path21.dirname(real), sibling);
52684
+ return path23.resolve(path23.dirname(real), sibling);
52671
52685
  }
52672
52686
  function findDefaultsRoot(logger) {
52673
52687
  const candidates = [];
52674
52688
  try {
52675
- const here = path21.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
52676
- candidates.push(path21.resolve(here, "defaults"));
52677
- candidates.push(path21.resolve(here, "persona-defaults"));
52689
+ const here = path23.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
52690
+ candidates.push(path23.resolve(here, "defaults"));
52691
+ candidates.push(path23.resolve(here, "persona-defaults"));
52678
52692
  } catch {
52679
52693
  }
52680
52694
  const fromArgv = bundleSiblingFromArgv(process.argv[1], "persona-defaults");
52681
52695
  if (fromArgv) candidates.push(fromArgv);
52682
52696
  for (const c2 of candidates) {
52683
52697
  try {
52684
- if (fs17.statSync(c2).isDirectory()) {
52698
+ if (fs20.statSync(c2).isDirectory()) {
52685
52699
  logger?.info("persona.defaults-root.resolved", { root: c2 });
52686
52700
  return c2;
52687
52701
  }
@@ -52698,8 +52712,8 @@ function seedDefaultPersonas(args) {
52698
52712
  args.logger.info("persona.seed.skip", { personaId: entry.personaId, reason: "exists" });
52699
52713
  continue;
52700
52714
  }
52701
- const bundleDir = path21.join(args.defaultsRoot, entry.personaId);
52702
- if (!fs17.existsSync(bundleDir)) {
52715
+ const bundleDir = path23.join(args.defaultsRoot, entry.personaId);
52716
+ if (!fs20.existsSync(bundleDir)) {
52703
52717
  args.logger.warn("persona.seed.skip", {
52704
52718
  personaId: entry.personaId,
52705
52719
  reason: "bundle-missing",
@@ -52707,8 +52721,8 @@ function seedDefaultPersonas(args) {
52707
52721
  });
52708
52722
  continue;
52709
52723
  }
52710
- const claudeMdPath = path21.join(bundleDir, "CLAUDE.md");
52711
- if (!fs17.existsSync(claudeMdPath)) {
52724
+ const claudeMdPath = path23.join(bundleDir, "CLAUDE.md");
52725
+ if (!fs20.existsSync(claudeMdPath)) {
52712
52726
  args.logger.warn("persona.seed.skip", {
52713
52727
  personaId: entry.personaId,
52714
52728
  reason: "no-CLAUDE.md",
@@ -52716,7 +52730,7 @@ function seedDefaultPersonas(args) {
52716
52730
  });
52717
52731
  continue;
52718
52732
  }
52719
- const personality = fs17.readFileSync(claudeMdPath, "utf8");
52733
+ const personality = fs20.readFileSync(claudeMdPath, "utf8");
52720
52734
  const now = Date.now();
52721
52735
  const persona = {
52722
52736
  personaId: entry.personaId,
@@ -52743,51 +52757,51 @@ function seedDefaultPersonas(args) {
52743
52757
  }
52744
52758
  }
52745
52759
  function skipNodeModulesUnder(srcRoot) {
52746
- return (src) => !path21.relative(srcRoot, src).split(path21.sep).includes("node_modules");
52760
+ return (src) => !path23.relative(srcRoot, src).split(path23.sep).includes("node_modules");
52747
52761
  }
52748
52762
  function copyBundleExtras(srcDir, dstDir) {
52749
- for (const entry of fs17.readdirSync(srcDir, { withFileTypes: true })) {
52763
+ for (const entry of fs20.readdirSync(srcDir, { withFileTypes: true })) {
52750
52764
  if (entry.name === "CLAUDE.md" || entry.name === ".clawd") continue;
52751
- const srcPath = path21.join(srcDir, entry.name);
52752
- const dstPath = path21.join(dstDir, entry.name);
52765
+ const srcPath = path23.join(srcDir, entry.name);
52766
+ const dstPath = path23.join(dstDir, entry.name);
52753
52767
  if (entry.isDirectory()) {
52754
- fs17.cpSync(srcPath, dstPath, { recursive: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
52768
+ fs20.cpSync(srcPath, dstPath, { recursive: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
52755
52769
  } else if (entry.isFile()) {
52756
- fs17.copyFileSync(srcPath, dstPath);
52770
+ fs20.copyFileSync(srcPath, dstPath);
52757
52771
  }
52758
52772
  }
52759
52773
  }
52760
52774
  var DAEMON_MANAGED_PATHS = ["extension-kit", "CLAUDE.md", ".mcp.json", ".claude/skills", ".claude/agents", "mcp"];
52761
52775
  function replaceManagedPath(src, dst) {
52762
- if (!fs17.statSync(src).isDirectory()) {
52763
- fs17.mkdirSync(path21.dirname(dst), { recursive: true });
52764
- fs17.rmSync(dst, { recursive: true, force: true });
52765
- fs17.cpSync(src, dst, { dereference: true });
52776
+ if (!fs20.statSync(src).isDirectory()) {
52777
+ fs20.mkdirSync(path23.dirname(dst), { recursive: true });
52778
+ fs20.rmSync(dst, { recursive: true, force: true });
52779
+ fs20.cpSync(src, dst, { dereference: true });
52766
52780
  return;
52767
52781
  }
52768
- fs17.mkdirSync(dst, { recursive: true });
52769
- for (const e of fs17.readdirSync(src, { withFileTypes: true })) {
52782
+ fs20.mkdirSync(dst, { recursive: true });
52783
+ for (const e of fs20.readdirSync(src, { withFileTypes: true })) {
52770
52784
  if (e.name === "node_modules") continue;
52771
- const child = path21.join(dst, e.name);
52772
- fs17.rmSync(child, { recursive: true, force: true });
52773
- fs17.cpSync(path21.join(src, e.name), child, { recursive: true, dereference: true });
52785
+ const child = path23.join(dst, e.name);
52786
+ fs20.rmSync(child, { recursive: true, force: true });
52787
+ fs20.cpSync(path23.join(src, e.name), child, { recursive: true, dereference: true });
52774
52788
  }
52775
52789
  }
52776
52790
  function refreshDaemonManagedDirs(args) {
52777
52791
  const entries = args.entries ?? DEFAULT_PERSONAS;
52778
52792
  for (const entry of entries) {
52779
- const bundleDir = path21.join(args.defaultsRoot, entry.personaId);
52780
- if (!fs17.existsSync(bundleDir)) continue;
52793
+ const bundleDir = path23.join(args.defaultsRoot, entry.personaId);
52794
+ if (!fs20.existsSync(bundleDir)) continue;
52781
52795
  const personaDir = args.store.personaDirPath(entry.personaId);
52782
- if (!fs17.existsSync(personaDir)) continue;
52796
+ if (!fs20.existsSync(personaDir)) continue;
52783
52797
  for (const relPath of DAEMON_MANAGED_PATHS) {
52784
- const srcPath = path21.join(bundleDir, relPath);
52785
- if (!fs17.existsSync(srcPath)) continue;
52786
- const dstPath = path21.join(personaDir, relPath);
52798
+ const srcPath = path23.join(bundleDir, relPath);
52799
+ if (!fs20.existsSync(srcPath)) continue;
52800
+ const dstPath = path23.join(personaDir, relPath);
52787
52801
  try {
52788
52802
  replaceManagedPath(srcPath, dstPath);
52789
52803
  if (relPath === "CLAUDE.md") {
52790
- replaceManagedPath(srcPath, path21.join(personaDir, "AGENTS.md"));
52804
+ replaceManagedPath(srcPath, path23.join(personaDir, "AGENTS.md"));
52791
52805
  }
52792
52806
  args.logger.info("persona.refresh.synced", {
52793
52807
  personaId: entry.personaId,
@@ -52811,12 +52825,12 @@ function migratePersonalityOverlay(args) {
52811
52825
  for (const entry of entries) {
52812
52826
  const personaId2 = entry.personaId;
52813
52827
  try {
52814
- if (fs17.existsSync(args.store.personalityLocalPath(personaId2))) continue;
52815
- const bundleClaudeMd = path21.join(args.defaultsRoot, personaId2, "CLAUDE.md");
52816
- if (!fs17.existsSync(bundleClaudeMd)) continue;
52828
+ if (fs20.existsSync(args.store.personalityLocalPath(personaId2))) continue;
52829
+ const bundleClaudeMd = path23.join(args.defaultsRoot, personaId2, "CLAUDE.md");
52830
+ if (!fs20.existsSync(bundleClaudeMd)) continue;
52817
52831
  const current = args.store.readPersonality(personaId2);
52818
52832
  if (current === null) continue;
52819
- const bundle = fs17.readFileSync(bundleClaudeMd, "utf8");
52833
+ const bundle = fs20.readFileSync(bundleClaudeMd, "utf8");
52820
52834
  if (current === bundle) continue;
52821
52835
  if (!current.startsWith(bundle)) continue;
52822
52836
  const tail2 = current.slice(bundle.length).trim();
@@ -52915,7 +52929,7 @@ function migrateSandboxAllowRead(args) {
52915
52929
  for (const personaId2 of args.store.list()) {
52916
52930
  try {
52917
52931
  const readPath = tildePath(args.store.personaDirPath(personaId2));
52918
- if (!fs17.existsSync(args.store.sandboxSettingsPath(personaId2))) {
52932
+ if (!fs20.existsSync(args.store.sandboxSettingsPath(personaId2))) {
52919
52933
  args.store.writeSandboxSettings(personaId2, buildGuestSettingsV1());
52920
52934
  n2++;
52921
52935
  continue;
@@ -52958,13 +52972,13 @@ var PERSONA_BUILDER_TOMBSTONE = `${PERSONA_BUILDER_TOMBSTONE_MARKER}
52958
52972
  function containsAnyFile(dir) {
52959
52973
  let entries;
52960
52974
  try {
52961
- entries = fs17.readdirSync(dir, { withFileTypes: true });
52975
+ entries = fs20.readdirSync(dir, { withFileTypes: true });
52962
52976
  } catch {
52963
52977
  return false;
52964
52978
  }
52965
52979
  for (const e of entries) {
52966
52980
  if (e.isDirectory()) {
52967
- if (containsAnyFile(path21.join(dir, e.name))) return true;
52981
+ if (containsAnyFile(path23.join(dir, e.name))) return true;
52968
52982
  } else {
52969
52983
  return true;
52970
52984
  }
@@ -52973,9 +52987,9 @@ function containsAnyFile(dir) {
52973
52987
  }
52974
52988
  function retirePersonaBuilder(args) {
52975
52989
  const dir = args.store.personaDirPath(PERSONA_BUILDER_ID);
52976
- if (!fs17.existsSync(dir)) return;
52990
+ if (!fs20.existsSync(dir)) return;
52977
52991
  try {
52978
- const used = containsAnyFile(path21.join(dir, ".clawd", "sessions")) || containsAnyFile(path21.join(dir, ".claude", "skills")) || containsAnyFile(path21.join(dir, "projects"));
52992
+ const used = containsAnyFile(path23.join(dir, ".clawd", "sessions")) || containsAnyFile(path23.join(dir, ".claude", "skills")) || containsAnyFile(path23.join(dir, "projects"));
52979
52993
  if (!used) {
52980
52994
  args.store.remove(PERSONA_BUILDER_ID);
52981
52995
  args.logger.info("persona.retire-builder.removed", { personaId: PERSONA_BUILDER_ID });
@@ -52983,10 +52997,10 @@ function retirePersonaBuilder(args) {
52983
52997
  }
52984
52998
  let wrote = false;
52985
52999
  for (const name of ["CLAUDE.md", "AGENTS.md"]) {
52986
- const p3 = path21.join(dir, name);
52987
- const cur = fs17.existsSync(p3) ? fs17.readFileSync(p3, "utf8") : null;
53000
+ const p3 = path23.join(dir, name);
53001
+ const cur = fs20.existsSync(p3) ? fs20.readFileSync(p3, "utf8") : null;
52988
53002
  if (cur?.startsWith(PERSONA_BUILDER_TOMBSTONE_MARKER)) continue;
52989
- fs17.writeFileSync(p3, PERSONA_BUILDER_TOMBSTONE);
53003
+ fs20.writeFileSync(p3, PERSONA_BUILDER_TOMBSTONE);
52990
53004
  wrote = true;
52991
53005
  }
52992
53006
  if (wrote) args.logger.info("persona.retire-builder.tombstoned", { personaId: PERSONA_BUILDER_ID });
@@ -52999,9 +53013,9 @@ function retirePersonaBuilder(args) {
52999
53013
  }
53000
53014
 
53001
53015
  // src/skills/scanner.ts
53002
- var import_node_fs14 = __toESM(require("fs"), 1);
53003
- var import_node_os9 = __toESM(require("os"), 1);
53004
- var import_node_path15 = __toESM(require("path"), 1);
53016
+ var import_node_fs17 = __toESM(require("fs"), 1);
53017
+ var import_node_os11 = __toESM(require("os"), 1);
53018
+ var import_node_path17 = __toESM(require("path"), 1);
53005
53019
 
53006
53020
  // src/skills/frontmatter.ts
53007
53021
  var STRIP_QUOTES = /^["']|["']$/g;
@@ -53110,7 +53124,7 @@ function parseDescription(content) {
53110
53124
  }
53111
53125
  function isDirLikeSync(p3) {
53112
53126
  try {
53113
- return import_node_fs14.default.statSync(p3).isDirectory();
53127
+ return import_node_fs17.default.statSync(p3).isDirectory();
53114
53128
  } catch {
53115
53129
  return false;
53116
53130
  }
@@ -53118,19 +53132,19 @@ function isDirLikeSync(p3) {
53118
53132
  function scanSkillDir(dir, source, seen, out, pluginName) {
53119
53133
  let entries;
53120
53134
  try {
53121
- entries = import_node_fs14.default.readdirSync(dir, { withFileTypes: true });
53135
+ entries = import_node_fs17.default.readdirSync(dir, { withFileTypes: true });
53122
53136
  } catch {
53123
53137
  return;
53124
53138
  }
53125
53139
  for (const ent of entries) {
53126
- const entryPath = import_node_path15.default.join(dir, ent.name);
53140
+ const entryPath = import_node_path17.default.join(dir, ent.name);
53127
53141
  if (!ent.isDirectory() && !(ent.isSymbolicLink() && isDirLikeSync(entryPath))) continue;
53128
53142
  let content;
53129
53143
  try {
53130
- content = import_node_fs14.default.readFileSync(import_node_path15.default.join(entryPath, "SKILL.md"), "utf8");
53144
+ content = import_node_fs17.default.readFileSync(import_node_path17.default.join(entryPath, "SKILL.md"), "utf8");
53131
53145
  } catch {
53132
53146
  try {
53133
- content = import_node_fs14.default.readFileSync(import_node_path15.default.join(entryPath, "skill.md"), "utf8");
53147
+ content = import_node_fs17.default.readFileSync(import_node_path17.default.join(entryPath, "skill.md"), "utf8");
53134
53148
  } catch {
53135
53149
  continue;
53136
53150
  }
@@ -53154,26 +53168,26 @@ function listSkillsForDir(dir, source) {
53154
53168
  function scanCommandDir(dir, source, seen, out, pluginName) {
53155
53169
  let entries;
53156
53170
  try {
53157
- entries = import_node_fs14.default.readdirSync(dir, { withFileTypes: true });
53171
+ entries = import_node_fs17.default.readdirSync(dir, { withFileTypes: true });
53158
53172
  } catch {
53159
53173
  return;
53160
53174
  }
53161
53175
  for (const ent of entries) {
53162
- const entryPath = import_node_path15.default.join(dir, ent.name);
53176
+ const entryPath = import_node_path17.default.join(dir, ent.name);
53163
53177
  if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync(entryPath)) {
53164
53178
  const ns = ent.name;
53165
53179
  let subEntries;
53166
53180
  try {
53167
- subEntries = import_node_fs14.default.readdirSync(entryPath, { withFileTypes: true });
53181
+ subEntries = import_node_fs17.default.readdirSync(entryPath, { withFileTypes: true });
53168
53182
  } catch {
53169
53183
  continue;
53170
53184
  }
53171
53185
  for (const se2 of subEntries) {
53172
53186
  if (!se2.name.endsWith(".md")) continue;
53173
- const sePath = import_node_path15.default.join(entryPath, se2.name);
53187
+ const sePath = import_node_path17.default.join(entryPath, se2.name);
53174
53188
  let content;
53175
53189
  try {
53176
- content = import_node_fs14.default.readFileSync(sePath, "utf8");
53190
+ content = import_node_fs17.default.readFileSync(sePath, "utf8");
53177
53191
  } catch {
53178
53192
  continue;
53179
53193
  }
@@ -53190,7 +53204,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
53190
53204
  } else if (ent.name.endsWith(".md")) {
53191
53205
  let content;
53192
53206
  try {
53193
- content = import_node_fs14.default.readFileSync(entryPath, "utf8");
53207
+ content = import_node_fs17.default.readFileSync(entryPath, "utf8");
53194
53208
  } catch {
53195
53209
  continue;
53196
53210
  }
@@ -53206,10 +53220,10 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
53206
53220
  }
53207
53221
  }
53208
53222
  function readInstalledPlugins(home) {
53209
- const file = import_node_path15.default.join(home, ".claude", "plugins", "installed_plugins.json");
53223
+ const file = import_node_path17.default.join(home, ".claude", "plugins", "installed_plugins.json");
53210
53224
  let raw;
53211
53225
  try {
53212
- raw = import_node_fs14.default.readFileSync(file, "utf8");
53226
+ raw = import_node_fs17.default.readFileSync(file, "utf8");
53213
53227
  } catch {
53214
53228
  return [];
53215
53229
  }
@@ -53234,7 +53248,7 @@ var SkillsScanner = class {
53234
53248
  home;
53235
53249
  extraPluginRoots;
53236
53250
  constructor(opts = {}) {
53237
- this.home = opts.home ?? import_node_os9.default.homedir();
53251
+ this.home = opts.home ?? import_node_os11.default.homedir();
53238
53252
  this.extraPluginRoots = opts.extraPluginRoots ?? [];
53239
53253
  }
53240
53254
  /** First-seen names win: builtins, global sources, project sources, then plugins. */
@@ -53251,14 +53265,14 @@ var SkillsScanner = class {
53251
53265
  });
53252
53266
  }
53253
53267
  const fsBlock = [];
53254
- scanSkillDir(import_node_path15.default.join(this.home, ".claude", "skills"), "global", seen, fsBlock);
53255
- scanCommandDir(import_node_path15.default.join(this.home, ".claude", "commands"), "global", seen, fsBlock);
53256
- scanSkillDir(import_node_path15.default.join(args.cwd, ".claude", "skills"), "project", seen, fsBlock);
53257
- scanCommandDir(import_node_path15.default.join(args.cwd, ".claude", "commands"), "project", seen, fsBlock);
53268
+ scanSkillDir(import_node_path17.default.join(this.home, ".claude", "skills"), "global", seen, fsBlock);
53269
+ scanCommandDir(import_node_path17.default.join(this.home, ".claude", "commands"), "global", seen, fsBlock);
53270
+ scanSkillDir(import_node_path17.default.join(args.cwd, ".claude", "skills"), "project", seen, fsBlock);
53271
+ scanCommandDir(import_node_path17.default.join(args.cwd, ".claude", "commands"), "project", seen, fsBlock);
53258
53272
  const plugins = [...readInstalledPlugins(this.home), ...this.extraPluginRoots];
53259
53273
  for (const { name, root } of plugins) {
53260
- scanSkillDir(import_node_path15.default.join(root, "skills"), "plugin", seen, fsBlock, name);
53261
- scanCommandDir(import_node_path15.default.join(root, "commands"), "plugin", seen, fsBlock, name);
53274
+ scanSkillDir(import_node_path17.default.join(root, "skills"), "plugin", seen, fsBlock, name);
53275
+ scanCommandDir(import_node_path17.default.join(root, "commands"), "plugin", seen, fsBlock, name);
53262
53276
  }
53263
53277
  fsBlock.sort((a2, b3) => a2.name < b3.name ? -1 : a2.name > b3.name ? 1 : 0);
53264
53278
  return [...builtinBlock, ...fsBlock];
@@ -53371,12 +53385,12 @@ var PersonaManager = class {
53371
53385
  };
53372
53386
 
53373
53387
  // src/share-md-viewer/load.ts
53374
- var import_node_fs16 = __toESM(require("fs"), 1);
53375
- var import_node_path16 = __toESM(require("path"), 1);
53388
+ var import_node_fs19 = __toESM(require("fs"), 1);
53389
+ var import_node_path18 = __toESM(require("path"), 1);
53376
53390
  var import_node_url2 = require("url");
53377
53391
 
53378
53392
  // src/share-md-viewer/asset-loader.ts
53379
- var import_node_fs15 = __toESM(require("fs"), 1);
53393
+ var import_node_fs18 = __toESM(require("fs"), 1);
53380
53394
  function htmlEscape(s2) {
53381
53395
  return s2.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
53382
53396
  }
@@ -53384,12 +53398,12 @@ function createViewerAssetLoader(opts) {
53384
53398
  let viewerTemplate;
53385
53399
  let errorTemplate;
53386
53400
  try {
53387
- viewerTemplate = import_node_fs15.default.readFileSync(opts.viewerHtmlPath, "utf8");
53401
+ viewerTemplate = import_node_fs18.default.readFileSync(opts.viewerHtmlPath, "utf8");
53388
53402
  } catch (err) {
53389
53403
  throw new Error(`viewer asset not found at ${opts.viewerHtmlPath}: ${err.message}`);
53390
53404
  }
53391
53405
  try {
53392
- errorTemplate = import_node_fs15.default.readFileSync(opts.errorHtmlPath, "utf8");
53406
+ errorTemplate = import_node_fs18.default.readFileSync(opts.errorHtmlPath, "utf8");
53393
53407
  } catch (err) {
53394
53408
  throw new Error(`viewer error asset not found at ${opts.errorHtmlPath}: ${err.message}`);
53395
53409
  }
@@ -53408,25 +53422,25 @@ var import_meta2 = {};
53408
53422
  function tryLoadViewerAssets(logger) {
53409
53423
  const candidates = [];
53410
53424
  try {
53411
- const here = import_node_path16.default.dirname((0, import_node_url2.fileURLToPath)(import_meta2.url));
53425
+ const here = import_node_path18.default.dirname((0, import_node_url2.fileURLToPath)(import_meta2.url));
53412
53426
  candidates.push(here);
53413
- candidates.push(import_node_path16.default.resolve(here, ".."));
53414
- candidates.push(import_node_path16.default.resolve(here, "..", "..", "dist"));
53427
+ candidates.push(import_node_path18.default.resolve(here, ".."));
53428
+ candidates.push(import_node_path18.default.resolve(here, "..", "..", "dist"));
53415
53429
  } catch {
53416
53430
  }
53417
53431
  if (process.argv[1]) {
53418
53432
  let real = process.argv[1];
53419
53433
  try {
53420
- real = import_node_fs16.default.realpathSync(process.argv[1]);
53434
+ real = import_node_fs19.default.realpathSync(process.argv[1]);
53421
53435
  } catch {
53422
53436
  }
53423
- candidates.push(import_node_path16.default.dirname(real));
53437
+ candidates.push(import_node_path18.default.dirname(real));
53424
53438
  }
53425
53439
  for (const root of candidates) {
53426
- const viewerHtmlPath = import_node_path16.default.join(root, "share-md-viewer.html");
53427
- const errorHtmlPath = import_node_path16.default.join(root, "share-md-viewer-error.html");
53440
+ const viewerHtmlPath = import_node_path18.default.join(root, "share-md-viewer.html");
53441
+ const errorHtmlPath = import_node_path18.default.join(root, "share-md-viewer-error.html");
53428
53442
  try {
53429
- if (import_node_fs16.default.statSync(viewerHtmlPath).isFile() && import_node_fs16.default.statSync(errorHtmlPath).isFile()) {
53443
+ if (import_node_fs19.default.statSync(viewerHtmlPath).isFile() && import_node_fs19.default.statSync(errorHtmlPath).isFile()) {
53430
53444
  logger?.info("share-md-viewer.assets-root.resolved", { root });
53431
53445
  return createViewerAssetLoader({ viewerHtmlPath, errorHtmlPath });
53432
53446
  }
@@ -53441,25 +53455,25 @@ function tryLoadViewerAssets(logger) {
53441
53455
  }
53442
53456
 
53443
53457
  // src/dashboard/load.ts
53444
- var import_node_fs17 = __toESM(require("fs"), 1);
53445
- var import_node_path17 = __toESM(require("path"), 1);
53458
+ var import_node_fs20 = __toESM(require("fs"), 1);
53459
+ var import_node_path19 = __toESM(require("path"), 1);
53446
53460
  var import_node_url3 = require("url");
53447
53461
  init_protocol();
53448
53462
  var import_meta3 = {};
53449
53463
  function candidateRoots() {
53450
53464
  const roots = [];
53451
53465
  try {
53452
- const here = import_node_path17.default.dirname((0, import_node_url3.fileURLToPath)(import_meta3.url));
53453
- roots.push(here, import_node_path17.default.resolve(here, ".."), import_node_path17.default.resolve(here, "..", "..", "dist"));
53466
+ const here = import_node_path19.default.dirname((0, import_node_url3.fileURLToPath)(import_meta3.url));
53467
+ roots.push(here, import_node_path19.default.resolve(here, ".."), import_node_path19.default.resolve(here, "..", "..", "dist"));
53454
53468
  } catch {
53455
53469
  }
53456
53470
  if (process.argv[1]) {
53457
53471
  let real = process.argv[1];
53458
53472
  try {
53459
- real = import_node_fs17.default.realpathSync(process.argv[1]);
53473
+ real = import_node_fs20.default.realpathSync(process.argv[1]);
53460
53474
  } catch {
53461
53475
  }
53462
- roots.push(import_node_path17.default.dirname(real));
53476
+ roots.push(import_node_path19.default.dirname(real));
53463
53477
  }
53464
53478
  return roots;
53465
53479
  }
@@ -53467,10 +53481,10 @@ function loadDashboardPages(logger, roots = candidateRoots()) {
53467
53481
  const pages = /* @__PURE__ */ new Map();
53468
53482
  for (const page of DASHBOARD_PAGES) {
53469
53483
  for (const root of roots) {
53470
- const file = import_node_path17.default.join(root, `${page}.html`);
53484
+ const file = import_node_path19.default.join(root, `${page}.html`);
53471
53485
  try {
53472
- if (import_node_fs17.default.statSync(file).isFile()) {
53473
- pages.set(page, import_node_fs17.default.readFileSync(file, "utf8"));
53486
+ if (import_node_fs20.default.statSync(file).isFile()) {
53487
+ pages.set(page, import_node_fs20.default.readFileSync(file, "utf8"));
53474
53488
  logger?.info("dashboard.page-asset.resolved", { page, root });
53475
53489
  break;
53476
53490
  }
@@ -53486,10 +53500,10 @@ function loadDashboardPages(logger, roots = candidateRoots()) {
53486
53500
  init_protocol();
53487
53501
 
53488
53502
  // src/dashboard/sign.ts
53489
- var import_node_crypto7 = __toESM(require("crypto"), 1);
53503
+ var import_node_crypto8 = __toESM(require("crypto"), 1);
53490
53504
 
53491
53505
  // src/attachment/sign-url.ts
53492
- var import_node_crypto6 = __toESM(require("crypto"), 1);
53506
+ var import_node_crypto7 = __toESM(require("crypto"), 1);
53493
53507
  var HMAC_ALGO = "sha256";
53494
53508
  function base64urlEncode(buf) {
53495
53509
  const b3 = typeof buf === "string" ? Buffer.from(buf, "utf8") : buf;
@@ -53507,7 +53521,7 @@ function decodeAbsPathFromUrl(encoded) {
53507
53521
  var DOMAIN_PREFIX = "clawd-attach-v1|";
53508
53522
  function computeSig(secret, absPath, e) {
53509
53523
  const msg = e === null ? `${DOMAIN_PREFIX}${absPath}` : `${DOMAIN_PREFIX}${absPath}|${e}`;
53510
- return import_node_crypto6.default.createHmac(HMAC_ALGO, secret).update(msg).digest();
53524
+ return import_node_crypto7.default.createHmac(HMAC_ALGO, secret).update(msg).digest();
53511
53525
  }
53512
53526
  function signUrlParts(secret, absPath, ttlSeconds, now = Date.now) {
53513
53527
  const e = ttlSeconds === null ? null : Math.floor(now() / 1e3) + ttlSeconds;
@@ -53542,7 +53556,7 @@ function verifySignedUrl(secret, absPath, eRaw, s2, now = Date.now) {
53542
53556
  if (provided.length !== expected.length) {
53543
53557
  return { ok: false, code: "BAD_SIG" };
53544
53558
  }
53545
- if (!import_node_crypto6.default.timingSafeEqual(provided, expected)) {
53559
+ if (!import_node_crypto7.default.timingSafeEqual(provided, expected)) {
53546
53560
  return { ok: false, code: "BAD_SIG" };
53547
53561
  }
53548
53562
  if (e !== null && now() / 1e3 > e) {
@@ -53570,7 +53584,7 @@ function resolveSignedFileUrl(secret, url, now = Date.now) {
53570
53584
 
53571
53585
  // src/dashboard/sign.ts
53572
53586
  var DOMAIN_PREFIX2 = "clawd-dashboard-v1|";
53573
- var sigOf = (secret, page, e) => import_node_crypto7.default.createHmac("sha256", secret).update(`${DOMAIN_PREFIX2}${page}|${e}`).digest();
53587
+ var sigOf = (secret, page, e) => import_node_crypto8.default.createHmac("sha256", secret).update(`${DOMAIN_PREFIX2}${page}|${e}`).digest();
53574
53588
  function signDashboardLink(secret, page, ttlSeconds, now = Date.now) {
53575
53589
  const e = Math.floor(now() / 1e3) + ttlSeconds;
53576
53590
  return { e, s: base64urlEncode(sigOf(secret, page, e)) };
@@ -53584,7 +53598,7 @@ function verifyDashboardLink(secret, page, eRaw, s2, now = Date.now) {
53584
53598
  const e = Number(eRaw);
53585
53599
  const want = sigOf(secret, page, e);
53586
53600
  const got = base64urlDecodeBuf(s2);
53587
- if (got.length !== want.length || !import_node_crypto7.default.timingSafeEqual(got, want)) return { ok: false, code: "BAD_SIG" };
53601
+ if (got.length !== want.length || !import_node_crypto8.default.timingSafeEqual(got, want)) return { ok: false, code: "BAD_SIG" };
53588
53602
  if (Math.floor(now() / 1e3) > e) return { ok: false, code: "EXPIRED" };
53589
53603
  return { ok: true };
53590
53604
  }
@@ -54056,30 +54070,30 @@ function createDashboardData(deps) {
54056
54070
  }
54057
54071
 
54058
54072
  // src/share-ui/load.ts
54059
- var import_node_fs19 = __toESM(require("fs"), 1);
54060
- var import_node_path19 = __toESM(require("path"), 1);
54073
+ var import_node_fs22 = __toESM(require("fs"), 1);
54074
+ var import_node_path21 = __toESM(require("path"), 1);
54061
54075
  var import_node_url4 = require("url");
54062
54076
 
54063
54077
  // src/share-ui/asset-loader.ts
54064
- var import_node_fs18 = __toESM(require("fs"), 1);
54065
- var import_node_path18 = __toESM(require("path"), 1);
54078
+ var import_node_fs21 = __toESM(require("fs"), 1);
54079
+ var import_node_path20 = __toESM(require("path"), 1);
54066
54080
  function createShareUiAssetLoader(opts) {
54067
54081
  let indexHtml;
54068
54082
  try {
54069
- indexHtml = import_node_fs18.default.readFileSync(opts.indexHtmlPath, "utf8");
54083
+ indexHtml = import_node_fs21.default.readFileSync(opts.indexHtmlPath, "utf8");
54070
54084
  } catch (err) {
54071
54085
  throw new Error(`share-ui index.html not found at ${opts.indexHtmlPath}: ${err.message}`);
54072
54086
  }
54073
- const assetsDir = import_node_path18.default.resolve(opts.assetsDir);
54087
+ const assetsDir = import_node_path20.default.resolve(opts.assetsDir);
54074
54088
  return {
54075
54089
  renderIndexHtml() {
54076
54090
  return indexHtml;
54077
54091
  },
54078
54092
  resolveAssetPath(rel) {
54079
- const resolved = import_node_path18.default.resolve(assetsDir, rel);
54080
- if (resolved !== assetsDir && !resolved.startsWith(assetsDir + import_node_path18.default.sep)) return null;
54093
+ const resolved = import_node_path20.default.resolve(assetsDir, rel);
54094
+ if (resolved !== assetsDir && !resolved.startsWith(assetsDir + import_node_path20.default.sep)) return null;
54081
54095
  try {
54082
- if (import_node_fs18.default.statSync(resolved).isFile()) return resolved;
54096
+ if (import_node_fs21.default.statSync(resolved).isFile()) return resolved;
54083
54097
  } catch {
54084
54098
  }
54085
54099
  return null;
@@ -54093,10 +54107,10 @@ function bundleDirFromArgv(argv1) {
54093
54107
  if (!argv1) return null;
54094
54108
  let real = argv1;
54095
54109
  try {
54096
- real = import_node_fs19.default.realpathSync(argv1);
54110
+ real = import_node_fs22.default.realpathSync(argv1);
54097
54111
  } catch {
54098
54112
  }
54099
- return import_node_path19.default.dirname(real);
54113
+ return import_node_path21.default.dirname(real);
54100
54114
  }
54101
54115
  function tryLoadShareUi(logger) {
54102
54116
  return tryLoadUi("share-ui", "guest.html", logger);
@@ -54104,20 +54118,20 @@ function tryLoadShareUi(logger) {
54104
54118
  function tryLoadUi(directory, entry, logger) {
54105
54119
  const candidates = [];
54106
54120
  try {
54107
- const here = import_node_path19.default.dirname((0, import_node_url4.fileURLToPath)(import_meta4.url));
54121
+ const here = import_node_path21.default.dirname((0, import_node_url4.fileURLToPath)(import_meta4.url));
54108
54122
  candidates.push(here);
54109
- candidates.push(import_node_path19.default.resolve(here, ".."));
54110
- candidates.push(import_node_path19.default.resolve(here, "..", "..", "dist"));
54123
+ candidates.push(import_node_path21.default.resolve(here, ".."));
54124
+ candidates.push(import_node_path21.default.resolve(here, "..", "..", "dist"));
54111
54125
  } catch {
54112
54126
  }
54113
54127
  const argvDir = bundleDirFromArgv(process.argv[1]);
54114
54128
  if (argvDir) candidates.push(argvDir);
54115
54129
  for (const root of candidates) {
54116
- const uiDir = import_node_path19.default.join(root, directory);
54117
- const indexHtmlPath = import_node_path19.default.join(uiDir, entry);
54118
- const assetsDir = import_node_path19.default.join(uiDir, "assets");
54130
+ const uiDir = import_node_path21.default.join(root, directory);
54131
+ const indexHtmlPath = import_node_path21.default.join(uiDir, entry);
54132
+ const assetsDir = import_node_path21.default.join(uiDir, "assets");
54119
54133
  try {
54120
- if (import_node_fs19.default.statSync(indexHtmlPath).isFile() && import_node_fs19.default.statSync(assetsDir).isDirectory()) {
54134
+ if (import_node_fs22.default.statSync(indexHtmlPath).isFile() && import_node_fs22.default.statSync(assetsDir).isDirectory()) {
54121
54135
  logger?.info(`${directory}.assets-root.resolved`, { root: uiDir });
54122
54136
  return createShareUiAssetLoader({ indexHtmlPath, assetsDir });
54123
54137
  }
@@ -54137,21 +54151,21 @@ function tryLoadOwnerUi(logger) {
54137
54151
  }
54138
54152
 
54139
54153
  // src/owner-web/session-store.ts
54140
- var import_node_crypto8 = require("crypto");
54141
- var import_node_fs20 = __toESM(require("fs"), 1);
54142
- var import_node_path20 = __toESM(require("path"), 1);
54154
+ var import_node_crypto9 = require("crypto");
54155
+ var import_node_fs23 = __toESM(require("fs"), 1);
54156
+ var import_node_path22 = __toESM(require("path"), 1);
54143
54157
  var WEB_SESSION_FILE = "web-sessions.json";
54144
54158
  var WEB_TOKEN_PREFIX = "cw_";
54145
54159
  var TICKET_TTL_MS = 6e4;
54146
54160
  var SESSION_TTL_MS = 7 * 24 * 36e5;
54147
54161
  var MAX_OUTSTANDING_TICKETS = 32;
54148
54162
  function digest(secret) {
54149
- return (0, import_node_crypto8.createHash)("sha256").update(secret).digest("hex");
54163
+ return (0, import_node_crypto9.createHash)("sha256").update(secret).digest("hex");
54150
54164
  }
54151
54165
  function createWebSessionStore(opts) {
54152
54166
  const now = opts.now ?? Date.now;
54153
- const random = opts.randomToken ?? ((bytes) => (0, import_node_crypto8.randomBytes)(bytes).toString("base64url"));
54154
- const file = import_node_path20.default.join(opts.dataDir, WEB_SESSION_FILE);
54167
+ const random = opts.randomToken ?? ((bytes) => (0, import_node_crypto9.randomBytes)(bytes).toString("base64url"));
54168
+ const file = import_node_path22.default.join(opts.dataDir, WEB_SESSION_FILE);
54155
54169
  const tickets = /* @__PURE__ */ new Map();
54156
54170
  let sessions = /* @__PURE__ */ new Map();
54157
54171
  const live = (m3) => {
@@ -54159,7 +54173,7 @@ function createWebSessionStore(opts) {
54159
54173
  return new Map([...m3].filter(([, r2]) => r2.expiresAt > t2));
54160
54174
  };
54161
54175
  try {
54162
- const parsed = JSON.parse(import_node_fs20.default.readFileSync(file, "utf8"));
54176
+ const parsed = JSON.parse(import_node_fs23.default.readFileSync(file, "utf8"));
54163
54177
  const entries = Object.entries(parsed.sessions ?? {}).filter(
54164
54178
  ([, r2]) => typeof r2?.origin === "string" && typeof r2?.expiresAt === "number"
54165
54179
  );
@@ -54167,14 +54181,14 @@ function createWebSessionStore(opts) {
54167
54181
  } catch {
54168
54182
  }
54169
54183
  const persist = (next) => {
54170
- import_node_fs20.default.mkdirSync(opts.dataDir, { recursive: true });
54184
+ import_node_fs23.default.mkdirSync(opts.dataDir, { recursive: true });
54171
54185
  const tmp = `${file}.${process.pid}.tmp`;
54172
54186
  try {
54173
- import_node_fs20.default.writeFileSync(tmp, JSON.stringify({ sessions: Object.fromEntries(next) }), { mode: 384 });
54174
- import_node_fs20.default.chmodSync(tmp, 384);
54175
- import_node_fs20.default.renameSync(tmp, file);
54187
+ import_node_fs23.default.writeFileSync(tmp, JSON.stringify({ sessions: Object.fromEntries(next) }), { mode: 384 });
54188
+ import_node_fs23.default.chmodSync(tmp, 384);
54189
+ import_node_fs23.default.renameSync(tmp, file);
54176
54190
  } catch (err) {
54177
- import_node_fs20.default.rmSync(tmp, { force: true });
54191
+ import_node_fs23.default.rmSync(tmp, { force: true });
54178
54192
  throw new Error(`web session persist failed: ${err.code ?? "unknown"}`);
54179
54193
  }
54180
54194
  };
@@ -54223,7 +54237,7 @@ function buildLaunchUrl(origin, issued) {
54223
54237
  }
54224
54238
 
54225
54239
  // src/visitor/visitor-token.ts
54226
- var import_node_crypto9 = __toESM(require("crypto"), 1);
54240
+ var import_node_crypto10 = __toESM(require("crypto"), 1);
54227
54241
 
54228
54242
  // ../protocol/src/index.ts
54229
54243
  init_runtime();
@@ -54231,7 +54245,7 @@ init_runtime();
54231
54245
  // src/visitor/visitor-token.ts
54232
54246
  var DOMAIN_PREFIX3 = "clawd-visitor-v1|";
54233
54247
  function hmac(secret, body) {
54234
- return import_node_crypto9.default.createHmac("sha256", secret).update(`${DOMAIN_PREFIX3}${body}`).digest("base64url");
54248
+ return import_node_crypto10.default.createHmac("sha256", secret).update(`${DOMAIN_PREFIX3}${body}`).digest("base64url");
54235
54249
  }
54236
54250
  function signVisitorToken(secret, payload) {
54237
54251
  const body = Buffer.from(JSON.stringify(payload)).toString("base64url");
@@ -54244,7 +54258,7 @@ function verifyVisitorToken(secret, token, now) {
54244
54258
  const sig = token.slice(dot + 1);
54245
54259
  const expected = hmac(secret, body);
54246
54260
  if (sig.length !== expected.length) return { ok: false, reason: "BAD_SIGNATURE" };
54247
- if (!import_node_crypto9.default.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
54261
+ if (!import_node_crypto10.default.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
54248
54262
  return { ok: false, reason: "BAD_SIGNATURE" };
54249
54263
  }
54250
54264
  let payload;
@@ -54291,20 +54305,20 @@ function buildVisitorLogin(deps) {
54291
54305
  }
54292
54306
 
54293
54307
  // src/visitor/visitor-store.ts
54294
- var import_node_fs21 = __toESM(require("fs"), 1);
54295
- var import_node_path21 = __toESM(require("path"), 1);
54308
+ var import_node_fs24 = __toESM(require("fs"), 1);
54309
+ var import_node_path23 = __toESM(require("path"), 1);
54296
54310
  function createVisitorStore(opts) {
54297
- const file = import_node_path21.default.join(opts.dir, "visitors.json");
54311
+ const file = import_node_path23.default.join(opts.dir, "visitors.json");
54298
54312
  const read = () => {
54299
54313
  try {
54300
- return JSON.parse(import_node_fs21.default.readFileSync(file, "utf8"));
54314
+ return JSON.parse(import_node_fs24.default.readFileSync(file, "utf8"));
54301
54315
  } catch {
54302
54316
  return [];
54303
54317
  }
54304
54318
  };
54305
54319
  const write = (rows) => {
54306
- import_node_fs21.default.mkdirSync(opts.dir, { recursive: true });
54307
- import_node_fs21.default.writeFileSync(file, JSON.stringify(rows, null, 2));
54320
+ import_node_fs24.default.mkdirSync(opts.dir, { recursive: true });
54321
+ import_node_fs24.default.writeFileSync(file, JSON.stringify(rows, null, 2));
54308
54322
  };
54309
54323
  return {
54310
54324
  upsert(r2) {
@@ -54676,23 +54690,6 @@ function stringValue(value) {
54676
54690
  return typeof value === "string" && value.length > 0 ? value : void 0;
54677
54691
  }
54678
54692
 
54679
- // src/tools/first-byte.ts
54680
- var VISIBLE = /* @__PURE__ */ new Set(["thinking", "tool_call", "text"]);
54681
- function createFirstByteClock(now = Date.now) {
54682
- let at3 = null;
54683
- return {
54684
- reset() {
54685
- at3 = null;
54686
- },
54687
- see(events) {
54688
- if (at3 === null && events.some((e) => VISIBLE.has(e.kind))) at3 = now();
54689
- },
54690
- afterFirstByteMs() {
54691
- return at3 === null ? void 0 : Math.max(0, Math.round(now() - at3));
54692
- }
54693
- };
54694
- }
54695
-
54696
54693
  // src/tools/codex-app-server-params.ts
54697
54694
  init_protocol();
54698
54695
  function resolveApprovalPolicy(ctx) {
@@ -55620,7 +55617,7 @@ var CodexAdapter = class {
55620
55617
  };
55621
55618
 
55622
55619
  // src/tools/claude-tui.ts
55623
- var import_node_crypto10 = require("crypto");
55620
+ var import_node_crypto11 = require("crypto");
55624
55621
  var import_node_fs28 = __toESM(require("fs"), 1);
55625
55622
  var import_node_os13 = __toESM(require("os"), 1);
55626
55623
  var import_node_path29 = __toESM(require("path"), 1);
@@ -56508,7 +56505,7 @@ function observeScreenIdle(surface, opts) {
56508
56505
  };
56509
56506
  }
56510
56507
  function shortHash(s2) {
56511
- return (0, import_node_crypto10.createHash)("sha1").update(s2).digest("hex").slice(0, 8);
56508
+ return (0, import_node_crypto11.createHash)("sha1").update(s2).digest("hex").slice(0, 8);
56512
56509
  }
56513
56510
  function firstLineDiff(prev, next) {
56514
56511
  const p3 = prev.split("\n");
@@ -57600,7 +57597,7 @@ function resolveSourceJsonlPath(sourceFile, home) {
57600
57597
  // src/shift/store.ts
57601
57598
  var import_promises3 = __toESM(require("fs/promises"), 1);
57602
57599
  var import_node_path40 = __toESM(require("path"), 1);
57603
- var import_node_crypto11 = require("crypto");
57600
+ var import_node_crypto12 = require("crypto");
57604
57601
 
57605
57602
  // src/shift/schedule.ts
57606
57603
  var import_cron_parser = __toESM(require_dist(), 1);
@@ -57704,7 +57701,7 @@ function createShiftStore(deps) {
57704
57701
  const shift = {
57705
57702
  ...input,
57706
57703
  schedule,
57707
- id: (0, import_node_crypto11.randomUUID)(),
57704
+ id: (0, import_node_crypto12.randomUUID)(),
57708
57705
  createdAtMs: now,
57709
57706
  updatedAtMs: now,
57710
57707
  state: { nextRunAtMs },
@@ -58157,7 +58154,7 @@ function buildShiftInternalHandlers(deps) {
58157
58154
  }
58158
58155
 
58159
58156
  // src/handlers/deploy.ts
58160
- var import_node_crypto15 = require("crypto");
58157
+ var import_node_crypto16 = require("crypto");
58161
58158
  var import_node_perf_hooks = require("perf_hooks");
58162
58159
 
58163
58160
  // src/deploy/persona-test.ts
@@ -58203,7 +58200,7 @@ function discoverPublisherTest(dir) {
58203
58200
  }
58204
58201
 
58205
58202
  // src/deploy/verified-release.ts
58206
- var import_node_crypto13 = require("crypto");
58203
+ var import_node_crypto14 = require("crypto");
58207
58204
 
58208
58205
  // src/deploy/release-archive.ts
58209
58206
  var import_jszip = __toESM(require_lib3(), 1);
@@ -58681,7 +58678,7 @@ init_protocol();
58681
58678
  // src/deploy/deploy-file.ts
58682
58679
  var import_promises4 = __toESM(require("fs/promises"), 1);
58683
58680
  var import_node_path43 = __toESM(require("path"), 1);
58684
- var import_node_crypto12 = require("crypto");
58681
+ var import_node_crypto13 = require("crypto");
58685
58682
  init_zod();
58686
58683
  init_protocol();
58687
58684
 
@@ -58926,7 +58923,7 @@ async function restoreDeployFileRaw(dir, raw) {
58926
58923
  }
58927
58924
  var emptyScanFile = () => ({ version: 4, scans: [], releases: [], promotions: [] });
58928
58925
  var LEGACY_SCAN_ID = "legacy";
58929
- var newScanId = () => (0, import_node_crypto12.randomBytes)(4).toString("hex");
58926
+ var newScanId = () => (0, import_node_crypto13.randomBytes)(4).toString("hex");
58930
58927
  var z1 = DeployScanSchema.omit({ id: true, manifest: true }).extend({ releasedHead: DeployScanSchema.shape.head }).strict();
58931
58928
  function migrateV1(v1, manifest) {
58932
58929
  const { releasedHead, ...rest } = v1;
@@ -63574,7 +63571,7 @@ init_protocol();
63574
63571
  function validatePersonaRelease(raw, expected) {
63575
63572
  const record4 = VerifiedPersonaReleaseSchema.parse(raw);
63576
63573
  if (record4.repository !== expected.repository || record4.commit !== expected.commit || new URL(record4.verification.endpoint).origin !== expected.endpoint) throw new Error("\u5236\u54C1\u4E0E\u672C\u6B21\u6D4B\u8BD5\u4ED3\u5E93\u3001\u63D0\u4EA4\u6216\u73AF\u5883\u4E0D\u4E00\u81F4");
63577
- const fingerprint = (0, import_node_crypto13.createHash)("sha256").update(JSON.stringify({
63574
+ const fingerprint = (0, import_node_crypto14.createHash)("sha256").update(JSON.stringify({
63578
63575
  component: record4.component,
63579
63576
  image: record4.image,
63580
63577
  commit: record4.commit,
@@ -63699,7 +63696,7 @@ async function resumePromotion(deps, original, options = {}) {
63699
63696
  init_protocol();
63700
63697
 
63701
63698
  // src/deploy/artifact.ts
63702
- var import_node_crypto14 = require("crypto");
63699
+ var import_node_crypto15 = require("crypto");
63703
63700
  var import_node_fs38 = __toESM(require("fs"), 1);
63704
63701
  var import_node_os14 = __toESM(require("os"), 1);
63705
63702
  var import_node_path45 = __toESM(require("path"), 1);
@@ -63761,7 +63758,7 @@ async function downloadOnce(exec, url, { listEntries }) {
63761
63758
  if (declared > ARTIFACT_MAX_BYTES) throw new Error(`\u8D44\u4EA7 ${declared} \u5B57\u8282\uFF0C\u8D85\u8FC7\u4E0A\u9650 ${ARTIFACT_MAX_BYTES}\uFF1A${url}`);
63762
63759
  const dir = await import_node_fs38.default.promises.mkdtemp(import_node_path45.default.join(import_node_os14.default.tmpdir(), "clawd-artifact-"));
63763
63760
  const file = import_node_path45.default.join(dir, "pkg");
63764
- const hash = (0, import_node_crypto14.createHash)("sha256");
63761
+ const hash = (0, import_node_crypto15.createHash)("sha256");
63765
63762
  let size = 0;
63766
63763
  const meter = new import_node_stream3.Transform({
63767
63764
  transform(chunk, _enc, cb) {
@@ -64868,7 +64865,7 @@ function buildDeployHandlers(deps) {
64868
64865
  checkPublisherTest();
64869
64866
  }
64870
64867
  if (await deps.claimPublisher(cloudPersonaIdOf(repo2.url), "integration") === "taken") throw invalid("\u6D4B\u8BD5\u73AF\u5883\u91CC\u7684\u8FD9\u4E2A\u540D\u5B57\u5DF2\u7531\u522B\u4EBA\u53D1\u5E03");
64871
- const releaseId = (0, import_node_crypto15.randomUUID)();
64868
+ const releaseId = (0, import_node_crypto16.randomUUID)();
64872
64869
  try {
64873
64870
  const result = await release(deps.exec, api, { dir, now: deps.now, auth, manifest, rescanOnRemoteChange: !rollback2, onPrepared: async (head) => {
64874
64871
  armUndo(void 0);
@@ -65025,7 +65022,7 @@ function buildDeployHandlers(deps) {
65025
65022
  const latest = await readHistory(mustPersona(personaId2));
65026
65023
  await writeScanFile(mustPersona(personaId2), { ...latest, promotions: latest.promotions.map((p3) => p3.id === old.id ? { ...p3, phase: "failed", error: "\u51C6\u5907\u9636\u6BB5\u6D4B\u8BD5\u7248\u672C\u5DF2\u53D8\u5316\uFF0C\u5DF2\u7531\u91CD\u65B0\u786E\u8BA4\u7684\u65B0\u4EFB\u52A1\u66FF\u4EE3" } : p3) });
65027
65024
  }
65028
- const promotion = await continuePromotion(personaId2, record4, reuse2 ? { ...old, verified: snapshot ?? record4.verified } : { id: (0, import_node_crypto15.randomUUID)(), releaseId, at: deps.now(), phase: "prepared", verified: record4.verified }, true);
65025
+ const promotion = await continuePromotion(personaId2, record4, reuse2 ? { ...old, verified: snapshot ?? record4.verified } : { id: (0, import_node_crypto16.randomUUID)(), releaseId, at: deps.now(), phase: "prepared", verified: record4.verified }, true);
65029
65026
  return { response: { type: "deploy:promote", promotion } };
65030
65027
  };
65031
65028
  const applyConfig = async (frame, _client, ctx) => {
@@ -65059,7 +65056,7 @@ function buildDeployHandlers(deps) {
65059
65056
  const keys = changedConfigKeys(config, await testedConfigOf(dir, source));
65060
65057
  if (!retryAfterFailure && keys?.length === 0) throw invalid("\u914D\u7F6E\u548C\u6D4B\u8BD5\u73AF\u5883\u91CC\u7684\u4E00\u81F4\uFF0C\u6CA1\u6709\u9700\u8981\u5E94\u7528\u7684");
65061
65058
  if (latest.workflowVersion < (keys ? workflowVersionForConfigKeys(keys) : DEPLOY_WORKFLOW_VERSION)) throw invalid("\u8FD9\u4E2A\u4ED3\u5E93\u7684\u53D1\u5E03\u6D41\u6C34\u7EBF\u662F\u65E7\u7248\u672C\uFF0C\u4E0D\u8BA4\u4FDD\u5E95 Pod \u6570\u2014\u2014\u8BF7\u5148\u5B8C\u6574\u91CD\u65B0\u53D1\u5E03\u4E00\u6B21\uFF08\u4F1A\u91CD\u65B0\u6784\u5EFA\uFF09");
65062
- const id = (0, import_node_crypto15.randomUUID)();
65059
+ const id = (0, import_node_crypto16.randomUUID)();
65063
65060
  try {
65064
65061
  await api.dispatchWorkflow(slug, DEPLOY_WORKFLOW_FILE, "integration", { environment: "integration", release_json: JSON.stringify(source.verified), config_json: JSON.stringify(config), config_id: id });
65065
65062
  } catch (err) {
@@ -65080,7 +65077,7 @@ function buildDeployHandlers(deps) {
65080
65077
  };
65081
65078
  function startTrace(personaId2, event) {
65082
65079
  const started = import_node_perf_hooks.performance.now();
65083
- const traceId = (0, import_node_crypto15.randomUUID)();
65080
+ const traceId = (0, import_node_crypto16.randomUUID)();
65084
65081
  const log = (phase, meta) => {
65085
65082
  try {
65086
65083
  deps.logger?.info(`${event}.${phase}`, { personaId: personaId2, traceId, ...meta });
@@ -66684,7 +66681,7 @@ ${formatLarkSpeakerReminder(speaker)}`
66684
66681
  }
66685
66682
 
66686
66683
  // src/lark-bot-connector/envelope.ts
66687
- var import_node_crypto16 = require("crypto");
66684
+ var import_node_crypto17 = require("crypto");
66688
66685
  var LARK_ENVELOPE_PREFIX = "clawdlbe1";
66689
66686
  function verifyLarkEventEnvelope(args) {
66690
66687
  const { token, publicKeyPem } = args;
@@ -66703,7 +66700,7 @@ function verifyLarkEventEnvelope(args) {
66703
66700
  const data = Buffer.from(`${prefix}.${payloadB64}`, "utf8");
66704
66701
  let sigOk = false;
66705
66702
  try {
66706
- sigOk = (0, import_node_crypto16.verify)(null, data, publicKeyPem, Buffer.from(sigB64, "base64url"));
66703
+ sigOk = (0, import_node_crypto17.verify)(null, data, publicKeyPem, Buffer.from(sigB64, "base64url"));
66707
66704
  } catch {
66708
66705
  sigOk = false;
66709
66706
  }
@@ -67325,7 +67322,7 @@ async function portableCloudInput(text, resolvers) {
67325
67322
  }
67326
67323
 
67327
67324
  // src/tools/cloud-turn-session.ts
67328
- var import_node_crypto17 = require("crypto");
67325
+ var import_node_crypto18 = require("crypto");
67329
67326
  function withBranchIntent(text, branch) {
67330
67327
  return `${text}
67331
67328
 
@@ -67352,7 +67349,7 @@ function createCloudTurnSession(args) {
67352
67349
  void client.commandTurn(personaId2, conversationId, turnId, command).catch((e) => sink.onError(`\u4E91\u4E0A\u547D\u4EE4\u5931\u8D25\uFF1A${e.message}`));
67353
67350
  };
67354
67351
  return {
67355
- startTurn(text, commandId = (0, import_node_crypto17.randomUUID)(), prepared = false) {
67352
+ startTurn(text, commandId = (0, import_node_crypto18.randomUUID)(), prepared = false) {
67356
67353
  if (closed || live.has(commandId)) return;
67357
67354
  conversationId ??= commandId;
67358
67355
  live.add(commandId);
@@ -67671,7 +67668,7 @@ var PiRpcClient = class {
67671
67668
 
67672
67669
  // src/tools/pi-session.ts
67673
67670
  var import_node_child_process12 = require("child_process");
67674
- var import_node_crypto18 = require("crypto");
67671
+ var import_node_crypto19 = require("crypto");
67675
67672
  var import_node_fs43 = __toESM(require("fs"), 1);
67676
67673
  var import_node_path49 = __toESM(require("path"), 1);
67677
67674
 
@@ -67953,7 +67950,7 @@ ${dirs.map((d2) => `- ${d2}`).join("\n")}`;
67953
67950
  }
67954
67951
  function createPiSession(ctx, sink, deps = {}) {
67955
67952
  const cmd = process.env.PI_BIN ?? "pi";
67956
- const sessionId = ctx.toolSessionId ?? (0, import_node_crypto18.randomUUID)();
67953
+ const sessionId = ctx.toolSessionId ?? (0, import_node_crypto19.randomUUID)();
67957
67954
  const skillsDir = import_node_path49.default.join(ctx.cwd, ".claude", "skills");
67958
67955
  const exists = deps.skillsDirExists ?? ((d2) => import_node_fs43.default.existsSync(d2));
67959
67956
  const args = buildPiArgs(ctx, {
@@ -68198,7 +68195,7 @@ var PiAdapter = class {
68198
68195
  }
68199
68196
  if (models.length === 0 && opts.strict) throw new Error("Pi model refresh returned no models");
68200
68197
  if (models.length === 0) models = [PI_DEFAULT_MODEL_ENTRY];
68201
- for (const m3 of models) if (m3.id) this.windows.set(m3.id, m3.contextWindowSize);
68198
+ for (const m3 of models) if (m3.id && m3.contextWindowSize) this.windows.set(m3.id, m3.contextWindowSize);
68202
68199
  return buildPiCapabilities(models);
68203
68200
  }
68204
68201
  // 纯函数无 IO:查 capabilities 加载时填好的表;未加载 / 未知 → undefined(运行时 get_state 的 meta_update 会补)
@@ -68311,7 +68308,6 @@ var CloudPiAdapter = class {
68311
68308
 
68312
68309
  // src/tools/claude-cloud.ts
68313
68310
  init_protocol();
68314
- init_claude();
68315
68311
 
68316
68312
  // src/tools/claude-cloud-session.ts
68317
68313
  function createCloudClaudeSession(ctx, sink, deps) {
@@ -68385,12 +68381,8 @@ var CloudClaudeAdapter = class {
68385
68381
  async capabilities() {
68386
68382
  return CLOUD_CLAUDE_CAPABILITIES;
68387
68383
  }
68388
- // 号池里的模型 id 不限 Anthropic:带 [1m] = 1M(CC 的写法),认得的 Claude 型号按本机的表;
68389
- // 别的 CC 不知道它的窗口、按 200K 算(官方 model-config:认不出的 id 不带 [1m] 就是 200K),这里报同一个数,部署页让用户自己选要不要 1M
68390
- resolveContextWindow(modelId) {
68391
- if (!modelId) return void 0;
68392
- if (/\[1m\]$/i.test(modelId)) return 1e6;
68393
- return resolveClaudeContextWindow(modelId) ?? 2e5;
68384
+ resolveContextWindow(_modelId) {
68385
+ return void 0;
68394
68386
  }
68395
68387
  createSession(ctx, sink) {
68396
68388
  return createCloudClaudeSession(ctx, sink, { client: this.clientForEnvironment?.(ctx.cloudEnvironment) ?? this.client, logger: this.logger });
@@ -69415,7 +69407,7 @@ var wrapper_default = import_websocket.default;
69415
69407
 
69416
69408
  // src/transport/local-ws-server.ts
69417
69409
  var import_node_http = __toESM(require("http"), 1);
69418
- var import_node_crypto19 = require("crypto");
69410
+ var import_node_crypto20 = require("crypto");
69419
69411
  var LocalWsServer = class {
69420
69412
  constructor(opts) {
69421
69413
  this.opts = opts;
@@ -69627,7 +69619,7 @@ var LocalWsServer = class {
69627
69619
  }
69628
69620
  }
69629
69621
  onConnection(socket, remoteAddress, origin) {
69630
- const id = (0, import_node_crypto19.randomUUID)();
69622
+ const id = (0, import_node_crypto20.randomUUID)();
69631
69623
  const subscribedSessions = /* @__PURE__ */ new Map();
69632
69624
  const handle = {
69633
69625
  id,
@@ -70566,7 +70558,7 @@ var import_node_path58 = __toESM(require("path"), 1);
70566
70558
  // src/attachment/upload.ts
70567
70559
  var import_node_fs50 = __toESM(require("fs"), 1);
70568
70560
  var import_node_path56 = __toESM(require("path"), 1);
70569
- var import_node_crypto20 = __toESM(require("crypto"), 1);
70561
+ var import_node_crypto21 = __toESM(require("crypto"), 1);
70570
70562
  var import_promises8 = require("stream/promises");
70571
70563
  var UploadError = class extends Error {
70572
70564
  constructor(code, message) {
@@ -70590,11 +70582,11 @@ async function writeUploadedAttachment(args) {
70590
70582
  } catch (err) {
70591
70583
  throw new UploadError("STORAGE_ERROR", `mkdir failed: ${err.message}`);
70592
70584
  }
70593
- const hasher = import_node_crypto20.default.createHash("sha256");
70585
+ const hasher = import_node_crypto21.default.createHash("sha256");
70594
70586
  let actualSize = 0;
70595
70587
  const tmpPath = import_node_path56.default.join(
70596
70588
  attachmentsRoot,
70597
- `.upload-${process.pid}-${Date.now()}-${import_node_crypto20.default.randomBytes(4).toString("hex")}`
70589
+ `.upload-${process.pid}-${Date.now()}-${import_node_crypto21.default.randomBytes(4).toString("hex")}`
70598
70590
  );
70599
70591
  try {
70600
70592
  await (0, import_promises8.pipeline)(
@@ -71526,7 +71518,7 @@ function runAttachmentGc(args) {
71526
71518
  // src/attachment/group.ts
71527
71519
  var import_node_fs53 = __toESM(require("fs"), 1);
71528
71520
  var import_node_path60 = __toESM(require("path"), 1);
71529
- var import_node_crypto21 = __toESM(require("crypto"), 1);
71521
+ var import_node_crypto22 = __toESM(require("crypto"), 1);
71530
71522
  init_protocol();
71531
71523
  var GroupFileStore = class {
71532
71524
  dataDir;
@@ -71604,7 +71596,7 @@ var GroupFileStore = class {
71604
71596
  entries[idx] = next;
71605
71597
  } else {
71606
71598
  next = {
71607
- id: `gf-${import_node_crypto21.default.randomBytes(6).toString("base64url")}`,
71599
+ id: `gf-${import_node_crypto22.default.randomBytes(6).toString("base64url")}`,
71608
71600
  relPath: input.relPath,
71609
71601
  from: input.from,
71610
71602
  label: input.label,
@@ -71726,7 +71718,7 @@ function readSpawnedByDesktopFromEnv(env = process.env) {
71726
71718
  // src/tunnel/tunnel-manager.ts
71727
71719
  var import_node_fs58 = __toESM(require("fs"), 1);
71728
71720
  var import_node_path65 = __toESM(require("path"), 1);
71729
- var import_node_crypto22 = __toESM(require("crypto"), 1);
71721
+ var import_node_crypto23 = __toESM(require("crypto"), 1);
71730
71722
  var import_node_child_process17 = require("child_process");
71731
71723
 
71732
71724
  // src/tunnel/tunnel-store.ts
@@ -72223,7 +72215,7 @@ var TunnelManager = class {
72223
72215
  override: this.deps.frpcBinaryOverride ?? void 0
72224
72216
  });
72225
72217
  const tomlPath = import_node_path65.default.join(this.deps.dataDir, "frpc.toml");
72226
- const proxyName = `clawd-${t2.subdomain}-${localPort}-${import_node_crypto22.default.randomBytes(3).toString("hex")}`;
72218
+ const proxyName = `clawd-${t2.subdomain}-${localPort}-${import_node_crypto23.default.randomBytes(3).toString("hex")}`;
72227
72219
  const toml = buildFrpcToml({
72228
72220
  serverAddr: t2.frpsHost,
72229
72221
  serverPort: t2.frpsPort,
@@ -72324,7 +72316,7 @@ async function waitForFrpcReady(proc, timeoutMs) {
72324
72316
  // src/tunnel/device-key.ts
72325
72317
  var import_node_os24 = __toESM(require("os"), 1);
72326
72318
  var import_node_path66 = __toESM(require("path"), 1);
72327
- var import_node_crypto23 = __toESM(require("crypto"), 1);
72319
+ var import_node_crypto24 = __toESM(require("crypto"), 1);
72328
72320
  var DERIVE_SALT = "clawd-tunnel-device-v1";
72329
72321
  function deriveStableDeviceKey(opts = {}) {
72330
72322
  const hostname = opts.hostname ?? import_node_os24.default.hostname();
@@ -72334,13 +72326,13 @@ function deriveStableDeviceKey(opts = {}) {
72334
72326
  const normalizedDataDir = opts.dataDir ? import_node_path66.default.resolve(opts.dataDir) : null;
72335
72327
  const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
72336
72328
  const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
72337
- return import_node_crypto23.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
72329
+ return import_node_crypto24.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
72338
72330
  }
72339
72331
 
72340
72332
  // src/auth-store.ts
72341
72333
  var import_node_fs59 = __toESM(require("fs"), 1);
72342
72334
  var import_node_path67 = __toESM(require("path"), 1);
72343
- var import_node_crypto24 = __toESM(require("crypto"), 1);
72335
+ var import_node_crypto25 = __toESM(require("crypto"), 1);
72344
72336
  var AUTH_FILE_NAME = "auth.json";
72345
72337
  function authFilePath(dataDir) {
72346
72338
  return import_node_path67.default.join(dataDir, AUTH_FILE_NAME);
@@ -72377,10 +72369,10 @@ function loadOrCreateTunnelDeviceKey(opts) {
72377
72369
  return tunnelDeviceKey;
72378
72370
  }
72379
72371
  function defaultGenerateToken() {
72380
- return import_node_crypto24.default.randomBytes(32).toString("base64url");
72372
+ return import_node_crypto25.default.randomBytes(32).toString("base64url");
72381
72373
  }
72382
72374
  function defaultGenerateOwnerPrincipalId() {
72383
- return `owner-${import_node_crypto24.default.randomUUID()}`;
72375
+ return `owner-${import_node_crypto25.default.randomUUID()}`;
72384
72376
  }
72385
72377
  function readAuthFile(file) {
72386
72378
  try {
@@ -72512,7 +72504,7 @@ var OwnerIdentityStore = class {
72512
72504
  };
72513
72505
 
72514
72506
  // src/feishu-auth/login-flow.ts
72515
- var import_node_crypto25 = __toESM(require("crypto"), 1);
72507
+ var import_node_crypto26 = __toESM(require("crypto"), 1);
72516
72508
  var STATE_TTL_MS = 5 * 60 * 1e3;
72517
72509
  var LoginFlow = class {
72518
72510
  constructor(deps) {
@@ -72522,7 +72514,7 @@ var LoginFlow = class {
72522
72514
  pendingStates = /* @__PURE__ */ new Map();
72523
72515
  generation = 0;
72524
72516
  start() {
72525
- const state = import_node_crypto25.default.randomBytes(16).toString("base64url");
72517
+ const state = import_node_crypto26.default.randomBytes(16).toString("base64url");
72526
72518
  const now = (this.deps.now ?? Date.now)();
72527
72519
  this.pendingStates.set(state, { issuedAt: now, owner: this.deps.expectedUnionId?.() });
72528
72520
  this.gcExpired(now);
@@ -73056,7 +73048,7 @@ init_protocol();
73056
73048
  var import_node_fs62 = __toESM(require("fs"), 1);
73057
73049
  var import_node_os26 = __toESM(require("os"), 1);
73058
73050
  var import_node_path70 = __toESM(require("path"), 1);
73059
- var import_node_crypto26 = require("crypto");
73051
+ var import_node_crypto27 = require("crypto");
73060
73052
  init_claude_history();
73061
73053
 
73062
73054
  // src/session/fork-transcript.ts
@@ -73119,7 +73111,7 @@ function forkSession(input) {
73119
73111
  sourceFile = found;
73120
73112
  projectDir = import_node_path70.default.dirname(found);
73121
73113
  }
73122
- const forkedToolSessionId = (0, import_node_crypto26.randomUUID)();
73114
+ const forkedToolSessionId = (0, import_node_crypto27.randomUUID)();
73123
73115
  const forkedLines = forkTranscriptEntries(readJsonlEntries(sourceFile), {
73124
73116
  messageUuid: input.messageUuid,
73125
73117
  sessionId: forkedToolSessionId,
@@ -73474,7 +73466,7 @@ function appendImportLedger(dataDir, entry) {
73474
73466
 
73475
73467
  // src/handlers/session.ts
73476
73468
  init_protocol();
73477
- var import_node_crypto27 = require("crypto");
73469
+ var import_node_crypto28 = require("crypto");
73478
73470
  var import_node_path74 = __toESM(require("path"), 1);
73479
73471
  function canReadSearchHit(ctx, file) {
73480
73472
  if (!ctx || ctx.principal.kind === "owner") return true;
@@ -73543,7 +73535,7 @@ function buildSessionHandlers(deps) {
73543
73535
  if (!source.toolSessionId || !sourceConversationId) throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, "fork: \u6E90\u4F1A\u8BDD\u8FD8\u6CA1\u6709\u4E91\u7AEF\u5386\u53F2");
73544
73536
  if (source.cloudPendingTurns?.length) throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, "fork: \u8BF7\u7B49\u5F85\u6E90\u4F1A\u8BDD\u5F53\u524D\u4EFB\u52A1\u5B8C\u6210");
73545
73537
  const sessionId = newSessionId();
73546
- const threadId = (0, import_node_crypto27.randomUUID)();
73538
+ const threadId = (0, import_node_crypto28.randomUUID)();
73547
73539
  const result = await deps.cloudFork(source, {
73548
73540
  engine,
73549
73541
  source: {
@@ -75680,7 +75672,7 @@ function buildCloudConnectorsHandlers(deps) {
75680
75672
 
75681
75673
  // src/handlers/cloud-workspace.ts
75682
75674
  init_protocol();
75683
- var import_node_crypto28 = require("crypto");
75675
+ var import_node_crypto29 = require("crypto");
75684
75676
  function buildCloudWorkspaceHandlers(deps) {
75685
75677
  return {
75686
75678
  "cloud:workspace": async (frame, _client, ctx) => {
@@ -75708,7 +75700,7 @@ function buildCloudWorkspaceHandlers(deps) {
75708
75700
  ) || file.cloudPendingTurns?.length))
75709
75701
  throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, "\u8BF7\u7B49\u5F85\u5F53\u524D\u4EFB\u52A1\u5B8C\u6210");
75710
75702
  const conversationId = file.cloudConversationId ?? file.cloudExecutionId ?? file.sessionId;
75711
- const traceId = typeof frame.requestId === "string" && /^[A-Za-z0-9:_-]{1,128}$/.test(frame.requestId) ? frame.requestId : (0, import_node_crypto28.randomUUID)();
75703
+ const traceId = typeof frame.requestId === "string" && /^[A-Za-z0-9:_-]{1,128}$/.test(frame.requestId) ? frame.requestId : (0, import_node_crypto29.randomUUID)();
75712
75704
  const started = performance.now();
75713
75705
  const meta = { traceId, sessionId: args.sessionId, action: args.action };
75714
75706
  const log = (event, detail) => {
@@ -76068,7 +76060,7 @@ function computeMethodAccess(args) {
76068
76060
  }
76069
76061
 
76070
76062
  // src/version.ts
76071
- var version = "0.2.719".length > 0 ? "0.2.719" : "dev";
76063
+ var version = "0.2.721".length > 0 ? "0.2.721" : "dev";
76072
76064
 
76073
76065
  // src/cli-probe/probe.ts
76074
76066
  var fs87 = __toESM(require("fs"), 1);
@@ -76466,7 +76458,7 @@ init_protocol();
76466
76458
  // src/extension/bundle-zip.ts
76467
76459
  var import_promises12 = __toESM(require("fs/promises"), 1);
76468
76460
  var import_node_path79 = __toESM(require("path"), 1);
76469
- var import_node_crypto29 = __toESM(require("crypto"), 1);
76461
+ var import_node_crypto30 = __toESM(require("crypto"), 1);
76470
76462
  var import_jszip3 = __toESM(require_lib3(), 1);
76471
76463
  async function bundleExtensionDir(dir) {
76472
76464
  const entries = await listFilesSorted(dir);
@@ -76481,7 +76473,7 @@ async function bundleExtensionDir(dir) {
76481
76473
  compression: "DEFLATE",
76482
76474
  compressionOptions: { level: 6 }
76483
76475
  });
76484
- const sha256 = import_node_crypto29.default.createHash("sha256").update(buffer).digest("hex");
76476
+ const sha256 = import_node_crypto30.default.createHash("sha256").update(buffer).digest("hex");
76485
76477
  return { buffer, sha256 };
76486
76478
  }
76487
76479
  var FIXED_DATE = /* @__PURE__ */ new Date("2020-01-01T00:00:00.000Z");
@@ -76549,7 +76541,7 @@ function computePublishCheck(args) {
76549
76541
  var import_promises13 = __toESM(require("fs/promises"), 1);
76550
76542
  var import_node_path81 = __toESM(require("path"), 1);
76551
76543
  var import_node_os30 = __toESM(require("os"), 1);
76552
- var import_node_crypto30 = __toESM(require("crypto"), 1);
76544
+ var import_node_crypto31 = __toESM(require("crypto"), 1);
76553
76545
  var import_jszip4 = __toESM(require_lib3(), 1);
76554
76546
 
76555
76547
  // src/extension/paths.ts
@@ -76578,7 +76570,7 @@ var InstallError = class extends Error {
76578
76570
  };
76579
76571
  async function installFromChannel(args, deps) {
76580
76572
  const { channelRef, snapshotHash, bundleZip } = args;
76581
- const computed = import_node_crypto30.default.createHash("sha256").update(bundleZip).digest("hex");
76573
+ const computed = import_node_crypto31.default.createHash("sha256").update(bundleZip).digest("hex");
76582
76574
  if (computed !== snapshotHash) {
76583
76575
  throw new InstallError(
76584
76576
  "HASH_MISMATCH",
@@ -76670,7 +76662,7 @@ async function installFromChannel(args, deps) {
76670
76662
  var import_promises14 = __toESM(require("fs/promises"), 1);
76671
76663
  var import_node_path82 = __toESM(require("path"), 1);
76672
76664
  var import_node_os31 = __toESM(require("os"), 1);
76673
- var import_node_crypto31 = __toESM(require("crypto"), 1);
76665
+ var import_node_crypto32 = __toESM(require("crypto"), 1);
76674
76666
  var import_jszip5 = __toESM(require_lib3(), 1);
76675
76667
  var UpdateError = class extends Error {
76676
76668
  constructor(code, message) {
@@ -76708,7 +76700,7 @@ async function updateFromChannel(args, deps) {
76708
76700
  if (e instanceof UpdateError) throw e;
76709
76701
  throw e;
76710
76702
  }
76711
- const computed = import_node_crypto31.default.createHash("sha256").update(bundleZip).digest("hex");
76703
+ const computed = import_node_crypto32.default.createHash("sha256").update(bundleZip).digest("hex");
76712
76704
  if (computed !== snapshotHash) {
76713
76705
  throw new UpdateError(
76714
76706
  "HASH_MISMATCH",
@@ -77863,7 +77855,7 @@ async function uninstall(deps) {
77863
77855
  }
77864
77856
 
77865
77857
  // src/handlers/index.ts
77866
- var import_node_crypto32 = require("crypto");
77858
+ var import_node_crypto33 = require("crypto");
77867
77859
 
77868
77860
  // src/handlers/peer-exec.ts
77869
77861
  init_protocol();
@@ -78020,7 +78012,7 @@ function buildMethodHandlers(deps) {
78020
78012
  const c2 = deps.contactStore.get(deviceId);
78021
78013
  return c2 ? { deviceId: c2.deviceId, remoteUrl: c2.remoteUrl, connectToken: c2.connectToken } : null;
78022
78014
  },
78023
- genId: () => (0, import_node_crypto32.randomUUID)(),
78015
+ genId: () => (0, import_node_crypto33.randomUUID)(),
78024
78016
  now: () => Date.now(),
78025
78017
  forwardInboxPostToPeer,
78026
78018
  logger: deps.logger
@@ -78754,7 +78746,7 @@ async function startDaemon(config) {
78754
78746
  const channelStore = createChannelStore({
78755
78747
  filePath: import_node_path90.default.join(config.dataDir, "channels.json"),
78756
78748
  now: () => Date.now(),
78757
- genId: () => `ch-${(0, import_node_crypto33.randomUUID)().slice(0, 8)}`,
78749
+ genId: () => `ch-${(0, import_node_crypto34.randomUUID)().slice(0, 8)}`,
78758
78750
  onFlushError: (err) => logger.error("channel store flush failed", {
78759
78751
  reason: err instanceof Error ? err.message : String(err)
78760
78752
  })
@@ -78763,7 +78755,7 @@ async function startDaemon(config) {
78763
78755
  const topicStore = createTopicStore({
78764
78756
  filePath: import_node_path90.default.join(config.dataDir, "topics.json"),
78765
78757
  now: () => Date.now(),
78766
- genId: () => `tp-${(0, import_node_crypto33.randomUUID)().slice(0, 8)}`,
78758
+ genId: () => `tp-${(0, import_node_crypto34.randomUUID)().slice(0, 8)}`,
78767
78759
  onFlushError: (err) => logger.error("topic store flush failed", {
78768
78760
  reason: err instanceof Error ? err.message : String(err)
78769
78761
  })
@@ -78771,7 +78763,7 @@ async function startDaemon(config) {
78771
78763
  await topicStore.load();
78772
78764
  let deliverPendingRef;
78773
78765
  const personaDispatchManager = new PersonaDispatchManager({
78774
- genId: () => (0, import_node_crypto33.randomUUID)(),
78766
+ genId: () => (0, import_node_crypto34.randomUUID)(),
78775
78767
  store: dispatchStore,
78776
78768
  now: () => Date.now(),
78777
78769
  onCompleted: (sid) => deliverPendingRef?.(sid),
@@ -78795,7 +78787,7 @@ async function startDaemon(config) {
78795
78787
  const readSecrets = () => readSecretTable({ bundleRoot: secretsBundleRoot, overrideDir: localSecretsDir, logger });
78796
78788
  const githubTokenFile = import_node_path90.default.join(localSecretsDir, GITHUB_TOKEN_FILE);
78797
78789
  const managedGithubVar = "CLAWD_GITHUB_MANAGED_TOKEN_SHA256";
78798
- const githubFingerprint = (token) => (0, import_node_crypto33.createHash)("sha256").update(token).digest("hex");
78790
+ const githubFingerprint = (token) => (0, import_node_crypto34.createHash)("sha256").update(token).digest("hex");
78799
78791
  const githubIdentity = createGithubIdentity({
78800
78792
  isManaged: (token) => readEnvFileVar(githubTokenFile, managedGithubVar) === githubFingerprint(token),
78801
78793
  markManaged: (token) => {