@yoooclaw/phone-notifications 1.12.1 → 1.12.2

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/index.cjs CHANGED
@@ -2959,7 +2959,7 @@ var import_node_path = require("node:path");
2959
2959
  var import_node_fs = require("node:fs");
2960
2960
  function readBuildInjectedVersion() {
2961
2961
  if (false) {}
2962
- const version = "1.12.1".trim();
2962
+ const version = "1.12.2".trim();
2963
2963
  return version || undefined;
2964
2964
  }
2965
2965
  function readPluginVersionFromPackageJson() {
@@ -6588,6 +6588,7 @@ function resolveUpdateBaseUrl(params) {
6588
6588
  }
6589
6589
 
6590
6590
  // src/update/index.ts
6591
+ var import_node_fs11 = require("node:fs");
6591
6592
  var import_node_path11 = require("node:path");
6592
6593
 
6593
6594
  // src/plugin/shared.ts
@@ -6693,15 +6694,17 @@ class UpdateChecker {
6693
6694
  intervalMs;
6694
6695
  channel;
6695
6696
  baseUrl;
6697
+ getCurrentVersion;
6696
6698
  timer = null;
6697
6699
  notifiedVersion = null;
6698
6700
  inflightCheck = null;
6699
- constructor(logger, onUpdateFound, intervalMs, channel, baseUrl = PRODUCTION_UPDATE_BASE_URL) {
6701
+ constructor(logger, onUpdateFound, intervalMs, channel, baseUrl = PRODUCTION_UPDATE_BASE_URL, getCurrentVersion = () => PLUGIN_VERSION) {
6700
6702
  this.logger = logger;
6701
6703
  this.onUpdateFound = onUpdateFound;
6702
6704
  this.intervalMs = intervalMs;
6703
6705
  this.channel = channel;
6704
6706
  this.baseUrl = baseUrl;
6707
+ this.getCurrentVersion = getCurrentVersion;
6705
6708
  }
6706
6709
  start() {
6707
6710
  this.timer = setTimeout(() => {
@@ -6724,17 +6727,18 @@ class UpdateChecker {
6724
6727
  return this.inflightCheck;
6725
6728
  }
6726
6729
  async runCheck() {
6730
+ const current = this.getCurrentVersion();
6727
6731
  const latest = await this.fetchLatestVersion();
6728
- if (!latest || latest === PLUGIN_VERSION)
6732
+ if (!latest || latest === current)
6729
6733
  return null;
6730
6734
  if (this.channel !== "beta" && latest.includes("-"))
6731
6735
  return null;
6732
- if (!isNewerVersion(latest, PLUGIN_VERSION))
6736
+ if (!isNewerVersion(latest, current))
6733
6737
  return null;
6734
- const info = { current: PLUGIN_VERSION, latest };
6738
+ const info = { current, latest };
6735
6739
  if (latest !== this.notifiedVersion) {
6736
6740
  this.notifiedVersion = latest;
6737
- this.logger.info(`发现新版本: ${PLUGIN_VERSION} → ${latest}`);
6741
+ this.logger.info(`发现新版本: ${current} → ${latest}`);
6738
6742
  this.onUpdateFound(info);
6739
6743
  }
6740
6744
  return info;
@@ -7398,6 +7402,7 @@ function scheduleGatewayRestart(logger, deps = {}) {
7398
7402
 
7399
7403
  // src/update/index.ts
7400
7404
  var PLUGIN_ID2 = "phone-notifications";
7405
+ var VERSION_PATTERN2 = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/;
7401
7406
  function shouldSkipAutoRestart() {
7402
7407
  return process.platform === "win32";
7403
7408
  }
@@ -7538,6 +7543,26 @@ async function reconcileSucceededUpdateRecord(api, logger, targetDir) {
7538
7543
  logger.warn(`更新已应用,但配置记录补写失败: ${String(err2)}`);
7539
7544
  }
7540
7545
  }
7546
+ function resolveEffectiveCurrentVersion(targetDir) {
7547
+ const installedVersion = readInstalledPackageVersion(targetDir);
7548
+ if (installedVersion && isNewerVersion(installedVersion, PLUGIN_VERSION)) {
7549
+ return installedVersion;
7550
+ }
7551
+ const status = readLastUpdateStatus(targetDir);
7552
+ if (status?.status === "succeeded" && status.version && isNewerVersion(status.version, PLUGIN_VERSION)) {
7553
+ return status.version;
7554
+ }
7555
+ return PLUGIN_VERSION;
7556
+ }
7557
+ function readInstalledPackageVersion(targetDir) {
7558
+ try {
7559
+ const parsed = JSON.parse(import_node_fs11.readFileSync(import_node_path11.join(targetDir, "package.json"), "utf-8"));
7560
+ const version = typeof parsed.version === "string" ? parsed.version.trim() : "";
7561
+ return VERSION_PATTERN2.test(version) ? version : undefined;
7562
+ } catch {
7563
+ return;
7564
+ }
7565
+ }
7541
7566
  function registerAutoUpdate(api, logger, config, getBroadcast, rememberBroadcast, externalUpdateNotifier) {
7542
7567
  if (config.enabled === false) {
7543
7568
  logger.info("自动更新已禁用 (autoUpdate.enabled = false)");
@@ -7631,7 +7656,7 @@ function registerAutoUpdate(api, logger, config, getBroadcast, rememberBroadcast
7631
7656
  externalUpdateNotifier?.notifyUpdateAvailable(update);
7632
7657
  }
7633
7658
  logger.info(`已通知更新 ${update.current} → ${update.latest}` + (broadcasted ? "(对话 + 网关)" : "(对话通道已生效,等待下次 gateway 请求时补发客户端事件)"));
7634
- }, intervalMs, channel, baseUrl);
7659
+ }, intervalMs, channel, baseUrl, () => resolveEffectiveCurrentVersion(resolveTargetDir(api)));
7635
7660
  api.registerGatewayMethod("plugin.update", async ({ params, respond, context }) => {
7636
7661
  const version = params.version;
7637
7662
  if (!version) {
@@ -7754,6 +7779,7 @@ function registerAutoUpdate(api, logger, config, getBroadcast, rememberBroadcast
7754
7779
  try {
7755
7780
  const targetDir = resolveTargetDir(api);
7756
7781
  const info = await checker.check();
7782
+ const current = resolveEffectiveCurrentVersion(targetDir);
7757
7783
  const lastUpdateStatus = readLastUpdateStatus(targetDir);
7758
7784
  const lastUpdateNotice = lastUpdateStatus ? buildLastUpdateNotice(lastUpdateStatus) : undefined;
7759
7785
  if (!info) {
@@ -7762,7 +7788,7 @@ function registerAutoUpdate(api, logger, config, getBroadcast, rememberBroadcast
7762
7788
  respond(true, {
7763
7789
  pluginId: PLUGIN_ID2,
7764
7790
  pluginName: "消息通知",
7765
- current: PLUGIN_VERSION,
7791
+ current,
7766
7792
  latest: info?.latest ?? null,
7767
7793
  hasUpdate: !!info,
7768
7794
  ...lastUpdateNotice ? { lastUpdateNotice } : {}
@@ -7837,7 +7863,7 @@ function registerAutoUpdateLifecycle(deps) {
7837
7863
  var import_node_path19 = require("node:path");
7838
7864
 
7839
7865
  // src/cli/auth.ts
7840
- var import_node_fs11 = require("node:fs");
7866
+ var import_node_fs12 = require("node:fs");
7841
7867
  function registerAuthCli(program) {
7842
7868
  const auth = program.command("auth").description("用户认证管理");
7843
7869
  auth.command("set-api-key <apiKey>").description("设置用户 API Key(持久化到本地配置)").action((apiKey) => {
@@ -7871,13 +7897,13 @@ function registerAuthCli(program) {
7871
7897
  });
7872
7898
  auth.command("clear").description("清除已保存的认证信息").action(() => {
7873
7899
  const path = credentialsPath();
7874
- if (import_node_fs11.existsSync(path)) {
7900
+ if (import_node_fs12.existsSync(path)) {
7875
7901
  const creds = readCredentials();
7876
7902
  delete creds.apiKey;
7877
7903
  delete creds.apiKeys;
7878
7904
  delete creds.token;
7879
7905
  if (Object.keys(creds).length === 0) {
7880
- import_node_fs11.rmSync(path, { force: true });
7906
+ import_node_fs12.rmSync(path, { force: true });
7881
7907
  } else {
7882
7908
  writeCredentials(creds);
7883
7909
  }
@@ -8023,7 +8049,7 @@ function registerNtfSummary(ntf, ctx) {
8023
8049
 
8024
8050
  // src/cli/ntf-summary-job.ts
8025
8051
  var import_node_crypto3 = require("node:crypto");
8026
- var import_node_fs12 = require("node:fs");
8052
+ var import_node_fs13 = require("node:fs");
8027
8053
  var import_node_path12 = require("node:path");
8028
8054
  var SUMMARY_ROOT = ".summaries";
8029
8055
  var JOBS_DIR = "jobs";
@@ -8165,11 +8191,11 @@ function chunkPath(jobDir, chunkId) {
8165
8191
  return import_node_path12.join(jobDir, CHUNKS_DIR, `${chunkId}.json`);
8166
8192
  }
8167
8193
  function writeJson(path, value) {
8168
- import_node_fs12.writeFileSync(path, JSON.stringify(value, null, 2), "utf-8");
8194
+ import_node_fs13.writeFileSync(path, JSON.stringify(value, null, 2), "utf-8");
8169
8195
  }
8170
8196
  function readJson(path) {
8171
8197
  try {
8172
- return JSON.parse(import_node_fs12.readFileSync(path, "utf-8"));
8198
+ return JSON.parse(import_node_fs13.readFileSync(path, "utf-8"));
8173
8199
  } catch {
8174
8200
  exitError("READ_FAILED", `无法读取 JSON: ${path}`);
8175
8201
  }
@@ -8177,7 +8203,7 @@ function readJson(path) {
8177
8203
  function readMeta2(notificationsDir, id) {
8178
8204
  const dir = summaryJobDir(notificationsDir, id);
8179
8205
  const path = metaPath(dir);
8180
- if (!import_node_fs12.existsSync(path)) {
8206
+ if (!import_node_fs13.existsSync(path)) {
8181
8207
  exitError("JOB_NOT_FOUND", `summary job 不存在: ${id}`);
8182
8208
  }
8183
8209
  const meta = readJson(path);
@@ -8265,7 +8291,7 @@ function resolveSummaryText(opts) {
8265
8291
  if (!hasSummary && !hasSummaryFile) {
8266
8292
  exitError("INVALID_COMMIT", "必须提供 --summary 或 --summary-file");
8267
8293
  }
8268
- const text = hasSummary ? opts.summary : import_node_fs12.readFileSync(import_node_path12.resolve(opts.summaryFile), "utf-8");
8294
+ const text = hasSummary ? opts.summary : import_node_fs13.readFileSync(import_node_path12.resolve(opts.summaryFile), "utf-8");
8269
8295
  if (!text.trim()) {
8270
8296
  exitError("INVALID_COMMIT", "分片摘要不能为空");
8271
8297
  }
@@ -8289,7 +8315,7 @@ function buildResultMarkdown(meta, jobDir) {
8289
8315
  lines.push("(未提交摘要)", "");
8290
8316
  continue;
8291
8317
  }
8292
- lines.push(import_node_fs12.readFileSync(import_node_path12.join(jobDir, chunk.summaryFile), "utf-8").trim(), "");
8318
+ lines.push(import_node_fs13.readFileSync(import_node_path12.join(jobDir, chunk.summaryFile), "utf-8").trim(), "");
8293
8319
  }
8294
8320
  return lines.join(`
8295
8321
  `).trimEnd() + `
@@ -8298,7 +8324,7 @@ function buildResultMarkdown(meta, jobDir) {
8298
8324
  function writeChunkSummary(notificationsDir, meta, chunk, text) {
8299
8325
  const jobDir = summaryJobDir(notificationsDir, meta.id);
8300
8326
  const relativeSummaryFile = import_node_path12.join(SUMMARIES_DIR, `${chunk.id}.md`);
8301
- import_node_fs12.writeFileSync(import_node_path12.join(jobDir, relativeSummaryFile), text, "utf-8");
8327
+ import_node_fs13.writeFileSync(import_node_path12.join(jobDir, relativeSummaryFile), text, "utf-8");
8302
8328
  chunk.status = "done";
8303
8329
  chunk.completedAt = nowIso2();
8304
8330
  chunk.summaryFile = relativeSummaryFile;
@@ -8310,7 +8336,7 @@ function finalizeResultIfReady(notificationsDir, meta) {
8310
8336
  }
8311
8337
  const jobDir = summaryJobDir(notificationsDir, meta.id);
8312
8338
  const markdown = buildResultMarkdown(meta, jobDir);
8313
- import_node_fs12.writeFileSync(import_node_path12.join(jobDir, RESULT_FILE), markdown, "utf-8");
8339
+ import_node_fs13.writeFileSync(import_node_path12.join(jobDir, RESULT_FILE), markdown, "utf-8");
8314
8340
  meta.status = "complete";
8315
8341
  meta.resultFile = RESULT_FILE;
8316
8342
  return markdown;
@@ -8332,8 +8358,8 @@ function registerNtfSummaryJob(ntf, ctx) {
8332
8358
  const id = createJobId();
8333
8359
  const createdAt = nowIso2();
8334
8360
  const jobDir = summaryJobDir(dir, id);
8335
- import_node_fs12.mkdirSync(import_node_path12.join(jobDir, CHUNKS_DIR), { recursive: true });
8336
- import_node_fs12.mkdirSync(import_node_path12.join(jobDir, SUMMARIES_DIR), { recursive: true });
8361
+ import_node_fs13.mkdirSync(import_node_path12.join(jobDir, CHUNKS_DIR), { recursive: true });
8362
+ import_node_fs13.mkdirSync(import_node_path12.join(jobDir, SUMMARIES_DIR), { recursive: true });
8337
8363
  const chunks = [];
8338
8364
  for (let start = 0;start < notifications.length; start += chunkSize) {
8339
8365
  const rawChunk = notifications.slice(start, start + chunkSize);
@@ -8628,7 +8654,7 @@ function registerNtfStats(ntf, ctx) {
8628
8654
 
8629
8655
  // src/cli/ntf-sync.ts
8630
8656
  var import_node_child_process2 = require("node:child_process");
8631
- var import_node_fs13 = require("node:fs");
8657
+ var import_node_fs14 = require("node:fs");
8632
8658
  var import_node_path13 = require("node:path");
8633
8659
  var SYNC_FETCH_LIMIT = 100;
8634
8660
  function checkpointPath(dir) {
@@ -8636,16 +8662,16 @@ function checkpointPath(dir) {
8636
8662
  }
8637
8663
  function readCheckpoint(dir) {
8638
8664
  const p = checkpointPath(dir);
8639
- if (!import_node_fs13.existsSync(p))
8665
+ if (!import_node_fs14.existsSync(p))
8640
8666
  return {};
8641
8667
  try {
8642
- return JSON.parse(import_node_fs13.readFileSync(p, "utf-8"));
8668
+ return JSON.parse(import_node_fs14.readFileSync(p, "utf-8"));
8643
8669
  } catch {
8644
8670
  return {};
8645
8671
  }
8646
8672
  }
8647
8673
  function writeCheckpoint(dir, data) {
8648
- import_node_fs13.writeFileSync(checkpointPath(dir), JSON.stringify(data, null, 2), "utf-8");
8674
+ import_node_fs14.writeFileSync(checkpointPath(dir), JSON.stringify(data, null, 2), "utf-8");
8649
8675
  }
8650
8676
  function validateDateKey(value, optionName) {
8651
8677
  const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value);
@@ -8916,7 +8942,7 @@ function registerNtfSync(ntf, ctx) {
8916
8942
  }
8917
8943
 
8918
8944
  // src/cli/ntf-monitor.ts
8919
- var import_node_fs14 = require("node:fs");
8945
+ var import_node_fs15 = require("node:fs");
8920
8946
  var import_node_path14 = require("node:path");
8921
8947
 
8922
8948
  // src/monitor/fetch-gen.ts
@@ -9008,16 +9034,16 @@ function tasksDir(ctx) {
9008
9034
  }
9009
9035
  function readMeta3(taskDir) {
9010
9036
  const metaPath2 = import_node_path14.join(taskDir, "meta.json");
9011
- if (!import_node_fs14.existsSync(metaPath2))
9037
+ if (!import_node_fs15.existsSync(metaPath2))
9012
9038
  return null;
9013
9039
  try {
9014
- return JSON.parse(import_node_fs14.readFileSync(metaPath2, "utf-8"));
9040
+ return JSON.parse(import_node_fs15.readFileSync(metaPath2, "utf-8"));
9015
9041
  } catch {
9016
9042
  return null;
9017
9043
  }
9018
9044
  }
9019
9045
  function writeMeta2(taskDir, meta) {
9020
- import_node_fs14.writeFileSync(import_node_path14.join(taskDir, "meta.json"), JSON.stringify(meta, null, 2), "utf-8");
9046
+ import_node_fs15.writeFileSync(import_node_path14.join(taskDir, "meta.json"), JSON.stringify(meta, null, 2), "utf-8");
9021
9047
  }
9022
9048
  function generateReadme(name, description) {
9023
9049
  return `# Monitor Task: ${name}
@@ -9036,12 +9062,12 @@ function registerNtfMonitor(ntf, ctx) {
9036
9062
  const monitor = ntf.command("monitor").description("通知监控任务管理");
9037
9063
  monitor.command("list").description("列出所有监控任务").action(() => {
9038
9064
  const dir = tasksDir(ctx);
9039
- if (!import_node_fs14.existsSync(dir)) {
9065
+ if (!import_node_fs15.existsSync(dir)) {
9040
9066
  output({ ok: true, tasks: [] });
9041
9067
  return;
9042
9068
  }
9043
9069
  const tasks = [];
9044
- for (const entry of import_node_fs14.readdirSync(dir, { withFileTypes: true })) {
9070
+ for (const entry of import_node_fs15.readdirSync(dir, { withFileTypes: true })) {
9045
9071
  if (!entry.isDirectory())
9046
9072
  continue;
9047
9073
  const meta = readMeta3(import_node_path14.join(dir, entry.name));
@@ -9057,9 +9083,9 @@ function registerNtfMonitor(ntf, ctx) {
9057
9083
  exitError("NOT_FOUND", `监控任务 '${name}' 不存在`);
9058
9084
  const checkpointPath2 = import_node_path14.join(taskDir, "checkpoint.json");
9059
9085
  let checkpoint = {};
9060
- if (import_node_fs14.existsSync(checkpointPath2)) {
9086
+ if (import_node_fs15.existsSync(checkpointPath2)) {
9061
9087
  try {
9062
- checkpoint = JSON.parse(import_node_fs14.readFileSync(checkpointPath2, "utf-8"));
9088
+ checkpoint = JSON.parse(import_node_fs15.readFileSync(checkpointPath2, "utf-8"));
9063
9089
  } catch {}
9064
9090
  }
9065
9091
  output({
@@ -9073,7 +9099,7 @@ function registerNtfMonitor(ntf, ctx) {
9073
9099
  monitor.command("create <name>").description("创建监控任务").requiredOption("--description <text>", "任务描述").requiredOption("--match-rules <json>", "匹配规则 JSON").requiredOption("--schedule <cron>", "cron 表达式").action((name, opts) => {
9074
9100
  const dir = tasksDir(ctx);
9075
9101
  const taskDir = import_node_path14.join(dir, name);
9076
- if (import_node_fs14.existsSync(taskDir)) {
9102
+ if (import_node_fs15.existsSync(taskDir)) {
9077
9103
  exitError("ALREADY_EXISTS", `监控任务 '${name}' 已存在`);
9078
9104
  }
9079
9105
  let matchRules;
@@ -9082,7 +9108,7 @@ function registerNtfMonitor(ntf, ctx) {
9082
9108
  } catch {
9083
9109
  exitError("VALIDATION_FAILED", "match-rules 必须是合法的 JSON");
9084
9110
  }
9085
- import_node_fs14.mkdirSync(taskDir, { recursive: true });
9111
+ import_node_fs15.mkdirSync(taskDir, { recursive: true });
9086
9112
  const meta = {
9087
9113
  name,
9088
9114
  description: opts.description,
@@ -9092,8 +9118,8 @@ function registerNtfMonitor(ntf, ctx) {
9092
9118
  createdAt: new Date().toISOString()
9093
9119
  };
9094
9120
  writeMeta2(taskDir, meta);
9095
- import_node_fs14.writeFileSync(import_node_path14.join(taskDir, "fetch.py"), generateFetchPy(name, matchRules), "utf-8");
9096
- import_node_fs14.writeFileSync(import_node_path14.join(taskDir, "README.md"), generateReadme(name, opts.description), "utf-8");
9121
+ import_node_fs15.writeFileSync(import_node_path14.join(taskDir, "fetch.py"), generateFetchPy(name, matchRules), "utf-8");
9122
+ import_node_fs15.writeFileSync(import_node_path14.join(taskDir, "README.md"), generateReadme(name, opts.description), "utf-8");
9097
9123
  output({
9098
9124
  ok: true,
9099
9125
  name,
@@ -9118,7 +9144,7 @@ function registerNtfMonitor(ntf, ctx) {
9118
9144
  });
9119
9145
  monitor.command("delete <name>").description("删除监控任务").option("--yes", "跳过确认").action((name, opts) => {
9120
9146
  const taskDir = import_node_path14.join(tasksDir(ctx), name);
9121
- if (!import_node_fs14.existsSync(taskDir)) {
9147
+ if (!import_node_fs15.existsSync(taskDir)) {
9122
9148
  exitError("NOT_FOUND", `监控任务 '${name}' 不存在`);
9123
9149
  }
9124
9150
  if (!opts.yes) {
@@ -9131,7 +9157,7 @@ function registerNtfMonitor(ntf, ctx) {
9131
9157
  });
9132
9158
  process.exit(1);
9133
9159
  }
9134
- import_node_fs14.rmSync(taskDir, { recursive: true, force: true });
9160
+ import_node_fs15.rmSync(taskDir, { recursive: true, force: true });
9135
9161
  output({
9136
9162
  ok: true,
9137
9163
  name,
@@ -9248,7 +9274,7 @@ function registerLightSend(light) {
9248
9274
  }
9249
9275
 
9250
9276
  // src/cli/light-setup-tools.ts
9251
- var import_node_fs15 = require("node:fs");
9277
+ var import_node_fs16 = require("node:fs");
9252
9278
  var import_node_path15 = require("node:path");
9253
9279
  function isObject(value) {
9254
9280
  return !!value && typeof value === "object" && !Array.isArray(value);
@@ -9317,12 +9343,12 @@ function upsertLightRuleToolsAlsoAllow(cfg) {
9317
9343
  function registerLightSetupTools(light) {
9318
9344
  light.command("setup").description("自动放行云端灯效规则工具(兼容 tools.allow / tools.alsoAllow)").action(() => {
9319
9345
  const configPath = resolveConfigPath2();
9320
- if (!import_node_fs15.existsSync(configPath)) {
9346
+ if (!import_node_fs16.existsSync(configPath)) {
9321
9347
  exitError("CONFIG_NOT_FOUND", `未找到配置文件: ${configPath}`);
9322
9348
  }
9323
9349
  let cfg = {};
9324
9350
  try {
9325
- const raw = import_node_fs15.readFileSync(configPath, "utf-8");
9351
+ const raw = import_node_fs16.readFileSync(configPath, "utf-8");
9326
9352
  const parsed = JSON.parse(raw);
9327
9353
  if (isObject(parsed))
9328
9354
  cfg = parsed;
@@ -9331,8 +9357,8 @@ function registerLightSetupTools(light) {
9331
9357
  }
9332
9358
  const result = upsertLightRuleToolsAlsoAllow(cfg);
9333
9359
  try {
9334
- import_node_fs15.mkdirSync(import_node_path15.dirname(configPath), { recursive: true });
9335
- import_node_fs15.writeFileSync(configPath, JSON.stringify(cfg, null, 2) + `
9360
+ import_node_fs16.mkdirSync(import_node_path15.dirname(configPath), { recursive: true });
9361
+ import_node_fs16.writeFileSync(configPath, JSON.stringify(cfg, null, 2) + `
9336
9362
  `, "utf-8");
9337
9363
  } catch (err2) {
9338
9364
  exitError("WRITE_FAILED", `写入配置失败: ${err2?.message ?? String(err2)}`);
@@ -9351,7 +9377,7 @@ function registerLightSetupTools(light) {
9351
9377
  }
9352
9378
 
9353
9379
  // src/tunnel/status.ts
9354
- var import_node_fs16 = require("node:fs");
9380
+ var import_node_fs17 = require("node:fs");
9355
9381
  var import_node_path16 = require("node:path");
9356
9382
  var TUNNEL_STATUS_REL_PATH = import_node_path16.join("plugins", "phone-notifications", "tunnel-status.json");
9357
9383
  var TUNNEL_LOCK_REL_PATH = import_node_path16.join("plugins", "phone-notifications", "relay-tunnel.lock");
@@ -9405,7 +9431,7 @@ function staleStatusMessage(status, lock) {
9405
9431
  function assessTunnelStatus(stateDir) {
9406
9432
  const statusFilePath = import_node_path16.join(stateDir, TUNNEL_STATUS_REL_PATH);
9407
9433
  const lockFilePath = import_node_path16.join(stateDir, TUNNEL_LOCK_REL_PATH);
9408
- if (!import_node_fs16.existsSync(statusFilePath)) {
9434
+ if (!import_node_fs17.existsSync(statusFilePath)) {
9409
9435
  return {
9410
9436
  status: null,
9411
9437
  issueCode: "STATUS_NOT_FOUND",
@@ -9413,7 +9439,7 @@ function assessTunnelStatus(stateDir) {
9413
9439
  statusFilePath,
9414
9440
  lockFilePath,
9415
9441
  lock: {
9416
- exists: import_node_fs16.existsSync(lockFilePath),
9442
+ exists: import_node_fs17.existsSync(lockFilePath),
9417
9443
  pid: null,
9418
9444
  startedAt: null,
9419
9445
  active: null
@@ -9422,7 +9448,7 @@ function assessTunnelStatus(stateDir) {
9422
9448
  }
9423
9449
  let rawStatus;
9424
9450
  try {
9425
- rawStatus = JSON.parse(import_node_fs16.readFileSync(statusFilePath, "utf-8"));
9451
+ rawStatus = JSON.parse(import_node_fs17.readFileSync(statusFilePath, "utf-8"));
9426
9452
  } catch {
9427
9453
  return {
9428
9454
  status: null,
@@ -9431,7 +9457,7 @@ function assessTunnelStatus(stateDir) {
9431
9457
  statusFilePath,
9432
9458
  lockFilePath,
9433
9459
  lock: {
9434
- exists: import_node_fs16.existsSync(lockFilePath),
9460
+ exists: import_node_fs17.existsSync(lockFilePath),
9435
9461
  pid: null,
9436
9462
  startedAt: null,
9437
9463
  active: null
@@ -9446,7 +9472,7 @@ function assessTunnelStatus(stateDir) {
9446
9472
  statusFilePath,
9447
9473
  lockFilePath,
9448
9474
  lock: {
9449
- exists: import_node_fs16.existsSync(lockFilePath),
9475
+ exists: import_node_fs17.existsSync(lockFilePath),
9450
9476
  pid: null,
9451
9477
  startedAt: null,
9452
9478
  active: null
@@ -9454,11 +9480,11 @@ function assessTunnelStatus(stateDir) {
9454
9480
  };
9455
9481
  }
9456
9482
  const status = rawStatus;
9457
- const lockExists = import_node_fs16.existsSync(lockFilePath);
9483
+ const lockExists = import_node_fs17.existsSync(lockFilePath);
9458
9484
  let lockInfo = null;
9459
9485
  if (lockExists) {
9460
9486
  try {
9461
- lockInfo = parseTunnelLockInfo(JSON.parse(import_node_fs16.readFileSync(lockFilePath, "utf-8")));
9487
+ lockInfo = parseTunnelLockInfo(JSON.parse(import_node_fs17.readFileSync(lockFilePath, "utf-8")));
9462
9488
  } catch {
9463
9489
  lockInfo = null;
9464
9490
  }
@@ -9561,12 +9587,12 @@ function registerNtfStoragePath(ntf, ctx) {
9561
9587
  }
9562
9588
 
9563
9589
  // src/cli/log-search.ts
9564
- var import_node_fs17 = require("node:fs");
9590
+ var import_node_fs18 = require("node:fs");
9565
9591
  var import_node_path17 = require("node:path");
9566
9592
  function resolveLogsDir(ctx) {
9567
9593
  if (ctx.stateDir) {
9568
9594
  const dir = import_node_path17.join(ctx.stateDir, "plugins", "phone-notifications", "logs");
9569
- if (import_node_fs17.existsSync(dir))
9595
+ if (import_node_fs18.existsSync(dir))
9570
9596
  return dir;
9571
9597
  }
9572
9598
  return null;
@@ -9574,7 +9600,7 @@ function resolveLogsDir(ctx) {
9574
9600
  function listLogDateKeys(dir) {
9575
9601
  const pattern = /^(\d{4}-\d{2}-\d{2})\.log$/;
9576
9602
  const keys = [];
9577
- for (const entry of import_node_fs17.readdirSync(dir, { withFileTypes: true })) {
9603
+ for (const entry of import_node_fs18.readdirSync(dir, { withFileTypes: true })) {
9578
9604
  if (!entry.isFile())
9579
9605
  continue;
9580
9606
  const m = pattern.exec(entry.name);
@@ -9585,9 +9611,9 @@ function listLogDateKeys(dir) {
9585
9611
  }
9586
9612
  function collectLogLines(dir, dateKey, keyword, limit, collected) {
9587
9613
  const filePath = import_node_path17.join(dir, `${dateKey}.log`);
9588
- if (!import_node_fs17.existsSync(filePath))
9614
+ if (!import_node_fs18.existsSync(filePath))
9589
9615
  return;
9590
- const content = import_node_fs17.readFileSync(filePath, "utf-8");
9616
+ const content = import_node_fs18.readFileSync(filePath, "utf-8");
9591
9617
  const lowerKeyword = keyword?.toLowerCase();
9592
9618
  for (const line of content.split(`
9593
9619
  `)) {
@@ -9728,11 +9754,11 @@ function registerEnvCli(ntf, deps = {}) {
9728
9754
  }
9729
9755
 
9730
9756
  // src/cli/doctor.ts
9731
- var import_node_fs20 = require("node:fs");
9757
+ var import_node_fs21 = require("node:fs");
9732
9758
  var import_node_readline = require("node:readline");
9733
9759
 
9734
9760
  // src/cli/doctor/check-dangerous-flags.ts
9735
- var import_node_fs18 = require("node:fs");
9761
+ var import_node_fs19 = require("node:fs");
9736
9762
  function isObject2(v) {
9737
9763
  return !!v && typeof v === "object" && !Array.isArray(v);
9738
9764
  }
@@ -9752,13 +9778,13 @@ var checkDangerousFlags = ({ cfg, configPath }) => {
9752
9778
  detail: "这会关闭 Control UI 的设备身份验证,任何人都可以访问控制面板。",
9753
9779
  fixDescription: "设为 false",
9754
9780
  fix: () => {
9755
- const raw = import_node_fs18.readFileSync(configPath, "utf-8");
9781
+ const raw = import_node_fs19.readFileSync(configPath, "utf-8");
9756
9782
  const config = JSON.parse(raw);
9757
9783
  const gw = config.gateway;
9758
9784
  const cui = gw.controlUi;
9759
9785
  cui.dangerouslyDisableDeviceAuth = false;
9760
- import_node_fs18.copyFileSync(configPath, configPath + ".bak");
9761
- import_node_fs18.writeFileSync(configPath, JSON.stringify(config, null, 2) + `
9786
+ import_node_fs19.copyFileSync(configPath, configPath + ".bak");
9787
+ import_node_fs19.writeFileSync(configPath, JSON.stringify(config, null, 2) + `
9762
9788
  `, "utf-8");
9763
9789
  }
9764
9790
  };
@@ -9815,11 +9841,11 @@ function warnEmpty() {
9815
9841
  }
9816
9842
 
9817
9843
  // src/cli/doctor/check-state-dir-perms.ts
9818
- var import_node_fs19 = require("node:fs");
9844
+ var import_node_fs20 = require("node:fs");
9819
9845
  var checkStateDirPerms = ({ stateDir }) => {
9820
9846
  let mode;
9821
9847
  try {
9822
- mode = import_node_fs19.statSync(stateDir).mode;
9848
+ mode = import_node_fs20.statSync(stateDir).mode;
9823
9849
  } catch {
9824
9850
  return null;
9825
9851
  }
@@ -9834,7 +9860,7 @@ var checkStateDirPerms = ({ stateDir }) => {
9834
9860
  detail: "其他用户可以读取该目录下的凭证和配置文件。",
9835
9861
  fixDescription: "chmod 700 " + stateDir,
9836
9862
  fix: () => {
9837
- import_node_fs19.chmodSync(stateDir, 448);
9863
+ import_node_fs20.chmodSync(stateDir, 448);
9838
9864
  }
9839
9865
  };
9840
9866
  };
@@ -10007,10 +10033,10 @@ function isObject5(v) {
10007
10033
  return !!v && typeof v === "object" && !Array.isArray(v);
10008
10034
  }
10009
10035
  function readConfig(configPath) {
10010
- if (!import_node_fs20.existsSync(configPath))
10036
+ if (!import_node_fs21.existsSync(configPath))
10011
10037
  return {};
10012
10038
  try {
10013
- const parsed = JSON.parse(import_node_fs20.readFileSync(configPath, "utf-8"));
10039
+ const parsed = JSON.parse(import_node_fs21.readFileSync(configPath, "utf-8"));
10014
10040
  return isObject5(parsed) ? parsed : {};
10015
10041
  } catch {
10016
10042
  return {};
@@ -10221,7 +10247,7 @@ function registerRecStoragePath(rec, ctx) {
10221
10247
 
10222
10248
  // src/cli/rec-setup.ts
10223
10249
  var import_node_readline2 = require("node:readline");
10224
- var import_node_fs21 = require("node:fs");
10250
+ var import_node_fs22 = require("node:fs");
10225
10251
  function ask(rl, question) {
10226
10252
  return new Promise((resolve3) => rl.question(question, resolve3));
10227
10253
  }
@@ -10322,9 +10348,9 @@ async function setupLocal(rl) {
10322
10348
  function registerRecSetup(rec, ctx) {
10323
10349
  rec.command("setup").description("交互式配置 ASR 转写参数,保存到本地配置文件").action(async () => {
10324
10350
  const configPath = resolveAsrConfigPath(ctx);
10325
- if (import_node_fs21.existsSync(configPath)) {
10351
+ if (import_node_fs22.existsSync(configPath)) {
10326
10352
  try {
10327
- const existing = JSON.parse(import_node_fs21.readFileSync(configPath, "utf-8"));
10353
+ const existing = JSON.parse(import_node_fs22.readFileSync(configPath, "utf-8"));
10328
10354
  process.stderr.write(`当前已有配置:mode = ${existing.mode}`);
10329
10355
  if (existing.updatedAt)
10330
10356
  process.stderr.write(`,更新于 ${existing.updatedAt}`);
@@ -10340,7 +10366,7 @@ function registerRecSetup(rec, ctx) {
10340
10366
  const modeIdx = await askChoice(rl, "选择模式", ["api(云端 model-proxy 长录音)", "local(本地 Whisper)"]);
10341
10367
  const config = modeIdx === 0 ? await setupApi(rl) : await setupLocal(rl);
10342
10368
  const stored = { ...config, updatedAt: new Date().toISOString() };
10343
- import_node_fs21.writeFileSync(configPath, JSON.stringify(stored, null, 2), "utf-8");
10369
+ import_node_fs22.writeFileSync(configPath, JSON.stringify(stored, null, 2), "utf-8");
10344
10370
  process.stderr.write(`
10345
10371
  ✓ 配置已保存到 ${configPath}
10346
10372
 
@@ -10437,7 +10463,7 @@ function registerImageStoragePath(image, ctx) {
10437
10463
 
10438
10464
  // src/cli/update.ts
10439
10465
  var import_node_child_process4 = require("node:child_process");
10440
- var import_node_fs22 = require("node:fs");
10466
+ var import_node_fs23 = require("node:fs");
10441
10467
  var import_node_path18 = require("node:path");
10442
10468
  var import_node_os2 = __toESM(require("node:os"));
10443
10469
  async function fetchText(url) {
@@ -10513,7 +10539,7 @@ async function runUpdate(ctx, opts) {
10513
10539
  }
10514
10540
  const tmpScript = import_node_path18.join(import_node_os2.default.tmpdir(), `openclaw-install-${Date.now()}.mjs`);
10515
10541
  try {
10516
- import_node_fs22.writeFileSync(tmpScript, installScript, "utf-8");
10542
+ import_node_fs23.writeFileSync(tmpScript, installScript, "utf-8");
10517
10543
  } catch (err2) {
10518
10544
  const msg = `写入临时文件失败: ${err2?.message ?? String(err2)}`;
10519
10545
  if (json) {
@@ -10527,7 +10553,7 @@ async function runUpdate(ctx, opts) {
10527
10553
  const stateDir = resolveStateDir(ctx.stateDir);
10528
10554
  const result = import_node_child_process4.spawnSync(process.execPath, [tmpScript, "--version", latest, "--state-dir", stateDir], { stdio: "inherit" });
10529
10555
  try {
10530
- import_node_fs22.unlinkSync(tmpScript);
10556
+ import_node_fs23.unlinkSync(tmpScript);
10531
10557
  } catch {}
10532
10558
  if (result.error) {
10533
10559
  const msg = `安装脚本执行失败: ${result.error.message}`;
@@ -10624,12 +10650,12 @@ function registerPluginCli(api, params) {
10624
10650
  }
10625
10651
 
10626
10652
  // src/plugin/ntf-bin.ts
10627
- var import_node_fs23 = require("node:fs");
10653
+ var import_node_fs24 = require("node:fs");
10628
10654
  var import_node_path20 = require("node:path");
10629
10655
  var import_node_process = __toESM(require("node:process"));
10630
10656
  function ensureNtfBinInstalled(opts) {
10631
10657
  const { ntfCjsPath, stateDir, logger } = opts;
10632
- if (!import_node_fs23.existsSync(ntfCjsPath)) {
10658
+ if (!import_node_fs24.existsSync(ntfCjsPath)) {
10633
10659
  logger.warn(`ntf wrapper: 目标不存在 ${ntfCjsPath},跳过`);
10634
10660
  return;
10635
10661
  }
@@ -10674,7 +10700,7 @@ function resolveNtfBinInstallDirs(opts) {
10674
10700
  }
10675
10701
  function tryInstallWrapper(dir, target) {
10676
10702
  try {
10677
- import_node_fs23.mkdirSync(dir, { recursive: true });
10703
+ import_node_fs24.mkdirSync(dir, { recursive: true });
10678
10704
  } catch (err2) {
10679
10705
  return { ok: false, reason: `mkdir ${dir} 失败: ${describeError(err2)}` };
10680
10706
  }
@@ -10688,13 +10714,13 @@ function tryInstallWrapper(dir, target) {
10688
10714
  }
10689
10715
  try {
10690
10716
  if (import_node_process.default.platform === "win32") {
10691
- import_node_fs23.writeFileSync(wrapperPath, `@echo off\r
10717
+ import_node_fs24.writeFileSync(wrapperPath, `@echo off\r
10692
10718
  node "${target}" %*\r
10693
10719
  `, "utf-8");
10694
10720
  } else {
10695
- import_node_fs23.symlinkSync(target, wrapperPath);
10721
+ import_node_fs24.symlinkSync(target, wrapperPath);
10696
10722
  try {
10697
- import_node_fs23.chmodSync(target, 493);
10723
+ import_node_fs24.chmodSync(target, 493);
10698
10724
  } catch {}
10699
10725
  }
10700
10726
  return { ok: true, path: wrapperPath, created: true };
@@ -10704,7 +10730,7 @@ node "${target}" %*\r
10704
10730
  }
10705
10731
  function pathExists(path) {
10706
10732
  try {
10707
- import_node_fs23.lstatSync(path);
10733
+ import_node_fs24.lstatSync(path);
10708
10734
  return true;
10709
10735
  } catch {
10710
10736
  return false;
@@ -10713,16 +10739,16 @@ function pathExists(path) {
10713
10739
  function isExistingWrapperForTarget(wrapperPath, target) {
10714
10740
  if (import_node_process.default.platform === "win32") {
10715
10741
  try {
10716
- return import_node_fs23.readFileSync(wrapperPath, "utf-8").includes(`"${target}"`);
10742
+ return import_node_fs24.readFileSync(wrapperPath, "utf-8").includes(`"${target}"`);
10717
10743
  } catch {
10718
10744
  return false;
10719
10745
  }
10720
10746
  }
10721
10747
  try {
10722
- if (!import_node_fs23.lstatSync(wrapperPath).isSymbolicLink()) {
10748
+ if (!import_node_fs24.lstatSync(wrapperPath).isSymbolicLink()) {
10723
10749
  return false;
10724
10750
  }
10725
- return import_node_fs23.realpathSync(wrapperPath) === import_node_fs23.realpathSync(target);
10751
+ return import_node_fs24.realpathSync(wrapperPath) === import_node_fs24.realpathSync(target);
10726
10752
  } catch {
10727
10753
  return false;
10728
10754
  }
@@ -10748,7 +10774,7 @@ function findCommandOnPath(command, pathDirs) {
10748
10774
  for (const dir of pathDirs) {
10749
10775
  for (const name of names) {
10750
10776
  const candidate = import_node_path20.join(dir, name);
10751
- if (import_node_fs23.existsSync(candidate)) {
10777
+ if (import_node_fs24.existsSync(candidate)) {
10752
10778
  return candidate;
10753
10779
  }
10754
10780
  }
@@ -10763,10 +10789,10 @@ function pushCandidate(candidates, dir, label, onPath) {
10763
10789
  }
10764
10790
 
10765
10791
  // src/plugin/lifecycle.ts
10766
- var import_node_fs34 = require("node:fs");
10792
+ var import_node_fs35 = require("node:fs");
10767
10793
 
10768
10794
  // src/notification/app-name-map.ts
10769
- var import_node_fs24 = require("node:fs");
10795
+ var import_node_fs25 = require("node:fs");
10770
10796
  var import_node_path21 = require("node:path");
10771
10797
  var PLUGIN_STATE_DIR = "phone-notifications";
10772
10798
  var CACHE_FILE = "app-name-map.json";
@@ -10800,10 +10826,10 @@ function createAppNameMapProvider(opts) {
10800
10826
  let inFlightFetch = null;
10801
10827
  function loadFromDisk() {
10802
10828
  const path = getCachePath(stateDir);
10803
- if (!import_node_fs24.existsSync(path))
10829
+ if (!import_node_fs25.existsSync(path))
10804
10830
  return;
10805
10831
  try {
10806
- const raw = JSON.parse(import_node_fs24.readFileSync(path, "utf-8"));
10832
+ const raw = JSON.parse(import_node_fs25.readFileSync(path, "utf-8"));
10807
10833
  if (!isRecordOfStrings(raw))
10808
10834
  return;
10809
10835
  map.clear();
@@ -10850,9 +10876,9 @@ function createAppNameMapProvider(opts) {
10850
10876
  return;
10851
10877
  }
10852
10878
  const dir = import_node_path21.join(stateDir, "plugins", PLUGIN_STATE_DIR);
10853
- import_node_fs24.mkdirSync(dir, { recursive: true });
10879
+ import_node_fs25.mkdirSync(dir, { recursive: true });
10854
10880
  const cachePath = getCachePath(stateDir);
10855
- import_node_fs24.writeFileSync(cachePath, JSON.stringify(Object.fromEntries(map), null, 2), "utf-8");
10881
+ import_node_fs25.writeFileSync(cachePath, JSON.stringify(Object.fromEntries(map), null, 2), "utf-8");
10856
10882
  logger.info(`[app-name-map] refreshed ${map.size} entries from server and saved: ${cachePath}`);
10857
10883
  } catch (e) {
10858
10884
  const message = e instanceof Error ? e.message : String(e);
@@ -10903,7 +10929,7 @@ function createAppNameMapProvider(opts) {
10903
10929
  }
10904
10930
 
10905
10931
  // src/recording/storage.ts
10906
- var import_node_fs25 = require("node:fs");
10932
+ var import_node_fs26 = require("node:fs");
10907
10933
  var import_node_path22 = require("node:path");
10908
10934
 
10909
10935
  // src/recording/state-machine.ts
@@ -11215,14 +11241,14 @@ function extractTranscriptContent(markdown) {
11215
11241
  function resolveRecordingStorageDir(ctx, logger) {
11216
11242
  const stateRecDir = import_node_path22.join(ctx.stateDir, "plugins", "phone-notifications", RECORDINGS_DIR);
11217
11243
  try {
11218
- import_node_fs25.mkdirSync(stateRecDir, { recursive: true });
11244
+ import_node_fs26.mkdirSync(stateRecDir, { recursive: true });
11219
11245
  logger.info(`录音将写入 stateDir 路径: ${stateRecDir}`);
11220
11246
  return stateRecDir;
11221
11247
  } catch {}
11222
11248
  if (ctx.workspaceDir) {
11223
11249
  const wsRecDir = import_node_path22.join(ctx.workspaceDir, RECORDINGS_DIR);
11224
11250
  try {
11225
- import_node_fs25.mkdirSync(wsRecDir, { recursive: true });
11251
+ import_node_fs26.mkdirSync(wsRecDir, { recursive: true });
11226
11252
  logger.warn(`stateDir 不可用,录音已回退到 workspace 路径: ${wsRecDir}`);
11227
11253
  return wsRecDir;
11228
11254
  } catch {}
@@ -11249,10 +11275,10 @@ class RecordingStorage {
11249
11275
  this.indexPath = import_node_path22.join(dir, INDEX_FILE);
11250
11276
  }
11251
11277
  async init() {
11252
- import_node_fs25.mkdirSync(this.audioDir, { recursive: true });
11253
- import_node_fs25.mkdirSync(this.transcriptDataDir, { recursive: true });
11254
- import_node_fs25.mkdirSync(this.transcriptsDir, { recursive: true });
11255
- import_node_fs25.mkdirSync(this.summariesDir, { recursive: true });
11278
+ import_node_fs26.mkdirSync(this.audioDir, { recursive: true });
11279
+ import_node_fs26.mkdirSync(this.transcriptDataDir, { recursive: true });
11280
+ import_node_fs26.mkdirSync(this.transcriptsDir, { recursive: true });
11281
+ import_node_fs26.mkdirSync(this.summariesDir, { recursive: true });
11256
11282
  this.loadIndex();
11257
11283
  this.logger.info(`录音存储已初始化: ${this.dir}(共 ${this.index.recordings.length} 条记录)`);
11258
11284
  }
@@ -11284,13 +11310,13 @@ class RecordingStorage {
11284
11310
  return id;
11285
11311
  }
11286
11312
  if (existing.transcriptDataFile) {
11287
- import_node_fs25.rmSync(import_node_path22.join(this.dir, existing.transcriptDataFile), { force: true });
11313
+ import_node_fs26.rmSync(import_node_path22.join(this.dir, existing.transcriptDataFile), { force: true });
11288
11314
  }
11289
11315
  if (existing.transcriptFile) {
11290
- import_node_fs25.rmSync(import_node_path22.join(this.dir, existing.transcriptFile), { force: true });
11316
+ import_node_fs26.rmSync(import_node_path22.join(this.dir, existing.transcriptFile), { force: true });
11291
11317
  }
11292
11318
  if (existing.summaryFile) {
11293
- import_node_fs25.rmSync(import_node_path22.join(this.dir, existing.summaryFile), { force: true });
11319
+ import_node_fs26.rmSync(import_node_path22.join(this.dir, existing.summaryFile), { force: true });
11294
11320
  }
11295
11321
  existing.metadata = metadata;
11296
11322
  existing.clientLabel = clientLabel;
@@ -11347,7 +11373,7 @@ class RecordingStorage {
11347
11373
  return;
11348
11374
  const nextAudioFile = `${AUDIO_DIR}/${filename}`;
11349
11375
  if (entry.audioFile && entry.audioFile !== nextAudioFile) {
11350
- import_node_fs25.rmSync(import_node_path22.join(this.dir, entry.audioFile), { force: true });
11376
+ import_node_fs26.rmSync(import_node_path22.join(this.dir, entry.audioFile), { force: true });
11351
11377
  }
11352
11378
  entry.audioFile = nextAudioFile;
11353
11379
  entry.updatedAt = new Date().toISOString();
@@ -11367,7 +11393,7 @@ class RecordingStorage {
11367
11393
  return;
11368
11394
  const nextTranscriptDataFile = `${TRANSCRIPT_DATA_DIR}/${filename}`;
11369
11395
  if (entry.transcriptDataFile && entry.transcriptDataFile !== nextTranscriptDataFile) {
11370
- import_node_fs25.rmSync(import_node_path22.join(this.dir, entry.transcriptDataFile), { force: true });
11396
+ import_node_fs26.rmSync(import_node_path22.join(this.dir, entry.transcriptDataFile), { force: true });
11371
11397
  }
11372
11398
  entry.transcriptDataFile = nextTranscriptDataFile;
11373
11399
  entry.updatedAt = new Date().toISOString();
@@ -11379,7 +11405,7 @@ class RecordingStorage {
11379
11405
  return;
11380
11406
  const nextTranscriptFile = `${TRANSCRIPTS_DIR}/${filename}`;
11381
11407
  if (entry.transcriptFile && entry.transcriptFile !== nextTranscriptFile) {
11382
- import_node_fs25.rmSync(import_node_path22.join(this.dir, entry.transcriptFile), { force: true });
11408
+ import_node_fs26.rmSync(import_node_path22.join(this.dir, entry.transcriptFile), { force: true });
11383
11409
  }
11384
11410
  entry.transcriptFile = nextTranscriptFile;
11385
11411
  entry.updatedAt = new Date().toISOString();
@@ -11391,7 +11417,7 @@ class RecordingStorage {
11391
11417
  return;
11392
11418
  const nextSummaryFile = `${SUMMARIES_DIR2}/${filename}`;
11393
11419
  if (entry.summaryFile && entry.summaryFile !== nextSummaryFile) {
11394
- import_node_fs25.rmSync(import_node_path22.join(this.dir, entry.summaryFile), { force: true });
11420
+ import_node_fs26.rmSync(import_node_path22.join(this.dir, entry.summaryFile), { force: true });
11395
11421
  }
11396
11422
  entry.summaryFile = nextSummaryFile;
11397
11423
  entry.updatedAt = new Date().toISOString();
@@ -11481,23 +11507,23 @@ class RecordingStorage {
11481
11507
  return false;
11482
11508
  if (entry.audioFile) {
11483
11509
  const audioPath = import_node_path22.join(this.dir, entry.audioFile);
11484
- import_node_fs25.rmSync(audioPath, { force: true });
11510
+ import_node_fs26.rmSync(audioPath, { force: true });
11485
11511
  }
11486
11512
  if (entry.srtFile) {
11487
11513
  const srtPath = import_node_path22.join(this.dir, entry.srtFile);
11488
- import_node_fs25.rmSync(srtPath, { force: true });
11514
+ import_node_fs26.rmSync(srtPath, { force: true });
11489
11515
  }
11490
11516
  if (entry.transcriptDataFile) {
11491
11517
  const transcriptDataPath = import_node_path22.join(this.dir, entry.transcriptDataFile);
11492
- import_node_fs25.rmSync(transcriptDataPath, { force: true });
11518
+ import_node_fs26.rmSync(transcriptDataPath, { force: true });
11493
11519
  }
11494
11520
  if (entry.transcriptFile) {
11495
11521
  const transcriptPath = import_node_path22.join(this.dir, entry.transcriptFile);
11496
- import_node_fs25.rmSync(transcriptPath, { force: true });
11522
+ import_node_fs26.rmSync(transcriptPath, { force: true });
11497
11523
  }
11498
11524
  if (entry.summaryFile) {
11499
11525
  const summaryPath = import_node_path22.join(this.dir, entry.summaryFile);
11500
- import_node_fs25.rmSync(summaryPath, { force: true });
11526
+ import_node_fs26.rmSync(summaryPath, { force: true });
11501
11527
  }
11502
11528
  if (opts?.localOnly) {
11503
11529
  entry.audioFile = undefined;
@@ -11545,12 +11571,12 @@ class RecordingStorage {
11545
11571
  return import_node_path22.join(this.summariesDir, this.buildSummaryFilename(recordingId));
11546
11572
  }
11547
11573
  loadIndex() {
11548
- if (!import_node_fs25.existsSync(this.indexPath)) {
11574
+ if (!import_node_fs26.existsSync(this.indexPath)) {
11549
11575
  this.index = { recordings: [] };
11550
11576
  return;
11551
11577
  }
11552
11578
  try {
11553
- const raw = JSON.parse(import_node_fs25.readFileSync(this.indexPath, "utf-8"));
11579
+ const raw = JSON.parse(import_node_fs26.readFileSync(this.indexPath, "utf-8"));
11554
11580
  if (raw && Array.isArray(raw.recordings)) {
11555
11581
  let needsRewrite = false;
11556
11582
  const normalized = raw.recordings.filter((entry) => entry && typeof entry === "object").map((entry) => {
@@ -11591,7 +11617,7 @@ class RecordingStorage {
11591
11617
  segments: []
11592
11618
  });
11593
11619
  const transcriptDataFilename = this.buildTranscriptDataFilename(compacted.id);
11594
- import_node_fs25.writeFileSync(import_node_path22.join(this.transcriptDataDir, transcriptDataFilename), JSON.stringify(transcriptDoc, null, 2), "utf-8");
11620
+ import_node_fs26.writeFileSync(import_node_path22.join(this.transcriptDataDir, transcriptDataFilename), JSON.stringify(transcriptDoc, null, 2), "utf-8");
11595
11621
  compacted.transcriptDataFile = `${TRANSCRIPT_DATA_DIR}/${transcriptDataFilename}`;
11596
11622
  needsRewrite = true;
11597
11623
  }
@@ -11600,14 +11626,14 @@ class RecordingStorage {
11600
11626
  compacted.summaryFile = entry.summaryFile;
11601
11627
  } else if (typeof entry.summary === "string" && entry.summary.trim()) {
11602
11628
  const summaryFilename = this.buildSummaryFilename(entry.id);
11603
- import_node_fs25.writeFileSync(import_node_path22.join(this.summariesDir, summaryFilename), entry.summary.trim(), "utf-8");
11629
+ import_node_fs26.writeFileSync(import_node_path22.join(this.summariesDir, summaryFilename), entry.summary.trim(), "utf-8");
11604
11630
  compacted.summaryFile = `${SUMMARIES_DIR2}/${summaryFilename}`;
11605
11631
  needsRewrite = true;
11606
11632
  } else {
11607
11633
  const summaryFromDocument = extractTranscriptSummaryFromDocument(transcriptDoc);
11608
11634
  if (summaryFromDocument) {
11609
11635
  const summaryFilename = this.buildSummaryFilename(entry.id);
11610
- import_node_fs25.writeFileSync(import_node_path22.join(this.summariesDir, summaryFilename), summaryFromDocument, "utf-8");
11636
+ import_node_fs26.writeFileSync(import_node_path22.join(this.summariesDir, summaryFilename), summaryFromDocument, "utf-8");
11611
11637
  compacted.summaryFile = `${SUMMARIES_DIR2}/${summaryFilename}`;
11612
11638
  needsRewrite = true;
11613
11639
  }
@@ -11648,7 +11674,7 @@ class RecordingStorage {
11648
11674
  }
11649
11675
  readRelativeTextFile(relativePath) {
11650
11676
  try {
11651
- return import_node_fs25.readFileSync(import_node_path22.join(this.dir, relativePath), "utf-8");
11677
+ return import_node_fs26.readFileSync(import_node_path22.join(this.dir, relativePath), "utf-8");
11652
11678
  } catch {
11653
11679
  return;
11654
11680
  }
@@ -11661,12 +11687,12 @@ class RecordingStorage {
11661
11687
  return parseTranscriptDocument(raw);
11662
11688
  }
11663
11689
  saveIndex() {
11664
- import_node_fs25.writeFileSync(this.indexPath, JSON.stringify(this.index, null, 2), "utf-8");
11690
+ import_node_fs26.writeFileSync(this.indexPath, JSON.stringify(this.index, null, 2), "utf-8");
11665
11691
  }
11666
11692
  async close() {}
11667
11693
  }
11668
11694
  // src/recording/downloader.ts
11669
- var import_node_fs26 = require("node:fs");
11695
+ var import_node_fs27 = require("node:fs");
11670
11696
  var import_node_path23 = require("node:path");
11671
11697
  var import_promises2 = require("node:stream/promises");
11672
11698
  var import_node_stream = require("node:stream");
@@ -11677,7 +11703,7 @@ async function downloadFile(url, destPath, logger, options) {
11677
11703
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
11678
11704
  const maxRetries = options?.maxRetries ?? DEFAULT_MAX_RETRIES;
11679
11705
  const retryBackoffMs = options?.retryBackoffMs ?? DEFAULT_RETRY_BACKOFF_MS;
11680
- import_node_fs26.mkdirSync(import_node_path23.dirname(destPath), { recursive: true });
11706
+ import_node_fs27.mkdirSync(import_node_path23.dirname(destPath), { recursive: true });
11681
11707
  let lastError;
11682
11708
  for (let attempt = 1;attempt <= maxRetries; attempt++) {
11683
11709
  const startMs = Date.now();
@@ -11693,11 +11719,11 @@ async function downloadFile(url, destPath, logger, options) {
11693
11719
  if (!res.body) {
11694
11720
  throw new Error("响应体为空");
11695
11721
  }
11696
- const writeStream = import_node_fs26.createWriteStream(destPath);
11722
+ const writeStream = import_node_fs27.createWriteStream(destPath);
11697
11723
  const readable = import_node_stream.Readable.fromWeb(res.body);
11698
11724
  await import_promises2.pipeline(readable, writeStream);
11699
11725
  const elapsed = Date.now() - startMs;
11700
- const fileSize = import_node_fs26.existsSync(destPath) ? import_node_fs26.statSync(destPath).size : 0;
11726
+ const fileSize = import_node_fs27.existsSync(destPath) ? import_node_fs27.statSync(destPath).size : 0;
11701
11727
  logger.info(`[downloader] 下载完成: ${destPath} (${formatBytes(fileSize)}, ${elapsed}ms)`);
11702
11728
  return { ok: true, sizeBytes: fileSize, elapsedMs: elapsed };
11703
11729
  } finally {
@@ -11706,8 +11732,8 @@ async function downloadFile(url, destPath, logger, options) {
11706
11732
  } catch (err2) {
11707
11733
  lastError = err2?.message ?? String(err2);
11708
11734
  try {
11709
- if (import_node_fs26.existsSync(destPath))
11710
- import_node_fs26.unlinkSync(destPath);
11735
+ if (import_node_fs27.existsSync(destPath))
11736
+ import_node_fs27.unlinkSync(destPath);
11711
11737
  } catch {}
11712
11738
  const isAbort = err2?.name === "AbortError";
11713
11739
  logger.warn(`[downloader] 下载失败 (attempt ${attempt}/${maxRetries}): ${isAbort ? "超时" : lastError}`);
@@ -11742,7 +11768,7 @@ function sleep(ms) {
11742
11768
  return new Promise((resolve3) => setTimeout(resolve3, ms));
11743
11769
  }
11744
11770
  // src/recording/asr.ts
11745
- var import_node_fs27 = require("node:fs");
11771
+ var import_node_fs28 = require("node:fs");
11746
11772
  var import_node_path24 = require("node:path");
11747
11773
  var DEFAULT_LONG_RECORDING_POLL_INTERVAL_MS = 2000;
11748
11774
  var DEFAULT_LONG_RECORDING_MAX_POLL_ATTEMPTS = 3600;
@@ -11822,7 +11848,7 @@ async function initializeAsr(config, dataDir, logger) {
11822
11848
  }
11823
11849
  }
11824
11850
  async function transcribeAudio(audioFilePath, config, logger, options = {}) {
11825
- if (!import_node_fs27.existsSync(audioFilePath)) {
11851
+ if (!import_node_fs28.existsSync(audioFilePath)) {
11826
11852
  return { ok: false, error: `音频文件不存在: ${audioFilePath}` };
11827
11853
  }
11828
11854
  logger.info(`[asr] 开始转写: mode=${config.mode}, file=${audioFilePath}`);
@@ -11955,18 +11981,18 @@ async function runTranscriptionWorkflow(params) {
11955
11981
  const markdown = buildTranscriptMarkdown(result, markers, recordingName, durationSec, createdAt);
11956
11982
  const transcriptDataFilename = buildTranscriptDataFilename(recordingId);
11957
11983
  const transcriptDataPath = import_node_path24.join(transcriptDataDir, transcriptDataFilename);
11958
- import_node_fs27.writeFileSync(transcriptDataPath, JSON.stringify(transcriptData, null, 2), "utf-8");
11984
+ import_node_fs28.writeFileSync(transcriptDataPath, JSON.stringify(transcriptData, null, 2), "utf-8");
11959
11985
  logger.info(`[asr] 转写 JSON 已写入: ${transcriptDataPath}`);
11960
11986
  const safeSummary = title.replace(/[/\\:*?"<>|]/g, "").trim().slice(0, 20);
11961
11987
  const filename = safeSummary ? `${recordingId}_${safeSummary}.md` : `${recordingId}.md`;
11962
11988
  const filePath = import_node_path24.join(transcriptsDir, filename);
11963
- import_node_fs27.writeFileSync(filePath, markdown, "utf-8");
11989
+ import_node_fs28.writeFileSync(filePath, markdown, "utf-8");
11964
11990
  logger.info(`[asr] 转写文本已写入: ${filePath}`);
11965
11991
  let summaryFilename;
11966
11992
  if (summary) {
11967
11993
  summaryFilename = `${recordingId}.md`;
11968
11994
  const summaryFilePath = import_node_path24.join(summariesDir, summaryFilename);
11969
- import_node_fs27.writeFileSync(summaryFilePath, summary, "utf-8");
11995
+ import_node_fs28.writeFileSync(summaryFilePath, summary, "utf-8");
11970
11996
  logger.info(`[asr] 摘要文本已写入: ${summaryFilePath}`);
11971
11997
  }
11972
11998
  return {
@@ -12558,7 +12584,7 @@ async function triggerTranscription(recordingId, storage2, asrConfig, logger, op
12558
12584
  }
12559
12585
  }
12560
12586
  // src/recording/result-writer.ts
12561
- var import_node_fs28 = require("node:fs");
12587
+ var import_node_fs29 = require("node:fs");
12562
12588
  var import_node_path25 = require("node:path");
12563
12589
  function handleRecordingResultWrite(params, storage2, logger, options = {}) {
12564
12590
  const recordingId = normalizeRequiredText(params.recordingId, "recordingId");
@@ -12639,11 +12665,11 @@ function writeTranscript(recordingId, recording, transcript, storage2, logger) {
12639
12665
  raw: transcript
12640
12666
  });
12641
12667
  const transcriptDataFilename = storage2.buildTranscriptDataFilename(recordingId);
12642
- import_node_fs28.writeFileSync(storage2.getTranscriptDataFilePath(recordingId), JSON.stringify(transcriptDocument, null, 2), "utf-8");
12668
+ import_node_fs29.writeFileSync(storage2.getTranscriptDataFilePath(recordingId), JSON.stringify(transcriptDocument, null, 2), "utf-8");
12643
12669
  storage2.setTranscriptDataFile(recordingId, transcriptDataFilename);
12644
12670
  const transcriptFilename = storage2.buildTranscriptFilename(recordingId, title);
12645
12671
  const markdown = normalizePossiblyEmptyText2(transcript.markdown) ?? buildTranscriptMarkdown2(recording, title, text, segments);
12646
- import_node_fs28.writeFileSync(import_node_path25.join(storage2.getTranscriptsDir(), transcriptFilename), ensureTrailingNewline(markdown), "utf-8");
12672
+ import_node_fs29.writeFileSync(import_node_path25.join(storage2.getTranscriptsDir(), transcriptFilename), ensureTrailingNewline(markdown), "utf-8");
12647
12673
  storage2.setTranscriptFile(recordingId, transcriptFilename);
12648
12674
  storage2.setTitle(recordingId, title);
12649
12675
  logger.info(`[recording-result] 转录文本已写入: ${recordingId}`);
@@ -12658,7 +12684,7 @@ function writeSummary(recordingId, summary, storage2, logger) {
12658
12684
  return;
12659
12685
  }
12660
12686
  const summaryFilename = storage2.buildSummaryFilename(recordingId);
12661
- import_node_fs28.writeFileSync(storage2.getSummaryFilePath(recordingId), ensureTrailingNewline(markdown), "utf-8");
12687
+ import_node_fs29.writeFileSync(storage2.getSummaryFilePath(recordingId), ensureTrailingNewline(markdown), "utf-8");
12662
12688
  storage2.setSummaryFile(recordingId, summaryFilename);
12663
12689
  logger.info(`[recording-result] 总结已写入: ${recordingId}`);
12664
12690
  return markdown.trim();
@@ -12831,7 +12857,7 @@ function formatTimestamp2(ms) {
12831
12857
  return `${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}`;
12832
12858
  }
12833
12859
  // src/image/store.ts
12834
- var import_node_fs29 = require("node:fs");
12860
+ var import_node_fs30 = require("node:fs");
12835
12861
  var import_node_path26 = require("node:path");
12836
12862
  var IMAGES_DIR = "images";
12837
12863
  var FILES_DIR = "files";
@@ -12849,14 +12875,14 @@ function extFromMime(mime) {
12849
12875
  function resolveImageStorageDir(ctx, logger) {
12850
12876
  const stateImagesDir = import_node_path26.join(ctx.stateDir, "plugins", "phone-notifications", IMAGES_DIR);
12851
12877
  try {
12852
- import_node_fs29.mkdirSync(stateImagesDir, { recursive: true });
12878
+ import_node_fs30.mkdirSync(stateImagesDir, { recursive: true });
12853
12879
  logger.info(`图片将写入 stateDir 路径: ${stateImagesDir}`);
12854
12880
  return stateImagesDir;
12855
12881
  } catch {}
12856
12882
  if (ctx.workspaceDir) {
12857
12883
  const wsImagesDir = import_node_path26.join(ctx.workspaceDir, IMAGES_DIR);
12858
12884
  try {
12859
- import_node_fs29.mkdirSync(wsImagesDir, { recursive: true });
12885
+ import_node_fs30.mkdirSync(wsImagesDir, { recursive: true });
12860
12886
  logger.warn(`stateDir 不可用,图片已回退到 workspace 路径: ${wsImagesDir}`);
12861
12887
  return wsImagesDir;
12862
12888
  } catch {}
@@ -12877,7 +12903,7 @@ class ImageStorage {
12877
12903
  this.indexPath = import_node_path26.join(dir, INDEX_FILE2);
12878
12904
  }
12879
12905
  async init() {
12880
- import_node_fs29.mkdirSync(this.filesDir, { recursive: true });
12906
+ import_node_fs30.mkdirSync(this.filesDir, { recursive: true });
12881
12907
  this.loadIndex();
12882
12908
  this.logger.info(`图片存储已初始化: ${this.dir}(共 ${this.index.images.length} 条记录)`);
12883
12909
  }
@@ -12895,7 +12921,7 @@ class ImageStorage {
12895
12921
  return existing;
12896
12922
  }
12897
12923
  if (existing.localFile) {
12898
- import_node_fs29.rmSync(import_node_path26.join(this.dir, existing.localFile), { force: true });
12924
+ import_node_fs30.rmSync(import_node_path26.join(this.dir, existing.localFile), { force: true });
12899
12925
  }
12900
12926
  existing.metadata = metadata;
12901
12927
  existing.clientLabel = clientLabel;
@@ -12956,12 +12982,12 @@ class ImageStorage {
12956
12982
  return [...this.index.images].sort((a, b) => b.metadata.created_at.localeCompare(a.metadata.created_at));
12957
12983
  }
12958
12984
  loadIndex() {
12959
- if (!import_node_fs29.existsSync(this.indexPath)) {
12985
+ if (!import_node_fs30.existsSync(this.indexPath)) {
12960
12986
  this.index = { images: [] };
12961
12987
  return;
12962
12988
  }
12963
12989
  try {
12964
- const raw = JSON.parse(import_node_fs29.readFileSync(this.indexPath, "utf-8"));
12990
+ const raw = JSON.parse(import_node_fs30.readFileSync(this.indexPath, "utf-8"));
12965
12991
  this.index = raw && Array.isArray(raw.images) ? { images: raw.images } : { images: [] };
12966
12992
  } catch {
12967
12993
  this.logger.warn(`图片索引文件损坏,已重建: ${this.indexPath}`);
@@ -12969,12 +12995,12 @@ class ImageStorage {
12969
12995
  }
12970
12996
  }
12971
12997
  saveIndex() {
12972
- import_node_fs29.writeFileSync(this.indexPath, JSON.stringify(this.index, null, 2), "utf-8");
12998
+ import_node_fs30.writeFileSync(this.indexPath, JSON.stringify(this.index, null, 2), "utf-8");
12973
12999
  }
12974
13000
  async close() {}
12975
13001
  }
12976
13002
  // src/image/handler.ts
12977
- var import_node_fs30 = require("node:fs");
13003
+ var import_node_fs31 = require("node:fs");
12978
13004
  var import_node_path27 = require("node:path");
12979
13005
  var DEFAULT_IMAGE_MAX_BYTES = 20 * 1024 * 1024;
12980
13006
  var DOWNLOAD_TIMEOUT_MS = 5 * 60 * 1000;
@@ -13008,13 +13034,13 @@ async function runImageDownloadInBackground(imageId, metadata, storage2, maxByte
13008
13034
  logger.info(`[image-sync] 图片已同步: ${imageId} (${result.sizeBytes} bytes)`);
13009
13035
  }
13010
13036
  async function downloadImage(url, destPath, maxBytes, logger) {
13011
- import_node_fs30.mkdirSync(import_node_path27.dirname(destPath), { recursive: true });
13037
+ import_node_fs31.mkdirSync(import_node_path27.dirname(destPath), { recursive: true });
13012
13038
  const controller = new AbortController;
13013
13039
  const timer = setTimeout(() => controller.abort(), DOWNLOAD_TIMEOUT_MS);
13014
13040
  const cleanup = () => {
13015
13041
  try {
13016
- if (import_node_fs30.existsSync(destPath))
13017
- import_node_fs30.unlinkSync(destPath);
13042
+ if (import_node_fs31.existsSync(destPath))
13043
+ import_node_fs31.unlinkSync(destPath);
13018
13044
  } catch {}
13019
13045
  };
13020
13046
  try {
@@ -13029,7 +13055,7 @@ async function downloadImage(url, destPath, maxBytes, logger) {
13029
13055
  if (contentLength > 0 && contentLength > maxBytes) {
13030
13056
  return { ok: false, error: `图片超过上限 ${maxBytes} 字节` };
13031
13057
  }
13032
- const writeStream = import_node_fs30.createWriteStream(destPath);
13058
+ const writeStream = import_node_fs31.createWriteStream(destPath);
13033
13059
  let total = 0;
13034
13060
  try {
13035
13061
  for await (const chunk of res.body) {
@@ -13063,11 +13089,11 @@ async function downloadImage(url, destPath, maxBytes, logger) {
13063
13089
  }
13064
13090
  }
13065
13091
  // src/tunnel/service.ts
13066
- var import_node_fs32 = require("node:fs");
13092
+ var import_node_fs33 = require("node:fs");
13067
13093
  var import_node_path30 = require("node:path");
13068
13094
 
13069
13095
  // src/tunnel/relay-client.ts
13070
- var import_node_fs31 = require("node:fs");
13096
+ var import_node_fs32 = require("node:fs");
13071
13097
  var import_node_path28 = require("node:path");
13072
13098
 
13073
13099
  // node_modules/ws/wrapper.mjs
@@ -13184,8 +13210,8 @@ class RelayClient {
13184
13210
  lastDisconnectReason
13185
13211
  };
13186
13212
  try {
13187
- import_node_fs31.mkdirSync(import_node_path28.dirname(this.opts.statusFilePath), { recursive: true });
13188
- import_node_fs31.writeFileSync(this.opts.statusFilePath, JSON.stringify(info, null, 2));
13213
+ import_node_fs32.mkdirSync(import_node_path28.dirname(this.opts.statusFilePath), { recursive: true });
13214
+ import_node_fs32.writeFileSync(this.opts.statusFilePath, JSON.stringify(info, null, 2));
13189
13215
  } catch {}
13190
13216
  }
13191
13217
  onInbound(handler) {
@@ -15047,7 +15073,7 @@ function createTunnelService(opts) {
15047
15073
  }
15048
15074
  function readLockInfo(filePath) {
15049
15075
  try {
15050
- const parsed = JSON.parse(import_node_fs32.readFileSync(filePath, "utf-8"));
15076
+ const parsed = JSON.parse(import_node_fs33.readFileSync(filePath, "utf-8"));
15051
15077
  const pid = typeof parsed.pid === "number" ? parsed.pid : null;
15052
15078
  const updatedAtMs = typeof parsed.updatedAt === "string" ? Date.parse(parsed.updatedAt) : Number.NaN;
15053
15079
  return {
@@ -15080,7 +15106,7 @@ function createTunnelService(opts) {
15080
15106
  if (!filePath)
15081
15107
  return;
15082
15108
  try {
15083
- import_node_fs32.writeFileSync(filePath, buildLockPayload(), { mode: 384 });
15109
+ import_node_fs33.writeFileSync(filePath, buildLockPayload(), { mode: 384 });
15084
15110
  } catch {}
15085
15111
  }, intervalMs);
15086
15112
  lockRefreshTimer.unref?.();
@@ -15094,25 +15120,25 @@ function createTunnelService(opts) {
15094
15120
  lockStartedAt = null;
15095
15121
  if (fd !== null) {
15096
15122
  try {
15097
- import_node_fs32.closeSync(fd);
15123
+ import_node_fs33.closeSync(fd);
15098
15124
  } catch {}
15099
15125
  }
15100
15126
  if (filePath) {
15101
15127
  try {
15102
- import_node_fs32.unlinkSync(filePath);
15128
+ import_node_fs33.unlinkSync(filePath);
15103
15129
  } catch {}
15104
15130
  }
15105
15131
  }
15106
15132
  function acquireLock(filePath) {
15107
- import_node_fs32.mkdirSync(import_node_path30.dirname(filePath), { recursive: true });
15133
+ import_node_fs33.mkdirSync(import_node_path30.dirname(filePath), { recursive: true });
15108
15134
  const heartbeatSec = opts.heartbeatSec ?? DEFAULT_HEARTBEAT_SEC;
15109
15135
  const refreshMs = heartbeatSec * 1000 * LOCK_REFRESH_HEARTBEAT_MULTIPLIER;
15110
15136
  const staleMs = heartbeatSec * 1000 * LOCK_STALE_HEARTBEAT_MULTIPLIER;
15111
15137
  for (let attempt = 0;attempt < 2; attempt++) {
15112
15138
  try {
15113
15139
  lockStartedAt = new Date().toISOString();
15114
- const fd = import_node_fs32.openSync(filePath, "wx", 384);
15115
- import_node_fs32.writeFileSync(fd, buildLockPayload());
15140
+ const fd = import_node_fs33.openSync(filePath, "wx", 384);
15141
+ import_node_fs33.writeFileSync(fd, buildLockPayload());
15116
15142
  lockFilePath = filePath;
15117
15143
  lockFd = fd;
15118
15144
  startLockRefresh(refreshMs);
@@ -15130,7 +15156,7 @@ function createTunnelService(opts) {
15130
15156
  const staleReason = describeStaleLock(ownerPid, updatedAt, staleMs);
15131
15157
  opts.logger.warn(`Relay tunnel: removing stale local lock (${staleReason})`);
15132
15158
  try {
15133
- import_node_fs32.unlinkSync(filePath);
15159
+ import_node_fs33.unlinkSync(filePath);
15134
15160
  } catch {}
15135
15161
  continue;
15136
15162
  }
@@ -15379,7 +15405,7 @@ class ArkclawAuthProvider extends BaseApiKeyAuthProvider {
15379
15405
  // src/profile/auth/jvsclaw.ts
15380
15406
  var import_node_crypto6 = require("node:crypto");
15381
15407
  var import_node_os3 = __toESM(require("node:os"));
15382
- var import_node_fs33 = require("node:fs");
15408
+ var import_node_fs34 = require("node:fs");
15383
15409
  var import_node_path31 = require("node:path");
15384
15410
  var CLAW_CODE = "JvsClaw";
15385
15411
  var RETRY_BASE_MS = 2000;
@@ -15517,7 +15543,7 @@ class JvsclawAuthProvider extends BaseApiKeyAuthProvider {
15517
15543
  debounceTimer.unref?.();
15518
15544
  };
15519
15545
  try {
15520
- configWatcher = import_node_fs33.watch(configDir, { persistent: false }, (_event, changedName) => {
15546
+ configWatcher = import_node_fs34.watch(configDir, { persistent: false }, (_event, changedName) => {
15521
15547
  if (!changedName)
15522
15548
  return;
15523
15549
  const name = String(changedName);
@@ -15542,7 +15568,7 @@ function hashLinkSecret(value) {
15542
15568
  function readJvsclawLinkSecretFromConfigFile(configPath = resolveConfigPath()) {
15543
15569
  let config;
15544
15570
  try {
15545
- config = JSON.parse(import_node_fs33.readFileSync(configPath, "utf-8"));
15571
+ config = JSON.parse(import_node_fs34.readFileSync(configPath, "utf-8"));
15546
15572
  } catch {
15547
15573
  return;
15548
15574
  }
@@ -15656,7 +15682,7 @@ function readHostGatewayConfig(params) {
15656
15682
  let configData;
15657
15683
  if (configPath) {
15658
15684
  try {
15659
- configData = JSON.parse(import_node_fs34.readFileSync(configPath, "utf-8"));
15685
+ configData = JSON.parse(import_node_fs35.readFileSync(configPath, "utf-8"));
15660
15686
  } catch (err2) {
15661
15687
  if (err2?.code !== "ENOENT") {
15662
15688
  params.logger.warn(`Relay tunnel: 无法读取 gateway 鉴权配置 (${configPath})`);
@@ -16997,5 +17023,5 @@ var src_default = {
16997
17023
  }
16998
17024
  };
16999
17025
 
17000
- //# debugId=A049F0603517791A64756E2164756E21
17026
+ //# debugId=3838A06742EC9ED664756E2164756E21
17001
17027
  //# sourceMappingURL=index.cjs.map